Merge "content: Use Language::factory( 'en' ) instead of wfGetLangObj( 'en' )"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 18 Nov 2016 22:53:48 +0000 (22:53 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 18 Nov 2016 22:53:48 +0000 (22:53 +0000)
1082 files changed:
.eslintrc.json [new file with mode: 0644]
.gitreview
.jscsrc [deleted file]
.jshintignore [deleted file]
.jshintrc [deleted file]
.mailmap
.travis.yml
CREDITS
FAQ
Gruntfile.js
HISTORY
INSTALL
README
RELEASE-NOTES-1.28
RELEASE-NOTES-1.29 [new file with mode: 0644]
autoload.php
composer.json
docs/README
docs/extension.schema.json
docs/extension.schema.v1.json
docs/hooks.txt
includes/AjaxDispatcher.php
includes/AjaxResponse.php
includes/Block.php
includes/CategoryViewer.php
includes/DefaultSettings.php
includes/Defines.php
includes/EditPage.php
includes/Feed.php
includes/ForkController.php
includes/FormOptions.php
includes/GlobalFunctions.php
includes/Html.php
includes/HttpFunctions.php [deleted file]
includes/Linker.php
includes/MWGrants.php [new file with mode: 0644]
includes/MediaWiki.php
includes/MediaWikiServices.php
includes/MergeHistory.php
includes/Message.php
includes/MimeMagic.php
includes/MovePage.php
includes/OutputPage.php
includes/PHPVersionCheck.php
includes/PageProps.php
includes/Preferences.php
includes/PrefixSearch.php
includes/Revision.php
includes/Sanitizer.php
includes/ServiceWiring.php
includes/Setup.php
includes/Status.php
includes/TemplatesOnThisPageFormatter.php
includes/Title.php
includes/WatchedItemQueryService.php
includes/WatchedItemQueryServiceExtension.php [new file with mode: 0644]
includes/WatchedItemStore.php
includes/WebRequest.php
includes/WebRequestUpload.php
includes/Xml.php
includes/actions/HistoryAction.php
includes/actions/InfoAction.php
includes/actions/MarkpatrolledAction.php
includes/api/ApiAuthManagerHelper.php
includes/api/ApiBase.php
includes/api/ApiClearHasMsg.php
includes/api/ApiContinuationManager.php
includes/api/ApiFormatBase.php
includes/api/ApiHelp.php
includes/api/ApiHelpParamValueMessage.php
includes/api/ApiImageRotate.php
includes/api/ApiLogin.php
includes/api/ApiMain.php
includes/api/ApiPageSet.php
includes/api/ApiParse.php
includes/api/ApiQuery.php
includes/api/ApiQueryAllImages.php
includes/api/ApiQueryAllRevisions.php
includes/api/ApiQueryBase.php
includes/api/ApiQueryGeneratorBase.php
includes/api/ApiQueryMyStashedFiles.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiQueryRevisions.php
includes/api/ApiQuerySearch.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryTags.php
includes/api/ApiQueryUserContributions.php
includes/api/ApiQueryWatchlist.php
includes/api/ApiRsd.php
includes/api/ApiSetNotificationTimestamp.php
includes/api/ApiStashEdit.php
includes/api/i18n/ast.json
includes/api/i18n/be-tarask.json
includes/api/i18n/bg.json
includes/api/i18n/bn.json
includes/api/i18n/de.json
includes/api/i18n/diq.json
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/eu.json
includes/api/i18n/fr.json
includes/api/i18n/gl.json
includes/api/i18n/he.json
includes/api/i18n/id.json
includes/api/i18n/it.json
includes/api/i18n/ja.json
includes/api/i18n/ka.json [new file with mode: 0644]
includes/api/i18n/ko.json
includes/api/i18n/lb.json
includes/api/i18n/lt.json
includes/api/i18n/mr.json
includes/api/i18n/nl.json
includes/api/i18n/nso.json [new file with mode: 0644]
includes/api/i18n/oc.json
includes/api/i18n/pl.json
includes/api/i18n/pt.json
includes/api/i18n/qqq.json
includes/api/i18n/ru.json
includes/api/i18n/sv.json
includes/api/i18n/uk.json
includes/api/i18n/zh-hans.json
includes/api/i18n/zu.json [new file with mode: 0644]
includes/auth/AuthManager.php
includes/auth/LocalPasswordPrimaryAuthenticationProvider.php
includes/auth/TemporaryPasswordPrimaryAuthenticationProvider.php
includes/auth/Throttler.php
includes/cache/BacklinkCache.php
includes/cache/HTMLFileCache.php
includes/cache/MessageCache.php
includes/cache/UserCache.php
includes/cache/localisation/LCStoreCDB.php
includes/cache/localisation/LocalisationCache.php
includes/changes/RecentChange.php
includes/changetags/ChangeTags.php
includes/collation/Collation.php
includes/collation/IcuCollation.php
includes/collation/NumericUppercaseCollation.php
includes/compat/ScopedCallback.php [new file with mode: 0644]
includes/config/HashConfig.php
includes/content/ContentHandler.php
includes/content/WikiTextStructure.php
includes/context/RequestContext.php
includes/dao/DBAccessBase.php
includes/db/DatabaseMssql.php
includes/db/MWLBFactory.php [new file with mode: 0644]
includes/db/loadbalancer/LBFactoryMW.php [deleted file]
includes/debug/logger/LegacyLogger.php
includes/debug/logger/monolog/AvroFormatter.php
includes/deferred/DeferredUpdates.php
includes/deferred/LinksDeletionUpdate.php
includes/deferred/LinksUpdate.php
includes/deferred/SearchUpdate.php
includes/diff/DifferenceEngine.php
includes/diff/WordLevelDiff.php
includes/exception/MWException.php
includes/exception/MWExceptionHandler.php
includes/exception/MWExceptionRenderer.php
includes/exception/PermissionsError.php
includes/export/XmlDumpWriter.php
includes/filebackend/FileBackendGroup.php
includes/filebackend/lockmanager/MemcLockManager.php [deleted file]
includes/filebackend/lockmanager/MySqlLockManager.php
includes/filerepo/FileRepo.php
includes/filerepo/ForeignDBRepo.php
includes/filerepo/ForeignDBViaLBRepo.php
includes/filerepo/LocalRepo.php
includes/filerepo/file/File.php
includes/filerepo/file/ForeignDBFile.php
includes/filerepo/file/LocalFile.php
includes/filerepo/file/OldLocalFile.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormField.php
includes/htmlform/HTMLNestedFilterable.php
includes/htmlform/OOUIHTMLForm.php
includes/htmlform/VFormHTMLForm.php
includes/htmlform/fields/HTMLAutoCompleteSelectField.php
includes/htmlform/fields/HTMLCheckField.php
includes/htmlform/fields/HTMLCheckMatrix.php
includes/htmlform/fields/HTMLComboboxField.php
includes/htmlform/fields/HTMLDateTimeField.php
includes/htmlform/fields/HTMLFloatField.php
includes/htmlform/fields/HTMLHiddenField.php
includes/htmlform/fields/HTMLInfoField.php
includes/htmlform/fields/HTMLIntField.php
includes/htmlform/fields/HTMLMultiSelectField.php
includes/htmlform/fields/HTMLRadioField.php
includes/htmlform/fields/HTMLRestrictionsField.php
includes/htmlform/fields/HTMLSelectAndOtherField.php
includes/htmlform/fields/HTMLSelectField.php
includes/htmlform/fields/HTMLSelectLimitField.php
includes/htmlform/fields/HTMLSelectNamespace.php
includes/htmlform/fields/HTMLSelectOrOtherField.php
includes/htmlform/fields/HTMLSizeFilterField.php [new file with mode: 0644]
includes/htmlform/fields/HTMLSubmitField.php
includes/htmlform/fields/HTMLTagFilter.php
includes/htmlform/fields/HTMLTextAreaField.php
includes/htmlform/fields/HTMLTextField.php
includes/http/CurlHttpRequest.php [new file with mode: 0644]
includes/http/Http.php [new file with mode: 0644]
includes/http/MWHttpRequest.php [new file with mode: 0644]
includes/http/PhpHttpRequest.php [new file with mode: 0644]
includes/installer/DatabaseInstaller.php
includes/installer/DatabaseUpdater.php
includes/installer/Installer.php
includes/installer/MssqlInstaller.php
includes/installer/MssqlUpdater.php
includes/installer/MysqlInstaller.php
includes/installer/MysqlUpdater.php
includes/installer/OracleInstaller.php
includes/installer/OracleUpdater.php
includes/installer/PhpBugTests.php
includes/installer/PostgresInstaller.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteUpdater.php
includes/installer/i18n/ar.json
includes/installer/i18n/ast.json
includes/installer/i18n/be-tarask.json
includes/installer/i18n/bg.json
includes/installer/i18n/bn.json
includes/installer/i18n/cs.json
includes/installer/i18n/de.json
includes/installer/i18n/diq.json
includes/installer/i18n/en.json
includes/installer/i18n/es.json
includes/installer/i18n/et.json
includes/installer/i18n/fi.json
includes/installer/i18n/fr.json
includes/installer/i18n/gl.json
includes/installer/i18n/he.json
includes/installer/i18n/hu.json
includes/installer/i18n/ia.json
includes/installer/i18n/inh.json
includes/installer/i18n/it.json
includes/installer/i18n/ja.json
includes/installer/i18n/ko.json
includes/installer/i18n/lb.json
includes/installer/i18n/lt.json
includes/installer/i18n/lv.json
includes/installer/i18n/mai.json
includes/installer/i18n/mk.json
includes/installer/i18n/nb.json
includes/installer/i18n/ne.json
includes/installer/i18n/nl.json
includes/installer/i18n/nn.json
includes/installer/i18n/pl.json
includes/installer/i18n/pt.json
includes/installer/i18n/qqq.json
includes/installer/i18n/ru.json
includes/installer/i18n/sd.json
includes/installer/i18n/sl.json
includes/installer/i18n/sr-ec.json
includes/installer/i18n/sr-el.json
includes/installer/i18n/sv.json
includes/installer/i18n/uk.json
includes/installer/i18n/vi.json
includes/installer/i18n/zh-hans.json
includes/installer/i18n/zh-hant.json
includes/interwiki/InterwikiLookupAdapter.php [new file with mode: 0644]
includes/jobqueue/Job.php
includes/jobqueue/JobQueueDB.php
includes/jobqueue/JobRunner.php
includes/jobqueue/jobs/AssembleUploadChunksJob.php
includes/jobqueue/jobs/PublishStashedFileJob.php
includes/json/FormatJson.php
includes/libs/CSSMin.php
includes/libs/CryptHKDF.php [new file with mode: 0644]
includes/libs/CryptRand.php [new file with mode: 0644]
includes/libs/IEContentAnalyzer.php [deleted file]
includes/libs/MWCryptHash.php [new file with mode: 0644]
includes/libs/MemoizedCallable.php
includes/libs/MultiHttpClient.php
includes/libs/ScopedCallback.php [deleted file]
includes/libs/StatusValue.php
includes/libs/Timing.php
includes/libs/WaitConditionLoop.php [deleted file]
includes/libs/XmlTypeCheck.php [deleted file]
includes/libs/composer/ComposerJson.php
includes/libs/composer/ComposerLock.php
includes/libs/filebackend/FSFile.php [deleted file]
includes/libs/filebackend/FileBackend.php
includes/libs/filebackend/FileBackendMultiWrite.php
includes/libs/filebackend/FileBackendStore.php
includes/libs/filebackend/SwiftFileBackend.php
includes/libs/filebackend/TempFSFile.php [deleted file]
includes/libs/filebackend/fsfile/FSFile.php [new file with mode: 0644]
includes/libs/filebackend/fsfile/TempFSFile.php [new file with mode: 0644]
includes/libs/iterators/IteratorDecorator.php [new file with mode: 0644]
includes/libs/iterators/NotRecursiveIterator.php [new file with mode: 0644]
includes/libs/jsminplus.php
includes/libs/lockmanager/DBLockManager.php
includes/libs/lockmanager/LockManager.php
includes/libs/lockmanager/MemcLockManager.php [new file with mode: 0644]
includes/libs/lockmanager/QuorumLockManager.php
includes/libs/lockmanager/RedisLockManager.php
includes/libs/mime/IEContentAnalyzer.php [new file with mode: 0644]
includes/libs/mime/MimeAnalyzer.php [new file with mode: 0644]
includes/libs/mime/XmlTypeCheck.php [new file with mode: 0644]
includes/libs/mime/defines.php [new file with mode: 0644]
includes/libs/mime/mime.info [new file with mode: 0644]
includes/libs/mime/mime.types [new file with mode: 0644]
includes/libs/objectcache/APCBagOStuff.php
includes/libs/objectcache/APCUBagOStuff.php [new file with mode: 0644]
includes/libs/objectcache/BagOStuff.php
includes/libs/objectcache/MemcachedBagOStuff.php
includes/libs/objectcache/WANObjectCache.php
includes/libs/objectcache/WinCacheBagOStuff.php
includes/libs/rdbms/ChronologyProtector.php [new file with mode: 0644]
includes/libs/rdbms/TransactionProfiler.php
includes/libs/rdbms/chronologyprotector/ChronologyProtector.php [deleted file]
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseBase.php [deleted file]
includes/libs/rdbms/database/DatabaseDomain.php
includes/libs/rdbms/database/DatabaseMysqlBase.php
includes/libs/rdbms/database/DatabaseMysqli.php
includes/libs/rdbms/database/DatabasePostgres.php
includes/libs/rdbms/database/DatabaseSqlite.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/database/IMaintainableDatabase.php
includes/libs/rdbms/database/position/MySQLMasterPos.php
includes/libs/rdbms/database/utils/SavepointPostgres.php
includes/libs/rdbms/exception/DBAccessError.php
includes/libs/rdbms/field/PostgresField.php
includes/libs/rdbms/lbfactory/ILBFactory.php
includes/libs/rdbms/lbfactory/LBFactory.php
includes/libs/rdbms/lbfactory/LBFactoryMulti.php
includes/libs/rdbms/lbfactory/LBFactorySimple.php
includes/libs/rdbms/lbfactory/LBFactorySingle.php
includes/libs/rdbms/loadbalancer/ILoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancerSingle.php
includes/libs/rdbms/loadmonitor/ILoadMonitor.php
includes/libs/rdbms/loadmonitor/LoadMonitor.php
includes/libs/rdbms/loadmonitor/LoadMonitorMySQL.php
includes/libs/rdbms/loadmonitor/LoadMonitorNull.php
includes/libs/time/ConvertibleTimestamp.php
includes/libs/virtualrest/ParsoidVirtualRESTService.php
includes/libs/virtualrest/RestbaseVirtualRESTService.php
includes/libs/xmp/XMP.php
includes/mail/UserMailer.php
includes/media/DjVuImage.php
includes/media/FormatMetadata.php
includes/media/JpegMetadataExtractor.php
includes/media/MediaHandler.php
includes/media/PNGMetadataExtractor.php
includes/media/SVG.php
includes/media/SVGMetadataExtractor.php
includes/media/TransformationalImageHandler.php
includes/media/XCF.php
includes/mime.info [deleted file]
includes/mime.types [deleted file]
includes/objectcache/ObjectCache.php
includes/page/Article.php
includes/page/CategoryPage.php
includes/page/ImagePage.php
includes/page/WikiFilePage.php
includes/page/WikiPage.php
includes/pager/ReverseChronologicalPager.php
includes/pager/TablePager.php
includes/parser/LinkHolderArray.php
includes/parser/Parser.php
includes/parser/ParserOptions.php
includes/parser/ParserOutput.php
includes/password/EncryptedPassword.php
includes/password/MWOldPassword.php
includes/profiler/Profiler.php
includes/profiler/SectionProfiler.php
includes/registration/ExtensionProcessor.php
includes/registration/ExtensionRegistry.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderClientHtml.php
includes/resourceloader/ResourceLoaderContext.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderLanguageDataModule.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/search/SearchEngine.php
includes/search/SearchPostgres.php
includes/session/PHPSessionHandler.php
includes/session/Session.php
includes/session/SessionBackend.php
includes/session/SessionManager.php
includes/site/DBSiteStore.php
includes/skins/BaseTemplate.php
includes/skins/Skin.php
includes/skins/SkinTemplate.php
includes/specialpage/FormSpecialPage.php
includes/specialpage/LoginSignupSpecialPage.php
includes/specialpage/PageQueryPage.php
includes/specialpage/QueryPage.php
includes/specialpage/SpecialPageFactory.php
includes/specialpage/WantedQueryPage.php
includes/specials/SpecialActiveusers.php
includes/specials/SpecialAncientpages.php
includes/specials/SpecialBlockList.php
includes/specials/SpecialBooksources.php
includes/specials/SpecialBotPasswords.php
includes/specials/SpecialBrokenRedirects.php
includes/specials/SpecialConfirmemail.php
includes/specials/SpecialContributions.php
includes/specials/SpecialEditWatchlist.php
includes/specials/SpecialEmailInvalidate.php
includes/specials/SpecialImport.php
includes/specials/SpecialLinkSearch.php
includes/specials/SpecialListDuplicatedFiles.php
includes/specials/SpecialMIMEsearch.php
includes/specials/SpecialMediaStatistics.php
includes/specials/SpecialMostcategories.php
includes/specials/SpecialMostinterwikis.php
includes/specials/SpecialMostlinked.php
includes/specials/SpecialMostlinkedcategories.php
includes/specials/SpecialMostlinkedtemplates.php
includes/specials/SpecialMovepage.php
includes/specials/SpecialNewpages.php [changed mode: 0644->0755]
includes/specials/SpecialPasswordReset.php
includes/specials/SpecialRevisiondelete.php
includes/specials/SpecialSearch.php
includes/specials/SpecialShortpages.php
includes/specials/SpecialTags.php
includes/specials/SpecialTrackingCategories.php
includes/specials/SpecialUnusedcategories.php
includes/specials/SpecialUnwatchedpages.php
includes/specials/SpecialUploadStash.php
includes/specials/SpecialWantedpages.php
includes/specials/SpecialWatchlist.php
includes/specials/pagers/ActiveUsersPager.php
includes/specials/pagers/NewPagesPager.php
includes/tidy/Balancer.php
includes/tidy/RaggettInternalPHP.php
includes/upload/UploadBase.php
includes/upload/UploadStash.php
includes/user/BotPassword.php
includes/user/PasswordReset.php
includes/user/User.php
includes/utils/AutoloadGenerator.php
includes/utils/BatchRowIterator.php
includes/utils/BatchRowUpdate.php
includes/utils/MWCryptHKDF.php
includes/utils/MWCryptHash.php [deleted file]
includes/utils/MWCryptRand.php
includes/utils/MWGrants.php [deleted file]
includes/utils/UIDGenerator.php
includes/utils/iterators/IteratorDecorator.php [deleted file]
includes/utils/iterators/NotRecursiveIterator.php [deleted file]
includes/widget/AUTHORS.txt
includes/widget/DateInputWidget.php [new file with mode: 0644]
languages/Language.php
languages/LanguageConverter.php
languages/classes/LanguageIu.php
languages/classes/LanguageRu.php
languages/classes/LanguageShi.php
languages/classes/LanguageSr.php
languages/classes/LanguageTr.php
languages/classes/LanguageZh.php
languages/classes/data/grammar.ru.json [deleted file]
languages/data/Names.php
languages/data/grammarTransformations/ru.json [new file with mode: 0644]
languages/i18n/ace.json
languages/i18n/ady-cyrl.json
languages/i18n/aeb-arab.json
languages/i18n/af.json
languages/i18n/aln.json
languages/i18n/am.json
languages/i18n/an.json
languages/i18n/ang.json
languages/i18n/anp.json
languages/i18n/ar.json
languages/i18n/arc.json
languages/i18n/arn.json
languages/i18n/arq.json
languages/i18n/ary.json
languages/i18n/arz.json
languages/i18n/as.json
languages/i18n/ase.json
languages/i18n/ast.json
languages/i18n/av.json
languages/i18n/avk.json
languages/i18n/awa.json
languages/i18n/az.json
languages/i18n/azb.json
languages/i18n/ba.json
languages/i18n/ban.json
languages/i18n/bar.json
languages/i18n/bcc.json
languages/i18n/bcl.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bg.json
languages/i18n/bgn.json
languages/i18n/bho.json
languages/i18n/bjn.json
languages/i18n/bn.json
languages/i18n/bo.json
languages/i18n/bpy.json
languages/i18n/bqi.json
languages/i18n/br.json
languages/i18n/bs.json
languages/i18n/bto.json
languages/i18n/ca.json
languages/i18n/cdo.json
languages/i18n/ce.json
languages/i18n/ceb.json
languages/i18n/ch.json
languages/i18n/ckb.json
languages/i18n/co.json
languages/i18n/cps.json
languages/i18n/crh-cyrl.json
languages/i18n/crh-latn.json
languages/i18n/cs.json
languages/i18n/csb.json
languages/i18n/cv.json
languages/i18n/cy.json
languages/i18n/da.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/dsb.json
languages/i18n/dtp.json
languages/i18n/dty.json
languages/i18n/dv.json
languages/i18n/egl.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/ext.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fo.json
languages/i18n/fr.json
languages/i18n/frc.json
languages/i18n/frp.json
languages/i18n/frr.json
languages/i18n/fur.json
languages/i18n/fy.json
languages/i18n/ga.json
languages/i18n/gag.json
languages/i18n/gan-hans.json
languages/i18n/gan-hant.json
languages/i18n/gd.json
languages/i18n/gl.json
languages/i18n/glk.json
languages/i18n/gom-deva.json
languages/i18n/gom-latn.json
languages/i18n/gor.json
languages/i18n/got.json
languages/i18n/grc.json
languages/i18n/gsw.json
languages/i18n/gu.json
languages/i18n/gv.json
languages/i18n/hak.json
languages/i18n/haw.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hif-latn.json
languages/i18n/hil.json
languages/i18n/hr.json
languages/i18n/hrx.json
languages/i18n/hsb.json
languages/i18n/ht.json
languages/i18n/hu.json
languages/i18n/hy.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/ie.json
languages/i18n/ig.json
languages/i18n/ilo.json
languages/i18n/inh.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jam.json
languages/i18n/jut.json
languages/i18n/jv.json
languages/i18n/ka.json
languages/i18n/kaa.json
languages/i18n/kab.json
languages/i18n/kbd-cyrl.json
languages/i18n/khw.json
languages/i18n/kk-arab.json
languages/i18n/kk-cyrl.json
languages/i18n/kk-latn.json
languages/i18n/km.json
languages/i18n/kn.json
languages/i18n/ko.json
languages/i18n/krc.json
languages/i18n/ksh.json
languages/i18n/ku-latn.json
languages/i18n/kw.json
languages/i18n/ky.json
languages/i18n/la.json
languages/i18n/lad.json
languages/i18n/lb.json
languages/i18n/lez.json
languages/i18n/lfn.json
languages/i18n/lg.json
languages/i18n/li.json
languages/i18n/lij.json
languages/i18n/liv.json
languages/i18n/lki.json
languages/i18n/lmo.json
languages/i18n/lo.json
languages/i18n/loz.json
languages/i18n/lrc.json
languages/i18n/lt.json
languages/i18n/ltg.json
languages/i18n/lus.json
languages/i18n/lv.json
languages/i18n/lzh.json
languages/i18n/lzz.json
languages/i18n/mai.json
languages/i18n/map-bms.json
languages/i18n/mdf.json
languages/i18n/mg.json
languages/i18n/mhr.json
languages/i18n/min.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/mn.json
languages/i18n/mr.json
languages/i18n/ms.json
languages/i18n/mt.json
languages/i18n/mwl.json
languages/i18n/my.json
languages/i18n/myv.json
languages/i18n/mzn.json
languages/i18n/nah.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/nso.json
languages/i18n/oc.json
languages/i18n/olo.json
languages/i18n/or.json
languages/i18n/os.json
languages/i18n/pa.json
languages/i18n/pam.json
languages/i18n/pcd.json
languages/i18n/pdc.json
languages/i18n/pfl.json
languages/i18n/pl.json
languages/i18n/pms.json
languages/i18n/pnb.json
languages/i18n/pnt.json
languages/i18n/prg.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/qu.json
languages/i18n/qug.json
languages/i18n/rm.json
languages/i18n/ro.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/rue.json
languages/i18n/sa.json
languages/i18n/sah.json
languages/i18n/sat.json
languages/i18n/sc.json
languages/i18n/scn.json
languages/i18n/sco.json
languages/i18n/sd.json
languages/i18n/sdc.json
languages/i18n/sdh.json
languages/i18n/se.json
languages/i18n/sei.json
languages/i18n/ses.json
languages/i18n/sgs.json
languages/i18n/sh.json
languages/i18n/shi.json
languages/i18n/shn.json
languages/i18n/si.json
languages/i18n/sk.json
languages/i18n/sl.json
languages/i18n/sli.json
languages/i18n/so.json
languages/i18n/sq.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/srn.json
languages/i18n/stq.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/sw.json
languages/i18n/szl.json
languages/i18n/ta.json
languages/i18n/tcy.json
languages/i18n/te.json
languages/i18n/tet.json
languages/i18n/tg-cyrl.json
languages/i18n/tg-latn.json
languages/i18n/th.json
languages/i18n/tk.json
languages/i18n/tl.json
languages/i18n/tly.json
languages/i18n/to.json
languages/i18n/tpi.json
languages/i18n/tr.json
languages/i18n/tru.json
languages/i18n/ts.json
languages/i18n/tt-cyrl.json
languages/i18n/tt-latn.json
languages/i18n/tyv.json
languages/i18n/udm.json
languages/i18n/ug-arab.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/uz.json
languages/i18n/vec.json
languages/i18n/vep.json
languages/i18n/vi.json
languages/i18n/vmf.json
languages/i18n/vo.json
languages/i18n/vot.json
languages/i18n/vro.json
languages/i18n/wa.json
languages/i18n/war.json
languages/i18n/wo.json
languages/i18n/wuu.json
languages/i18n/xal.json
languages/i18n/xmf.json
languages/i18n/yi.json
languages/i18n/yo.json
languages/i18n/yue.json
languages/i18n/zea.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/messages/MessagesBn.php
languages/messages/MessagesCdo.php
languages/messages/MessagesKn.php
languages/messages/MessagesKrl.php [new file with mode: 0644]
languages/messages/MessagesNn.php
languages/messages/MessagesOlo.php
languages/messages/MessagesSk.php
load.php
maintenance/Doxyfile
maintenance/Maintenance.php
maintenance/addRFCandPMIDInterwiki.php [new file with mode: 0644]
maintenance/archives/patch-change_tag-ct_id.sql [new file with mode: 0644]
maintenance/archives/patch-img_media_type.sql
maintenance/archives/patch-rc_ip_modify.sql [new file with mode: 0644]
maintenance/archives/patch-tag_summary-ts_id.sql [new file with mode: 0644]
maintenance/archives/upgradeLogging.php
maintenance/benchmarks/bench_delete_truncate.php
maintenance/checkComposerLockUpToDate.php
maintenance/cleanupUploadStash.php
maintenance/convertUserOptions.php
maintenance/createCommonPasswordCdb.php
maintenance/deleteOrphanedRevisions.php
maintenance/dev/includes/router.php
maintenance/doMaintenance.php
maintenance/dumpIterator.php
maintenance/dumpTextPass.php
maintenance/fetchText.php
maintenance/findHooks.php
maintenance/findMissingFiles.php
maintenance/findOrphanedFiles.php
maintenance/getLagTimes.php
maintenance/interwiki.list
maintenance/interwiki.sql
maintenance/jsduck/categories.json
maintenance/jsduck/external.js
maintenance/lag.php
maintenance/language/digit2html.php
maintenance/mssql/archives/patch-change_tag-ct_id.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-tag_summary-ts_id.sql [new file with mode: 0644]
maintenance/mssql/tables.sql
maintenance/mwdoc-filter.php
maintenance/namespaceDupes.php
maintenance/oracle/archives/patch-change_tag-ct_id.sql [new file with mode: 0644]
maintenance/oracle/archives/patch-tag_summary-ts_id.sql [new file with mode: 0644]
maintenance/oracle/tables.sql
maintenance/orphans.php
maintenance/populateContentModel.php
maintenance/populateRecentChangesSource.php
maintenance/postgres/tables.sql
maintenance/purgeChangedFiles.php
maintenance/purgeParserCache.php
maintenance/rebuildImages.php
maintenance/rebuildLocalisationCache.php
maintenance/rebuildtextindex.php
maintenance/refreshImageMetadata.php
maintenance/runBatchedQuery.php
maintenance/sql.php
maintenance/sqlite/archives/patch-change_tag-ct_id.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-tag_summary-ts_id.sql [new file with mode: 0644]
maintenance/sqlite/archives/searchindex-fts3.sql
maintenance/storage/recompressTracked.php
maintenance/tables.sql
maintenance/update.php
maintenance/updateCollation.php
maintenance/updateCredits.php [new file with mode: 0644]
maintenance/validateRegistrationFile.php
maintenance/wrapOldPasswords.php
package.json
resources/Resources.php
resources/lib/oojs-ui/i18n/ar.json
resources/lib/oojs-ui/i18n/bg.json
resources/lib/oojs-ui/i18n/da.json
resources/lib/oojs-ui/i18n/mr.json
resources/lib/oojs-ui/i18n/nds.json
resources/lib/oojs-ui/i18n/tr.json
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/bigger-ltr.png
resources/lib/oojs-ui/themes/apex/images/icons/bigger-ltr.svg
resources/lib/oojs-ui/themes/apex/images/icons/bigger-rtl.png
resources/lib/oojs-ui/themes/apex/images/icons/bigger-rtl.svg
resources/lib/oojs-ui/themes/apex/images/icons/smaller-ltr.png
resources/lib/oojs-ui/themes/apex/images/icons/smaller-ltr.svg
resources/lib/oojs-ui/themes/apex/images/icons/smaller-rtl.png
resources/lib/oojs-ui/themes/apex/images/icons/smaller-rtl.svg
resources/lib/oojs-ui/themes/mediawiki/icons-media.json
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-ltr-invert.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-ltr-progressive.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-ltr-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-ltr.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-ltr.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-rtl-invert.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-rtl-progressive.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-rtl-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-rtl.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-rtl.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-ltr-invert.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-ltr-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-ltr-progressive.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-ltr-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-ltr.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-ltr.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-rtl-invert.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-rtl-invert.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-rtl-progressive.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-rtl-progressive.svg
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-rtl.png
resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-rtl.svg
resources/src/jquery/jquery.accessKeyLabel.js
resources/src/jquery/jquery.autoEllipsis.js
resources/src/jquery/jquery.byteLimit.js
resources/src/jquery/jquery.color.js
resources/src/jquery/jquery.colorUtil.js
resources/src/jquery/jquery.confirmable.js
resources/src/jquery/jquery.expandableField.js
resources/src/jquery/jquery.hidpi.js
resources/src/jquery/jquery.highlightText.js
resources/src/jquery/jquery.localize.js
resources/src/jquery/jquery.makeCollapsible.js
resources/src/jquery/jquery.mwExtension.js
resources/src/jquery/jquery.placeholder.js
resources/src/jquery/jquery.qunit.completenessTest.js
resources/src/jquery/jquery.spinner.js
resources/src/jquery/jquery.suggestions.js
resources/src/jquery/jquery.tablesorter.js
resources/src/jquery/jquery.textSelection.js
resources/src/mediawiki.action/mediawiki.action.edit.preview.js
resources/src/mediawiki.action/mediawiki.action.edit.stash.js
resources/src/mediawiki.action/mediawiki.action.history.js
resources/src/mediawiki.action/mediawiki.action.view.dblClickEdit.js
resources/src/mediawiki.action/mediawiki.action.view.metadata.js
resources/src/mediawiki.action/mediawiki.action.view.redirect.js
resources/src/mediawiki.language/languages/ga.js
resources/src/mediawiki.language/languages/he.js
resources/src/mediawiki.language/languages/hy.js
resources/src/mediawiki.language/languages/ru.js
resources/src/mediawiki.language/mediawiki.language.js
resources/src/mediawiki.language/mediawiki.language.numbers.js
resources/src/mediawiki.legacy/commonPrint.css
resources/src/mediawiki.legacy/oldshared.css
resources/src/mediawiki.legacy/protect.js
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.legacy/wikibits.js
resources/src/mediawiki.less/mediawiki.ui/mixins.less
resources/src/mediawiki.less/mediawiki.ui/variables.less
resources/src/mediawiki.messagePoster/mediawiki.messagePoster.MessagePoster.js
resources/src/mediawiki.messagePoster/mediawiki.messagePoster.WikitextMessagePoster.js
resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js
resources/src/mediawiki.skinning/content.css
resources/src/mediawiki.skinning/elements.css
resources/src/mediawiki.special/mediawiki.special.apisandbox.css
resources/src/mediawiki.special/mediawiki.special.apisandbox.js
resources/src/mediawiki.special/mediawiki.special.edittags.js
resources/src/mediawiki.special/mediawiki.special.search.styles.css
resources/src/mediawiki.special/mediawiki.special.upload.js
resources/src/mediawiki.toolbar/toolbar.js
resources/src/mediawiki.ui/components/anchors.less
resources/src/mediawiki.ui/components/buttons.less
resources/src/mediawiki.ui/components/forms.less
resources/src/mediawiki.ui/components/inputs.less
resources/src/mediawiki.ui/components/text.less
resources/src/mediawiki.widgets.datetime/CalendarWidget.js
resources/src/mediawiki.widgets.datetime/DateTimeFormatter.js
resources/src/mediawiki.widgets.datetime/DateTimeInputWidget.js
resources/src/mediawiki.widgets.datetime/DiscordianDateTimeFormatter.js
resources/src/mediawiki.widgets.datetime/ProlepticGregorianDateTimeFormatter.js
resources/src/mediawiki.widgets/mw.widgets.CalendarWidget.js
resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js
resources/src/mediawiki.widgets/mw.widgets.CategorySelector.js
resources/src/mediawiki.widgets/mw.widgets.ComplexTitleInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.DateInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.NamespaceInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.SearchInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.TitleSearchWidget.js
resources/src/mediawiki.widgets/mw.widgets.TitleWidget.js
resources/src/mediawiki.widgets/mw.widgets.UserInputWidget.js
resources/src/mediawiki/ForeignApi.js
resources/src/mediawiki/api.js
resources/src/mediawiki/api/edit.js
resources/src/mediawiki/api/parse.js
resources/src/mediawiki/api/upload.js
resources/src/mediawiki/api/watch.js
resources/src/mediawiki/htmlform/hide-if.js
resources/src/mediawiki/htmlform/htmlform.Element.js
resources/src/mediawiki/htmlform/multiselect.js
resources/src/mediawiki/htmlform/ooui.styles.css
resources/src/mediawiki/mediawiki.ForeignStructuredUpload.BookletLayout.js
resources/src/mediawiki/mediawiki.ForeignStructuredUpload.js
resources/src/mediawiki/mediawiki.ForeignUpload.js
resources/src/mediawiki/mediawiki.Title.js
resources/src/mediawiki/mediawiki.Upload.BookletLayout.js
resources/src/mediawiki/mediawiki.Upload.Dialog.js
resources/src/mediawiki/mediawiki.Upload.js
resources/src/mediawiki/mediawiki.Uri.js
resources/src/mediawiki/mediawiki.checkboxtoggle.js
resources/src/mediawiki/mediawiki.confirmCloseWindow.js
resources/src/mediawiki/mediawiki.debug.js
resources/src/mediawiki/mediawiki.errorLogger.js
resources/src/mediawiki/mediawiki.experiments.js
resources/src/mediawiki/mediawiki.feedback.js
resources/src/mediawiki/mediawiki.filewarning.js
resources/src/mediawiki/mediawiki.inspect.js
resources/src/mediawiki/mediawiki.jqueryMsg.js
resources/src/mediawiki/mediawiki.js
resources/src/mediawiki/mediawiki.log.js
resources/src/mediawiki/mediawiki.notification.js
resources/src/mediawiki/mediawiki.searchSuggest.js
resources/src/mediawiki/mediawiki.storage.js
resources/src/mediawiki/mediawiki.template.mustache.js
resources/src/mediawiki/mediawiki.toc.js
resources/src/mediawiki/mediawiki.user.blockcookie.js [new file with mode: 0644]
resources/src/mediawiki/mediawiki.user.js
resources/src/mediawiki/mediawiki.util.js
resources/src/mediawiki/mediawiki.viewport.js
resources/src/mediawiki/page/gallery-slideshow.js
resources/src/mediawiki/page/image-pagination.js
resources/src/mediawiki/page/patrol.ajax.js
resources/src/mediawiki/page/rollback.js
resources/src/mediawiki/page/startup.js
resources/src/moment-dmy.js
resources/src/moment-locale-overrides.js
resources/src/oojs-ui-local.js
resources/src/polyfill-nodeTypes.js
resources/src/startup.js
tests/common/TestSetup.php
tests/common/TestsAutoLoader.php
tests/parser/ParserTestMockParser.php [new file with mode: 0644]
tests/parser/ParserTestRunner.php
tests/parser/TestFileEditor.php [new file with mode: 0644]
tests/parser/TestFileReader.php
tests/parser/TestRecorder.php
tests/parser/editTests.php [new file with mode: 0644]
tests/parser/fuzzTest.php
tests/parser/parserTests.php
tests/parser/parserTests.txt
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/ResourceLoaderTestCase.php
tests/phpunit/data/upload/buggynamespace-bad.svg [new file with mode: 0644]
tests/phpunit/data/upload/buggynamespace-evilhtml.svg [new file with mode: 0644]
tests/phpunit/data/upload/buggynamespace-okay.svg [new file with mode: 0644]
tests/phpunit/data/upload/buggynamespace-okay2.svg [new file with mode: 0644]
tests/phpunit/data/upload/buggynamespace-original.svg [new file with mode: 0644]
tests/phpunit/includes/FormOptionsTest.php
tests/phpunit/includes/GitInfoTest.php
tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php
tests/phpunit/includes/HtmlTest.php
tests/phpunit/includes/HttpTest.php
tests/phpunit/includes/LinkFilterTest.php
tests/phpunit/includes/MediaWikiServicesTest.php
tests/phpunit/includes/MediaWikiTest.php
tests/phpunit/includes/MessageTest.php
tests/phpunit/includes/MimeMagicTest.php [deleted file]
tests/phpunit/includes/PagePropsTest.php
tests/phpunit/includes/SampleTest.php
tests/phpunit/includes/SanitizerTest.php
tests/phpunit/includes/TemplateCategoriesTest.php
tests/phpunit/includes/WatchedItemQueryServiceUnitTest.php
tests/phpunit/includes/WatchedItemStoreUnitTest.php
tests/phpunit/includes/XmlSelectTest.php
tests/phpunit/includes/api/ApiContinuationManagerTest.php
tests/phpunit/includes/api/ApiLoginTest.php
tests/phpunit/includes/api/ApiMainTest.php
tests/phpunit/includes/api/ApiMessageTest.php
tests/phpunit/includes/api/ApiQueryWatchlistRawIntegrationTest.php
tests/phpunit/includes/api/ApiResultTest.php
tests/phpunit/includes/api/ApiRevisionDeleteTest.php
tests/phpunit/includes/auth/AuthManagerTest.php
tests/phpunit/includes/auth/CheckBlocksSecondaryAuthenticationProviderTest.php
tests/phpunit/includes/auth/EmailNotificationSecondaryAuthenticationProviderTest.php
tests/phpunit/includes/auth/LocalPasswordPrimaryAuthenticationProviderTest.php
tests/phpunit/includes/auth/TemporaryPasswordPrimaryAuthenticationProviderTest.php
tests/phpunit/includes/auth/ThrottlerTest.php
tests/phpunit/includes/auth/UserDataAuthenticationRequestTest.php
tests/phpunit/includes/changes/RecentChangeTest.php
tests/phpunit/includes/db/LBFactoryTest.php
tests/phpunit/includes/exception/MWExceptionTest.php
tests/phpunit/includes/htmlform/HTMLAutoCompleteSelectFieldTest.php
tests/phpunit/includes/installer/DatabaseUpdaterTest.php
tests/phpunit/includes/interwiki/InterwikiLookupAdapterTest.php [new file with mode: 0644]
tests/phpunit/includes/json/FormatJsonTest.php
tests/phpunit/includes/libs/CSSMinTest.php
tests/phpunit/includes/libs/MemoizedCallableTest.php
tests/phpunit/includes/libs/WaitConditionLoopTest.php [deleted file]
tests/phpunit/includes/libs/composer/ComposerJsonTest.php
tests/phpunit/includes/libs/composer/ComposerLockTest.php
tests/phpunit/includes/libs/mime/MimeAnalyzerTest.php [new file with mode: 0644]
tests/phpunit/includes/libs/objectcache/BagOStuffTest.php
tests/phpunit/includes/libs/objectcache/WANObjectCacheTest.php
tests/phpunit/includes/linker/LinkRendererTest.php
tests/phpunit/includes/media/ExifBitmapTest.php
tests/phpunit/includes/page/WikiCategoryPageTest.php
tests/phpunit/includes/page/WikiPageTest.php
tests/phpunit/includes/parser/ParserIntegrationTest.php
tests/phpunit/includes/parser/PreprocessorTest.php
tests/phpunit/includes/registration/ExtensionRegistryTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderClientHtmlTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderStartUpModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderWikiModuleTest.php
tests/phpunit/includes/session/PHPSessionHandlerTest.php
tests/phpunit/includes/session/SessionBackendTest.php
tests/phpunit/includes/session/SessionManagerTest.php
tests/phpunit/includes/session/SessionProviderTest.php
tests/phpunit/includes/session/SessionTest.php
tests/phpunit/includes/session/TestUtils.php
tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php
tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php
tests/phpunit/includes/specials/SpecialBooksourcesTest.php
tests/phpunit/includes/upload/UploadBaseTest.php
tests/phpunit/includes/user/BotPasswordTest.php
tests/phpunit/includes/user/UserTest.php
tests/phpunit/includes/utils/BatchRowUpdateTest.php
tests/phpunit/includes/utils/MWCryptHKDFTest.php
tests/phpunit/languages/classes/LanguageTrTest.php
tests/phpunit/mocks/media/MockDjVuHandler.php
tests/phpunit/structure/ApiDocumentationTest.php
tests/phpunit/structure/ExtensionJsonValidationTest.php
tests/phpunit/structure/ResourcesTest.php
tests/phpunit/suite.xml
tests/phpunit/suites/ParserTestTopLevelSuite.php
tests/phpunit/tests/MediaWikiTestCaseTest.php
tests/qunit/data/defineCallMwLoaderTestCallback.js
tests/qunit/data/requireCallMwLoaderTestCallback.js
tests/qunit/data/testrunner.js
tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js
tests/qunit/suites/resources/startup.test.js

diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644 (file)
index 0000000..044dd72
--- /dev/null
@@ -0,0 +1,18 @@
+{
+       "extends": "wikimedia",
+       "env": {
+               "browser": true,
+               "jquery": true,
+               "qunit": true
+       },
+       "globals": {
+               "require": false,
+               "module": false,
+               "mediaWiki": false,
+               "mwPerformance": false,
+               "OO": false
+       },
+       "rules": {
+               "dot-notation": 0
+       }
+}
index 0ec44b8..148be02 100644 (file)
@@ -2,5 +2,5 @@
 host=gerrit.wikimedia.org
 port=29418
 project=mediawiki/core.git
-defaultbranch=master
+track=1
 defaultrebase=0
diff --git a/.jscsrc b/.jscsrc
deleted file mode 100644 (file)
index 3f7e90d..0000000
--- a/.jscsrc
+++ /dev/null
@@ -1,36 +0,0 @@
-{
-       "preset": "wikimedia",
-       "es3": true,
-
-       "requireVarDeclFirst": null,
-
-       "requireDotNotation": { "allExcept": [ "keywords" ] },
-       "jsDoc": {
-               "checkAnnotations": {
-                       "preset": "jsduck5",
-                       "extra": {
-                               "context": "some",
-                               "see": "some"
-                       }
-               },
-               "checkParamNames": true,
-               "checkRedundantAccess": true,
-               "checkRedundantReturns": true,
-               "checkTypes": "strictNativeCase",
-               "requireNewlineAfterDescription": true,
-               "requireParamTypes": true,
-               "requireReturnTypes": true
-       },
-
-       "excludeFiles": [
-               "docs/**",
-               "extensions/**",
-               "node_modules/**",
-               "resources/lib/**",
-               "resources/src/jquery.tipsy/**",
-               "resources/src/jquery/jquery.farbtastic.js",
-               "resources/src/mediawiki.libs/**",
-               "skins/**",
-               "vendor/**"
-       ]
-}
diff --git a/.jshintignore b/.jshintignore
deleted file mode 100644 (file)
index fdde7d0..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# Generated documentation
-docs/**
-
-# third-party libs
-extensions/**
-node_modules/**
-resources/lib/**
-resources/src/jquery.tipsy/**
-resources/src/jquery/jquery.farbtastic.js
-resources/src/mediawiki.libs/**
-skins/**
-vendor/**
diff --git a/.jshintrc b/.jshintrc
deleted file mode 100644 (file)
index 441c4e3..0000000
--- a/.jshintrc
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-       // Enforcing
-       "bitwise": true,
-       "eqeqeq": true,
-       "esversion": 3,
-       "freeze": true,
-       "futurehostile": true,
-       "latedef": "nofunc",
-       "noarg": true,
-       "nonew": true,
-       "strict": false,
-       "undef": true,
-       "unused": true,
-
-       // Relaxing
-       "laxbreak": true,
-       "multistr": true,
-
-       // Environment
-       "browser": true,
-
-       "globals": {
-               "require": false,
-               "module": false,
-               "mediaWiki": true,
-               "JSON": true,
-               "OO": true,
-               "mwPerformance": true,
-               "jQuery": false,
-               "QUnit": false,
-               "sinon": false
-       }
-}
index 5c82af8..6d9f8e8 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -1,30 +1,62 @@
+# Map author and committer names and email addresses to canonical real names
+# and email addresses.
+#
+# To update the CREDITS file, run maintenance/updateCredits.php
+#
+# Two types of entries are useful here. The first sets a cannonical author
+# name for a given email address:
+#
+#   Cannonical Author Name <author email>
+#
+# The second allows collecting alternate email addresses into a single
+# cannonical author name and email address:
+#
+#   Cannonical Author Name <author email> <alternate email>
+#
+# Mappings are only needed for authors who have used multiple author names
+# and/or author emails for revisions over time. Author names begenning with
+# "[BOT]" will be omitted from the CREDITS file.
+#
+# See also: https://git-scm.com/docs/git-shortlog#_mapping_authors
+#
+[BOT] Gerrit Code Review <gerrit@wikimedia.org>
 [BOT] Gerrit Patch Uploader <gerritpatchuploader@gmail.com>
+[BOT] jenkins-bot <jenkins-bot@gerrit.wikimedia.org>
+[BOT] jenkins-bot <jenkins-bot@gerrit.wikimedia.org> <jenkins-bot@wikimedia.org>
 [BOT] Translation updater bot <l10n-bot@translatewiki.net>
 Aaron Schulz <aschulz@wikimedia.org>
 Aaron Schulz <aschulz@wikimedia.org> <aaron@users.mediawiki.org>
 Adam Roses Wight <awight@wikimedia.org>
+Adam Roses Wight <awight@wikimedia.org> <spam@ludd.net>
 addshore <addshorewiki@gmail.com>
+Aditya Sastry <ganeshaditya1@gmail.com>
 Adrian Heine <adrian.heine@wikimedia.de>
-Alex Monk <krenair@gmail.com>
-Alex Monk <krenair@gmail.com> <krenair@wikimedia.org>
-Alex Z <mrzmanwiki@gmail.com> <mrzman@users.mediawiki.org>
+Alex Z. <mrzmanwiki@gmail.com> <mrzman@users.mediawiki.org>
 Alexander Emsenhuber <ialex.wiki@gmail.com>
 Alexander Emsenhuber <ialex.wiki@gmail.com> <ialex@users.mediawiki.org>
 Alexander Emsenhuber <ialex.wiki@gmail.com> <mediawiki@emsenhuber.ch>
+Alexander Monk <krenair@gmail.com>
+Alexander Monk <krenair@gmail.com> <alex@wikimedia.org>
+Alexander Monk <krenair@gmail.com> <krenair@wikimedia.org>
 Alexia E. Smith <washuu@gmail.com>
 Amir E. Aharoni <amir.aharoni@mail.huji.ac.il>
 Amir E. Aharoni <amir.aharoni@mail.huji.ac.il> <amire80@users.mediawiki.org>
+Amir Sarabadani <ladsgroup@gmail.com> <Ladsgroup@gmail.com>
 Anders Wegge Jakobsen <awegge@gmail.com> <wegge@users.mediawiki.org>
 Andre Engels <andreengels@gmail.com> <a_engels@users.mediawiki.org>
+Andrew Garrett <agarrett@wikimedia.org>
 Andrew Garrett <agarrett@wikimedia.org> <werdna@users.mediawiki.org>
 Angela Beesley Starling <wiki@nge.la> <angelab@users.mediawiki.org>
 Antoine Musso <hashar@free.fr>
 Antoine Musso <hashar@free.fr> <hashar@users.mediawiki.org>
 Aran Dunkley <aran@organicdesign.co.nz> <nad@users.mediawiki.org>
 Ariel Glenn <ariel@wikimedia.org> <ariel@users.mediawiki.org>
+Ariel Glenn <ariel@wikimedia.org> <ariel@wikimedia.org>
 Arlo Breault <abreault@wikimedia.org>
+Arthur Richards <arichards@wikimedia.org>
 Arthur Richards <arichards@wikimedia.org> <awjrichards@users.mediawiki.org>
 Aryeh Gregor <simetrical+mw@gmail.com> <simetrical@users.mediawiki.org>
+Asher Feldman <afeldman@wikimedia.org>
 Asher Feldman <afeldman@wikimedia.org> <asher@users.mediawiki.org>
 aude <aude.wiki@gmail.com>
 Audrey Tang <audreyt@audreyt.org>
@@ -32,25 +64,30 @@ Audrey Tang <audreyt@audreyt.org> <au@localhost>
 ayush_garg <ayush.ce13@iitp.ac.in>
 Bahodir Mansurov <bmansurov@wikimedia.org>
 Bartosz Dziewoński <matma.rex@gmail.com>
-Bartosz Dziewoński <matma.rex@gmail.com> <matmarex@wikimedia.org>
 Bartosz Dziewoński <matma.rex@gmail.com> <bdziewonski@wikimedia.org>
+Bartosz Dziewoński <matma.rex@gmail.com> <matmarex@wikimedia.org>
 Ben Hartshorne <bhartshorne@wikimedia.org> <ben@users.mediawiki.org>
 Bene <benestar.wikimedia@gmail.com>
-Benjamin Lees <emufarmers@gmail.com> <emufarmers@users.mediawiki.org>
+Bene <benestar.wikimedia@gmail.com> <benestar.wikimedia@googlemail.com>
+Benny Situ <bsitu@wikimedia.org>
 Benny Situ <bsitu@wikimedia.org> <bsitu@users.mediawiki.org>
 Bertrand Grondin <bertrand.grondin@tiscali.fr> <grondin@users.mediawiki.org>
 Brad Jorsch <bjorsch@wikimedia.org>
+Brad Jorsch <bjorsch@wikimedia.org> <anomie.wikipedia@gmail.com>
 Brandon Harris <bharris@wikimedia.org> <bharris@users.mediawiki.org>
-Brian Wolff <bawolff+svn@gmail.com> <bawolff@users.mediawiki.org>
 Brian Wolff <bawolff+wn@gmail.com>
+Brian Wolff <bawolff+wn@gmail.com> <bawolff+svn@gmail.com>
+Brian Wolff <bawolff+wn@gmail.com> <bawolff@users.mediawiki.org>
 Brion Vibber <brion@wikimedia.org>
 Brion Vibber <brion@wikimedia.org> <brion@pobox.com>
 Brion Vibber <brion@wikimedia.org> <brion@users.mediawiki.org>
 Bryan Davis <bd808@wikimedia.org>
+Bryan Davis <bd808@wikimedia.org> <bd808@bd808.com>
+Bryan Tong Minh <bryan.tongminh@gmail.com>
 Bryan Tong Minh <bryan.tongminh@gmail.com> <btongminh@users.mediawiki.org>
 C. Scott Ananian <cscott@cscott.net>
 C. Scott Ananian <cscott@cscott.net> <cananian@wikimedia.org>
-cacycle@gerrit.wikimedia.org <cacyclewp@gmail.com>
+Cacycle <cacyclewp@gmail.com>
 cenarium <cenarium.sysop@gmail.com>
 Chad Horohoe <chadh@wikimedia.org>
 Chad Horohoe <chadh@wikimedia.org> <demon@users.mediawiki.org>
@@ -58,44 +95,64 @@ Charles Melbye <charlie@yourwiki.net> <charlie@users.mediawiki.org>
 Chiefwei <chiefwei1989@gmail.com>
 Chris McMahon <cmcmahon@wikimedia.org>
 Chris Steipp <csteipp@wikimedia.org>
-Christian Aistleitner <christian@quelltextlich.at> <qchris@users.mediawiki.org>
 Christian Aistleitner <christian@quelltextlich.at>
+Christian Aistleitner <christian@quelltextlich.at> <qchris@users.mediawiki.org>
 Christian Williams <orbit@framezero.com>
 Christian Williams <orbit@framezero.com> <christian@localhost>
 Christian Williams <orbit@framezero.com> <christian@wikia-inc.com>
+Christopher Johnson <root@bugzilla.wmde.de>
+church of emacs <churchofemacs@users.mediawiki.org>
+Cindy Cicalese <cicalese@mitre.org>
 ckoerner <nobelx@gmail.com>
 Conrad Irwin <conrad.irwin+wiki@gmail.com> <conrad@users.mediawiki.org>
 Dan Duvall <dduvall@wikimedia.org>
 dan-nl <d_entous@yahoo.com>
 Daniel A. R. Werner <daniel.a.r.werner@gmail.com>
 Daniel Cannon <cannon.danielc@gmail.com> <amidaniel@users.mediawiki.org>
+Daniel Friesen <mediawiki@danielfriesen.name>
+Daniel Friesen <mediawiki@danielfriesen.name> <daniel@nadir-seen-fire.com>
 Daniel Friesen <mediawiki@danielfriesen.name> <dantman@users.mediawiki.org>
+Daniel Friesen <mediawiki@danielfriesen.name> <pub-github@nadir-seen-fire.com>
 Daniel Kinzler <daniel.kinzler@wikimedia.de>
 Daniel Kinzler <daniel.kinzler@wikimedia.de> <daniel@users.mediawiki.org>
-Danny B <Wikipedia.Danny.B@email.cz> <danny_b@users.mediawiki.org>
+Danny B. <Wikipedia.Danny.B@email.cz>
+Danny B. <Wikipedia.Danny.B@email.cz> <danny.b@email.cz>
+Danny B. <Wikipedia.Danny.B@email.cz> <danny_b@users.mediawiki.org>
+Danny B. <Wikipedia.Danny.B@email.cz> <wikimedia.danny.b@email.cz>
+Darian Anthony Patrick <dpatrick@wikimedia.org>
+Darkdragon09 <ubuntu@ip-172-31-39-38.us-west-2.compute.internal>
 David Chan <david@sheetmusic.org.uk>
+Dereckson <dereckson@espace-win.org>
+Derk-Jan Hartman <hartman@videolan.org>
+Derk-Jan Hartman <hartman@videolan.org> <hartman.wiki@gmail.com>
 Derk-Jan Hartman <hartman@videolan.org> <hartman@users.mediawiki.org>
-Derk-Jan Hartman <hartman.wiki@gmail.com>
 Diederik van Liere <dvanliere@gmail.com> <diederik@users.mediawiki.org>
 Domas Mituzas <domas.mituzas@gmail.com> <midom@users.mediawiki.org>
 Douglas Gardner <douglas@chippy.ch>
 DPStokesNZ <duncan.stokes@gmail.com>
 Ebrahim Byagowi <ebrahim@gnu.org>
 Ed Sanders <esanders@wikimedia.org>
-Elliott Eggleston <ejegg@ejegg.com>
+Elliott Eggleston <eeggleston@wikimedia.org>
+Elliott Eggleston <eeggleston@wikimedia.org> <ejegg@ejegg.com>
 Emmanuel Engelhart <kelson@kiwix.org> <kelson42@users.mediawiki.org>
-eranroz <eranroz89@gmail.com>
+Emufarmers <emufarmers@gmail.com>
+Emufarmers <emufarmers@gmail.com> <emufarmers@users.mediawiki.org>
+Entlinkt <entlinkt@gmx-topmail.de>
+Eranroz <eranroz89@gmail.com>
 Erik Bernhardson <ebernhardson@wikimedia.org>
 Erik Moeller <erik@wikimedia.org>
 Erik Moeller <erik@wikimedia.org> <erik@users.mediawiki.org>
 Erwin Dokter <erwin@darcoury.nl>
 Evan McIntire <mcintire.evan@gmail.com>
+Evan Prodromou <evanprodromou@users.mediawiki.org> <evan@users.mediawiki.org>
 Federico Leva <federicoleva@tiscali.it>
 Fenzik Joseph <fenzik@gmail.com> <fenzik@users.mediawiki.org>
-Florianschmidtwelzow <florian.schmidt.welzow@t-online.de> <florian.schmidt.stargatewissen@gmail.com>
-Florianschmidtwelzow <florian.schmidt.welzow@t-online.de> Florian <florian.schmidt.welzow@t-online.de>
-Fomafix <fomafix@googlemail.com>
+Florian Schmidt <florian.schmidt.welzow@t-online.de>
+Florian Schmidt <florian.schmidt.welzow@t-online.de> <florian.schmidt.stargatewissen@gmail.com>
+fomafix <fomafix@googlemail.com>
+Fran Rogers <fran@dumetella.net>
 Fran Rogers <fran@dumetella.net> <krimpet@users.mediawiki.org>
+freakolowsky <freak@drajv.si>
 FunPika <funpikawiki@gmail.com>
 Gabriel Wicke <gwicke@wikimedia.org>
 Gabriel Wicke <gwicke@wikimedia.org> <gwicke@users.mediawiki.org>
@@ -110,31 +167,38 @@ glaisher <glaisher.wiki@gmail.com>
 Greg Sabino Mullane <greg@turnstep.com>
 Greg Sabino Mullane <greg@turnstep.com> <greg@endpoint.com>
 Greg Sabino Mullane <greg@turnstep.com> <greg@users.mediawiki.org>
+Grunny <mwgrunny@gmail.com>
 Guy Van den Broeck <guyvdb@gmail.com> <guyvdb@users.mediawiki.org>
 Happy-melon <happy-melon@live.com> <happy-melon@users.mediawiki.org>
 Helder <he7d3r@gmail.com>
 Helder <he7d3r@gmail.com> <helder.wiki@gmail.com>
 Hoo man <hoo@online.de>
+Huji <huji.huji@gmail.com>
 Huji <huji.huji@gmail.com> <huji@users.mediawiki.org>
 Ian Baker <ibaker@wikimedia.org> <raindrift@users.mediawiki.org>
 Ilmari Karonen <nospam@vyznev.net> <vyznev@users.mediawiki.org>
 Inez Korczyński <inez@wikia-inc.com>
 Inez Korczyński <inez@wikia-inc.com> <inez@users.mediawiki.org>
 isarra <s@zaori.org>
+isarra <s@zaori.org> <zhorishna@gmail.com>
 Ivan Lanin <ivanlanin@gmail.com> <ivanlanin@users.mediawiki.org>
-Jack Phoenix <jack@countervandalism.net> <ashley@users.mediawiki.org>
 Jack Phoenix <jack@countervandalism.net>
+Jack Phoenix <jack@countervandalism.net> <ashley@users.mediawiki.org>
 Jackmcbarn <jackmcbarn@gmail.com>
-Jackmcbarn <jackmcbarn@users.noreply.github.com>
+Jackmcbarn <jackmcbarn@gmail.com> <jackmcbarn@users.noreply.github.com>
 jagori <jagori79@gmail.com>
-James D. Forrester <jforrester@wikimedia.org>
+James Forrester <jforrester@wikimedia.org>
 Jan Gerber <j@thing.net> <j@users.mediawiki.org>
+Jan Luca Naumann <jan@jans-seite.de>
 Jan Luca Naumann <jan@jans-seite.de> <jan@users.mediawiki.org>
 Jan Paul Posma <jp.posma@gmail.com> <janpaul123@users.mediawiki.org>
 Jan Zerebecki <jan.wikimedia@zerebecki.de>
+Jared Flores <jaredflores2000@gmail.com>
 Jaroslav Škarvada <jskarvad@redhat.com>
 jarrettmunton <jmuntjmunt@gmail.com>
+Jason Richey <jasonr@wikia.com>
 Jason Richey <jasonr@wikia.com> <jasonr@users.mediawiki.org>
+Jason Richey <jasonr@wikia.com> <urichj00@users.mediawiki.org>
 Jeff Hall <jeffreyehall@gmail.com>
 Jeff Hall <jeffreyehall@gmail.com> <jhall@wikimedia.org>
 Jeff Janes <jeff.janes@gmail.com>
@@ -151,40 +215,58 @@ Jon Robson <jrobson@wikimedia.org> <jdlrobson@gmail.com>
 Juliusz Gonera <jgonera@gmail.com>
 Juliusz Gonera <jgonera@gmail.com> <jgonera@wikimedia.org>
 JuneHyeon Bae <devunt@gmail.com>
+Jure Kajzer <freak@drajv.si>
 Jure Kajzer <freak@drajv.si> <freakolowsky@users.mediawiki.org>
+Karun Dambiec <karun.84@gmx.de>
+Katie Filbert <aude.wiki@gmail.com>
 Katie Filbert <aude.wiki@gmail.com> <aude@users.mediawiki.org>
 Kevin Israel <pleasestand@live.com>
-Kunal Mehta <legoktm@gmail.com>
-Kunal Mehta <legoktm@gmail.com> <legoktm.wikipedia@gmail.com>
+Kunal Grover <kunalgrover05@gmail.com>
+Kunal Mehta <legoktm@member.fsf.org>
+Kunal Mehta <legoktm@member.fsf.org> <legoktm.wikipedia@gmail.com>
+Kunal Mehta <legoktm@member.fsf.org> <legoktm@gmail.com>
 Kwan Ting Chan <ktc@ktchan.info> <ktchan@users.mediawiki.org>
 lekshmi <andnlnbn18@gmail.com>
 Leo Koppelkamm <diebuche@gmail.com> <diebuche@users.mediawiki.org>
+Leon Liesener <leon.liesener@wikipedia.de>
 Leon Weber <leon@vserver152.masterssystems.com> <leon@users.mediawiki.org>
 Leonardo Gregianin <leogregianin@googlemail.com> <leogregianin@users.mediawiki.org>
 Leons Petrazickis <leons.petrazickis.haveyouconsiderednotincludingthisphrase@gmail.com> <leonsp@users.mediawiki.org>
-Liangent <liangent@gmail.com>
+liangent <liangent@gmail.com>
 Lisa Ridley <lhridley@gmail.com> <lhridley@users.mediawiki.org>
 Ljudusika <plo2000@i.ua>
 Luis Felipe Schenone <schenonef@gmail.com>
+Lupo <lupo.bugzilla@gmail.com>
 m4tx <m4tx@m4tx.pl>
+Madman <madman.enwiki@gmail.com>
 Magnus Manske <magnusmanske@googlemail.com> <magnusmanske@users.mediawiki.org>
 Manuel Schneider <manuel.schneider@wikimedia.ch> <80686@users.mediawiki.org>
+Marc-André Pelletier <marc@uberbox.org>
+Marcin Cieślak <saper@saper.info>
 Marcin Cieślak <saper@saper.info> <saper@users.mediawiki.org>
+Marco Falke <maic23@live.de>
+MarcoAurelio <strigiwm@gmail.com>
 Marielle Volz <marielle.volz@gmail.com>
 Marius Hoch <hoo@online.de>
-Mark A. Hershberger <mah@everybody.org>
-Mark A. Hershberger <mah@everybody.org> <mah@nichework.com>
-Mark A. Hershberger <mah@everybody.org> <mah@users.mediawiki.org>
 Mark Clements <mediawiki@kennel17.co.uk> <happydog@users.mediawiki.org>
+Mark Hershberger <mah@everybody.org>
+Mark Hershberger <mah@everybody.org> <mah@nichework.com>
+Mark Hershberger <mah@everybody.org> <mah@users.mediawiki.org>
+Mark Hershberger <mah@everybody.org> <mhershberger@wikimedia.org>
 Mark Holmquist <mtraceur@member.fsf.org>
+Mark Holmquist <mtraceur@member.fsf.org> <mholmquist@wikimedia.org>
 Marko Obrovac <mobrovac@wikimedia.org>
+Markus Glaser <glaser@hallowelt.biz>
+Markus Glaser <glaser@hallowelt.biz> <mglaser@users.mediawiki.org>
 Matt Johnston <mattj@emazestudios.com> <mattj@users.mediawiki.org>
 Matthew Britton <hugglegurch@gmail.com> <gurch@users.mediawiki.org>
 Matthew Flaschen <mflaschen@wikimedia.org>
 Matthias Mullie <git@mullie.eu>
+Matthias Mullie <git@mullie.eu> <mmullie@wikimedia.org>
 Matěj Grabovský <mgrabovsky@yahoo.com> <mgrabovsky@users.mediawiki.org>
 Max Semenik <maxsem.wiki@gmail.com>
 Max Semenik <maxsem.wiki@gmail.com> <maxsem@users.mediawiki.org>
+Max Semenik <maxsem.wiki@gmail.com> <semenik@gmail.com>
 mgooley <g0013y@gmail.com>
 Michael Dale <mdale@wikimedia.org> <dale@users.mediawiki.org>
 mjbmr <mjbmri@gmail.com>
@@ -192,23 +274,30 @@ Mohamed Magdy <mohamedmk@gmail.com> <alnokta@users.mediawiki.org>
 Moriel Schottlender <mschottlender@wikimedia.org>
 Moriel Schottlender <mschottlender@wikimedia.org> <moriel@gmail.com>
 Mormegil <mormegil@centrum.cz>
+MrBlueSky <mrbluesky@wikipedia.be>
+MrBlueSky <mrbluesky@wikipedia.be> <mrbluesky@localhost>
 Mukunda Modell <mmodell@wikimedia.org>
+Mwalker <mwalker@wikimedia.org>
 MZMcBride <g@mzmcbride.com>
 nadeesha <nadeesha@calcey.com> <nadeesha@users.mediawiki.org>
 Namit <namit.ohri@gmail.com>
 Nathaniel Herman <redwwjd@yahoo.com> <pinky@users.mediawiki.org>
 Neil Kandalgaonkar <neilk@wikimedia.org> <neilk@users.mediawiki.org>
 Nemo bis <federicoleva@tiscali.it>
-Nephele <nephele@skyhighway.com> <nephele@users.mediawiki.org>
+nephele <nephele@skyhighway.com> <nephele@users.mediawiki.org>
 Nick Jenkins <nickpj@gmail.com> <nickj@users.mediawiki.org>
 Nik Everett <neverett@wikimedia.org>
 Niklas Laxström <niklas.laxstrom@gmail.com>
 Niklas Laxström <niklas.laxstrom@gmail.com> <nikerabbit@users.mediawiki.org>
 Nimish Gautam <nimishg@wikimedia.org> <nimishg@users.mediawiki.org>
 Nuria Ruiz <nuria@wikimedia.org>
-Ori.livneh <ori@wikimedia.org>
+Ori Livneh <ori@wikimedia.org>
+Ori Livneh <ori@wikimedia.org> <ori.livneh@gmail.com>
 OverlordQ <wikipedia@thedarkcitadel.com> <overlordq@users.mediawiki.org>
+Owen Davis <owen@wikia-inc.com>
+Owen Davis <owen@wikia-inc.com> <owen@users.mediawiki.org>
 paladox <thomasmulhall410@yahoo.com>
+Patrick Reilly <preilly@wikimedia.org>
 Patrick Reilly <preilly@wikimedia.org> <preilly@users.mediawiki.org>
 Patrick Westerhoff <PatrickWesterhoff@gmail.com>
 Paul Copperman <paul.copperman@gmail.com> <pcopp@users.mediawiki.org>
@@ -223,9 +312,9 @@ PranavK <pranavmk98@gmail.com>
 Prateek Saxena <psaxena@wikimedia.org>
 Prateek Saxena <psaxena@wikimedia.org> <prtksxna@gmail.com>
 Priyanka Dhanda <pdhanda@wikimedia.org> <pdhanda@users.mediawiki.org>
-Purodha B Blissenbach <purodha@blissenbach.org>
-Purodha B Blissenbach <purodha@blissenbach.org> <purodha@users.mediawiki.org>
-Purodha B Blissenbach <purodha@blissenbach.org> <publi@web.de>
+Purodha Blissenbach <purodha@blissenbach.org>
+Purodha Blissenbach <purodha@blissenbach.org> <publi@web.de>
+Purodha Blissenbach <purodha@blissenbach.org> <purodha@users.mediawiki.org>
 Raimond Spekking <raimond.spekking@gmail.com>
 Raimond Spekking <raimond.spekking@gmail.com> <raymond@users.mediawiki.org>
 Remember the dot <rememberthedot@gmail.com> <rememberthedot@users.mediawiki.org>
@@ -233,13 +322,15 @@ Reza <reza.energy@gmail.com>
 Ricordisamoa <ricordisamoa@openmailbox.org>
 rillke <rillke@wikipedia.de>
 rillke <rillke@wikipedia.de> <rainerrillke@hotmail.com>
-River Tarnell <river@wikimedia.org> <river@users.mediawiki.org>
 River Tarnell <river@wikimedia.org> <kateturner@users.mediawiki.org>
+River Tarnell <river@wikimedia.org> <river@users.mediawiki.org>
 Roan Kattouw <roan.kattouw@gmail.com>
 Roan Kattouw <roan.kattouw@gmail.com> <catrope@users.mediawiki.org>
 Roan Kattouw <roan.kattouw@gmail.com> <roan@wikimedia.org>
 Rob Church <robchur@gmail.com> <robchurch@users.mediawiki.org>
+Rob Lanphier <robla@robla.net>
 Rob Lanphier <robla@robla.net> <robla@users.mediawiki.org>
+Rob Lanphier <robla@robla.net> <robla@wikimedia.org>
 Rob Moen <rmoen@mediawiki.org>
 Rob Moen <rmoen@mediawiki.org> <rmoen@users.mediawiki.org>
 Rob Moen <rmoen@mediawiki.org> <rmoen@wikimedia.org>
@@ -247,24 +338,30 @@ Robert Hoenig <indielives010@gmail.com>
 Robert Leverington <robert@rhl.me.uk> <roberthl@users.mediawiki.org>
 Robert Rohde <rarohde@gmail.com> <rarohde@users.mediawiki.org>
 Robert Stojnić <rainmansr@gmail.com> <rainman@users.mediawiki.org>
+Robin Pepermans <robinp.1273@gmail.com>
 Robin Pepermans <robinp.1273@gmail.com> <robin@users.mediawiki.org>
 robinhood701 <robinhood70@live.ca>
 Rohan <rohan1395@yahoo.com>
 Rotem Liss <rotemliss@gmail.com> <rotem@users.mediawiki.org>
 Rummana Yasmeen <ryasmeen@wikimedia.org>
 Russ Nelson <russnelson@gmail.com> <nelson@users.mediawiki.org>
-Ryan Kaldari <rkaldari@wikimedia.org> <kaldari@users.mediawiki.org>
 Ryan Kaldari <rkaldari@wikimedia.org>
 Ryan Kaldari <rkaldari@wikimedia.org> <kaldari@gmail.com>
+Ryan Kaldari <rkaldari@wikimedia.org> <kaldari@users.mediawiki.org>
+Ryan Lane <rlane32@gmail.com>
 Ryan Lane <rlane32@gmail.com> <laner@users.mediawiki.org>
+Ryan Lane <rlane32@gmail.com> <rlane@wikimedia.org>
+Ryan Schmidt <skizzerz@gmail.com>
+Ryan Schmidt <skizzerz@gmail.com> <skizzerz@skizzerz.net>
 Ryan Schmidt <skizzerz@gmail.com> <skizzerz@users.mediawiki.org>
 S Page <spage@wikimedia.org>
 Sam Reed <reedy@wikimedia.org>
+Sam Reed <reedy@wikimedia.org> <Reedy reedy@wikimedia.org>
+Sam Reed <reedy@wikimedia.org> <reedy@formey.wikimedia.org>
 Sam Reed <reedy@wikimedia.org> <reedy@users.mediawiki.org>
 Sam Smith <git@samsmith.io>
-Santhosh Thottingal <santhosh.thottingal@gmail.com> <santhosh@users.mediawiki.org>
 Santhosh Thottingal <santhosh.thottingal@gmail.com>
-saper <saper@saper.info>
+Santhosh Thottingal <santhosh.thottingal@gmail.com> <santhosh@users.mediawiki.org>
 Schnark <listenleser@gmail.com>
 Scimonster <tehalmightyscimonster@gmail.com>
 Sean Colombo <sean.colombo@gmail.com> <sean_colombo@users.mediawiki.org>
@@ -272,11 +369,14 @@ Sean Pringle <springle@wikimedia.org>
 Seb35 <seb35wikipedia@gmail.com>
 Sergio Santoro <santoro.srg@gmail.com>
 Shahyar <shahyar@gmail.com>
+Shinjiman <shinjiman@gmail.com>
 Shinjiman <shinjiman@gmail.com> <shinjiman@users.mediawiki.org>
 Siebrand Mazeland <s.mazeland@xs4all.nl>
 Siebrand Mazeland <s.mazeland@xs4all.nl> <siebrand@kitano.nl>
 Siebrand Mazeland <s.mazeland@xs4all.nl> <siebrand@users.mediawiki.org>
 Siebrand Mazeland <s.mazeland@xs4all.nl> <siebrand@wikimedia.org>
+Smriti Singh <smritis.31095@gmail.com>
+Sorawee Porncharoenwase <nullzero.free@gmail.com>
 Southparkfan <southparkfan223@hotmail.com>
 SQL <sxwiki@gmail.com> <sql@users.mediawiki.org>
 Stanislav Malyshev <smalyshev@gmail.com>
@@ -288,9 +388,10 @@ Steven Roddis <StevenRoddis@users.noreply.github.com>
 Subramanya Sastry <ssastry@wikimedia.org>
 Sucheta Ghoshal <sghoshal@wikimedia.org>
 Sumit Asthana <asthana.sumit23@gmail.com>
+Swalling <swalling@wikimedia.org>
 Thalia Chan <thalia@cantorion.org>
-TheDJ <hartman.wiki@gmail.com>
 Thiemo Mättig (WMDE) <thiemo.maettig@wikimedia.de>
+Thiemo Mättig (WMDE) <thiemo.maettig@wikimedia.de> <mr.heat@gmx.de>
 This, that and the other <at.light@live.com.au>
 tholam <t.lam@lamsinfosystem.com>
 Thomas Bleher <ThomasBleher@gmx.de> <tbleher@users.mediawiki.org>
@@ -305,29 +406,45 @@ Timo Tijhof <krinklemail@gmail.com> <krinkle@users.mediawiki.org>
 Timo Tijhof <krinklemail@gmail.com> <timo@wikimedia.org>
 Timo Tijhof <krinklemail@gmail.com> <ttijhof@wikimedia.org>
 Tina Johnson <tinajohnson.1234@gmail.com>
+Tisane <nathanlarson3141@gmail.com>
+Tjones <tjones@wikimedia.org>
 Tom Maaswinkel <tom.maaswinkel@12wiki.eu> <thedevilonline@users.mediawiki.org>
 Tomasz Finc <tfinc@wikimedia.org> <tomasz@users.mediawiki.org>
+Tomasz W. Kozlowski <tomasz@twkozlowski.com>
+Tomasz W. Kozlowski <tomasz@twkozlowski.com> <tomasz@twkozlowski.net>
+Tomasz W. Kozlowski <tomasz@twkozlowski.com> <twkozlowski@gmail.com>
 Tony Thomas <01tonythomas@gmail.com>
+Tpt <thomaspt@hotmail.fr>
 Trevor Parscal <trevorparscal@gmail.com>
 Trevor Parscal <trevorparscal@gmail.com> <tparscal@users.mediawiki.org>
 Trevor Parscal <trevorparscal@gmail.com> <tparscal@wikimedia.org>
 Tyler Cipriani <tcipriani@wikimedia.org>
 Tyler Romeo <tylerromeo@gmail.com>
-umherirrender <umherirrender_de.wp@web.de>
+Umherirrender <umherirrender_de.wp@web.de>
+Victor Vasiliev <vasilvv@mit.edu>
 Victor Vasiliev <vasilvv@mit.edu> <vasilievvv@users.mediawiki.org>
+Victor Vasiliev <vasilvv@mit.edu> <vasilvv@gmail.com>
 Vikas S Yaligar <vikasyaligar.it@gmail.com>
 Vivek Ghaisas <v.a.ghaisas@gmail.com>
 wctaiwan <wctaiwan@gmail.com>
 withoutaname <drevitchi@gmail.com>
 X! <soxred93@gmail.com> <soxred93@users.mediawiki.org>
+Yaron Koren <yaron57@gmail.com>
+Yaron Koren <yaron57@gmail.com> <yaron@users.mediawiki.org>
 Yaroslav Melnychuk <yaroslavmelnuchuk@gmail.com>
+Yongmin Hong <revi@member.fsf.org>
+Yongmin Hong <revi@member.fsf.org> <revi@pobox.com>
+Yongmin Hong <revi@member.fsf.org> <reviwiki@gmail.com>
 Yuri Astrakhan <yurik@wikimedia.org>
+Yuri Astrakhan <yurik@wikimedia.org> <yuriastrakhan@gmail.com>
 Yuri Astrakhan <yurik@wikimedia.org> <yurik@users.mediawiki.org>
 Yusuke Matsubara <whym@whym.org>
-YuviPanda <yuvipanda@gmail.com>
+Yuvi Panda <yuvipanda@gmail.com>
 Zak Greant <zak+mediawiki@fooassociates.com> <zak@users.mediawiki.org>
+Zhengzhu Feng <zhengzhu@gmail.com>
+Zhengzhu Feng <zhengzhu@gmail.com> <zhengzhu@users.mediawiki.org>
+Zppix <support@zppixballee.com>
 Ævar Arnfjörð Bjarmason <avarab@gmail.com> <avar@users.mediawiki.org>
+Étienne Beaulé <beauleetienne0@gmail.com>
 Željko Filipin <zeljko.filipin@gmail.com>
 Željko Filipin <zeljko.filipin@gmail.com> <zfilipin@wikimedia.org>
-Zhengzhu Feng <zhengzhu@gmail.com>
-Zhengzhu Feng <zhengzhu@gmail.com> <zhengzhu@users.mediawiki.org>
index 9062194..9738605 100644 (file)
@@ -55,7 +55,6 @@ notifications:
   email: false
   irc:
     channels:
-      - "chat.freenode.net#mediawiki-core"
       - "chat.freenode.net#mediawiki-feed"
     on_success: change
     on_failure: change
diff --git a/CREDITS b/CREDITS
index dca597e..1c1cf87 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -6,251 +6,657 @@ following names for their contribution to the product.
 -->
 <!-- Please notice that the following can be found parsed under Special:Version/Credits -->
 
-== Developers ==
-* Aaron Schulz
-* Alex Z.
-* Alexander Monk
-* Alexandre Emsenhuber
-* Andrew Garrett
-* Antoine Musso
-* Arthur Richards
-* Aryeh Gregor
-* Bartosz Dziewoński
-* Bertrand Grondin
-* Brad Jorsch
-* Brian Wolff
-* Brion Vibber
-* Bryan Davis
-* Bryan Tong Minh
-* Chad Horohoe
-* Charles Melbye
-* Chris Steipp
-* church of emacs
-* Daniel Friesen
-* Daniel Kinzler
-* Daniel Renfro
-* Danny B.
-* David McCabe
-* Derk-Jan Hartman
-* Domas Mituzas
-* Emufarmers
-* Fran Rogers
-* Greg Sabino Mullane
-* Guy Van den Broeck
-* Happy-melon
-* Hojjat
-* Ian Baker
-* Ilmari Karonen
-* Jack D. Pond
-* Jack Phoenix
-* Jackmcbarn
-* James Forrester
-* Jan Paul Posma
-* Jason Richey
-* Jeroen De Dauw
-* John Du Hart
-* Jon Harald Søby
-* Juliano F. Ravasi
-* Leo Koppelkamm
-* Leon Weber
-* Leslie Hoare
-* Marco Schuster
-* Marius Hoch
-* Matěj Grabovský
-* Matt Johnston
-* Matthew Flaschen
-* Max Semenik
-* Meno25
-* MinuteElectron
-* Mohamed Magdy
-* Nathaniel Herman
-* Neil Kandalgaonkar
-* Nicolas Dumazet
-* Niklas Laxström
-* Ori Livneh
-* Patrick Reilly
-* Philip Tzou
-* Platonides
-* Purodha Blissenbach
-* Raimond Spekking
-* Remember the dot
-* Roan Kattouw
-* Robert Stojnić
-* Robin Pepermans
-* Rotem Liss
-* Ryan Kaldari
-* Ryan Lane
-* Ryan Schmidt
-* Sam Reed
-* Shinjiman
-* Siebrand Mazeland
-* Soxred93
-* SQL
-* Szymon Świerkosz
-* This, that and the other
-* Thomas Bleher
-* Thomas Gries
-* Tim Starling
-* Timo Tijhof
-* Trevor Parscal
-* Tyler Anthony Romeo
-* Victor Vasiliev
-* Yesid Carrillo
-* Yuri Astrakhan
-
-== Patch Contributors ==
+== Contributors ==
+<!-- Updates to this list made with maintenance/updateCredits.php -->
+<!-- BEGIN CONTRIBUTOR LIST -->
+* aalekhN
 * Aaron Ball
 * Aaron Pramana
+* Aaron Schulz
+* Aarti Dwivedi
+* Aashaka Shah
+* abhinand
+* Abhishek Das
+* Adam Miller
+* Adam Roses Wight
+* addshore
+* Aditya Sastry
+* Adrian Heine
+* Adrian Lang
+* Ævar Arnfjörð Bjarmason
 * Agbad
 * Ahmad Sherif
+* Ajayrahul P
+* Alangi Derick
+* Albert221
 * Alejandro Mery
+* AlephNull
+* Alex Ivanov
+* Alex Shih-Han Lin
+* Alex Z.
+* Alexander Emsenhuber
+* Alexander I. Mashin
+* Alexander Lehmann
+* Alexander Monk
+* Alexander Sigachov
+* Alexandre Emsenhuber
+* Alexia E. Smith
 * Amalthea
 * Amir E. Aharoni
+* Amir Sarabadani
+* ananay
+* Anders Wegge Jakobsen
+* Andre Engels
+* Andrew Bogott
 * Andrew Dunbar
+* Andrew Garrett
+* Andrew Green
+* Andrew H
+* Andrew Harris
+* Andrew Otto
+* Andrius R
+* andymw
+* Angela Beesley Starling
+* ankur
+* Antoine Musso
 * Antonio Ospite
+* apexkid
+* April King
+* Aran Dunkley
+* Arash Boostani
+* Arcane21
+* Ariel Glenn
+* Arlo Breault
+* Arne Heizmann
+* Arthur Richards
+* Aryeh Gregor
+* Asher Feldman
 * Asier Lostalé
+* ayush_garg
 * Azliq7
 * Bagariavivek
+* Bahodir Mansurov
+* balloonguy
+* Bartosz Dziewoński
 * Beau
+* Ben Davis
+* Ben Hartshorne
+* Bene
 * Benny Situ
 * Bergi
+* Bertrand Grondin
+* Bill Traynor
+* Billinghurst
+* billm
+* blotmandroid
+* Bogdan Stancescu
+* Boris Nagaev
 * Borislav Manolov
+* Brad Jorsch
+* Brandon Black
+* Brandon Harris
 * Brent G
+* Brent Garber
+* Brian Wolff
 * Brianna Laugher
+* Brion Vibber
+* Bryan Davis
+* Bryan Tong Minh
+* burthsceh
+* C. Scott Ananian
+* Cacycle
+* Calak
+* Camille Constans
+* Carl Fürstenberg
 * Carlin
 * Carsten Nielsen
+* Cblair91
+* cenarium
+* Chad Horohoe
+* Charles Melbye
+* Chiefwei
+* Chris McMahon
+* Chris Seaton
+* Chris Steipp
 * Christian Aistleitner
+* Christian List
 * Christian Neubauer
+* Christopher Johnson
+* church of emacs
+* Cindy Cicalese
+* ckoerner
 * Conrad Irwin
 * cryptocoryne
 * Dan Barrett
 * Dan Collins
+* Dan Duvall
 * Dan Nessett
+* Dan Poltawski
+* dan-nl
+* Daniel A. R. Werner
 * Daniel Arnold
+* Daniel Cannon
+* Daniel De Marco
+* Daniel Evans
+* Daniel Friesen
+* Daniel Kinzler
+* Daniel Renfro
 * Daniel Werner
+* DanielRenfro
+* Danny B.
+* Darian Anthony Patrick
+* Darkdragon09
+* DaSch
 * David Baumgarten
+* David Chan
+* David E. Narváez
+* David Lynch
+* David McCabe
+* David Mudrák
+* dcausse
+* dennisroczek
 * Denny Vrandecic
+* Dereckson
+* Derk-Jan Hartman
+* Derric Atzrott
+* Derrick Coetzee
 * Dévai Tamás
+* Devi Krishnan
+* Diederik van Liere
+* Domas Mituzas
+* Douglas Gardner
+* DPStokesNZ
+* dr0ptp4kt
 * Ebrahim Byagowi
+* Ed Sanders
+* Edward Chernenko
 * Edward Z. Yang
+* Elisabeth Bauer
+* Elliott Eggleston
 * Elvis Stansvik
+* Emil Podlaszewski
+* Emmanuel Engelhart
+* Emmanuel Gil Peyrot
+* Emmet Hikory
+* Emufarmers
+* enigmaeth
+* Entlinkt
 * Eranroz
+* Eric Evans
+* Eric Schneider
+* Erich Lerch
+* Erick Guan
+* Erik Bernhardson
+* Erik Moeller
 * Erwin Dokter
 * Étienne Beaulé
+* Evan McIntire
+* Evan Prodromou
+* ExplosiveHippo
+* Faidon Liambotis
 * Federico Leva
+* Fenzik Joseph
+* firebus
 * Florian Schmidt
 * fomafix
+* Fran Rogers
+* Fred Emmott
 * FunPika
 * Gabriel Wicke
+* Gary Guo
+* gbt248
 * Geoffrey Mon
+* georggi
+* Gergő Tisza
 * Gero Scholz
+* gicode
+* Giftpflanze
+* Gilles Dubuc
 * Gilles van den Hoven
+* Giuseppe Lavagetto
+* gladoscc
+* glaisher
+* Greg Maxwell
+* Greg Sabino Mullane
+* Gregory Szorc
 * Grunny
+* Guillaume Blanchard
+* Guy Van den Broeck
+* Happy-melon
+* haritha28
 * Harry Burt
+* Hazard-SJ
+* Hector A Escobedo
+* Helder
+* Henning Snater
+* Hojjat
+* Huji
+* Hydriz
+* Ian Baker
+* Ilmari Karonen
+* Inez Korczyński
+* IoannisKydonis
 * Ireas
+* isarra
+* Ivan Lanin
+* Jack D. Pond
+* Jack Phoenix
+* Jackmcbarn
 * Jacob Block
+* Jacob Clark
+* jagori
+* Jakub Vrana
+* James Earl Douglas
+* James Forrester
+* Jan Berkel
+* Jan Drewniak
 * Jan Gerber
 * Jan Luca Naumann
+* Jan Paul Posma
+* Jan Zerebecki
+* Jared Flores
+* Jaroslav Škarvada
+* jarrettmunton
+* jarry1250
 * Jaska Zedlik
+* Jason Richey
+* jeblad
+* Jeff Janes
+* jeff303
+* Jens Frank
+* Jens Ohlig
+* Jérémie Roquet
 * Jeremy Baron
+* Jeremy Postlethwaite
+* jeremyb
+* Jeroen De Dauw
+* Jerome Jamnicky
+* Jesús Martínez Novo
+* jhobs
+* Jiabao
 * Jidanni
+* Jimmy Collins
 * Jimmy Xu
+* joakin
+* Joan Creus
+* Joel Natividad
+* Joerg
+* Johan Dahlin
+* John Du Hart
 * John N
+* Jon Harald Søby
+* Jon Robson
 * Jonathan Wiltshire
+* Jools Wills
+* jsahleen
+* Julian Ostrow
+* Juliano F. Ravasi
+* Juliusz Gonera
 * JuneHyeon Bae
 * Jure Kajzer
+* Justin Du
+* Kai_WMDE
+* kaligula
+* Kartik Mistry
 * Karun Dambiec
 * Katie Filbert
 * Kevin Israel
+* Kghbln
+* Kim Eik
 * Kim Hyun-Joon
+* kipod
+* kishanio
+* konarak
+* krishna keshav
+* Krzysztof Krzyzaniak
+* Krzysztof Zbudniewek
+* Kunal Grover
+* Kunal Mehta
+* Kwan Ting Chan
+* Laurence Parry
+* Lee Bousfield
+* Lee Daniel Crocker
 * Lee Worden
 * Lejonel
+* lekshmi
+* Leo Koppelkamm
 * Leon Liesener
+* Leon Weber
+* Leonardo Gregianin
+* Leons Petrazickis
+* Leslie Hoare
+* Leszek Manicki
+* lethosor
+* Lewis Cawte
+* Liam Edwards-Playne
 * liangent
+* Lisa Ridley
+* Ljudusika
+* Lojjik Braughler
 * Louperivois
+* Ltrlg
+* Luc Van Oostenryck
 * Lucas Garczewski
 * Luigi Corsaro
+* Luis Felipe Schenone
 * Luke Faraone
+* Lupin
 * Lupo
+* lwelling
+* m4tx
 * Madman
+* madurangasiriwardena
+* Magnus Manske
 * Manuel Menal
+* Manuel Schneider
+* Marc Ordinas i Llopis
 * Marc-André Pelletier
 * Marcin Cieślak
+* Marco Falke
+* Marco Schuster
+* MarcoAurelio
 * Marcus Buck
+* Marius Hoch
+* Mark Bergsma
+* Mark Clements
 * Mark Hershberger
 * Mark Holmquist
+* Marko Obrovac
+* Markus Glaser
+* Markus Krötzsch
 * Marooned
+* Martin Urbanec
+* Massaf
+* Matěj Grabovský
+* matejsuchanek
 * Mathias Ertl
 * mati
+* Matt Fitzpatrick
+* Matt Johnston
+* Matt Russell
+* Matthew Bowker
 * Matthew Britton
+* Matthew Flaschen
+* Matthias Jordan
 * Matthias Mullie
+* MatthiasDD
 * Max
+* Max Semenik
 * Max Sikström
+* mayankmadan
+* Meno25
 * merl
+* Merlijn S. van Deen
+* MGChecker
+* mgooley
+* mhutti1
 * Michael Dale
 * Michael De La Rue
+* Michael Holloway
 * Michael M.
 * Michael Newton
 * Michael Walsh
+* Michał Łazowik
+* Michał Roszka
+* Michał Zieliński
 * Mike Horvath
+* Minh Nguyễn
+* MinuteElectron
+* Misza13
+* mjbmr
 * moejoe0000
+* Mohamed Magdy
+* Molly White
+* Moriel Schottlender
 * Mormegil
+* Mr. E23
 * MrBlueSky
 * MrPete
+* Mukunda Modell
+* Mwalker
+* mwjames
 * mybugs.mail
 * MZMcBride
+* nadeesha
 * Nakon
+* Namit
 * Nathan Larson
+* Nathaniel Herman
+* Neil Kandalgaonkar
+* Nemo bis
 * nephele
+* Nicholas Pisarro, Jr
+* Nick Jenkins
+* nicoco007
+* Nicolas Dumazet
+* Nicolas Weeger
 * Nik
+* Nik Everett
+* Niklas Laxström
 * Nikola Kovacs
+* Nikola Smolenski
 * Nikolaos S. Karastathis
+* Nimish Gautam
 * Nischay Nahata
+* nischayn22
+* nomoa
+* nullspoon
+* Nuria Ruiz
 * Nx.devnull
+* Ocean behind ears
 * Olaf Lenz
 * Olivier Finlay Beaton
+* onei
+* opatel99
+* Oren Held
+* Ori Livneh
+* oskar.jauch@gmail.com
+* OverlordQ
+* Owen Davis
+* Paa Kwesi Imbeah
+* paladox
 * Patricio Molina
+* Patrick Reilly
+* Patrick Westerhoff
+* Pau Giner
 * Paul Copperman
 * Paul Oranje
+* Pavel Astakhov
+* Pavel Selitskas
+* Pcoombe
+* Perside Rosalie
 * Peter Gehres
+* Peter Hedenskog
+* Peter Potrowl
+* Petr Bena
+* Petr Kadlec
 * Petr Onderka
+* Petr Pchelko
+* Philip Tzou
+* physikerwelt (Moritz Schubotz)
 * PieRRoMaN
+* Pikne
+* PiRSquared17
+* Platonides
+* Pmlineditor
+* pmolina
+* prageck
+* Pranav Ravichandran
+* PranavK
+* Prateek Saxena
+* Priyanka Dhanda
+* Prod
+* ptarjan
+* pubudu538
+* Purodha Blissenbach
+* quiddity
 * quietust
+* Quim Gil
+* rahul21
+* Raimond Spekking
+* Ramunas Geciauskas
+* Remember the dot
 * René Kijewski
+* Reza
 * rgcjonas
+* Ricordisamoa
+* rillke
+* River Tarnell
+* Roan Kattouw
+* Rob Church
+* Rob Lanphier
 * Rob Moen
+* Robert Hoenig
+* Robert Leverington
+* Robert Rohde
+* Robert Stojnić
 * Robert Treat
+* Robert Vogel
+* Robin Pepermans
+* robinhood701
 * RockMFR
+* Rohan
+* Roman Nosov
+* Roman Tsukanov
+* Rotem Liss
+* Rowan Collins
+* Russ Nelson
 * Russell Blau
 * Rusty Burchfield
+* Ruud Koot
+* Ryan Bies
+* Ryan Finnie
+* Ryan Kaldari
+* Ryan Lane
+* Ryan Schmidt
 * S Page
 * Salvatore Ingala
+* Sam Reed
+* Sam Smith
 * Santhosh Thottingal
+* Schnark
+* Scimonster
+* scnd
 * Scott Colcord
 * se4598
+* Sean Colombo
+* Sean Pringle
+* Seb35
+* Sebastian Brückner
 * Sébastien Santoro
+* Sergio Santoro
+* Sethakill
+* Shahyar
+* Shane Gibbons
+* Shane King
+* Shinjiman
+* shirayuki
+* Sidhant Gupta
+* Siebrand Mazeland
 * Simon Walker
+* Smriti Singh
 * Solitarius
+* Sorawee Porncharoenwase
 * Søren Løvborg
 * Southparkfan
+* Soxred93
+* SQL
 * Srikanth Lakshmanan
+* Stanislav Malyshev
 * Stefano Codari
+* Steinsplitter
+* Stephan Gambke
+* Stephan Muggli
+* Stephane Bisson
+* Stephen Liang
+* Steve Sanbeg
+* Steven Roddis
 * Str4nd
 * Subramanya Sastry
+* Sumit Asthana
 * svip
+* Swalling
+* Szymon Świerkosz
+* T.D. Corell
+* Tarquin
+* The Discoverer
 * The Evil IP address
+* theopolisme
+* Thiemo Mättig (WMDE)
+* This, that and the other
+* tholam
+* Thomas Arrow
+* Thomas Bleher
+* Thomas Dalton
+* Thomas Gries
+* ThomasV
+* Tim Hollmann
 * Tim Landscheidt
+* Tim Laqua
+* Tim Starling
+* Timo Tijhof
+* Tina Johnson
 * Tisane
+* tjlsangria
+* Tjones
+* TK-999
+* Tobias Gritschacher
+* Tom Arrow
+* Tom Gilder
+* Tom Maaswinkel
+* Tomasz Finc
+* Tomasz W. Kozlowski
+* Tomasz Wegrzanowski
+* tomek
+* Tony Thomas
+* Tpt
+* Trevor Parscal
+* TyA
+* Tychay
+* Tyler Anthony Romeo
+* Tyler Cipriani
+* Tyler Romeo
+* U-REDMOND\emadelw
+* UltrasonicNXT
 * Umherirrender
+* utkarsh95
 * Van de Bugger
+* Viačeslav
+* Victor Porton
+* Victor Vasiliev
+* victorbarbu
 * Ville Stadista
+* vishnu
 * Vitaliy Filippov
 * Vivek Ghaisas
+* vlakoff
+* Volker E
 * Waldir Pimenta
+* wctaiwan
+* Wikinaut
+* Wil Mahan
 * William Demchick
+* withoutaname
+* WMDE-Fisch
+* X!
+* XP1
+* Yaron Koren
+* Yaroslav Melnychuk
+* Yesid Carrillo
+* Yogesh K S
+* Yongmin Hong
+* yoonghm
+* Yuri Astrakhan
 * Yusuke Matsubara
 * Yuvi Panda
 * Zachary Hauri
+* Zak Greant
+* Željko Filipin
+* Zhaofeng Li
+* Zhengzhu Feng
+* Zppix
+* محمد شعیب
+<!-- END CONTRIBUTOR LIST -->
 
 == Translators ==
 
diff --git a/FAQ b/FAQ
index cfacf14..29017bc 100644 (file)
--- a/FAQ
+++ b/FAQ
@@ -1,2 +1,2 @@
 The MediaWiki FAQ can be found at:
-https://www.mediawiki.org/wiki/Manual:FAQ
+https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ
\ No newline at end of file
index a08db5c..b38bc9a 100644 (file)
@@ -1,33 +1,44 @@
-/*jshint node:true */
+/* eslint-env node */
+
 module.exports = function ( grunt ) {
-       grunt.loadNpmTasks( 'grunt-contrib-copy' );
-       grunt.loadNpmTasks( 'grunt-contrib-jshint' );
-       grunt.loadNpmTasks( 'grunt-stylelint' );
-       grunt.loadNpmTasks( 'grunt-contrib-watch' );
-       grunt.loadNpmTasks( 'grunt-banana-checker' );
-       grunt.loadNpmTasks( 'grunt-jscs' );
-       grunt.loadNpmTasks( 'grunt-jsonlint' );
-       grunt.loadNpmTasks( 'grunt-karma' );
 
        var wgServer = process.env.MW_SERVER,
                wgScriptPath = process.env.MW_SCRIPT_PATH,
                karmaProxy = {};
 
+       grunt.loadNpmTasks( 'grunt-banana-checker' );
+       grunt.loadNpmTasks( 'grunt-contrib-copy' );
+       grunt.loadNpmTasks( 'grunt-contrib-watch' );
+       grunt.loadNpmTasks( 'grunt-eslint' );
+       grunt.loadNpmTasks( 'grunt-jsonlint' );
+       grunt.loadNpmTasks( 'grunt-karma' );
+       grunt.loadNpmTasks( 'grunt-stylelint' );
+
        karmaProxy[ wgScriptPath ] = wgServer + wgScriptPath;
 
        grunt.initConfig( {
-               jshint: {
-                       options: {
-                               jshintrc: true
-                       },
-                       all: '.'
-               },
-               jscs: {
-                       all: '.'
+               eslint: {
+                       all: [
+                               '**/*.js',
+                               '!docs/**',
+                               '!tests/**',
+                               '!extensions/**',
+                               '!node_modules/**',
+                               '!resources/lib/**',
+                               '!resources/src/jquery.tipsy/**',
+                               '!resources/src/jquery/jquery.farbtastic.js',
+                               '!resources/src/mediawiki.libs/**',
+                               '!skins/**',
+                               '!vendor/**',
+                               // Skip functions aren't even parseable
+                               '!resources/src/dom-level2-skip.js',
+                               '!resources/src/es5-skip.js',
+                               '!resources/src/json-skip.js',
+                               '!resources/src/mediawiki.hidpi-skip.js'
+                       ]
                },
                jsonlint: {
                        all: [
-                               '.jscsrc',
                                '**/*.json',
                                '!{docs/js,extensions,node_modules,skins,vendor}/**'
                        ]
@@ -48,7 +59,7 @@ module.exports = function ( grunt ) {
                },
                watch: {
                        files: [
-                               '.{stylelintrc,jscsrc,jshintignore,jshintrc}',
+                               '.{stylelintrc,eslintrc.json}',
                                '**/*',
                                '!{docs,extensions,node_modules,skins,vendor}/**'
                        ],
@@ -103,7 +114,7 @@ module.exports = function ( grunt ) {
                return !!( process.env.MW_SERVER && process.env.MW_SCRIPT_PATH );
        } );
 
-       grunt.registerTask( 'lint', [ 'jshint', 'jscs', 'jsonlint', 'banana', 'stylelint' ] );
+       grunt.registerTask( 'lint', [ 'eslint', 'banana', 'stylelint' ] );
        grunt.registerTask( 'qunit', [ 'assert-mw-env', 'karma:main' ] );
 
        grunt.registerTask( 'test', [ 'lint' ] );
diff --git a/HISTORY b/HISTORY
index 868b21a..6de7de4 100644 (file)
--- a/HISTORY
+++ b/HISTORY
@@ -1001,8 +1001,8 @@ This is a bug fix release of the MediaWiki 1.25 branch.
 * Added a new hook, "ContentAlterParserOutput", to allow extensions to modify the
   parser output for a content object before links update.
 * (T37785) Enhanced recent changes and extended watchlist are now default.
-  Documentation: https://meta.wikimedia.org/wiki/Help:Enhanced_recent_changes
-  and https://www.mediawiki.org/wiki/Manual:$wgDefaultUserOptions.
+  Documentation: https://meta.wikimedia.org/wiki/Special:MyLanguage/Help:Enhanced_recent_changes
+  and https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgDefaultUserOptions.
 * (T69341) SVG images will no longer be base64-encoded when being embedded
   in CSS. This results in slight size increase before gzip compression (due to
   percent-encoding), but up to 20% decrease after it.
@@ -1014,7 +1014,7 @@ This is a bug fix release of the MediaWiki 1.25 branch.
   - Basic wikitext syntax: <indicator name="foo">[[File:Foo.svg|20px]]</indicator>
   - Usage instructions: https://www.mediawiki.org/wiki/Help:Page_status_indicators
   - Adjusting custom skins to support indicators:
-    https://www.mediawiki.org/wiki/Manual:Skinning#Page_status_indicators
+    https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skinning#Page_status_indicators
 * Edit tokens may now be time-limited: passing a maximum age to
   User::matchEditToken will reject any older tokens.
 * The debug logging internals have been overhauled, and are now using the
@@ -1087,7 +1087,7 @@ This is a bug fix release of the MediaWiki 1.25 branch.
    This library provides the interfaces set by the PSR-3 standard (http://www.php-fig.org/psr/psr-3/)
    which are used by MediaWiki internally via the
    MediaWiki\Logger\LoggerFactory class.
-   See the structured logging RfC (https://www.mediawiki.org/wiki/Requests_for_comment/Structured_logging)
+   See the structured logging RfC (https://www.mediawiki.org/wiki/Special:MyLanguage/Requests_for_comment/Structured_logging)
    for more background information.
 ** cssjanus/cssjanus
    This library was formerly bundled with MediaWiki core and has been removed.
@@ -1098,7 +1098,7 @@ This is a bug fix release of the MediaWiki 1.25 branch.
 ** wikimedia/cdb
    This library was formerly a part of MediaWiki core, and has been moved into a separate library.
    It provides CDB functions which are used in the Interwiki and Localization caches.
-   More information about the library can be found at https://www.mediawiki.org/wiki/CDB.
+   More information about the library can be found at https://www.mediawiki.org/wiki/Special:MyLanguage/CDB.
 ** liuggio/statsd-php-client
    This library provides a StatsD client API for logging application metrics to a remote server.
 
diff --git a/INSTALL b/INSTALL
index 0e8eb92..90da381 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -21,7 +21,7 @@ If your PHP is configured as a CGI plug-in rather than an Apache module you may
 experience problems, as this configuration is not well tested.
 
 Support for rendering mathematical formulas requires installing the Math extension,
-see https://www.mediawiki.org/wiki/Extension:Math
+see https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:Math
 
 Don't forget to check the RELEASE-NOTES file...
 
@@ -30,7 +30,7 @@ Additional documentation is available online, which may include more detailed
 notes on particular operating systems and workarounds for difficult hosting
 environments:
 
-https://www.mediawiki.org/wiki/Manual:Installation_guide
+https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Installation_guide
 
 
 ******************* WARNING *******************
diff --git a/README b/README
index 6352e62..6d3ab80 100644 (file)
--- a/README
+++ b/README
@@ -17,15 +17,15 @@ For system requirements, installation, and upgrade details, see the files
 RELEASE-NOTES, INSTALL, and UPGRADE.
 
 * Ready to get started?
-** https://www.mediawiki.org/wiki/Download
+** https://www.mediawiki.org/wiki/Special:MyLanguage/Download
 * Looking for the technical manual?
-** https://www.mediawiki.org/wiki/Manual:Contents
+** https://www.mediawiki.org/wiki/Special:MyLangyage/Manual:Contents
 * Seeking help from a person?
-** https://www.mediawiki.org/wiki/Communication
+** https://www.mediawiki.org/wiki/Special:MyLanguage/Communication
 * Looking to file a bug report or a feature request?
 ** https://bugs.mediawiki.org/
 * Interested in helping out?
-** https://www.mediawiki.org/wiki/How_to_contribute
+** https://www.mediawiki.org/wiki/Special:MyLanguage/How_to_contribute
 
 MediaWiki is the result of global collaboration and cooperation. The CREDITS
 file lists technical contributors to the project. The COPYING file explains
index a24f97a..58ae23b 100644 (file)
@@ -5,7 +5,22 @@ THIS IS NOT A RELEASE YET
 MediaWiki 1.28 is an alpha-quality branch and is not recommended for use in
 production.
 
+=== Changes since 1.28.0rc0 ===
+* (T142210) The changes to move the parser "NewPP limit report" from a HTML
+  comment to a machine-readable JavaScript config option 'wgPageParseReport'
+  have been undone. They caused the human-readable limit report to be shown
+  incompletely or not at all. ParserOutput::setLimitReportData() and
+  getLimitReportData() behave as they did in MediaWiki 1.27 again.
+* (T149510) Value of {{DISPLAYTITLE:}} parser function will not be used for
+  the text of subheadings on a category page when creating it. This wasn't
+  working correctly.
+* (T106793) MediaWiki will no longer try to perform a HTTP redirect to the
+  canonical pretty URL when a non-pretty URL is used. It resulted in redirect
+  loops in some clients and in some server configurations. This undoes a change
+  made in MediaWiki 1.26.
+
 === Configuration changes in 1.28 ===
+* $wgSend404Code now affects status code of action=history if the page is not there.
 * BREAKING CHANGE: $wgHTTPProxy is now *required* for all external requests
   made by MediaWiki via a proxy. Relying on the http_proxy environment
   variable is no longer supported.
@@ -33,6 +48,14 @@ production.
   instead of just administrators ('sysop'). Documentation for this feature is
   available at <https://www.mediawiki.org/wiki/Help:ChangeContentModel>.
 * $wgRevisionCacheExpiry is now set to one week by default instead of being disabled.
+* Magic links are now disabled by default, and can be re-enabled by modifying the value
+  of $wgEnableMagicLinks. Their usage is discouraged, but if they are manually enabled,
+  a tracking category will be added to help identify usage and make it easier to migrate
+  away from. If you depend upon magic link functionality, it is requested that you comment
+  on <https://www.mediawiki.org/wiki/Requests_for_comment/Future_of_magic_links> and
+  explain your use case(s).
+* New config variable $wgCSPFalsePositiveUrls to control what URLs to ignore
+  in upcoming Content-Security-Policy feature's reporting.
 
 === New features in 1.28 ===
 * User::isBot() method for checking if an account is a bot role account.
@@ -60,17 +83,25 @@ production.
   on the wiki farm with a different domain, MediaWiki will instead alter the redirect
   URL to include a ?cpPosTime parameter that triggers the database synchronization when
   the URL is followed by the client. The same-domain case uses a new cpPosTime cookie.
+* Added new hooks, 'ApiQueryBaseBeforeQuery', 'ApiQueryBaseAfterQuery', and
+  'ApiQueryBaseProcessRow', to make it easier for extensions to add 'prop' and
+  'show' parameters to existing API query modules.
 
 === External library changes in 1.28 ===
 
 ==== Upgraded external libraries ====
 * Updated es5-shim from v4.1.5 to v4.5.8
+* Updated composer/semver from v1.4.1 to v1.4.2
+* Updated wikimedia/php-session-serializer from v1.0.3 to v1.0.4
 
 ==== New external libraries ====
+* Added wikimedia/scoped-callback v1.0.0
+* Added wikimedia/wait-condition-loop v1.0.1
 
 ==== Removed and replaced external libraries ====
 
 === Bug fixes in 1.28 ===
+* (T146496) action=history pages should return 404 HTTP error code if the page does not exist
 * (T137264) SECURITY: XSS in unclosed internal links
 * (T133147) SECURITY: Escape '<' and ']]>' in inline <style> blocks
 * (T133147) SECURITY: Require login to preview user CSS pages
@@ -108,12 +139,17 @@ production.
   indicated by a 'fromencoded' boolean alongside the existing 'from' parameter.
 * (T28680) action=paraminfo can now return info about all submodules of a
   module without listing them all explicitly.
+* (T146770) It is now possible to assert that the current user is a specific
+  named user, using the 'assertuser' parameter.
+* (T141963) Added a 'known' property when missing-but-known titles (e.g. from
+  the 'TitleIsAlwaysKnown' hook) are output in various modules.
 
 === Action API internal changes in 1.28 ===
 * Added a new hook, 'ApiMakeParserOptions', to allow extensions to better
   interact with ApiParse and ApiExpandTemplates.
 * (T139565) SECURITY: API: Generate head items in the context of the given title
 * (T115333) SECURITY: Check read permission when loading page content in ApiParse
+* ApiBase::getResultData() was removed (deprecated since 1.25)
 * ApiBase::makeHelpArrayToString() was removed (deprecated since 1.25)
 * ApiBase::makeHelpMsgParameters() was removed (deprecated since 1.25)
 * ApiBase::makeHelpMsg() was removed (deprecated since 1.25)
@@ -144,6 +180,12 @@ production.
 * ApiResult::setParsedLimit() was removed (deprecated since 1.25)
 * ApiResult::setRawMode() was removed (deprecated since 1.25)
 * ApiResult::size() was removed (deprecated since 1.25)
+* Added new hooks, 'ApiQueryBaseBeforeQuery', 'ApiQueryBaseAfterQuery', and
+  'ApiQueryBaseProcessRow', to make it easier for extensions to add 'prop' and
+  'show' parameters to existing API query modules. A query module can enable
+  these hooks by passing an array for $hookData to ApiQueryBase::select() and
+  by calling ApiQueryBase->processRow() before adding a row's data to the
+  result.
 
 === Languages updated in 1.28 ===
 
@@ -155,7 +197,12 @@ changes to languages because of Phabricator reports.
   BASAbali, M. Adiputra, Naval Scene, Nemo bis, NoiX180, and 아라.
 * (T135867) shn (Shan), thanks to translators Khun Sar, Piangpha,
   Saiddzone Saimawnkham, Saosukham, and Sengwan.
-* Czech (cs) and Slovak (sk) set as reciprocal fallbacks
+* Czech (cs) and Slovak (sk) set as reciprocal fallbacks.
+* (T146744) Livvi-Karelian (olo) namespace messages created thanks to translator Ilja.mos.
+* Karelian (krl), thanks to translators Flrn, Ilja.mos, Likopiän tyttö, Mashoi7, Matma Rex,
+  Ontoi, Theunitedstatesofme, and Varvana.
+* Gorontalo (gor), thanks to translators Ilham, Lukman Tomayahu, Marwan Mohamad, Matma Rex,
+  NoiX180, and Zhoelyakin.
 
 === Other changes in 1.28 ===
 * (T128697) Improved handling of large diffs.
@@ -182,7 +229,6 @@ changes to languages because of Phabricator reports.
   * Skin::linkKnown() (use MediaWiki\Linker\LinkRenderer instead)
   * Skin::userLink() (use Linker::userLink() instead)
   * Skin::userToolLinks() (use Linker::userToolLinks() instead)
-* The 'ParserLimitReportFormat' hook was removed.
 * Disabled "bug 2702" HTML tidying of parsed UI messages on wikis where Tidy is
   disabled.
 * DifferenceEngine::generateDiffBody() was removed (deprecated since 1.21).
@@ -205,6 +251,11 @@ changes to languages because of Phabricator reports.
 * IP::isConfiguredProxy() and IP::isTrustedProxy() were removed. Callers should
   migrate to using the same functions on a ProxyLookup instance, obtainable from
   MediaWikiServices.
+* The ArticleAfterFetchContent, ArticleInsertComplete, ArticleSave, ArticleSaveComplete,
+  ArticleViewCustom, EditFilterMerged, EditPageGetDiffText, EditPageGetPreviewText and
+  ShowRawCssJs hooks will now emit deprecation warnings if used.
+* (T68404) CSS3 attr() function with url type is no longer allowed
+  in inline styles.
 
 == Compatibility ==
 
diff --git a/RELEASE-NOTES-1.29 b/RELEASE-NOTES-1.29
new file mode 100644 (file)
index 0000000..3a7cde9
--- /dev/null
@@ -0,0 +1,112 @@
+== MediaWiki 1.29 ==
+
+THIS IS NOT A RELEASE YET
+
+MediaWiki 1.29 is an alpha-quality branch and is not recommended for use in
+production.
+
+=== Configuration changes in 1.29 ===
+* Default cookie expiration time has been reduced to 30 days. Login cookie expiration time is
+  kept at 180 days.
+* A new configuration variable has been added: $wgCookieSetOnAutoblock. This
+  determines whether to set a cookie when a user is autoblocked. Doing so means
+  that a blocked user, even after logging out and moving to a new IP address,
+  will still be blocked.
+
+=== New features in 1.29 ===
+* (T5233) A cookie can now be set when a user is autoblocked, to track that user if
+  they move to a new IP address. This is disabled by default.
+
+=== External library changes in 1.29 ===
+
+==== Upgraded external libraries ====
+
+==== New external libraries ====
+
+==== Removed and replaced external libraries ====
+
+=== Bug fixes in 1.29 ===
+
+=== Action API changes in 1.29 ===
+* Submitting sensitive authentication request parameters to action=clientlogin,
+  action=createaccount, action=linkaccount, and action=changeauthenticationdata
+  in the query string is now an error. They should be submitted in the POST
+  body instead.
+
+=== Action API internal changes in 1.29 ===
+
+=== Languages updated in 1.29 ===
+
+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.29 ===
+* Database::getSearchEngine() (deprecated in 1.28) was removed. Use
+  SearchEngineFactory::getSearchEngineClass() instead.
+
+== Compatibility ==
+
+MediaWiki 1.29 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.29 has several database changes since 1.28, 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.28.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/Special:MyLanguage/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 dfb0bf6..30ef985 100644 (file)
@@ -5,10 +5,12 @@ global $wgAutoloadLocalClasses;
 
 $wgAutoloadLocalClasses = [
        'APCBagOStuff' => __DIR__ . '/includes/libs/objectcache/APCBagOStuff.php',
+       'APCUBagOStuff' => __DIR__ . '/includes/libs/objectcache/APCUBagOStuff.php',
        'AbstractContent' => __DIR__ . '/includes/content/AbstractContent.php',
        'Action' => __DIR__ . '/includes/actions/Action.php',
        'ActiveUsersPager' => __DIR__ . '/includes/specials/pagers/ActiveUsersPager.php',
        'ActivityUpdateJob' => __DIR__ . '/includes/jobqueue/jobs/ActivityUpdateJob.php',
+       'AddRFCAndPMIDInterwiki' => __DIR__ . '/maintenance/addRFCandPMIDInterwiki.php',
        'AjaxDispatcher' => __DIR__ . '/includes/AjaxDispatcher.php',
        'AjaxResponse' => __DIR__ . '/includes/AjaxResponse.php',
        'AllMessagesTablePager' => __DIR__ . '/includes/specials/pagers/AllMessagesTablePager.php',
@@ -242,7 +244,7 @@ $wgAutoloadLocalClasses = [
        'CheckStorage' => __DIR__ . '/maintenance/storage/checkStorage.php',
        'CheckSyntax' => __DIR__ . '/maintenance/checkSyntax.php',
        'CheckUsernames' => __DIR__ . '/maintenance/checkUsernames.php',
-       'ChronologyProtector' => __DIR__ . '/includes/libs/rdbms/chronologyprotector/ChronologyProtector.php',
+       'ChronologyProtector' => __DIR__ . '/includes/libs/rdbms/ChronologyProtector.php',
        'ClassCollector' => __DIR__ . '/includes/utils/AutoloadGenerator.php',
        'CleanupAncientTables' => __DIR__ . '/maintenance/cleanupAncientTables.php',
        'CleanupBlocks' => __DIR__ . '/maintenance/cleanupBlocks.php',
@@ -294,10 +296,12 @@ $wgAutoloadLocalClasses = [
        'CreateAndPromote' => __DIR__ . '/maintenance/createAndPromote.php',
        'CreateFileOp' => __DIR__ . '/includes/libs/filebackend/fileop/CreateFileOp.php',
        'CreditsAction' => __DIR__ . '/includes/actions/CreditsAction.php',
+       'CryptHKDF' => __DIR__ . '/includes/libs/CryptHKDF.php',
+       'CryptRand' => __DIR__ . '/includes/libs/CryptRand.php',
        'CssContent' => __DIR__ . '/includes/content/CssContent.php',
        'CssContentHandler' => __DIR__ . '/includes/content/CssContentHandler.php',
        'CsvStatsOutput' => __DIR__ . '/maintenance/language/StatOutputs.php',
-       'CurlHttpRequest' => __DIR__ . '/includes/HttpFunctions.php',
+       'CurlHttpRequest' => __DIR__ . '/includes/http/CurlHttpRequest.php',
        'DBAccessBase' => __DIR__ . '/includes/dao/DBAccessBase.php',
        'DBAccessError' => __DIR__ . '/includes/libs/rdbms/exception/DBAccessError.php',
        'DBAccessObjectUtils' => __DIR__ . '/includes/dao/DBAccessObjectUtils.php',
@@ -317,7 +321,7 @@ $wgAutoloadLocalClasses = [
        'DBUnexpectedError' => __DIR__ . '/includes/libs/rdbms/exception/DBUnexpectedError.php',
        'DataUpdate' => __DIR__ . '/includes/deferred/DataUpdate.php',
        'Database' => __DIR__ . '/includes/libs/rdbms/database/Database.php',
-       'DatabaseBase' => __DIR__ . '/includes/libs/rdbms/database/DatabaseBase.php',
+       'DatabaseBase' => __DIR__ . '/includes/libs/rdbms/database/Database.php',
        'DatabaseDomain' => __DIR__ . '/includes/libs/rdbms/database/DatabaseDomain.php',
        'DatabaseInstaller' => __DIR__ . '/includes/installer/DatabaseInstaller.php',
        'DatabaseLag' => __DIR__ . '/maintenance/lag.php',
@@ -432,7 +436,7 @@ $wgAutoloadLocalClasses = [
        'ExternalStoreHttp' => __DIR__ . '/includes/externalstore/ExternalStoreHttp.php',
        'ExternalStoreMedium' => __DIR__ . '/includes/externalstore/ExternalStoreMedium.php',
        'ExternalStoreMwstore' => __DIR__ . '/includes/externalstore/ExternalStoreMwstore.php',
-       'FSFile' => __DIR__ . '/includes/libs/filebackend/FSFile.php',
+       'FSFile' => __DIR__ . '/includes/libs/filebackend/fsfile/FSFile.php',
        'FSFileBackend' => __DIR__ . '/includes/libs/filebackend/FSFileBackend.php',
        'FSFileBackendDirList' => __DIR__ . '/includes/libs/filebackend/FSFileBackend.php',
        'FSFileBackendFileList' => __DIR__ . '/includes/libs/filebackend/FSFileBackend.php',
@@ -552,6 +556,7 @@ $wgAutoloadLocalClasses = [
        'HTMLSelectNamespace' => __DIR__ . '/includes/htmlform/fields/HTMLSelectNamespace.php',
        'HTMLSelectNamespaceWithButton' => __DIR__ . '/includes/htmlform/fields/HTMLSelectNamespaceWithButton.php',
        'HTMLSelectOrOtherField' => __DIR__ . '/includes/htmlform/fields/HTMLSelectOrOtherField.php',
+       'HTMLSizeFilterField' => __DIR__ . '/includes/htmlform/fields/HTMLSizeFilterField.php',
        'HTMLSubmitField' => __DIR__ . '/includes/htmlform/fields/HTMLSubmitField.php',
        'HTMLTagFilter' => __DIR__ . '/includes/htmlform/fields/HTMLTagFilter.php',
        'HTMLTextAreaField' => __DIR__ . '/includes/htmlform/fields/HTMLTextAreaField.php',
@@ -575,7 +580,7 @@ $wgAutoloadLocalClasses = [
        'Html' => __DIR__ . '/includes/Html.php',
        'HtmlArmor' => __DIR__ . '/includes/libs/HtmlArmor.php',
        'HtmlFormatter' => __DIR__ . '/includes/HtmlFormatter.php',
-       'Http' => __DIR__ . '/includes/HttpFunctions.php',
+       'Http' => __DIR__ . '/includes/http/Http.php',
        'HttpError' => __DIR__ . '/includes/exception/HttpError.php',
        'HttpStatus' => __DIR__ . '/includes/libs/HttpStatus.php',
        'IApiMessage' => __DIR__ . '/includes/api/ApiMessage.php',
@@ -583,7 +588,7 @@ $wgAutoloadLocalClasses = [
        'IContextSource' => __DIR__ . '/includes/context/IContextSource.php',
        'IDBAccessObject' => __DIR__ . '/includes/dao/IDBAccessObject.php',
        'IDatabase' => __DIR__ . '/includes/libs/rdbms/database/IDatabase.php',
-       'IEContentAnalyzer' => __DIR__ . '/includes/libs/IEContentAnalyzer.php',
+       'IEContentAnalyzer' => __DIR__ . '/includes/libs/mime/IEContentAnalyzer.php',
        'IEUrlExtension' => __DIR__ . '/includes/libs/IEUrlExtension.php',
        'IExpiringStore' => __DIR__ . '/includes/libs/objectcache/IExpiringStore.php',
        'IJobSpecification' => __DIR__ . '/includes/jobqueue/JobSpecification.php',
@@ -628,7 +633,7 @@ $wgAutoloadLocalClasses = [
        'Interwiki' => __DIR__ . '/includes/interwiki/Interwiki.php',
        'InvalidPassword' => __DIR__ . '/includes/password/InvalidPassword.php',
        'InvalidateUserSesssions' => __DIR__ . '/maintenance/invalidateUserSessions.php',
-       'IteratorDecorator' => __DIR__ . '/includes/utils/iterators/IteratorDecorator.php',
+       'IteratorDecorator' => __DIR__ . '/includes/libs/iterators/IteratorDecorator.php',
        'IuConverter' => __DIR__ . '/languages/classes/LanguageIu.php',
        'JSCompilerContext' => __DIR__ . '/includes/libs/jsminplus.php',
        'JSMinPlus' => __DIR__ . '/includes/libs/jsminplus.php',
@@ -663,7 +668,6 @@ $wgAutoloadLocalClasses = [
        'KkConverter' => __DIR__ . '/languages/classes/LanguageKk.php',
        'KuConverter' => __DIR__ . '/languages/classes/LanguageKu.php',
        'LBFactory' => __DIR__ . '/includes/libs/rdbms/lbfactory/LBFactory.php',
-       'LBFactoryMW' => __DIR__ . '/includes/db/loadbalancer/LBFactoryMW.php',
        'LBFactoryMulti' => __DIR__ . '/includes/libs/rdbms/lbfactory/LBFactoryMulti.php',
        'LBFactorySimple' => __DIR__ . '/includes/libs/rdbms/lbfactory/LBFactorySimple.php',
        'LBFactorySingle' => __DIR__ . '/includes/libs/rdbms/lbfactory/LBFactorySingle.php',
@@ -771,7 +775,7 @@ $wgAutoloadLocalClasses = [
        'MWCallableUpdate' => __DIR__ . '/includes/deferred/MWCallableUpdate.php',
        'MWContentSerializationException' => __DIR__ . '/includes/content/ContentHandler.php',
        'MWCryptHKDF' => __DIR__ . '/includes/utils/MWCryptHKDF.php',
-       'MWCryptHash' => __DIR__ . '/includes/utils/MWCryptHash.php',
+       'MWCryptHash' => __DIR__ . '/includes/libs/MWCryptHash.php',
        'MWCryptRand' => __DIR__ . '/includes/utils/MWCryptRand.php',
        'MWDebug' => __DIR__ . '/includes/debug/MWDebug.php',
        'MWDocGen' => __DIR__ . '/maintenance/mwdocgen.php',
@@ -779,8 +783,9 @@ $wgAutoloadLocalClasses = [
        'MWExceptionHandler' => __DIR__ . '/includes/exception/MWExceptionHandler.php',
        'MWExceptionRenderer' => __DIR__ . '/includes/exception/MWExceptionRenderer.php',
        'MWFileProps' => __DIR__ . '/includes/utils/MWFileProps.php',
-       'MWGrants' => __DIR__ . '/includes/utils/MWGrants.php',
-       'MWHttpRequest' => __DIR__ . '/includes/HttpFunctions.php',
+       'MWGrants' => __DIR__ . '/includes/MWGrants.php',
+       'MWHttpRequest' => __DIR__ . '/includes/http/MWHttpRequest.php',
+       'MWLBFactory' => __DIR__ . '/includes/db/MWLBFactory.php',
        'MWMemcached' => __DIR__ . '/includes/compat/MemcachedClientCompat.php',
        'MWMessagePack' => __DIR__ . '/includes/libs/MWMessagePack.php',
        'MWNamespace' => __DIR__ . '/includes/MWNamespace.php',
@@ -854,6 +859,7 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Diff\\WordAccumulator' => __DIR__ . '/includes/diff/WordAccumulator.php',
        'MediaWiki\\Interwiki\\ClassicInterwikiLookup' => __DIR__ . '/includes/interwiki/ClassicInterwikiLookup.php',
        'MediaWiki\\Interwiki\\InterwikiLookup' => __DIR__ . '/includes/interwiki/InterwikiLookup.php',
+       'MediaWiki\\Interwiki\\InterwikiLookupAdapter' => __DIR__ . '/includes/interwiki/InterwikiLookupAdapter.php',
        'MediaWiki\\Languages\\Data\\Names' => __DIR__ . '/languages/data/Names.php',
        'MediaWiki\\Languages\\Data\\ZhConversion' => __DIR__ . '/languages/data/ZhConversion.php',
        'MediaWiki\\Linker\\LinkRenderer' => __DIR__ . '/includes/linker/LinkRenderer.php',
@@ -915,13 +921,14 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Tidy\\TidyDriverBase' => __DIR__ . '/includes/tidy/TidyDriverBase.php',
        'MediaWiki\\Widget\\ComplexNamespaceInputWidget' => __DIR__ . '/includes/widget/ComplexNamespaceInputWidget.php',
        'MediaWiki\\Widget\\ComplexTitleInputWidget' => __DIR__ . '/includes/widget/ComplexTitleInputWidget.php',
+       'MediaWiki\\Widget\\DateInputWidget' => __DIR__ . '/includes/widget/DateInputWidget.php',
        'MediaWiki\\Widget\\DateTimeInputWidget' => __DIR__ . '/includes/widget/DateTimeInputWidget.php',
        'MediaWiki\\Widget\\NamespaceInputWidget' => __DIR__ . '/includes/widget/NamespaceInputWidget.php',
        'MediaWiki\\Widget\\SearchInputWidget' => __DIR__ . '/includes/widget/SearchInputWidget.php',
        'MediaWiki\\Widget\\TitleInputWidget' => __DIR__ . '/includes/widget/TitleInputWidget.php',
        'MediaWiki\\Widget\\UserInputWidget' => __DIR__ . '/includes/widget/UserInputWidget.php',
        'MemCachedClientforWiki' => __DIR__ . '/includes/compat/MemcachedClientCompat.php',
-       'MemcLockManager' => __DIR__ . '/includes/filebackend/lockmanager/MemcLockManager.php',
+       'MemcLockManager' => __DIR__ . '/includes/libs/lockmanager/MemcLockManager.php',
        'MemcachedBagOStuff' => __DIR__ . '/includes/libs/objectcache/MemcachedBagOStuff.php',
        'MemcachedClient' => __DIR__ . '/includes/libs/objectcache/MemcachedClient.php',
        'MemcachedPeclBagOStuff' => __DIR__ . '/includes/libs/objectcache/MemcachedPeclBagOStuff.php',
@@ -940,6 +947,7 @@ $wgAutoloadLocalClasses = [
        'MessageSpecifier' => __DIR__ . '/includes/libs/MessageSpecifier.php',
        'MigrateFileRepoLayout' => __DIR__ . '/maintenance/migrateFileRepoLayout.php',
        'MigrateUserGroup' => __DIR__ . '/maintenance/migrateUserGroup.php',
+       'MimeAnalyzer' => __DIR__ . '/includes/libs/mime/MimeAnalyzer.php',
        'MimeMagic' => __DIR__ . '/includes/MimeMagic.php',
        'MinifyScript' => __DIR__ . '/maintenance/minify.php',
        'MostcategoriesPage' => __DIR__ . '/includes/specials/SpecialMostcategories.php',
@@ -979,7 +987,7 @@ $wgAutoloadLocalClasses = [
        'NewPagesPager' => __DIR__ . '/includes/specials/pagers/NewPagesPager.php',
        'NewUsersLogFormatter' => __DIR__ . '/includes/logging/NewUsersLogFormatter.php',
        'NolinesImageGallery' => __DIR__ . '/includes/gallery/NolinesImageGallery.php',
-       'NotRecursiveIterator' => __DIR__ . '/includes/utils/iterators/NotRecursiveIterator.php',
+       'NotRecursiveIterator' => __DIR__ . '/includes/libs/iterators/NotRecursiveIterator.php',
        'NukeNS' => __DIR__ . '/maintenance/nukeNS.php',
        'NukePage' => __DIR__ . '/maintenance/nukePage.php',
        'NullFileJournal' => __DIR__ . '/includes/libs/filebackend/filejournal/NullFileJournal.php',
@@ -1002,6 +1010,7 @@ $wgAutoloadLocalClasses = [
        'OrphanStats' => __DIR__ . '/maintenance/storage/orphanStats.php',
        'Orphans' => __DIR__ . '/maintenance/orphans.php',
        'OutputPage' => __DIR__ . '/includes/OutputPage.php',
+       'PHPVersionCheck' => __DIR__ . '/includes/PHPVersionCheck.php',
        'PNGHandler' => __DIR__ . '/includes/media/PNG.php',
        'PNGMetadataExtractor' => __DIR__ . '/includes/media/PNGMetadataExtractor.php',
        'PPCustomFrame_DOM' => __DIR__ . '/includes/parser/Preprocessor_DOM.php',
@@ -1056,7 +1065,7 @@ $wgAutoloadLocalClasses = [
        'Pbkdf2Password' => __DIR__ . '/includes/password/Pbkdf2Password.php',
        'PerRowAugmentor' => __DIR__ . '/includes/search/PerRowAugmentor.php',
        'PermissionsError' => __DIR__ . '/includes/exception/PermissionsError.php',
-       'PhpHttpRequest' => __DIR__ . '/includes/HttpFunctions.php',
+       'PhpHttpRequest' => __DIR__ . '/includes/http/PhpHttpRequest.php',
        'PhpXmlBugTester' => __DIR__ . '/includes/installer/PhpBugTests.php',
        'Pingback' => __DIR__ . '/includes/Pingback.php',
        'PoolCounter' => __DIR__ . '/includes/poolcounter/PoolCounter.php',
@@ -1235,7 +1244,7 @@ $wgAutoloadLocalClasses = [
        'SamplingStatsdClient' => __DIR__ . '/includes/libs/stats/SamplingStatsdClient.php',
        'Sanitizer' => __DIR__ . '/includes/Sanitizer.php',
        'SavepointPostgres' => __DIR__ . '/includes/libs/rdbms/database/utils/SavepointPostgres.php',
-       'ScopedCallback' => __DIR__ . '/includes/libs/ScopedCallback.php',
+       'ScopedCallback' => __DIR__ . '/includes/compat/ScopedCallback.php',
        'ScopedLock' => __DIR__ . '/includes/libs/lockmanager/ScopedLock.php',
        'SearchApi' => __DIR__ . '/includes/api/SearchApi.php',
        'SearchDatabase' => __DIR__ . '/includes/search/SearchDatabase.php',
@@ -1410,7 +1419,7 @@ $wgAutoloadLocalClasses = [
        'TableDiffFormatter' => __DIR__ . '/includes/diff/TableDiffFormatter.php',
        'TablePager' => __DIR__ . '/includes/pager/TablePager.php',
        'TagLogFormatter' => __DIR__ . '/includes/logging/TagLogFormatter.php',
-       'TempFSFile' => __DIR__ . '/includes/libs/filebackend/TempFSFile.php',
+       'TempFSFile' => __DIR__ . '/includes/libs/filebackend/fsfile/TempFSFile.php',
        'TempFileRepo' => __DIR__ . '/includes/filerepo/FileRepo.php',
        'TemplateParser' => __DIR__ . '/includes/TemplateParser.php',
        'TemplatesOnThisPageFormatter' => __DIR__ . '/includes/TemplatesOnThisPageFormatter.php',
@@ -1516,7 +1525,6 @@ $wgAutoloadLocalClasses = [
        'VirtualRESTService' => __DIR__ . '/includes/libs/virtualrest/VirtualRESTService.php',
        'VirtualRESTServiceClient' => __DIR__ . '/includes/libs/virtualrest/VirtualRESTServiceClient.php',
        'WANObjectCache' => __DIR__ . '/includes/libs/objectcache/WANObjectCache.php',
-       'WaitConditionLoop' => __DIR__ . '/includes/libs/WaitConditionLoop.php',
        'WantedCategoriesPage' => __DIR__ . '/includes/specials/SpecialWantedcategories.php',
        'WantedFilesPage' => __DIR__ . '/includes/specials/SpecialWantedfiles.php',
        'WantedPagesPage' => __DIR__ . '/includes/specials/SpecialWantedpages.php',
@@ -1525,6 +1533,7 @@ $wgAutoloadLocalClasses = [
        'WatchAction' => __DIR__ . '/includes/actions/WatchAction.php',
        'WatchedItem' => __DIR__ . '/includes/WatchedItem.php',
        'WatchedItemQueryService' => __DIR__ . '/includes/WatchedItemQueryService.php',
+       'WatchedItemQueryServiceExtension' => __DIR__ . '/includes/WatchedItemQueryServiceExtension.php',
        'WatchedItemStore' => __DIR__ . '/includes/WatchedItemStore.php',
        'WatchlistCleanup' => __DIR__ . '/maintenance/cleanupWatchlist.php',
        'WebInstaller' => __DIR__ . '/includes/installer/WebInstaller.php',
@@ -1578,7 +1587,7 @@ $wgAutoloadLocalClasses = [
        'XmlDumpWriter' => __DIR__ . '/includes/export/XmlDumpWriter.php',
        'XmlJsCode' => __DIR__ . '/includes/Xml.php',
        'XmlSelect' => __DIR__ . '/includes/XmlSelect.php',
-       'XmlTypeCheck' => __DIR__ . '/includes/libs/XmlTypeCheck.php',
+       'XmlTypeCheck' => __DIR__ . '/includes/libs/mime/XmlTypeCheck.php',
        'ZhConverter' => __DIR__ . '/languages/classes/LanguageZh.php',
        'ZipDirectoryReader' => __DIR__ . '/includes/utils/ZipDirectoryReader.php',
        'ZipDirectoryReaderError' => __DIR__ . '/includes/utils/ZipDirectoryReader.php',
index eedaa4e..e1d9f47 100644 (file)
@@ -16,7 +16,7 @@
                "wiki": "https://www.mediawiki.org/"
        },
        "require": {
-               "composer/semver": "1.4.1",
+               "composer/semver": "1.4.2",
                "cssjanus/cssjanus": "1.1.2",
                "ext-ctype": "*",
                "ext-iconv": "*",
@@ -25,7 +25,7 @@
                "ext-xml": "*",
                "liuggio/statsd-php-client": "1.0.18",
                "mediawiki/at-ease": "1.1.0",
-               "oojs/oojs-ui": "0.17.9",
+               "oojs/oojs-ui": "0.18.0",
                "oyejorge/less.php": "1.7.0.10",
                "php": ">=5.5.9",
                "psr/log": "1.0.0",
                "wikimedia/composer-merge-plugin": "1.3.1",
                "wikimedia/html-formatter": "1.0.1",
                "wikimedia/ip-set": "1.1.0",
-               "wikimedia/php-session-serializer": "1.0.3",
+               "wikimedia/php-session-serializer": "1.0.4",
                "wikimedia/relpath": "1.0.3",
                "wikimedia/running-stat": "1.1.0",
-               "wikimedia/utfnormal": "1.0.3",
+               "wikimedia/scoped-callback": "1.0.0",
+               "wikimedia/utfnormal": "1.1.0",
+               "wikimedia/wait-condition-loop": "1.0.1",
                "wikimedia/wrappedstring": "2.2.0",
                "zordius/lightncandy": "0.23"
        },
        "require-dev": {
+               "composer/spdx-licenses": "1.1.4",
                "jakub-onderka/php-parallel-lint": "0.9.2",
                "justinrainbow/json-schema": "~3.0",
                "mediawiki/mediawiki-codesniffer": "0.7.2",
index 6f3da97..2d82270 100644 (file)
@@ -4,8 +4,8 @@
 The 'docs' directory contain various text files that should help you understand
 the most important parts of the code of MediaWiki. More in-depth documentation
 can be found at:
-  https://www.mediawiki.org/wiki/Manual:Code
-  https://www.mediawiki.org/wiki/Developer_hub
+  https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Code
+  https://www.mediawiki.org/wiki/Special:MyLanguage/Developer_hub
 API documentation is automatically generated and updated daily at:
   https://doc.wikimedia.org/mediawiki-core/master/php/html/
 
@@ -14,6 +14,6 @@ You can get a fresh version using 'make doc' or mwdocgen.php in the
 
 
 For end users, most of the documentation is located online at:
-  https://www.mediawiki.org/wiki/Help:Contents
+  https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents
 Documentation for MediaWiki site administrators is at:
-  https://www.mediawiki.org/wiki/Manual:Contents
+  https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents
index 384bfb4..638ee5d 100644 (file)
                },
                "license-name": {
                        "type": "string",
-                       "description": "Short identifier for the license under which the extension is released.",
-                       "enum": [
-                               "AFL-1.1",
-                               "AFL-1.2",
-                               "AFL-2.0",
-                               "AFL-2.1",
-                               "AFL-3.0",
-                               "APL-1.0",
-                               "Aladdin",
-                               "ANTLR-PD",
-                               "Apache-1.0",
-                               "Apache-1.1",
-                               "Apache-2.0",
-                               "APSL-1.0",
-                               "APSL-1.1",
-                               "APSL-1.2",
-                               "APSL-2.0",
-                               "Artistic-1.0",
-                               "Artistic-1.0-cl8",
-                               "Artistic-1.0-Perl",
-                               "Artistic-2.0",
-                               "AAL",
-                               "BitTorrent-1.0",
-                               "BitTorrent-1.1",
-                               "BSL-1.0",
-                               "BSD-2-Clause",
-                               "BSD-2-Clause-FreeBSD",
-                               "BSD-2-Clause-NetBSD",
-                               "BSD-3-Clause",
-                               "BSD-3-Clause-Clear",
-                               "BSD-4-Clause",
-                               "BSD-4-Clause-UC",
-                               "CECILL-1.0",
-                               "CECILL-1.1",
-                               "CECILL-2.0",
-                               "CECILL-B",
-                               "CECILL-C",
-                               "ClArtistic",
-                               "CNRI-Python",
-                               "CNRI-Python-GPL-Compatible",
-                               "CPOL-1.02",
-                               "CDDL-1.0",
-                               "CDDL-1.1",
-                               "CPAL-1.0",
-                               "CPL-1.0",
-                               "CATOSL-1.1",
-                               "Condor-1.1",
-                               "CC-BY-1.0",
-                               "CC-BY-2.0",
-                               "CC-BY-2.5",
-                               "CC-BY-3.0",
-                               "CC-BY-ND-1.0",
-                               "CC-BY-ND-2.0",
-                               "CC-BY-ND-2.5",
-                               "CC-BY-ND-3.0",
-                               "CC-BY-NC-1.0",
-                               "CC-BY-NC-2.0",
-                               "CC-BY-NC-2.5",
-                               "CC-BY-NC-3.0",
-                               "CC-BY-NC-ND-1.0",
-                               "CC-BY-NC-ND-2.0",
-                               "CC-BY-NC-ND-2.5",
-                               "CC-BY-NC-ND-3.0",
-                               "CC-BY-NC-SA-1.0",
-                               "CC-BY-NC-SA-2.0",
-                               "CC-BY-NC-SA-2.5",
-                               "CC-BY-NC-SA-3.0",
-                               "CC-BY-SA-1.0",
-                               "CC-BY-SA-2.0",
-                               "CC-BY-SA-2.5",
-                               "CC-BY-SA-3.0",
-                               "CC0-1.0",
-                               "CUA-OPL-1.0",
-                               "D-FSL-1.0",
-                               "WTFPL",
-                               "EPL-1.0",
-                               "eCos-2.0",
-                               "ECL-1.0",
-                               "ECL-2.0",
-                               "EFL-1.0",
-                               "EFL-2.0",
-                               "Entessa",
-                               "ErlPL-1.1",
-                               "EUDatagrid",
-                               "EUPL-1.0",
-                               "EUPL-1.1",
-                               "Fair",
-                               "Frameworx-1.0",
-                               "FTL",
-                               "AGPL-1.0",
-                               "AGPL-3.0",
-                               "GFDL-1.1",
-                               "GFDL-1.2",
-                               "GFDL-1.3",
-                               "GPL-1.0",
-                               "GPL-1.0+",
-                               "GPL-2.0",
-                               "GPL-2.0+",
-                               "GPL-2.0-with-autoconf-exception",
-                               "GPL-2.0-with-bison-exception",
-                               "GPL-2.0-with-classpath-exception",
-                               "GPL-2.0-with-font-exception",
-                               "GPL-2.0-with-GCC-exception",
-                               "GPL-3.0",
-                               "GPL-3.0+",
-                               "GPL-3.0-with-autoconf-exception",
-                               "GPL-3.0-with-GCC-exception",
-                               "LGPL-2.1",
-                               "LGPL-2.1+",
-                               "LGPL-3.0",
-                               "LGPL-3.0+",
-                               "LGPL-2.0",
-                               "LGPL-2.0+",
-                               "gSOAP-1.3b",
-                               "HPND",
-                               "IBM-pibs",
-                               "IPL-1.0",
-                               "Imlib2",
-                               "IJG",
-                               "Intel",
-                               "IPA",
-                               "ISC",
-                               "JSON",
-                               "LPPL-1.3a",
-                               "LPPL-1.0",
-                               "LPPL-1.1",
-                               "LPPL-1.2",
-                               "LPPL-1.3c",
-                               "Libpng",
-                               "LPL-1.02",
-                               "LPL-1.0",
-                               "MS-PL",
-                               "MS-RL",
-                               "MirOS",
-                               "MIT",
-                               "Motosoto",
-                               "MPL-1.0",
-                               "MPL-1.1",
-                               "MPL-2.0",
-                               "MPL-2.0-no-copyleft-exception",
-                               "Multics",
-                               "NASA-1.3",
-                               "Naumen",
-                               "NBPL-1.0",
-                               "NGPL",
-                               "NOSL",
-                               "NPL-1.0",
-                               "NPL-1.1",
-                               "Nokia",
-                               "NPOSL-3.0",
-                               "NTP",
-                               "OCLC-2.0",
-                               "ODbL-1.0",
-                               "PDDL-1.0",
-                               "OGTSL",
-                               "OLDAP-2.2.2",
-                               "OLDAP-1.1",
-                               "OLDAP-1.2",
-                               "OLDAP-1.3",
-                               "OLDAP-1.4",
-                               "OLDAP-2.0",
-                               "OLDAP-2.0.1",
-                               "OLDAP-2.1",
-                               "OLDAP-2.2",
-                               "OLDAP-2.2.1",
-                               "OLDAP-2.3",
-                               "OLDAP-2.4",
-                               "OLDAP-2.5",
-                               "OLDAP-2.6",
-                               "OLDAP-2.7",
-                               "OPL-1.0",
-                               "OSL-1.0",
-                               "OSL-2.0",
-                               "OSL-2.1",
-                               "OSL-3.0",
-                               "OLDAP-2.8",
-                               "OpenSSL",
-                               "PHP-3.0",
-                               "PHP-3.01",
-                               "PostgreSQL",
-                               "Python-2.0",
-                               "QPL-1.0",
-                               "RPSL-1.0",
-                               "RPL-1.1",
-                               "RPL-1.5",
-                               "RHeCos-1.1",
-                               "RSCPL",
-                               "Ruby",
-                               "SAX-PD",
-                               "SGI-B-1.0",
-                               "SGI-B-1.1",
-                               "SGI-B-2.0",
-                               "OFL-1.0",
-                               "OFL-1.1",
-                               "SimPL-2.0",
-                               "Sleepycat",
-                               "SMLNJ",
-                               "SugarCRM-1.1.3",
-                               "SISSL",
-                               "SISSL-1.2",
-                               "SPL-1.0",
-                               "Watcom-1.0",
-                               "NCSA",
-                               "VSL-1.0",
-                               "W3C",
-                               "WXwindows",
-                               "Xnet",
-                               "X11",
-                               "XFree86-1.1",
-                               "YPL-1.0",
-                               "YPL-1.1",
-                               "Zimbra-1.3",
-                               "Zlib",
-                               "ZPL-1.1",
-                               "ZPL-2.0",
-                               "ZPL-2.1",
-                               "Unlicense"
-                       ]
+                       "description": "SPDX identifier for the license under which the extension is released."
                },
                "requires": {
                        "type": "object",
                                                                        "items": {
                                                                                "type": "string"
                                                                        }
+                                                               },
+                                                               "noflip": {
+                                                                       "type": "boolean",
+                                                                       "description": "Whether to skip CSSJanus LTR-to-RTL flipping for this module. Recommended for styles imported from libraries that already properly handle their RTL styles. Default is false, meaning CSSJanus will be applied on RTL-mode output."
                                                                }
                                                        }
                                                },
                "SkinOOUIThemes": {
                        "type": "object"
                },
+               "PasswordPolicy": {
+                       "type": "object",
+                       "description": "Password policies"
+               },
+               "FileExtensions": {
+                       "type": "object",
+                       "description": "Preferred file extensions for uploading"
+               },
                "callback": {
                        "type": [
                                "array",
                                                        "type": "string",
                                                        "enum": [
                                                                "array_merge_recursive",
+                                                               "array_replace_recursive",
                                                                "array_plus_2d",
                                                                "array_plus",
                                                                "array_merge"
index c4a1a8d..4d5c44f 100644 (file)
                },
                "license-name": {
                        "type": "string",
-                       "description": "Short identifier for the license under which the extension is released.",
-                       "enum": [
-                               "AFL-1.1",
-                               "AFL-1.2",
-                               "AFL-2.0",
-                               "AFL-2.1",
-                               "AFL-3.0",
-                               "APL-1.0",
-                               "Aladdin",
-                               "ANTLR-PD",
-                               "Apache-1.0",
-                               "Apache-1.1",
-                               "Apache-2.0",
-                               "APSL-1.0",
-                               "APSL-1.1",
-                               "APSL-1.2",
-                               "APSL-2.0",
-                               "Artistic-1.0",
-                               "Artistic-1.0-cl8",
-                               "Artistic-1.0-Perl",
-                               "Artistic-2.0",
-                               "AAL",
-                               "BitTorrent-1.0",
-                               "BitTorrent-1.1",
-                               "BSL-1.0",
-                               "BSD-2-Clause",
-                               "BSD-2-Clause-FreeBSD",
-                               "BSD-2-Clause-NetBSD",
-                               "BSD-3-Clause",
-                               "BSD-3-Clause-Clear",
-                               "BSD-4-Clause",
-                               "BSD-4-Clause-UC",
-                               "CECILL-1.0",
-                               "CECILL-1.1",
-                               "CECILL-2.0",
-                               "CECILL-B",
-                               "CECILL-C",
-                               "ClArtistic",
-                               "CNRI-Python",
-                               "CNRI-Python-GPL-Compatible",
-                               "CPOL-1.02",
-                               "CDDL-1.0",
-                               "CDDL-1.1",
-                               "CPAL-1.0",
-                               "CPL-1.0",
-                               "CATOSL-1.1",
-                               "Condor-1.1",
-                               "CC-BY-1.0",
-                               "CC-BY-2.0",
-                               "CC-BY-2.5",
-                               "CC-BY-3.0",
-                               "CC-BY-ND-1.0",
-                               "CC-BY-ND-2.0",
-                               "CC-BY-ND-2.5",
-                               "CC-BY-ND-3.0",
-                               "CC-BY-NC-1.0",
-                               "CC-BY-NC-2.0",
-                               "CC-BY-NC-2.5",
-                               "CC-BY-NC-3.0",
-                               "CC-BY-NC-ND-1.0",
-                               "CC-BY-NC-ND-2.0",
-                               "CC-BY-NC-ND-2.5",
-                               "CC-BY-NC-ND-3.0",
-                               "CC-BY-NC-SA-1.0",
-                               "CC-BY-NC-SA-2.0",
-                               "CC-BY-NC-SA-2.5",
-                               "CC-BY-NC-SA-3.0",
-                               "CC-BY-SA-1.0",
-                               "CC-BY-SA-2.0",
-                               "CC-BY-SA-2.5",
-                               "CC-BY-SA-3.0",
-                               "CC0-1.0",
-                               "CUA-OPL-1.0",
-                               "D-FSL-1.0",
-                               "WTFPL",
-                               "EPL-1.0",
-                               "eCos-2.0",
-                               "ECL-1.0",
-                               "ECL-2.0",
-                               "EFL-1.0",
-                               "EFL-2.0",
-                               "Entessa",
-                               "ErlPL-1.1",
-                               "EUDatagrid",
-                               "EUPL-1.0",
-                               "EUPL-1.1",
-                               "Fair",
-                               "Frameworx-1.0",
-                               "FTL",
-                               "AGPL-1.0",
-                               "AGPL-3.0",
-                               "GFDL-1.1",
-                               "GFDL-1.2",
-                               "GFDL-1.3",
-                               "GPL-1.0",
-                               "GPL-1.0+",
-                               "GPL-2.0",
-                               "GPL-2.0+",
-                               "GPL-2.0-with-autoconf-exception",
-                               "GPL-2.0-with-bison-exception",
-                               "GPL-2.0-with-classpath-exception",
-                               "GPL-2.0-with-font-exception",
-                               "GPL-2.0-with-GCC-exception",
-                               "GPL-3.0",
-                               "GPL-3.0+",
-                               "GPL-3.0-with-autoconf-exception",
-                               "GPL-3.0-with-GCC-exception",
-                               "LGPL-2.1",
-                               "LGPL-2.1+",
-                               "LGPL-3.0",
-                               "LGPL-3.0+",
-                               "LGPL-2.0",
-                               "LGPL-2.0+",
-                               "gSOAP-1.3b",
-                               "HPND",
-                               "IBM-pibs",
-                               "IPL-1.0",
-                               "Imlib2",
-                               "IJG",
-                               "Intel",
-                               "IPA",
-                               "ISC",
-                               "JSON",
-                               "LPPL-1.3a",
-                               "LPPL-1.0",
-                               "LPPL-1.1",
-                               "LPPL-1.2",
-                               "LPPL-1.3c",
-                               "Libpng",
-                               "LPL-1.02",
-                               "LPL-1.0",
-                               "MS-PL",
-                               "MS-RL",
-                               "MirOS",
-                               "MIT",
-                               "Motosoto",
-                               "MPL-1.0",
-                               "MPL-1.1",
-                               "MPL-2.0",
-                               "MPL-2.0-no-copyleft-exception",
-                               "Multics",
-                               "NASA-1.3",
-                               "Naumen",
-                               "NBPL-1.0",
-                               "NGPL",
-                               "NOSL",
-                               "NPL-1.0",
-                               "NPL-1.1",
-                               "Nokia",
-                               "NPOSL-3.0",
-                               "NTP",
-                               "OCLC-2.0",
-                               "ODbL-1.0",
-                               "PDDL-1.0",
-                               "OGTSL",
-                               "OLDAP-2.2.2",
-                               "OLDAP-1.1",
-                               "OLDAP-1.2",
-                               "OLDAP-1.3",
-                               "OLDAP-1.4",
-                               "OLDAP-2.0",
-                               "OLDAP-2.0.1",
-                               "OLDAP-2.1",
-                               "OLDAP-2.2",
-                               "OLDAP-2.2.1",
-                               "OLDAP-2.3",
-                               "OLDAP-2.4",
-                               "OLDAP-2.5",
-                               "OLDAP-2.6",
-                               "OLDAP-2.7",
-                               "OPL-1.0",
-                               "OSL-1.0",
-                               "OSL-2.0",
-                               "OSL-2.1",
-                               "OSL-3.0",
-                               "OLDAP-2.8",
-                               "OpenSSL",
-                               "PHP-3.0",
-                               "PHP-3.01",
-                               "PostgreSQL",
-                               "Python-2.0",
-                               "QPL-1.0",
-                               "RPSL-1.0",
-                               "RPL-1.1",
-                               "RPL-1.5",
-                               "RHeCos-1.1",
-                               "RSCPL",
-                               "Ruby",
-                               "SAX-PD",
-                               "SGI-B-1.0",
-                               "SGI-B-1.1",
-                               "SGI-B-2.0",
-                               "OFL-1.0",
-                               "OFL-1.1",
-                               "SimPL-2.0",
-                               "Sleepycat",
-                               "SMLNJ",
-                               "SugarCRM-1.1.3",
-                               "SISSL",
-                               "SISSL-1.2",
-                               "SPL-1.0",
-                               "Watcom-1.0",
-                               "NCSA",
-                               "VSL-1.0",
-                               "W3C",
-                               "WXwindows",
-                               "Xnet",
-                               "X11",
-                               "XFree86-1.1",
-                               "YPL-1.0",
-                               "YPL-1.1",
-                               "Zimbra-1.3",
-                               "Zlib",
-                               "ZPL-1.1",
-                               "ZPL-2.0",
-                               "ZPL-2.1",
-                               "Unlicense"
-                       ]
+                       "description": "SPDX identifier for the license under which the extension is released."
                },
                "requires": {
                        "type": "object",
                                                                        "items": {
                                                                                "type": "string"
                                                                        }
+                                                               },
+                                                               "noflip": {
+                                                                       "type": "boolean",
+                                                                       "description": "Whether to skip CSSJanus LTR-to-RTL flipping for this module. Recommended for styles imported from libraries that already properly handle their RTL styles. Default is false, meaning CSSJanus will be applied on RTL-mode output."
                                                                }
                                                        }
                                                },
                "SkinOOUIThemes": {
                        "type": "object"
                },
+               "PasswordPolicy": {
+                       "type": "object",
+                       "description": "Password policies"
+               },
+               "FileExtensions": {
+                       "type": "object",
+                       "description": "Preferred file extensions for uploading"
+               },
                "callback": {
                        "type": [
                                "array",
                                                        "type": "string",
                                                        "enum": [
                                                                "array_merge_recursive",
+                                                               "array_replace_recursive",
                                                                "array_plus_2d",
                                                                "array_plus",
                                                                "array_merge"
index 2bfeb66..a73d50f 100644 (file)
@@ -464,6 +464,41 @@ $moduleManager: ApiModuleManager Module manager instance
 action=query submodule. Use this to extend core API modules.
 &$module: Module object
 
+'ApiQueryBaseAfterQuery': Called for (some) API query modules after the
+database query has returned. An API query module wanting to use this hook
+should see the ApiQueryBase::select() and ApiQueryBase::processRow()
+documentation.
+$module: ApiQueryBase module in question
+$result: ResultWrapper|bool returned from the IDatabase::select()
+&$hookData: array that was passed to the 'ApiQueryBaseBeforeQuery' hook and
+ will be passed to the 'ApiQueryBaseProcessRow' hook, intended for inter-hook
+ communication.
+
+'ApiQueryBaseBeforeQuery': Called for (some) API query modules before a
+database query is made. WARNING: It would be very easy to misuse this hook and
+break the module! Any joins added *must* join on a unique key of the target
+table unless you really know what you're doing. An API query module wanting to
+use this hook should see the ApiQueryBase::select() and
+ApiQueryBase::processRow() documentation.
+$module: ApiQueryBase module in question
+&$tables: array of tables to be queried
+&$fields: array of columns to select
+&$conds: array of WHERE conditionals for query
+&$query_options: array of options for the database request
+&$join_conds: join conditions for the tables
+&$hookData: array that will be passed to the 'ApiQueryBaseAfterQuery' and
+ 'ApiQueryBaseProcessRow' hooks, intended for inter-hook communication.
+
+'ApiQueryBaseProcessRow': Called for (some) API query modules as each row of
+the database result is processed. Return false to stop processing the result
+set. An API query module wanting to use this hook should see the
+ApiQueryBase::select() and ApiQueryBase::processRow() documentation.
+$module: ApiQueryBase module in question
+$row: stdClass Database result row
+&$data: array to be included in the ApiResult.
+&$hookData: array that was be passed to the 'ApiQueryBaseBeforeQuery' and
+ 'ApiQueryBaseAfterQuery' hooks, intended for inter-hook communication.
+
 'APIQueryGeneratorAfterExecute': After calling the executeGenerator() method of
 an action=query submodule. Use this to extend core API modules.
 &$module: Module object
@@ -530,6 +565,18 @@ your callback to the $tokenFunctions array and return true (returning false
 makes no sense).
 &$tokenFunctions: array(action => callback)
 
+'ApiQueryWatchlistExtractOutputData': Extract row data for ApiQueryWatchlist.
+$module: ApiQueryWatchlist instance
+$watchedItem: WatchedItem instance
+$recentChangeInfo: Array of recent change info data
+&$vals: Associative array of data to be output for the row
+
+'ApiQueryWatchlistPrepareWatchedItemQueryServiceOptions': Populate the options
+to be passed from ApiQueryWatchlist to WatchedItemQueryService.
+$module: ApiQueryWatchlist instance
+$params: Array of parameters, as would be returned by $module->extractRequestParams()
+&$options: Array of options for WatchedItemQueryService::getWatchedItemsWithRecentChangeInfo()
+
 'ApiRsdServiceApis': Add or remove APIs from the RSD services list. Each service
 should have its own entry in the $apis array and have a unique name, passed as
 key for the array that represents the service data. In this data array, the
@@ -1019,6 +1066,18 @@ $user: user initiating the action
 uses are in active use.
 &$tags: list of all active tags. Append to this array.
 
+'ChangeTagsAfterUpdateTags': Called after tags have been updated with the
+ChangeTags::updateTags function. Params:
+$addedTags: tags effectively added in the update
+$removedTags: tags effectively removed in the update
+$prevTags: tags that were present prior to the update
+$rc_id: recentchanges table id
+$rev_id: revision table id
+$log_id: logging table id
+$params: tag params
+$rc: RecentChange being tagged when the tagging accompanies the action or null
+$user: User who performed the tagging when the tagging is subsequent to the action or null
+
 'Collation::factory': Called if $wgCategoryCollation is an unknown collation.
 $collationName: Name of the collation in question
 &$collationObject: Null. Replace with a subclass of the Collation class that
@@ -1141,7 +1200,6 @@ wrapped in a span element which has class="patrollink".
 $differenceEngine: DifferenceEngine object
 &$markAsPatrolledLink: The "mark as patrolled" link HTML (string)
 $rcid: Recent change ID (rc_id) for this change (int)
-$token: Patrol token; $rcid is used in generating this variable
 
 'DifferenceEngineMarkPatrolledRCID': Allows extensions to possibly change the rcid parameter.
 For example the rcid might be set to zero due to the user being the same as the
@@ -1196,7 +1254,7 @@ $out: OutputPage object
 $parserOutput: ParserOutput object
 $wikiPage: WikiPage object
 
-DifferenceEngineRenderRevisionShowFinalPatrolLink': An extension can hook into this hook
+'DifferenceEngineRenderRevisionShowFinalPatrolLink': An extension can hook into this hook
 point and return false to not show the final "mark as patrolled" link on the bottom
 of a page.
 This hook has no arguments.
@@ -1867,8 +1925,8 @@ $code: language of the preferred translations
 in various places to allow extensions to define the effective language
 links for a page.
 $title: The page's Title.
-&$links: Associative array mapping language codes to prefixed links of the
-  form "language:title".
+&$links: Array with elements of the form "language:title" in the order
+  that they will be output.
 &$linkFlags: Associative array mapping prefixed links to arrays of flags.
   Currently unused, but planned to provide support for marking individual
   language links in the UI, e.g. for featured articles.
@@ -2406,6 +2464,13 @@ $revId: ID of the revision that was parsed to create $parserOutput
 'ParserCloned': Called when the parser is cloned.
 $parser: Newly-cloned Parser object
 
+'ParserFetchTemplate': Called when the parser fetches a template
+$parser: Parser Parser object or false
+$title: Title object of the template to be fetched
+$rev: Revision object of the template
+&$text: Transclusion text of the template or false or null
+&$deps: Array of template dependencies with 'title', 'page_id', 'rev_id' keys
+
 'ParserFirstCallInit': Called when the parser initialises for the first time.
 &$parser: Parser object being cleared
 
@@ -2428,12 +2493,24 @@ cache or return false to not use it.
 &$parser: Parser object
 &$varCache: variable cache (array)
 
-'ParserLimitReport': DEPRECATED! Use ParserLimitReportPrepare instead.
+'ParserLimitReport': DEPRECATED! Use ParserLimitReportPrepare and
+ParserLimitReportFormat instead.
 Called at the end of Parser:parse() when the parser will
 include comments about size of the text parsed.
 $parser: Parser object
 &$limitReport: text that will be included (without comment tags)
 
+'ParserLimitReportFormat': Called for each row in the parser limit report that
+needs formatting. If nothing handles this hook, the default is to use "$key" to
+get the label, and "$key-value" or "$key-value-text"/"$key-value-html" to
+format the value.
+$key: Key for the limit report item (string)
+&$value: Value of the limit report item
+&$report: String onto which to append the data
+$isHTML: If true, $report is an HTML table with two columns; if false, it's
+  text intended for display in a monospaced font.
+$localize: If false, $report should be output in English.
+
 'ParserLimitReportPrepare': Called at the end of Parser:parse() when the parser
 will include comments about size of the text parsed. Hooks should use
 $output->setLimitReportData() to populate data. Functions for this hook should
@@ -2462,10 +2539,6 @@ $showEditLinks: boolean describing whether this section has an edit link
 &$globals: Array with all the globals which should be set for parser tests.
   The arrays keys serve as the globals names, its values are the globals values.
 
-'ParserTestParser': Called when creating a new instance of Parser in
-tests/parser/parserTest.inc.
-&$parser: Parser object created
-
 'ParserTestTables': Alter the list of tables to duplicate when parser tests are
 run. Use when page save hooks require the presence of custom tables to ensure
 that tests continue to run properly.
@@ -3151,6 +3224,15 @@ $engine: the search engine
   message key to use in the name column,
 $context: IContextSource object
 
+'SpecialTrackingCategories::preprocess': Called after LinkBatch on Special:TrackingCategories
+$specialPage: The SpecialTrackingCategories object
+$trackingCategories: Array of data from Special:TrackingCategories with msg and cats
+
+'SpecialTrackingCategories::generateCatLink': Called for each cat link on Special:TrackingCategories
+$specialPage: The SpecialTrackingCategories object
+$catTitle: The Title object of the linked category
+&$html: The Result html
+
 'SpecialUploadComplete': Called after successfully uploading a file from
 Special:Upload.
 &$form: The SpecialUpload object
@@ -3302,7 +3384,7 @@ PageArchive object has been created but before any further processing is done.
 &$archive: PageArchive object
 $title: Title object of the page that we're viewing
 
-'UndeleteForm::undelete': Called un UndeleteForm::undelete, after checking that
+'UndeleteForm::undelete': Called in UndeleteForm::undelete, after checking that
 the site is not in read-only mode, that the Title object is not null and after
 a PageArchive object has been constructed but before performing any further
 processing.
@@ -3688,6 +3770,10 @@ used to alter the SQL query which gets the list of wanted pages.
 &$user: user that watched
 &$page: WikiPage object watched
 
+'WatchedItemQueryServiceExtensions': Create a WatchedItemQueryServiceExtension.
+&$extensions: Add WatchedItemQueryServiceExtension objects to this array
+$watchedItemQueryService: Service object
+
 'WatchlistEditorBeforeFormRender': Before building the Special:EditWatchlist
 form, used to manipulate the list of pages or preload data based on that list.
 &$watchlistInfo: array of watchlisted pages in
@@ -3744,6 +3830,10 @@ $content: the Content to generate updates for (or null, if the Content could not
 due to an error)
 &$updates: the array of DataUpdate objects. Hook function may want to add to it.
 
+'WikiPageFactory': Override WikiPage class used for a title
+$title: Title of the page
+&$page: Variable to set the created WikiPage to.
+
 'XmlDumpWriterOpenPage': Called at the end of XmlDumpWriter::openPage, to allow
 extra metadata to be added.
 $obj: The XmlDumpWriter object.
index 9142238..d444a27 100644 (file)
@@ -90,7 +90,6 @@ class AjaxDispatcher {
                                # Or we could throw an exception:
                                # throw new MWException( __METHOD__ . ' called without any data (mode empty).' );
                }
-
        }
 
        /**
@@ -156,6 +155,5 @@ class AjaxDispatcher {
                                }
                        }
                }
-
        }
 }
index 4fe46dd..0686578 100644 (file)
@@ -161,7 +161,7 @@ class AjaxResponse {
                        // For back-compat, it is supported that mResponseCode be a string like " 200 OK"
                        // (with leading space and the status message after). Cast response code to an integer
                        // to take advantage of PHP's conversion rules which will turn "  200 OK" into 200.
-                       // http://php.net/string#language.types.string.conversion
+                       // https://secure.php.net/manual/en/language.types.string.php#language.types.string.conversion
                        $n = intval( trim( $this->mResponseCode ) );
                        HttpStatus::header( $n );
                }
index 098d51c..8663d03 100644 (file)
@@ -692,11 +692,13 @@ class Block {
        public static function isWhitelistedFromAutoblocks( $ip ) {
                // Try to get the autoblock_whitelist from the cache, as it's faster
                // than getting the msg raw and explode()'ing it.
-               $cache = ObjectCache::getMainWANInstance();
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                $lines = $cache->getWithSetCallback(
                        wfMemcKey( 'ipb', 'autoblock', 'whitelist' ),
                        $cache::TTL_DAY,
-                       function () {
+                       function ( $curValue, &$ttl, array &$setOpts ) {
+                               $setOpts += Database::getCacheSetOptions( wfGetDB( DB_REPLICA ) );
+
                                return explode( "\n",
                                        wfMessage( 'autoblock_whitelist' )->inContentLanguage()->plain() );
                        }
@@ -1415,6 +1417,33 @@ class Block {
                $this->blocker = $user;
        }
 
+       /**
+        * Set the 'BlockID' cookie to this block's ID and expiry time. The cookie's expiry will be
+        * the same as the block's, unless it's greater than $wgCookieExpiration in which case
+        * $wgCookieExpiration will be used instead (defaults to 30 days).
+        *
+        * An empty value can also be set, in order to retain the cookie but remove the block ID
+        * (e.g. as used in User::getBlockedStatus).
+        *
+        * @param WebResponse $response The response on which to set the cookie.
+        * @param boolean $setEmpty Whether to set the cookie's value to the empty string.
+        */
+       public function setCookie( WebResponse $response, $setEmpty = false ) {
+               // Calculate the default expiry time.
+               $config = RequestContext::getMain()->getConfig();
+               $defaultExpiry = wfTimestamp() + $config->get( 'CookieExpiration' );
+
+               // Use the Block's expiry time only if it's less than the default.
+               $expiry = wfTimestamp( TS_UNIX, $this->getExpiry() );
+               if ( $expiry > $defaultExpiry ) {
+                       // The *default* default expiry is 30 days.
+                       $expiry = $defaultExpiry;
+               }
+
+               $cookieValue = $setEmpty ? '' : $this->getId();
+               $response->setCookie( 'BlockID', $cookieValue, $expiry );
+       }
+
        /**
         * Get the key and parameters for the corresponding error message.
         *
index 53e855b..b95f274 100644 (file)
@@ -321,6 +321,8 @@ class CategoryViewer extends ContextSource {
                                array_merge(
                                        LinkCache::getSelectFields(),
                                        [
+                                               'page_namespace',
+                                               'page_title',
                                                'cl_sortkey',
                                                'cat_id',
                                                'cat_title',
@@ -420,26 +422,11 @@ class CategoryViewer extends ContextSource {
                return $r;
        }
 
-       /**
-        * Return pretty name which is display name if given and different from prefix text or
-        * the unprefixed page name.
-        *
-        * @return string HTML safe name.
-        */
-       function getPrettyPageNameHtml() {
-               $displayTitle = $this->getOutput()->getPageTitle();
-               if ( $displayTitle === $this->getTitle()->getPrefixedText() ) {
-                       return htmlspecialchars( $this->getTitle()->getText() );
-               } else {
-                       return $displayTitle;
-               }
-       }
-
        /**
         * @return string
         */
        function getPagesSection() {
-               $name = $this->getPrettyPageNameHtml();
+               $ti = wfEscapeWikiText( $this->title->getText() );
                # Don't show articles section if there are none.
                $r = '';
 
@@ -455,7 +442,7 @@ class CategoryViewer extends ContextSource {
 
                if ( $rescnt > 0 ) {
                        $r = "<div id=\"mw-pages\">\n";
-                       $r .= '<h2>' . $this->msg( 'category_header' )->rawParams( $name )->parse() . "</h2>\n";
+                       $r .= '<h2>' . $this->msg( 'category_header', $ti )->parse() . "</h2>\n";
                        $r .= $countmsg;
                        $r .= $this->getSectionPagingLinks( 'page' );
                        $r .= $this->formatList( $this->articles, $this->articles_start_char );
@@ -469,7 +456,6 @@ class CategoryViewer extends ContextSource {
         * @return string
         */
        function getImageSection() {
-               $name = $this->getPrettyPageNameHtml();
                $r = '';
                $rescnt = $this->showGallery ? $this->gallery->count() : count( $this->imgsNoGallery );
                $dbcnt = $this->cat->getFileCount();
@@ -479,7 +465,10 @@ class CategoryViewer extends ContextSource {
                if ( $rescnt > 0 ) {
                        $r .= "<div id=\"mw-category-media\">\n";
                        $r .= '<h2>' .
-                               $this->msg( 'category-media-header' )->rawParams( $name )->parse() .
+                               $this->msg(
+                                       'category-media-header',
+                                       wfEscapeWikiText( $this->title->getText() )
+                               )->text() .
                                "</h2>\n";
                        $r .= $countmsg;
                        $r .= $this->getSectionPagingLinks( 'file' );
index 7facf2f..32717f1 100644 (file)
@@ -75,7 +75,7 @@ $wgConfigRegistry = [
  * MediaWiki version number
  * @since 1.2
  */
-$wgVersion = '1.28.0-alpha';
+$wgVersion = '1.29.0-alpha';
 
 /**
  * Name of the site. It must be changed in LocalSettings.php
@@ -311,7 +311,7 @@ $wgAppleTouchIcon = false;
  * Value for the referrer policy meta tag.
  * One of 'never', 'default', 'origin', 'always'. Setting it to false just
  * prevents the meta tag from being output.
- * See http://www.w3.org/TR/referrer-policy/ for details.
+ * See https://www.w3.org/TR/referrer-policy/ for details.
  *
  * @since 1.25
  */
@@ -658,7 +658,7 @@ $wgLockManagers = [];
 
 /**
  * Show Exif data, on by default if available.
- * Requires PHP's Exif extension: http://www.php.net/manual/en/ref.exif.php
+ * Requires PHP's Exif extension: https://secure.php.net/manual/en/ref.exif.php
  *
  * @note FOR WINDOWS USERS:
  * To enable Exif functions, add the following line to the "Windows
@@ -1511,7 +1511,7 @@ $wgDjvuTxt = null;
  * For now we recommend you use djvudump instead. The djvuxml output is
  * probably more stable, so we'll switch back to it as soon as they fix
  * the efficiency problem.
- * http://sourceforge.net/tracker/index.php?func=detail&aid=1704049&group_id=32953&atid=406583
+ * https://sourceforge.net/tracker/index.php?func=detail&aid=1704049&group_id=32953&atid=406583
  *
  * @par Example:
  * @code
@@ -1973,7 +1973,7 @@ $wgDBerrorLog = false;
  * Defaults to the wiki timezone ($wgLocaltimezone).
  *
  * A list of usable timezones can found at:
- * http://php.net/manual/en/timezones.php
+ * https://secure.php.net/manual/en/timezones.php
  *
  * @par Examples:
  * @code
@@ -2211,7 +2211,7 @@ $wgCacheDirectory = false;
  *   - CACHE_NONE:       Do not cache
  *   - CACHE_DB:         Store cache objects in the DB
  *   - CACHE_MEMCACHED:  MemCached, must specify servers in $wgMemCachedServers
- *   - CACHE_ACCEL:      APC, XCache or WinCache
+ *   - CACHE_ACCEL:      APC, APCU, XCache or WinCache
  *   - (other):          A string may be used which identifies a cache
  *                       configuration in $wgObjectCaches.
  *
@@ -2288,6 +2288,7 @@ $wgObjectCaches = [
        ],
 
        'apc' => [ 'class' => 'APCBagOStuff', 'reportDupes' => false ],
+       'apcu' => [ 'class' => 'APCUBagOStuff', 'reportDupes' => false ],
        'xcache' => [ 'class' => 'XCacheBagOStuff', 'reportDupes' => false ],
        'wincache' => [ 'class' => 'WinCacheBagOStuff', 'reportDupes' => false ],
        'memcached-php' => [ 'class' => 'MemcachedPhpBagOStuff', 'loggroup' => 'memcached' ],
@@ -3109,7 +3110,7 @@ $wgForceUIMsgAsContentMsg = [];
  * timezone-nameinlowercase like timezone-utc.
  *
  * A list of usable timezones can found at:
- * http://php.net/manual/en/timezones.php
+ * https://secure.php.net/manual/en/timezones.php
  *
  * @par Examples:
  * @code
@@ -3177,7 +3178,7 @@ $wgHtml5 = true;
  *
  * If your wiki uses RDFa, set it to the correct value for RDFa+HTML5.
  * Correct current values are 'HTML+RDFa 1.0' or 'XHTML+RDFa 1.0'.
- * See also http://www.w3.org/TR/rdfa-in-html/#document-conformance
+ * See also https://www.w3.org/TR/rdfa-in-html/#document-conformance
  * @since 1.16
  */
 $wgHtml5Version = null;
@@ -4215,7 +4216,7 @@ $wgAllowImageTag = false;
 /**
  * Configuration for HTML postprocessing tool. Set this to a configuration
  * array to enable an external tool. Dave Raggett's "HTML Tidy" is typically
- * used. See http://www.w3.org/People/Raggett/tidy/
+ * used. See https://www.w3.org/People/Raggett/tidy/
  *
  * If this is null and $wgUseTidy is true, the deprecated configuration
  * parameters will be used instead.
@@ -4362,9 +4363,9 @@ $wgTranscludeCacheExpiry = 3600;
  * @since 1.28
  */
 $wgEnableMagicLinks = [
-       'ISBN' => true,
-       'PMID' => true,
-       'RFC' => true
+       'ISBN' => false,
+       'PMID' => false,
+       'RFC' => false
 ];
 
 /** @} */ # end of parser settings }
@@ -5532,13 +5533,7 @@ $wgApplyIpBlocksToXff = false;
  * elapses.
  *
  * @par Example:
- * To set a generic maximum of 4 hits in 60 seconds:
- * @code
- *     $wgRateLimits = [ 4, 60 ];
- * @endcode
- *
- * @par Example:
- * You could also limit per action and then type of users.
+ * Limits per configured per action and then type of users.
  * @code
  *     $wgRateLimits = [
  *         'edit' => [
@@ -5547,8 +5542,20 @@ $wgApplyIpBlocksToXff = false;
  *             'newbie' => [ x, y ], // each new autoconfirmed accounts; overrides 'user'
  *             'ip' => [ x, y ], // each anon and recent account
  *             'subnet' => [ x, y ], // ... within a /24 subnet in IPv4 or /64 in IPv6
+ *             'groupName' => [ x, y ], // by group membership
  *         ]
- *     ]
+ *     ];
+ * @endcode
+ *
+ * @par Normally, the 'noratelimit' right allows a user to bypass any rate
+ * limit checks. This can be disabled on a per-action basis by setting the
+ * special '&can-bypass' key to false in that action's configuration.
+ * @code
+ *     $wgRateLimits = [
+ *         'some-action' => [
+ *             '&can-bypass' => false,
+ *             'user' => [ x, y ],
+ *     ];
  * @endcode
  *
  * @warning Requires that $wgMainCacheType is set to something persistent
@@ -5740,6 +5747,8 @@ $wgGrantPermissions['viewdeleted']['browsearchive'] = true;
 $wgGrantPermissions['viewdeleted']['deletedhistory'] = true;
 $wgGrantPermissions['viewdeleted']['deletedtext'] = true;
 
+$wgGrantPermissions['viewrestrictedlogs']['suppressionlog'] = true;
+
 $wgGrantPermissions['delete'] = $wgGrantPermissions['editpage'] +
        $wgGrantPermissions['viewdeleted'];
 $wgGrantPermissions['delete']['delete'] = true;
@@ -5790,6 +5799,7 @@ $wgGrantPermissionGroups = [
        'blockusers'          => 'administration',
        'delete'              => 'administration',
        'viewdeleted'         => 'administration',
+       'viewrestrictedlogs'  => 'administration',
        'protect'             => 'administration',
        'createaccount'       => 'administration',
 
@@ -5854,7 +5864,7 @@ $wgProxyList = [];
 /**
  * Default cookie lifetime, in seconds. Setting to 0 makes all cookies session-only.
  */
-$wgCookieExpiration = 180 * 86400;
+$wgCookieExpiration = 30 * 86400;
 
 /**
  * Default login cookie lifetime, in seconds. Setting
@@ -5862,7 +5872,7 @@ $wgCookieExpiration = 180 * 86400;
  * calculate the cookie lifetime. As with $wgCookieExpiration, 0 will make
  * login cookies session-only.
  */
-$wgExtendedLoginCookieExpiration = null;
+$wgExtendedLoginCookieExpiration = 180 * 86400;
 
 /**
  * Set to set an explicit domain on the login cookies eg, "justthis.domain.org"
@@ -5916,6 +5926,12 @@ $wgCacheVaryCookies = [];
  */
 $wgSessionName = false;
 
+/**
+ * Whether to set a cookie when a user is autoblocked. Doing so means that a blocked user, even
+ * after logging out and moving to a new IP address, will still be blocked.
+ */
+$wgCookieSetOnAutoblock = false;
+
 /** @} */ # end of cookie settings }
 
 /************************************************************************//**
@@ -6022,7 +6038,7 @@ $wgTrxProfilerLimits = [
        'JobRunner' => [
                'readQueryTime' => 30,
                'writeQueryTime' => 5,
-               'maxAffected' => 1000
+               'maxAffected' => 500 // ballpark of $wgUpdateRowsPerQuery
        ],
        // Command-line scripts
        'Maintenance' => [
@@ -6365,9 +6381,9 @@ $wgDisableInternalSearch = false;
  * To forward to Google you'd have something like:
  * @code
  * $wgSearchForwardUrl =
- *     'http://www.google.com/search?q=$1' .
- *     '&domains=http://example.com' .
- *     '&sitesearch=http://example.com' .
+ *     'https://www.google.com/search?q=$1' .
+ *     '&domains=https://example.com' .
+ *     '&sitesearch=https://example.com' .
  *     '&ie=utf-8&oe=utf-8';
  * @endcode
  */
@@ -6700,9 +6716,9 @@ $wgFeedDiffCutoff = 32768;
  * Should be a format as key (either 'rss' or 'atom') and an URL to the feed
  * as value.
  * @par Example:
- * Configure the 'atom' feed to http://example.com/somefeed.xml
+ * Configure the 'atom' feed to https://example.com/somefeed.xml
  * @code
- * $wgSiteFeed['atom'] = "http://example.com/somefeed.xml";
+ * $wgSiteFeed['atom'] = "https://example.com/somefeed.xml";
  * @endcode
  */
 $wgOverrideSiteFeed = [];
@@ -7111,7 +7127,7 @@ $wgAutoloadAttemptLowercase = true;
  *         'Foo Barstein',
  *     ],
  *     'version' => '1.9.0',
- *     'url' => 'http://example.org/example-extension/',
+ *     'url' => 'https://example.org/example-extension/',
  *     'descriptionmsg' => 'exampleextension-desc',
  *     'license-name' => 'GPL-2.0+',
  * ];
@@ -7138,7 +7154,7 @@ $wgAutoloadAttemptLowercase = true;
  * - author: A string or an array of strings. Authors can be linked using
  *    the regular wikitext link syntax. To have an internationalized version of
  *    "and others" show, add an element "...". This element can also be linked,
- *    for instance "[http://example ...]".
+ *    for instance "[https://example ...]".
  *
  * - descriptionmsg: A message key or an an array with message key and parameters:
  *    `'descriptionmsg' => 'exampleextension-desc',`
@@ -7356,7 +7372,7 @@ $wgCategoryPagingLimit = 200;
  *     all languages in a mediocre way. However, it is better than "uppercase".
  *
  * To use the uca-default collation, you must have PHP's intl extension
- * installed. See http://php.net/manual/en/intl.setup.php . The details of the
+ * installed. See https://secure.php.net/manual/en/intl.setup.php . The details of the
  * resulting collation will depend on the version of ICU installed on the
  * server.
  *
@@ -8025,7 +8041,7 @@ $wgShellCgroup = false;
 $wgPhpCli = '/usr/bin/php';
 
 /**
- * Locale for LC_CTYPE, to work around http://bugs.php.net/bug.php?id=45132
+ * Locale for LC_CTYPE, to work around https://bugs.php.net/bug.php?id=45132
  * For Unix-like operating systems, set this to to a locale that has a UTF-8
  * character set. Only the character set is relevant.
  */
@@ -8370,9 +8386,9 @@ $wgSearchRunSuggestedQuery = true;
 /**
  * Where popular password file is located.
  *
- * Default in core contains 50,000 most popular. This config
+ * Default in core contains 10,000 most popular. This config
  * allows you to change which file, in case you want to generate
- * a password file with > 50000 entries in it.
+ * a password file with > 10000 entries in it.
  *
  * @see maintenance/createCommonPasswordCdb.php
  * @since 1.27
index 529dfb3..0616898 100644 (file)
@@ -77,8 +77,13 @@ define( 'NS_CATEGORY_TALK', 15 );
  * When writing code that should be compatible with older MediaWiki
  * versions, either stick to the old names or define the new constants
  * yourself, if they're not defined already.
+ *
+ * @deprecated since 1.14
  */
 define( 'NS_IMAGE', NS_FILE );
+/**
+ * @deprecated since 1.14
+ */
 define( 'NS_IMAGE_TALK', NS_FILE_TALK );
 /**@}*/
 
@@ -92,32 +97,7 @@ define( 'CACHE_MEMCACHED', 2 );  // MemCached, must specify servers in $wgMemCac
 define( 'CACHE_ACCEL', 3 );      // APC, XCache or WinCache
 /**@}*/
 
-/**@{
- * Media types.
- * This defines constants for the value returned by File::getMediaType()
- */
-// unknown format
-define( 'MEDIATYPE_UNKNOWN', 'UNKNOWN' );
-// some bitmap image or image source (like psd, etc). Can't scale up.
-define( 'MEDIATYPE_BITMAP', 'BITMAP' );
-// some vector drawing (SVG, WMF, PS, ...) or image source (oo-draw, etc). Can scale up.
-define( 'MEDIATYPE_DRAWING', 'DRAWING' );
-// simple audio file (ogg, mp3, wav, midi, whatever)
-define( 'MEDIATYPE_AUDIO', 'AUDIO' );
-// simple video file (ogg, mpg, etc;
-// no not include formats here that may contain executable sections or scripts!)
-define( 'MEDIATYPE_VIDEO', 'VIDEO' );
-// Scriptable Multimedia (flash, advanced video container formats, etc)
-define( 'MEDIATYPE_MULTIMEDIA', 'MULTIMEDIA' );
-// Office Documents, Spreadsheets (office formats possibly containing apples, scripts, etc)
-define( 'MEDIATYPE_OFFICE', 'OFFICE' );
-// Plain text (possibly containing program code or scripts)
-define( 'MEDIATYPE_TEXT', 'TEXT' );
-// binary executable
-define( 'MEDIATYPE_EXECUTABLE', 'EXECUTABLE' );
-// archive file (zip, tar, etc)
-define( 'MEDIATYPE_ARCHIVE', 'ARCHIVE' );
-/**@}*/
+require_once __DIR__ . '/libs/mime/defines.php';
 
 /**@{
  * Antivirus result codes, for use in $wgAntivirusSetup.
index f449283..745f8de 100644 (file)
@@ -22,6 +22,7 @@
 
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
+use Wikimedia\ScopedCallback;
 
 /**
  * The edit page/HTML interface (split from Article)
@@ -407,6 +408,11 @@ class EditPage {
         */
        protected $context;
 
+       /**
+        * @var bool Whether an old revision is edited
+        */
+       private $isOldRev = false;
+
        /**
         * @param Article $article
         */
@@ -1038,7 +1044,6 @@ class EditPage {
 
                // Allow extensions to modify form data
                Hooks::run( 'EditPage::importFormData', [ $this, $request ] );
-
        }
 
        /**
@@ -1613,8 +1618,9 @@ class EditPage {
        protected function runPostMergeFilters( Content $content, Status $status, User $user ) {
                // Run old style post-section-merge edit filter
                if ( !ContentHandler::runLegacyHooks( 'EditFilterMerged',
-                       [ $this, $content, &$this->hookError, $this->summary ] )
-               ) {
+                       [ $this, $content, &$this->hookError, $this->summary ],
+                       '1.21'
+               ) ) {
                        # Error messages etc. could be handled within the hook...
                        $status->fatal( 'hookaborted' );
                        $status->value = self::AS_HOOK_ERROR;
@@ -2230,7 +2236,6 @@ class EditPage {
         * @return bool
         */
        private function mergeChangesIntoContent( &$editContent ) {
-
                $db = wfGetDB( DB_MASTER );
 
                // This is the revision the editor started from
@@ -2321,9 +2326,12 @@ class EditPage {
        }
 
        function setHeaders() {
-               global $wgOut, $wgUser, $wgAjaxEditStash;
+               global $wgOut, $wgUser, $wgAjaxEditStash, $wgCookieSetOnAutoblock;
 
                $wgOut->addModules( 'mediawiki.action.edit' );
+               if ( $wgCookieSetOnAutoblock === true ) {
+                       $wgOut->addModules( 'mediawiki.user.blockcookie' );
+               }
                $wgOut->addModuleStyles( 'mediawiki.action.edit.styles' );
 
                if ( $wgUser->getOption( 'showtoolbar' ) ) {
@@ -2593,10 +2601,21 @@ class EditPage {
 
                $this->setHeaders();
 
-               if ( $this->showHeader() === false ) {
+               $this->addTalkPageText();
+               $this->addEditNotices();
+
+               if ( !$this->isConflict &&
+                       $this->section != '' &&
+                       !$this->isSectionEditSupported() ) {
+                       // We use $this->section to much before this and getVal('wgSection') directly in other places
+                       // at this point we can't reset $this->section to '' to fallback to non-section editing.
+                       // Someone is welcome to try refactoring though
+                       $wgOut->showErrorPage( 'sectioneditnotsupported-title', 'sectioneditnotsupported-text' );
                        return;
                }
 
+               $this->showHeader();
+
                $wgOut->addHTML( $this->editFormPageTop );
 
                if ( $wgUser->getOption( 'previewontop' ) ) {
@@ -2766,9 +2785,8 @@ class EditPage {
                $wgOut->addHTML( Html::rawElement( 'div', [ 'class' => 'hiddencats' ],
                        Linker::formatHiddenCategories( $this->page->getHiddenCategories() ) ) );
 
-               if ( $this->mParserOutput ) {
-                       $wgOut->setLimitReportData( $this->mParserOutput->getLimitReportData() );
-               }
+               $wgOut->addHTML( Html::rawElement( 'div', [ 'class' => 'limitreport' ],
+                       self::getPreviewLimitReport( $this->mParserOutput ) ) );
 
                $wgOut->addModules( 'mediawiki.action.edit.collapsibleFooter' );
 
@@ -2807,7 +2825,6 @@ class EditPage {
                if ( !$wgUser->getOption( 'previewontop' ) ) {
                        $this->displayPreviewArea( $previewOutput, false );
                }
-
        }
 
        /**
@@ -2833,7 +2850,6 @@ class EditPage {
                return Html::rawElement( 'div', [ 'class' => 'templatesUsed' ],
                        $templateListFormatter->format( $templates, $type )
                );
-
        }
 
        /**
@@ -2852,44 +2868,14 @@ class EditPage {
                }
        }
 
-       /**
-        * @return bool
-        */
        protected function showHeader() {
-               global $wgOut, $wgUser, $wgMaxArticleSize, $wgLang;
+               global $wgOut, $wgUser;
                global $wgAllowUserCss, $wgAllowUserJs;
 
-               if ( $this->mTitle->isTalkPage() ) {
-                       $wgOut->addWikiMsg( 'talkpagetext' );
-               }
-
-               // Add edit notices
-               $editNotices = $this->mTitle->getEditNotices( $this->oldid );
-               if ( count( $editNotices ) ) {
-                       $wgOut->addHTML( implode( "\n", $editNotices ) );
-               } else {
-                       $msg = $this->context->msg( 'editnotice-notext' );
-                       if ( !$msg->isDisabled() ) {
-                               $wgOut->addHTML(
-                                       '<div class="mw-editnotice-notext">'
-                                       . $msg->parseAsBlock()
-                                       . '</div>'
-                               );
-                       }
-               }
-
                if ( $this->isConflict ) {
-                       $wgOut->wrapWikiMsg( "<div class='mw-explainconflict'>\n$1\n</div>", 'explainconflict' );
+                       $this->addExplainConflictHeader( $wgOut );
                        $this->editRevId = $this->page->getLatest();
                } else {
-                       if ( $this->section != '' && !$this->isSectionEditSupported() ) {
-                               // We use $this->section to much before this and getVal('wgSection') directly in other places
-                               // at this point we can't reset $this->section to '' to fallback to non-section editing.
-                               // Someone is welcome to try refactoring though
-                               $wgOut->showErrorPage( 'sectioneditnotsupported-title', 'sectioneditnotsupported-text' );
-                               return false;
-                       }
-
                        if ( $this->section != '' && $this->section != 'new' ) {
                                if ( !$this->summary && !$this->preview && !$this->diff ) {
                                        $sectionTitle = self::extractSectionTitle( $this->textbox1 ); // FIXME: use Content object
@@ -2947,6 +2933,7 @@ class EditPage {
                                        if ( !$revision->isCurrent() ) {
                                                $this->mArticle->setOldSubtitle( $revision->getId() );
                                                $wgOut->addWikiMsg( 'editingold' );
+                                               $this->isOldRev = true;
                                        }
                                } elseif ( $this->mTitle->exists() ) {
                                        // Something went wrong
@@ -3014,69 +3001,12 @@ class EditPage {
                        }
                }
 
-               if ( $this->mTitle->isProtected( 'edit' ) &&
-                       MWNamespace::getRestrictionLevels( $this->mTitle->getNamespace() ) !== [ '' ]
-               ) {
-                       # Is the title semi-protected?
-                       if ( $this->mTitle->isSemiProtected() ) {
-                               $noticeMsg = 'semiprotectedpagewarning';
-                       } else {
-                               # Then it must be protected based on static groups (regular)
-                               $noticeMsg = 'protectedpagewarning';
-                       }
-                       LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle, '',
-                               [ 'lim' => 1, 'msgKey' => [ $noticeMsg ] ] );
-               }
-               if ( $this->mTitle->isCascadeProtected() ) {
-                       # Is this page under cascading protection from some source pages?
-                       /** @var Title[] $cascadeSources */
-                       list( $cascadeSources, /* $restrictions */ ) = $this->mTitle->getCascadeProtectionSources();
-                       $notice = "<div class='mw-cascadeprotectedwarning'>\n$1\n";
-                       $cascadeSourcesCount = count( $cascadeSources );
-                       if ( $cascadeSourcesCount > 0 ) {
-                               # Explain, and list the titles responsible
-                               foreach ( $cascadeSources as $page ) {
-                                       $notice .= '* [[:' . $page->getPrefixedText() . "]]\n";
-                               }
-                       }
-                       $notice .= '</div>';
-                       $wgOut->wrapWikiMsg( $notice, [ 'cascadeprotectedwarning', $cascadeSourcesCount ] );
-               }
-               if ( !$this->mTitle->exists() && $this->mTitle->getRestrictions( 'create' ) ) {
-                       LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle, '',
-                               [ 'lim' => 1,
-                                       'showIfEmpty' => false,
-                                       'msgKey' => [ 'titleprotectedwarning' ],
-                                       'wrap' => "<div class=\"mw-titleprotectedwarning\">\n$1</div>" ] );
-               }
+               $this->addPageProtectionWarningHeaders();
 
-               if ( $this->contentLength === false ) {
-                       $this->contentLength = strlen( $this->textbox1 );
-               }
+               $this->addLongPageWarningHeader();
 
-               if ( $this->tooBig || $this->contentLength > $wgMaxArticleSize * 1024 ) {
-                       $wgOut->wrapWikiMsg( "<div class='error' id='mw-edit-longpageerror'>\n$1\n</div>",
-                               [
-                                       'longpageerror',
-                                       $wgLang->formatNum( round( $this->contentLength / 1024, 3 ) ),
-                                       $wgLang->formatNum( $wgMaxArticleSize )
-                               ]
-                       );
-               } else {
-                       if ( !$this->context->msg( 'longpage-hint' )->isDisabled() ) {
-                               $wgOut->wrapWikiMsg( "<div id='mw-edit-longpage-hint'>\n$1\n</div>",
-                                       [
-                                               'longpage-hint',
-                                               $wgLang->formatSize( strlen( $this->textbox1 ) ),
-                                               strlen( $this->textbox1 )
-                                       ]
-                               );
-                       }
-               }
                # Add header copyright warning
                $this->showHeaderCopyrightWarning();
-
-               return true;
        }
 
        /**
@@ -3257,6 +3187,10 @@ HTML
                                        $classes[] = 'mw-textarea-cprotected';
                                }
                        }
+                       # Is an old revision being edited?
+                       if ( $this->isOldRev ) {
+                               $classes[] = 'mw-textarea-oldrev';
+                       }
 
                        $attribs = [ 'tabindex' => 1 ];
 
@@ -3287,27 +3221,9 @@ HTML
                global $wgOut, $wgUser;
 
                $wikitext = $this->safeUnicodeOutput( $text );
-               if ( strval( $wikitext ) !== '' ) {
-                       // Ensure there's a newline at the end, otherwise adding lines
-                       // is awkward.
-                       // But don't add a newline if the ext is empty, or Firefox in XHTML
-                       // mode will show an extra newline. A bit annoying.
-                       $wikitext .= "\n";
-               }
+               $wikitext = $this->addNewLineAtEnd( $wikitext );
 
-               $attribs = $customAttribs + [
-                       'accesskey' => ',',
-                       'id' => $name,
-                       'cols' => $wgUser->getIntOption( 'cols' ),
-                       'rows' => $wgUser->getIntOption( 'rows' ),
-                       // Avoid PHP notices when appending preferences
-                       // (appending allows customAttribs['style'] to still work).
-                       'style' => ''
-               ];
-
-               $pageLang = $this->mTitle->getPageLanguage();
-               $attribs['lang'] = $pageLang->getHtmlCode();
-               $attribs['dir'] = $pageLang->getDir();
+               $attribs = $this->buildTextboxAttribs( $name, $customAttribs, $wgUser );
 
                $wgOut->addHTML( Html::textarea( $name, $wikitext, $attribs ) );
        }
@@ -3410,7 +3326,7 @@ HTML
                }
 
                if ( $newContent ) {
-                       ContentHandler::runLegacyHooks( 'EditPageGetDiffText', [ $this, &$newContent ] );
+                       ContentHandler::runLegacyHooks( 'EditPageGetDiffText', [ $this, &$newContent ], '1.21' );
                        Hooks::run( 'EditPageGetDiffContent', [ $this, &$newContent ] );
 
                        $popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang );
@@ -3494,6 +3410,7 @@ HTML
         *
         * @param Title $title
         * @param string $format Output format, valid values are any function of a Message object
+        * @param Language|string|null $langcode Language code or Language object.
         * @return string
         */
        public static function getCopyrightWarning( $title, $format = 'plain', $langcode = null ) {
@@ -3529,12 +3446,41 @@ HTML
                        return '';
                }
 
-               return ResourceLoader::makeInlineScript(
-                       ResourceLoader::makeConfigSetScript(
-                               [ 'wgPageParseReport' => $output->getLimitReportData() ],
-                               true
-                       )
+               $limitReport = Html::rawElement( 'div', [ 'class' => 'mw-limitReportExplanation' ],
+                       wfMessage( 'limitreport-title' )->parseAsBlock()
                );
+
+               // Show/hide animation doesn't work correctly on a table, so wrap it in a div.
+               $limitReport .= Html::openElement( 'div', [ 'class' => 'preview-limit-report-wrapper' ] );
+
+               $limitReport .= Html::openElement( 'table', [
+                       'class' => 'preview-limit-report wikitable'
+               ] ) .
+                       Html::openElement( 'tbody' );
+
+               foreach ( $output->getLimitReportData() as $key => $value ) {
+                       if ( Hooks::run( 'ParserLimitReportFormat',
+                               [ $key, &$value, &$limitReport, true, true ]
+                       ) ) {
+                               $keyMsg = wfMessage( $key );
+                               $valueMsg = wfMessage( [ "$key-value-html", "$key-value" ] );
+                               if ( !$valueMsg->exists() ) {
+                                       $valueMsg = new RawMessage( '$1' );
+                               }
+                               if ( !$keyMsg->isDisabled() && !$valueMsg->isDisabled() ) {
+                                       $limitReport .= Html::openElement( 'tr' ) .
+                                               Html::rawElement( 'th', null, $keyMsg->parse() ) .
+                                               Html::rawElement( 'td', null, $valueMsg->params( $value )->parse() ) .
+                                               Html::closeElement( 'tr' );
+                               }
+                       }
+               }
+
+               $limitReport .= Html::closeElement( 'tbody' ) .
+                       Html::closeElement( 'table' ) .
+                       Html::closeElement( 'div' );
+
+               return $limitReport;
        }
 
        protected function showStandardInputs( &$tabindex = 2 ) {
@@ -3592,7 +3538,7 @@ HTML
                global $wgOut;
 
                if ( Hooks::run( 'EditPageBeforeConflictDiff', [ &$this, &$wgOut ] ) ) {
-                       $stats = $wgOut->getContext()->getStats();
+                       $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
                        $stats->increment( 'edit.failures.conflict' );
                        // Only include 'standard' namespaces to avoid creating unknown numbers of statsd metrics
                        if (
@@ -3731,7 +3677,7 @@ HTML
                global $wgOut, $wgRawHtml, $wgLang;
                global $wgAllowUserCss, $wgAllowUserJs;
 
-               $stats = $wgOut->getContext()->getStats();
+               $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
 
                if ( $wgRawHtml && !$this->mTokenOk ) {
                        // Could be an offsite preview attempt. This is very unsafe if
@@ -3823,7 +3769,7 @@ HTML
                        }
 
                        $hook_args = [ $this, &$content ];
-                       ContentHandler::runLegacyHooks( 'EditPageGetPreviewText', $hook_args );
+                       ContentHandler::runLegacyHooks( 'EditPageGetPreviewText', $hook_args, '1.25' );
                        Hooks::run( 'EditPageGetPreviewContent', $hook_args );
 
                        $parserResult = $this->doPreviewParse( $content );
@@ -4125,7 +4071,7 @@ HTML
 
        /**
         * Returns an array of html code of the following buttons:
-        * save, diff, preview and live
+        * save, diff and preview
         *
         * @param int $tabindex Current tabindex
         *
@@ -4149,7 +4095,7 @@ HTML
                        'name' => 'wpSave',
                        'tabindex' => ++$tabindex,
                ] + Linker::tooltipAndAccesskeyAttribs( 'save' );
-               $buttons['save'] = Html::submitButton( $buttonLabel, $attribs, [ 'mw-ui-constructive' ] );
+               $buttons['save'] = Html::submitButton( $buttonLabel, $attribs, [ 'mw-ui-progressive' ] );
 
                ++$tabindex; // use the same for preview and live preview
                $attribs = [
@@ -4159,7 +4105,6 @@ HTML
                ] + Linker::tooltipAndAccesskeyAttribs( 'preview' );
                $buttons['preview'] = Html::submitButton( $this->context->msg( 'showpreview' )->text(),
                        $attribs );
-               $buttons['live'] = '';
 
                $attribs = [
                        'id' => 'wpDiff',
@@ -4352,4 +4297,177 @@ HTML
                // reverse the transform that we made for reversibility reasons.
                return strtr( $result, [ "&#x0" => "&#x" ] );
        }
+
+       /**
+        * @since 1.29
+        */
+       protected function addEditNotices() {
+               global $wgOut;
+
+               $editNotices = $this->mTitle->getEditNotices( $this->oldid );
+               if ( count( $editNotices ) ) {
+                       $wgOut->addHTML( implode( "\n", $editNotices ) );
+               } else {
+                       $msg = $this->context->msg( 'editnotice-notext' );
+                       if ( !$msg->isDisabled() ) {
+                               $wgOut->addHTML(
+                                       '<div class="mw-editnotice-notext">'
+                                       . $msg->parseAsBlock()
+                                       . '</div>'
+                               );
+                       }
+               }
+       }
+
+       /**
+        * @since 1.29
+        */
+       protected function addTalkPageText() {
+               global $wgOut;
+
+               if ( $this->mTitle->isTalkPage() ) {
+                       $wgOut->addWikiMsg( 'talkpagetext' );
+               }
+       }
+
+       /**
+        * @since 1.29
+        */
+       protected function addLongPageWarningHeader() {
+               global $wgMaxArticleSize, $wgOut, $wgLang;
+
+               if ( $this->contentLength === false ) {
+                       $this->contentLength = strlen( $this->textbox1 );
+               }
+
+               if ( $this->tooBig || $this->contentLength > $wgMaxArticleSize * 1024 ) {
+                       $wgOut->wrapWikiMsg( "<div class='error' id='mw-edit-longpageerror'>\n$1\n</div>",
+                               [
+                                       'longpageerror',
+                                       $wgLang->formatNum( round( $this->contentLength / 1024, 3 ) ),
+                                       $wgLang->formatNum( $wgMaxArticleSize )
+                               ]
+                       );
+               } else {
+                       if ( !$this->context->msg( 'longpage-hint' )->isDisabled() ) {
+                               $wgOut->wrapWikiMsg( "<div id='mw-edit-longpage-hint'>\n$1\n</div>",
+                                       [
+                                               'longpage-hint',
+                                               $wgLang->formatSize( strlen( $this->textbox1 ) ),
+                                               strlen( $this->textbox1 )
+                                       ]
+                               );
+                       }
+               }
+       }
+
+       /**
+        * @since 1.29
+        */
+       protected function addPageProtectionWarningHeaders() {
+               global $wgOut;
+
+               if ( $this->mTitle->isProtected( 'edit' ) &&
+                       MWNamespace::getRestrictionLevels( $this->mTitle->getNamespace() ) !== [ '' ]
+               ) {
+                       # Is the title semi-protected?
+                       if ( $this->mTitle->isSemiProtected() ) {
+                               $noticeMsg = 'semiprotectedpagewarning';
+                       } else {
+                               # Then it must be protected based on static groups (regular)
+                               $noticeMsg = 'protectedpagewarning';
+                       }
+                       LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle, '',
+                               [ 'lim' => 1, 'msgKey' => [ $noticeMsg ] ] );
+               }
+               if ( $this->mTitle->isCascadeProtected() ) {
+                       # Is this page under cascading protection from some source pages?
+                       /** @var Title[] $cascadeSources */
+                       list( $cascadeSources, /* $restrictions */ ) = $this->mTitle->getCascadeProtectionSources();
+                       $notice = "<div class='mw-cascadeprotectedwarning'>\n$1\n";
+                       $cascadeSourcesCount = count( $cascadeSources );
+                       if ( $cascadeSourcesCount > 0 ) {
+                               # Explain, and list the titles responsible
+                               foreach ( $cascadeSources as $page ) {
+                                       $notice .= '* [[:' . $page->getPrefixedText() . "]]\n";
+                               }
+                       }
+                       $notice .= '</div>';
+                       $wgOut->wrapWikiMsg( $notice, [ 'cascadeprotectedwarning', $cascadeSourcesCount ] );
+               }
+               if ( !$this->mTitle->exists() && $this->mTitle->getRestrictions( 'create' ) ) {
+                       LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle, '',
+                               [ 'lim' => 1,
+                                       'showIfEmpty' => false,
+                                       'msgKey' => [ 'titleprotectedwarning' ],
+                                       'wrap' => "<div class=\"mw-titleprotectedwarning\">\n$1</div>" ] );
+               }
+       }
+
+       /**
+        * @param OutputPage $out
+        * @since 1.29
+        */
+       protected function addExplainConflictHeader( OutputPage $out ) {
+               $out->wrapWikiMsg( "<div class='mw-explainconflict'>\n$1\n</div>", 'explainconflict' );
+       }
+
+       /**
+        * @param string $name
+        * @param mixed[] $customAttribs
+        * @param User $user
+        * @return mixed[]
+        * @since 1.29
+        */
+       protected function buildTextboxAttribs( $name, array $customAttribs, User $user ) {
+               $attribs = $customAttribs + [
+                               'accesskey' => ',',
+                               'id' => $name,
+                               'cols' => $user->getIntOption( 'cols' ),
+                               'rows' => $user->getIntOption( 'rows' ),
+                               // Avoid PHP notices when appending preferences
+                               // (appending allows customAttribs['style'] to still work).
+                               'style' => ''
+                       ];
+
+               // The following classes can be used here:
+               // * mw-editfont-default
+               // * mw-editfont-monospace
+               // * mw-editfont-sans-serif
+               // * mw-editfont-serif
+               $class = 'mw-editfont-' . $user->getOption( 'editfont' );
+
+               if ( isset( $attribs['class'] ) ) {
+                       if ( is_string( $attribs['class'] ) ) {
+                               $attribs['class'] .= ' ' . $class;
+                       } elseif ( is_array( $attribs['class'] ) ) {
+                               $attribs['class'][] = $class;
+                       }
+               } else {
+                       $attribs['class'] = $class;
+               }
+
+               $pageLang = $this->mTitle->getPageLanguage();
+               $attribs['lang'] = $pageLang->getHtmlCode();
+               $attribs['dir'] = $pageLang->getDir();
+
+               return $attribs;
+       }
+
+       /**
+        * @param string $wikitext
+        * @return string
+        * @since 1.29
+        */
+       protected function addNewLineAtEnd( $wikitext ) {
+               if ( strval( $wikitext ) !== '' ) {
+                       // Ensure there's a newline at the end, otherwise adding lines
+                       // is awkward.
+                       // But don't add a newline if the text is empty, or Firefox in XHTML
+                       // mode will show an extra newline. A bit annoying.
+                       $wikitext .= "\n";
+                       return $wikitext;
+               }
+               return $wikitext;
+       }
 }
index 8bfe1c7..189fd9f 100644 (file)
@@ -236,7 +236,6 @@ abstract class ChannelFeed extends FeedItem {
                        $wgOut->addVaryHeader( 'X-Forwarded-Proto' );
                }
                $wgOut->sendCacheControl();
-
        }
 
        /**
index 2725753..2dde17b 100644 (file)
@@ -19,6 +19,7 @@
  *
  * @file
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * Class for managing forking command line scripts.
@@ -150,7 +151,7 @@ class ForkController {
        protected function prepareEnvironment() {
                global $wgMemc;
                // Don't share DB, storage, or memcached connections
-               wfGetLBFactory()->destroyInstance();
+               MediaWikiServices::resetChildProcessServices();
                FileBackendGroup::destroySingleton();
                LockManagerGroup::destroySingletons();
                JobQueueGroup::destroySingletons();
index 5e5e8d4..725a512 100644 (file)
@@ -52,6 +52,9 @@ class FormOptions implements ArrayAccess {
         * This is useful for the namespace selector.
         */
        const INTNULL = 3;
+       /** Array type, maps guessType() to WebRequest::getArray()
+        * @since 1.29 */
+       const ARR = 5;
        /* @} */
 
        /**
@@ -120,6 +123,8 @@ class FormOptions implements ArrayAccess {
                        return self::FLOAT;
                } elseif ( is_string( $data ) ) {
                        return self::STRING;
+               } elseif ( is_array( $data ) ) {
+                       return self::ARR;
                } else {
                        throw new MWException( 'Unsupported datatype' );
                }
@@ -358,6 +363,9 @@ class FormOptions implements ArrayAccess {
                                case self::INTNULL:
                                        $value = $r->getIntOrNull( $name );
                                        break;
+                               case self::ARR:
+                                       $value = $r->getArray( $name );
+                                       break;
                                default:
                                        throw new MWException( 'Unsupported datatype' );
                        }
@@ -370,7 +378,7 @@ class FormOptions implements ArrayAccess {
 
        /** @name ArrayAccess functions
         * These functions implement the ArrayAccess PHP interface.
-        * @see http://php.net/manual/en/class.arrayaccess.php
+        * @see https://secure.php.net/manual/en/class.arrayaccess.php
         */
        /* @{ */
        /**
index 5fe4b4e..b3ccc56 100644 (file)
@@ -27,6 +27,7 @@ if ( !defined( 'MEDIAWIKI' ) ) {
 use Liuggio\StatsdClient\Sender\SocketSender;
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\Session\SessionManager;
+use Wikimedia\ScopedCallback;
 
 // Hide compatibility functions from Doxygen
 /// @cond
@@ -39,7 +40,7 @@ use MediaWiki\Session\SessionManager;
  */
 
 // hash_equals function only exists in PHP >= 5.6.0
-// http://php.net/hash_equals
+// https://secure.php.net/hash_equals
 if ( !function_exists( 'hash_equals' ) ) {
        /**
         * Check whether a user-provided string is equal to a fixed-length secret string
@@ -1624,11 +1625,13 @@ function wfShowingResults( $offset, $limit ) {
 }
 
 /**
- * @todo document
- * @todo FIXME: We may want to blacklist some broken browsers
+ * Whether the client accept gzip encoding
  *
- * @param bool $force
- * @return bool Whereas client accept gzip compression
+ * Uses the Accept-Encoding header to check if the client supports gzip encoding.
+ * Use this when considering to send a gzip-encoded response to the client.
+ *
+ * @param bool $force Forces another check even if we already have a cached result.
+ * @return bool
  */
 function wfClientAcceptsGzip( $force = false ) {
        static $result = null;
@@ -1667,7 +1670,9 @@ function wfClientAcceptsGzip( $force = false ) {
 function wfEscapeWikiText( $text ) {
        global $wgEnableMagicLinks;
        static $repl = null, $repl2 = null;
-       if ( $repl === null ) {
+       if ( $repl === null || defined( 'MW_PARSER_TEST' ) || defined( 'MW_PHPUNIT_TEST' ) ) {
+               // Tests depend upon being able to change $wgEnableMagicLinks, so don't cache
+               // in those situations
                $repl = [
                        '"' => '&#34;', '&' => '&#38;', "'" => '&#39;', '<' => '&#60;',
                        '=' => '&#61;', '>' => '&#62;', '[' => '&#91;', ']' => '&#93;',
@@ -2133,7 +2138,7 @@ function wfMkdirParents( $dir, $mode = null, $caller = null ) {
  */
 function wfRecursiveRemoveDir( $dir ) {
        wfDebug( __FUNCTION__ . "( $dir )\n" );
-       // taken from http://de3.php.net/manual/en/function.rmdir.php#98622
+       // taken from https://secure.php.net/manual/en/function.rmdir.php#98622
        if ( is_dir( $dir ) ) {
                $objects = scandir( $dir );
                foreach ( $objects as $object ) {
@@ -2226,8 +2231,8 @@ function wfEscapeShellArg( /*...*/ ) {
                        // Escaping for an MSVC-style command line parser and CMD.EXE
                        // @codingStandardsIgnoreStart For long URLs
                        // Refs:
-                       //  * http://web.archive.org/web/20020708081031/http://mailman.lyra.org/pipermail/scite-interest/2002-March/000436.html
-                       //  * http://technet.microsoft.com/en-us/library/cc723564.aspx
+                       //  * https://web.archive.org/web/20020708081031/http://mailman.lyra.org/pipermail/scite-interest/2002-March/000436.html
+                       //  * https://technet.microsoft.com/en-us/library/cc723564.aspx
                        //  * T15518
                        //  * CR r63214
                        // Double the backslashes before any double quotes. Escape the double quotes.
@@ -2327,7 +2332,7 @@ function wfShellExec( $cmd, &$retval = null, $environ = [],
                if ( wfIsWindows() ) {
                        /* Surrounding a set in quotes (method used by wfEscapeShellArg) makes the quotes themselves
                         * appear in the environment variable, so we must use carat escaping as documented in
-                        * http://technet.microsoft.com/en-us/library/cc723564.aspx
+                        * https://technet.microsoft.com/en-us/library/cc723564.aspx
                         * Note however that the quote isn't listed there, but is needed, and the parentheses
                         * are listed there but doesn't appear to need it.
                         */
@@ -2545,7 +2550,7 @@ function wfShellExecWithStderr( $cmd, &$retval = null, $environ = [], $limits =
 }
 
 /**
- * Workaround for http://bugs.php.net/bug.php?id=45132
+ * Workaround for https://bugs.php.net/bug.php?id=45132
  * escapeshellarg() destroys non-ASCII characters if LANG is not a UTF-8 locale
  */
 function wfInitShellLocale() {
@@ -2797,7 +2802,7 @@ function wfUseMW( $req_ver ) {
 /**
  * Return the final portion of a pathname.
  * Reimplemented because PHP5's "basename()" is buggy with multibyte text.
- * http://bugs.php.net/bug.php?id=33898
+ * https://bugs.php.net/bug.php?id=33898
  *
  * PHP's basename() only considers '\' a pathchar on Windows and Netware.
  * We'll consider it so always, as we don't want '\s' in our Unix paths either.
@@ -3066,7 +3071,7 @@ function wfSplitWikiID( $wiki ) {
  * @todo Replace calls to wfGetDB with calls to LoadBalancer::getConnection()
  *       on an injected instance of LoadBalancer.
  *
- * @return DatabaseBase
+ * @return Database
  */
 function wfGetDB( $db, $groups = [], $wiki = false ) {
        return wfGetLB( $wiki )->getConnection( $db, $groups, $wiki );
index 48b30c7..0b6b655 100644 (file)
@@ -3,7 +3,7 @@
  * Collection of methods to generate HTML content
  *
  * Copyright © 2009 Aryeh Gregor
- * http://www.mediawiki.org/
+ * https://www.mediawiki.org/
  *
  * 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
@@ -156,10 +156,10 @@ class Html {
         * @param string $contents The raw HTML contents of the element: *not*
         *   escaped!
         * @param array $attrs Associative array of attributes, e.g., [
-        *   'href' => 'http://www.mediawiki.org/' ]. See expandAttributes() for
+        *   'href' => 'https://www.mediawiki.org/' ]. See expandAttributes() for
         *   further documentation.
         * @param string[] $modifiers classes to add to the button
-        * @see http://tools.wmflabs.org/styleguide/desktop/index.html for guidance on available modifiers
+        * @see https://tools.wmflabs.org/styleguide/desktop/index.html for guidance on available modifiers
         * @return string Raw HTML
         */
        public static function linkButton( $contents, array $attrs, array $modifiers = [] ) {
@@ -176,10 +176,10 @@ class Html {
         * @param string $contents The raw HTML contents of the element: *not*
         *   escaped!
         * @param array $attrs Associative array of attributes, e.g., [
-        *   'href' => 'http://www.mediawiki.org/' ]. See expandAttributes() for
+        *   'href' => 'https://www.mediawiki.org/' ]. See expandAttributes() for
         *   further documentation.
         * @param string[] $modifiers classes to add to the button
-        * @see http://tools.wmflabs.org/styleguide/desktop/index.html for guidance on available modifiers
+        * @see https://tools.wmflabs.org/styleguide/desktop/index.html for guidance on available modifiers
         * @return string Raw HTML
         */
        public static function submitButton( $contents, array $attrs, array $modifiers = [] ) {
@@ -200,7 +200,7 @@ class Html {
         *
         * @param string $element The element's name, e.g., 'a'
         * @param array $attribs Associative array of attributes, e.g., [
-        *   'href' => 'http://www.mediawiki.org/' ]. See expandAttributes() for
+        *   'href' => 'https://www.mediawiki.org/' ]. See expandAttributes() for
         *   further documentation.
         * @param string $contents The raw HTML contents of the element: *not*
         *   escaped!
@@ -321,7 +321,7 @@ class Html {
         *
         * @param string $element Name of the element, e.g., 'a'
         * @param array $attribs Associative array of attributes, e.g., [
-        *   'href' => 'http://www.mediawiki.org/' ].  See expandAttributes() for
+        *   'href' => 'https://www.mediawiki.org/' ].  See expandAttributes() for
         *   further documentation.
         * @return array An array of attributes functionally identical to $attribs
         */
@@ -431,8 +431,8 @@ class Html {
        /**
         * Given an associative array of element attributes, generate a string
         * to stick after the element name in HTML output.  Like [ 'href' =>
-        * 'http://www.mediawiki.org/' ] becomes something like
-        * ' href="http://www.mediawiki.org"'.  Again, this is like
+        * 'https://www.mediawiki.org/' ] becomes something like
+        * ' href="https://www.mediawiki.org"'.  Again, this is like
         * Xml::expandAttributes(), but it implements some HTML-specific logic.
         *
         * Attributes that can contain space-separated lists ('class', 'accesskey' and 'rel') array
@@ -458,7 +458,7 @@ class Html {
         * @endcode
         *
         * @param array $attribs Associative array of attributes, e.g., [
-        *   'href' => 'http://www.mediawiki.org/' ].  Values will be HTML-escaped.
+        *   'href' => 'https://www.mediawiki.org/' ].  Values will be HTML-escaped.
         *   A value of false means to omit the attribute.  For boolean attributes,
         *   you can omit the key, e.g., [ 'checked' ] instead of
         *   [ 'checked' => 'checked' ] or such.
@@ -501,8 +501,8 @@ class Html {
                                continue;
                        }
 
-                       // http://www.w3.org/TR/html401/index/attributes.html ("space-separated")
-                       // http://www.w3.org/TR/html5/index.html#attributes-1 ("space-separated")
+                       // https://www.w3.org/TR/html401/index/attributes.html ("space-separated")
+                       // https://www.w3.org/TR/html5/index.html#attributes-1 ("space-separated")
                        $spaceSeparatedListAttributes = [
                                'class', // html4, html5
                                'accesskey', // as of html5, multiple space-separated values allowed
@@ -956,7 +956,7 @@ class Html {
         * @return bool
         */
        public static function isXmlMimeType( $mimetype ) {
-               # http://www.whatwg.org/html/infrastructure.html#xml-mime-type
+               # https://html.spec.whatwg.org/multipage/infrastructure.html#xml-mime-type
                # * text/xml
                # * application/xml
                # * Any MIME type with a subtype ending in +xml (this implicitly includes application/xhtml+xml)
@@ -1005,7 +1005,7 @@ class Html {
         *
         * @note srcset width and height values are not supported.
         *
-        * @see http://www.whatwg.org/html/embedded-content-1.html#attr-img-srcset
+        * @see https://html.spec.whatwg.org/#attr-img-srcset
         *
         * @par Example:
         * @code
diff --git a/includes/HttpFunctions.php b/includes/HttpFunctions.php
deleted file mode 100644 (file)
index 2ca5e1b..0000000
+++ /dev/null
@@ -1,1122 +0,0 @@
-<?php
-/**
- * Various HTTP related functions.
- *
- * 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 HTTP
- */
-
-/**
- * @defgroup HTTP HTTP
- */
-
-use MediaWiki\Logger\LoggerFactory;
-
-/**
- * Various HTTP related functions
- * @ingroup HTTP
- */
-class Http {
-       static public $httpEngine = false;
-
-       /**
-        * Perform an HTTP request
-        *
-        * @param string $method HTTP method. Usually GET/POST
-        * @param string $url Full URL to act on. If protocol-relative, will be expanded to an http:// URL
-        * @param array $options Options to pass to MWHttpRequest object.
-        *      Possible keys for the array:
-        *    - timeout             Timeout length in seconds
-        *    - connectTimeout      Timeout for connection, in seconds (curl only)
-        *    - postData            An array of key-value pairs or a url-encoded form data
-        *    - proxy               The proxy to use.
-        *                          Otherwise it will use $wgHTTPProxy (if set)
-        *                          Otherwise it will use the environment variable "http_proxy" (if set)
-        *    - noProxy             Don't use any proxy at all. Takes precedence over proxy value(s).
-        *    - sslVerifyHost       Verify hostname against certificate
-        *    - sslVerifyCert       Verify SSL certificate
-        *    - caInfo              Provide CA information
-        *    - maxRedirects        Maximum number of redirects to follow (defaults to 5)
-        *    - followRedirects     Whether to follow redirects (defaults to false).
-        *                                  Note: this should only be used when the target URL is trusted,
-        *                                  to avoid attacks on intranet services accessible by HTTP.
-        *    - userAgent           A user agent, if you want to override the default
-        *                          MediaWiki/$wgVersion
-        * @param string $caller The method making this request, for profiling
-        * @return string|bool (bool)false on failure or a string on success
-        */
-       public static function request( $method, $url, $options = [], $caller = __METHOD__ ) {
-               wfDebug( "HTTP: $method: $url\n" );
-
-               $options['method'] = strtoupper( $method );
-
-               if ( !isset( $options['timeout'] ) ) {
-                       $options['timeout'] = 'default';
-               }
-               if ( !isset( $options['connectTimeout'] ) ) {
-                       $options['connectTimeout'] = 'default';
-               }
-
-               $req = MWHttpRequest::factory( $url, $options, $caller );
-               $status = $req->execute();
-
-               if ( $status->isOK() ) {
-                       return $req->getContent();
-               } else {
-                       $errors = $status->getErrorsByType( 'error' );
-                       $logger = LoggerFactory::getInstance( 'http' );
-                       $logger->warning( $status->getWikiText( false, false, 'en' ),
-                               [ 'error' => $errors, 'caller' => $caller, 'content' => $req->getContent() ] );
-                       return false;
-               }
-       }
-
-       /**
-        * Simple wrapper for Http::request( 'GET' )
-        * @see Http::request()
-        * @since 1.25 Second parameter $timeout removed. Second parameter
-        * is now $options which can be given a 'timeout'
-        *
-        * @param string $url
-        * @param array $options
-        * @param string $caller The method making this request, for profiling
-        * @return string|bool false on error
-        */
-       public static function get( $url, $options = [], $caller = __METHOD__ ) {
-               $args = func_get_args();
-               if ( isset( $args[1] ) && ( is_string( $args[1] ) || is_numeric( $args[1] ) ) ) {
-                       // Second was used to be the timeout
-                       // And third parameter used to be $options
-                       wfWarn( "Second parameter should not be a timeout.", 2 );
-                       $options = isset( $args[2] ) && is_array( $args[2] ) ?
-                               $args[2] : [];
-                       $options['timeout'] = $args[1];
-                       $caller = __METHOD__;
-               }
-               return Http::request( 'GET', $url, $options, $caller );
-       }
-
-       /**
-        * Simple wrapper for Http::request( 'POST' )
-        * @see Http::request()
-        *
-        * @param string $url
-        * @param array $options
-        * @param string $caller The method making this request, for profiling
-        * @return string|bool false on error
-        */
-       public static function post( $url, $options = [], $caller = __METHOD__ ) {
-               return Http::request( 'POST', $url, $options, $caller );
-       }
-
-       /**
-        * A standard user-agent we can use for external requests.
-        * @return string
-        */
-       public static function userAgent() {
-               global $wgVersion;
-               return "MediaWiki/$wgVersion";
-       }
-
-       /**
-        * Checks that the given URI is a valid one. Hardcoding the
-        * protocols, because we only want protocols that both cURL
-        * and php support.
-        *
-        * file:// should not be allowed here for security purpose (r67684)
-        *
-        * @todo FIXME this is wildly inaccurate and fails to actually check most stuff
-        *
-        * @param string $uri URI to check for validity
-        * @return bool
-        */
-       public static function isValidURI( $uri ) {
-               return preg_match(
-                       '/^https?:\/\/[^\/\s]\S*$/D',
-                       $uri
-               );
-       }
-
-       /**
-        * Gets the relevant proxy from $wgHTTPProxy
-        *
-        * @return mixed The proxy address or an empty string if not set.
-        */
-       public static function getProxy() {
-               global $wgHTTPProxy;
-
-               if ( $wgHTTPProxy ) {
-                       return $wgHTTPProxy;
-               }
-
-               return "";
-       }
-}
-
-/**
- * This wrapper class will call out to curl (if available) or fallback
- * to regular PHP if necessary for handling internal HTTP requests.
- *
- * Renamed from HttpRequest to MWHttpRequest to avoid conflict with
- * PHP's HTTP extension.
- */
-class MWHttpRequest {
-       const SUPPORTS_FILE_POSTS = false;
-
-       protected $content;
-       protected $timeout = 'default';
-       protected $headersOnly = null;
-       protected $postData = null;
-       protected $proxy = null;
-       protected $noProxy = false;
-       protected $sslVerifyHost = true;
-       protected $sslVerifyCert = true;
-       protected $caInfo = null;
-       protected $method = "GET";
-       protected $reqHeaders = [];
-       protected $url;
-       protected $parsedUrl;
-       protected $callback;
-       protected $maxRedirects = 5;
-       protected $followRedirects = false;
-
-       /**
-        * @var CookieJar
-        */
-       protected $cookieJar;
-
-       protected $headerList = [];
-       protected $respVersion = "0.9";
-       protected $respStatus = "200 Ok";
-       protected $respHeaders = [];
-
-       public $status;
-
-       /**
-        * @var Profiler
-        */
-       protected $profiler;
-
-       /**
-        * @var string
-        */
-       protected $profileName;
-
-       /**
-        * @param string $url Url to use. If protocol-relative, will be expanded to an http:// URL
-        * @param array $options (optional) extra params to pass (see Http::request())
-        * @param string $caller The method making this request, for profiling
-        * @param Profiler $profiler An instance of the profiler for profiling, or null
-        */
-       protected function __construct(
-               $url, $options = [], $caller = __METHOD__, $profiler = null
-       ) {
-               global $wgHTTPTimeout, $wgHTTPConnectTimeout;
-
-               $this->url = wfExpandUrl( $url, PROTO_HTTP );
-               $this->parsedUrl = wfParseUrl( $this->url );
-
-               if ( !$this->parsedUrl || !Http::isValidURI( $this->url ) ) {
-                       $this->status = Status::newFatal( 'http-invalid-url', $url );
-               } else {
-                       $this->status = Status::newGood( 100 ); // continue
-               }
-
-               if ( isset( $options['timeout'] ) && $options['timeout'] != 'default' ) {
-                       $this->timeout = $options['timeout'];
-               } else {
-                       $this->timeout = $wgHTTPTimeout;
-               }
-               if ( isset( $options['connectTimeout'] ) && $options['connectTimeout'] != 'default' ) {
-                       $this->connectTimeout = $options['connectTimeout'];
-               } else {
-                       $this->connectTimeout = $wgHTTPConnectTimeout;
-               }
-               if ( isset( $options['userAgent'] ) ) {
-                       $this->setUserAgent( $options['userAgent'] );
-               }
-
-               $members = [ "postData", "proxy", "noProxy", "sslVerifyHost", "caInfo",
-                               "method", "followRedirects", "maxRedirects", "sslVerifyCert", "callback" ];
-
-               foreach ( $members as $o ) {
-                       if ( isset( $options[$o] ) ) {
-                               // ensure that MWHttpRequest::method is always
-                               // uppercased. Bug 36137
-                               if ( $o == 'method' ) {
-                                       $options[$o] = strtoupper( $options[$o] );
-                               }
-                               $this->$o = $options[$o];
-                       }
-               }
-
-               if ( $this->noProxy ) {
-                       $this->proxy = ''; // noProxy takes precedence
-               }
-
-               // Profile based on what's calling us
-               $this->profiler = $profiler;
-               $this->profileName = $caller;
-       }
-
-       /**
-        * Simple function to test if we can make any sort of requests at all, using
-        * cURL or fopen()
-        * @return bool
-        */
-       public static function canMakeRequests() {
-               return function_exists( 'curl_init' ) || wfIniGetBool( 'allow_url_fopen' );
-       }
-
-       /**
-        * Generate a new request object
-        * @param string $url Url to use
-        * @param array $options (optional) extra params to pass (see Http::request())
-        * @param string $caller The method making this request, for profiling
-        * @throws MWException
-        * @return CurlHttpRequest|PhpHttpRequest
-        * @see MWHttpRequest::__construct
-        */
-       public static function factory( $url, $options = null, $caller = __METHOD__ ) {
-               if ( !Http::$httpEngine ) {
-                       Http::$httpEngine = function_exists( 'curl_init' ) ? 'curl' : 'php';
-               } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) {
-                       throw new MWException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' .
-                               ' Http::$httpEngine is set to "curl"' );
-               }
-
-               switch ( Http::$httpEngine ) {
-                       case 'curl':
-                               return new CurlHttpRequest( $url, $options, $caller, Profiler::instance() );
-                       case 'php':
-                               if ( !wfIniGetBool( 'allow_url_fopen' ) ) {
-                                       throw new MWException( __METHOD__ . ': allow_url_fopen ' .
-                                               'needs to be enabled for pure PHP http requests to ' .
-                                               'work. If possible, curl should be used instead. See ' .
-                                               'http://php.net/curl.'
-                                       );
-                               }
-                               return new PhpHttpRequest( $url, $options, $caller, Profiler::instance() );
-                       default:
-                               throw new MWException( __METHOD__ . ': The setting of Http::$httpEngine is not valid.' );
-               }
-       }
-
-       /**
-        * Get the body, or content, of the response to the request
-        *
-        * @return string
-        */
-       public function getContent() {
-               return $this->content;
-       }
-
-       /**
-        * Set the parameters of the request
-        *
-        * @param array $args
-        * @todo overload the args param
-        */
-       public function setData( $args ) {
-               $this->postData = $args;
-       }
-
-       /**
-        * Take care of setting up the proxy (do nothing if "noProxy" is set)
-        *
-        * @return void
-        */
-       public function proxySetup() {
-               // If there is an explicit proxy set and proxies are not disabled, then use it
-               if ( $this->proxy && !$this->noProxy ) {
-                       return;
-               }
-
-               // Otherwise, fallback to $wgHTTPProxy if this is not a machine
-               // local URL and proxies are not disabled
-               if ( self::isLocalURL( $this->url ) || $this->noProxy ) {
-                       $this->proxy = '';
-               } else {
-                       $this->proxy = Http::getProxy();
-               }
-       }
-
-       /**
-        * Check if the URL can be served by localhost
-        *
-        * @param string $url Full url to check
-        * @return bool
-        */
-       private static function isLocalURL( $url ) {
-               global $wgCommandLineMode, $wgLocalVirtualHosts;
-
-               if ( $wgCommandLineMode ) {
-                       return false;
-               }
-
-               // Extract host part
-               $matches = [];
-               if ( preg_match( '!^https?://([\w.-]+)[/:].*$!', $url, $matches ) ) {
-                       $host = $matches[1];
-                       // Split up dotwise
-                       $domainParts = explode( '.', $host );
-                       // Check if this domain or any superdomain is listed as a local virtual host
-                       $domainParts = array_reverse( $domainParts );
-
-                       $domain = '';
-                       $countParts = count( $domainParts );
-                       for ( $i = 0; $i < $countParts; $i++ ) {
-                               $domainPart = $domainParts[$i];
-                               if ( $i == 0 ) {
-                                       $domain = $domainPart;
-                               } else {
-                                       $domain = $domainPart . '.' . $domain;
-                               }
-
-                               if ( in_array( $domain, $wgLocalVirtualHosts ) ) {
-                                       return true;
-                               }
-                       }
-               }
-
-               return false;
-       }
-
-       /**
-        * Set the user agent
-        * @param string $UA
-        */
-       public function setUserAgent( $UA ) {
-               $this->setHeader( 'User-Agent', $UA );
-       }
-
-       /**
-        * Set an arbitrary header
-        * @param string $name
-        * @param string $value
-        */
-       public function setHeader( $name, $value ) {
-               // I feel like I should normalize the case here...
-               $this->reqHeaders[$name] = $value;
-       }
-
-       /**
-        * Get an array of the headers
-        * @return array
-        */
-       public function getHeaderList() {
-               $list = [];
-
-               if ( $this->cookieJar ) {
-                       $this->reqHeaders['Cookie'] =
-                               $this->cookieJar->serializeToHttpRequest(
-                                       $this->parsedUrl['path'],
-                                       $this->parsedUrl['host']
-                               );
-               }
-
-               foreach ( $this->reqHeaders as $name => $value ) {
-                       $list[] = "$name: $value";
-               }
-
-               return $list;
-       }
-
-       /**
-        * Set a read callback to accept data read from the HTTP request.
-        * By default, data is appended to an internal buffer which can be
-        * retrieved through $req->getContent().
-        *
-        * To handle data as it comes in -- especially for large files that
-        * would not fit in memory -- you can instead set your own callback,
-        * in the form function($resource, $buffer) where the first parameter
-        * is the low-level resource being read (implementation specific),
-        * and the second parameter is the data buffer.
-        *
-        * You MUST return the number of bytes handled in the buffer; if fewer
-        * bytes are reported handled than were passed to you, the HTTP fetch
-        * will be aborted.
-        *
-        * @param callable $callback
-        * @throws MWException
-        */
-       public function setCallback( $callback ) {
-               if ( !is_callable( $callback ) ) {
-                       throw new MWException( 'Invalid MwHttpRequest callback' );
-               }
-               $this->callback = $callback;
-       }
-
-       /**
-        * A generic callback to read the body of the response from a remote
-        * server.
-        *
-        * @param resource $fh
-        * @param string $content
-        * @return int
-        */
-       public function read( $fh, $content ) {
-               $this->content .= $content;
-               return strlen( $content );
-       }
-
-       /**
-        * Take care of whatever is necessary to perform the URI request.
-        *
-        * @return Status
-        */
-       public function execute() {
-
-               $this->content = "";
-
-               if ( strtoupper( $this->method ) == "HEAD" ) {
-                       $this->headersOnly = true;
-               }
-
-               $this->proxySetup(); // set up any proxy as needed
-
-               if ( !$this->callback ) {
-                       $this->setCallback( [ $this, 'read' ] );
-               }
-
-               if ( !isset( $this->reqHeaders['User-Agent'] ) ) {
-                       $this->setUserAgent( Http::userAgent() );
-               }
-
-       }
-
-       /**
-        * Parses the headers, including the HTTP status code and any
-        * Set-Cookie headers.  This function expects the headers to be
-        * found in an array in the member variable headerList.
-        */
-       protected function parseHeader() {
-
-               $lastname = "";
-
-               foreach ( $this->headerList as $header ) {
-                       if ( preg_match( "#^HTTP/([0-9.]+) (.*)#", $header, $match ) ) {
-                               $this->respVersion = $match[1];
-                               $this->respStatus = $match[2];
-                       } elseif ( preg_match( "#^[ \t]#", $header ) ) {
-                               $last = count( $this->respHeaders[$lastname] ) - 1;
-                               $this->respHeaders[$lastname][$last] .= "\r\n$header";
-                       } elseif ( preg_match( "#^([^:]*):[\t ]*(.*)#", $header, $match ) ) {
-                               $this->respHeaders[strtolower( $match[1] )][] = $match[2];
-                               $lastname = strtolower( $match[1] );
-                       }
-               }
-
-               $this->parseCookies();
-
-       }
-
-       /**
-        * Sets HTTPRequest status member to a fatal value with the error
-        * message if the returned integer value of the status code was
-        * not successful (< 300) or a redirect (>=300 and < 400).  (see
-        * RFC2616, section 10,
-        * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html for a
-        * list of status codes.)
-        */
-       protected function setStatus() {
-               if ( !$this->respHeaders ) {
-                       $this->parseHeader();
-               }
-
-               if ( (int)$this->respStatus > 399 ) {
-                       list( $code, $message ) = explode( " ", $this->respStatus, 2 );
-                       $this->status->fatal( "http-bad-status", $code, $message );
-               }
-       }
-
-       /**
-        * Get the integer value of the HTTP status code (e.g. 200 for "200 Ok")
-        * (see RFC2616, section 10, http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
-        * for a list of status codes.)
-        *
-        * @return int
-        */
-       public function getStatus() {
-               if ( !$this->respHeaders ) {
-                       $this->parseHeader();
-               }
-
-               return (int)$this->respStatus;
-       }
-
-       /**
-        * Returns true if the last status code was a redirect.
-        *
-        * @return bool
-        */
-       public function isRedirect() {
-               if ( !$this->respHeaders ) {
-                       $this->parseHeader();
-               }
-
-               $status = (int)$this->respStatus;
-
-               if ( $status >= 300 && $status <= 303 ) {
-                       return true;
-               }
-
-               return false;
-       }
-
-       /**
-        * Returns an associative array of response headers after the
-        * request has been executed.  Because some headers
-        * (e.g. Set-Cookie) can appear more than once the, each value of
-        * the associative array is an array of the values given.
-        *
-        * @return array
-        */
-       public function getResponseHeaders() {
-               if ( !$this->respHeaders ) {
-                       $this->parseHeader();
-               }
-
-               return $this->respHeaders;
-       }
-
-       /**
-        * Returns the value of the given response header.
-        *
-        * @param string $header
-        * @return string|null
-        */
-       public function getResponseHeader( $header ) {
-               if ( !$this->respHeaders ) {
-                       $this->parseHeader();
-               }
-
-               if ( isset( $this->respHeaders[strtolower( $header )] ) ) {
-                       $v = $this->respHeaders[strtolower( $header )];
-                       return $v[count( $v ) - 1];
-               }
-
-               return null;
-       }
-
-       /**
-        * Tells the MWHttpRequest object to use this pre-loaded CookieJar.
-        *
-        * @param CookieJar $jar
-        */
-       public function setCookieJar( $jar ) {
-               $this->cookieJar = $jar;
-       }
-
-       /**
-        * Returns the cookie jar in use.
-        *
-        * @return CookieJar
-        */
-       public function getCookieJar() {
-               if ( !$this->respHeaders ) {
-                       $this->parseHeader();
-               }
-
-               return $this->cookieJar;
-       }
-
-       /**
-        * Sets a cookie. Used before a request to set up any individual
-        * cookies. Used internally after a request to parse the
-        * Set-Cookie headers.
-        * @see Cookie::set
-        * @param string $name
-        * @param mixed $value
-        * @param array $attr
-        */
-       public function setCookie( $name, $value = null, $attr = null ) {
-               if ( !$this->cookieJar ) {
-                       $this->cookieJar = new CookieJar;
-               }
-
-               $this->cookieJar->setCookie( $name, $value, $attr );
-       }
-
-       /**
-        * Parse the cookies in the response headers and store them in the cookie jar.
-        */
-       protected function parseCookies() {
-
-               if ( !$this->cookieJar ) {
-                       $this->cookieJar = new CookieJar;
-               }
-
-               if ( isset( $this->respHeaders['set-cookie'] ) ) {
-                       $url = parse_url( $this->getFinalUrl() );
-                       foreach ( $this->respHeaders['set-cookie'] as $cookie ) {
-                               $this->cookieJar->parseCookieResponseHeader( $cookie, $url['host'] );
-                       }
-               }
-
-       }
-
-       /**
-        * Returns the final URL after all redirections.
-        *
-        * Relative values of the "Location" header are incorrect as
-        * stated in RFC, however they do happen and modern browsers
-        * support them.  This function loops backwards through all
-        * locations in order to build the proper absolute URI - Marooned
-        * at wikia-inc.com
-        *
-        * Note that the multiple Location: headers are an artifact of
-        * CURL -- they shouldn't actually get returned this way. Rewrite
-        * this when bug 29232 is taken care of (high-level redirect
-        * handling rewrite).
-        *
-        * @return string
-        */
-       public function getFinalUrl() {
-               $headers = $this->getResponseHeaders();
-
-               // return full url (fix for incorrect but handled relative location)
-               if ( isset( $headers['location'] ) ) {
-                       $locations = $headers['location'];
-                       $domain = '';
-                       $foundRelativeURI = false;
-                       $countLocations = count( $locations );
-
-                       for ( $i = $countLocations - 1; $i >= 0; $i-- ) {
-                               $url = parse_url( $locations[$i] );
-
-                               if ( isset( $url['host'] ) ) {
-                                       $domain = $url['scheme'] . '://' . $url['host'];
-                                       break; // found correct URI (with host)
-                               } else {
-                                       $foundRelativeURI = true;
-                               }
-                       }
-
-                       if ( $foundRelativeURI ) {
-                               if ( $domain ) {
-                                       return $domain . $locations[$countLocations - 1];
-                               } else {
-                                       $url = parse_url( $this->url );
-                                       if ( isset( $url['host'] ) ) {
-                                               return $url['scheme'] . '://' . $url['host'] .
-                                                       $locations[$countLocations - 1];
-                                       }
-                               }
-                       } else {
-                               return $locations[$countLocations - 1];
-                       }
-               }
-
-               return $this->url;
-       }
-
-       /**
-        * Returns true if the backend can follow redirects. Overridden by the
-        * child classes.
-        * @return bool
-        */
-       public function canFollowRedirects() {
-               return true;
-       }
-}
-
-/**
- * MWHttpRequest implemented using internal curl compiled into PHP
- */
-class CurlHttpRequest extends MWHttpRequest {
-       const SUPPORTS_FILE_POSTS = true;
-
-       protected $curlOptions = [];
-       protected $headerText = "";
-
-       /**
-        * @param resource $fh
-        * @param string $content
-        * @return int
-        */
-       protected function readHeader( $fh, $content ) {
-               $this->headerText .= $content;
-               return strlen( $content );
-       }
-
-       public function execute() {
-
-               parent::execute();
-
-               if ( !$this->status->isOK() ) {
-                       return $this->status;
-               }
-
-               $this->curlOptions[CURLOPT_PROXY] = $this->proxy;
-               $this->curlOptions[CURLOPT_TIMEOUT] = $this->timeout;
-
-               // Only supported in curl >= 7.16.2
-               if ( defined( 'CURLOPT_CONNECTTIMEOUT_MS' ) ) {
-                       $this->curlOptions[CURLOPT_CONNECTTIMEOUT_MS] = $this->connectTimeout * 1000;
-               }
-
-               $this->curlOptions[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0;
-               $this->curlOptions[CURLOPT_WRITEFUNCTION] = $this->callback;
-               $this->curlOptions[CURLOPT_HEADERFUNCTION] = [ $this, "readHeader" ];
-               $this->curlOptions[CURLOPT_MAXREDIRS] = $this->maxRedirects;
-               $this->curlOptions[CURLOPT_ENCODING] = ""; # Enable compression
-
-               $this->curlOptions[CURLOPT_USERAGENT] = $this->reqHeaders['User-Agent'];
-
-               $this->curlOptions[CURLOPT_SSL_VERIFYHOST] = $this->sslVerifyHost ? 2 : 0;
-               $this->curlOptions[CURLOPT_SSL_VERIFYPEER] = $this->sslVerifyCert;
-
-               if ( $this->caInfo ) {
-                       $this->curlOptions[CURLOPT_CAINFO] = $this->caInfo;
-               }
-
-               if ( $this->headersOnly ) {
-                       $this->curlOptions[CURLOPT_NOBODY] = true;
-                       $this->curlOptions[CURLOPT_HEADER] = true;
-               } elseif ( $this->method == 'POST' ) {
-                       $this->curlOptions[CURLOPT_POST] = true;
-                       $postData = $this->postData;
-                       // Don't interpret POST parameters starting with '@' as file uploads, because this
-                       // makes it impossible to POST plain values starting with '@' (and causes security
-                       // issues potentially exposing the contents of local files).
-                       // The PHP manual says this option was introduced in PHP 5.5 defaults to true in PHP 5.6,
-                       // but we support lower versions, and the option doesn't exist in HHVM 5.6.99.
-                       if ( defined( 'CURLOPT_SAFE_UPLOAD' ) ) {
-                               $this->curlOptions[CURLOPT_SAFE_UPLOAD] = true;
-                       } elseif ( is_array( $postData ) ) {
-                               // In PHP 5.2 and later, '@' is interpreted as a file upload if POSTFIELDS
-                               // is an array, but not if it's a string. So convert $req['body'] to a string
-                               // for safety.
-                               $postData = wfArrayToCgi( $postData );
-                       }
-                       $this->curlOptions[CURLOPT_POSTFIELDS] = $postData;
-
-                       // Suppress 'Expect: 100-continue' header, as some servers
-                       // will reject it with a 417 and Curl won't auto retry
-                       // with HTTP 1.0 fallback
-                       $this->reqHeaders['Expect'] = '';
-               } else {
-                       $this->curlOptions[CURLOPT_CUSTOMREQUEST] = $this->method;
-               }
-
-               $this->curlOptions[CURLOPT_HTTPHEADER] = $this->getHeaderList();
-
-               $curlHandle = curl_init( $this->url );
-
-               if ( !curl_setopt_array( $curlHandle, $this->curlOptions ) ) {
-                       throw new MWException( "Error setting curl options." );
-               }
-
-               if ( $this->followRedirects && $this->canFollowRedirects() ) {
-                       MediaWiki\suppressWarnings();
-                       if ( !curl_setopt( $curlHandle, CURLOPT_FOLLOWLOCATION, true ) ) {
-                               wfDebug( __METHOD__ . ": Couldn't set CURLOPT_FOLLOWLOCATION. " .
-                                       "Probably open_basedir is set.\n" );
-                               // Continue the processing. If it were in curl_setopt_array,
-                               // processing would have halted on its entry
-                       }
-                       MediaWiki\restoreWarnings();
-               }
-
-               if ( $this->profiler ) {
-                       $profileSection = $this->profiler->scopedProfileIn(
-                               __METHOD__ . '-' . $this->profileName
-                       );
-               }
-
-               $curlRes = curl_exec( $curlHandle );
-               if ( curl_errno( $curlHandle ) == CURLE_OPERATION_TIMEOUTED ) {
-                       $this->status->fatal( 'http-timed-out', $this->url );
-               } elseif ( $curlRes === false ) {
-                       $this->status->fatal( 'http-curl-error', curl_error( $curlHandle ) );
-               } else {
-                       $this->headerList = explode( "\r\n", $this->headerText );
-               }
-
-               curl_close( $curlHandle );
-
-               if ( $this->profiler ) {
-                       $this->profiler->scopedProfileOut( $profileSection );
-               }
-
-               $this->parseHeader();
-               $this->setStatus();
-
-               return $this->status;
-       }
-
-       /**
-        * @return bool
-        */
-       public function canFollowRedirects() {
-               $curlVersionInfo = curl_version();
-               if ( $curlVersionInfo['version_number'] < 0x071304 ) {
-                       wfDebug( "Cannot follow redirects with libcurl < 7.19.4 due to CVE-2009-0037\n" );
-                       return false;
-               }
-
-               if ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) {
-                       if ( strval( ini_get( 'open_basedir' ) ) !== '' ) {
-                               wfDebug( "Cannot follow redirects when open_basedir is set\n" );
-                               return false;
-                       }
-               }
-
-               return true;
-       }
-}
-
-class PhpHttpRequest extends MWHttpRequest {
-
-       private $fopenErrors = [];
-
-       /**
-        * @param string $url
-        * @return string
-        */
-       protected function urlToTcp( $url ) {
-               $parsedUrl = parse_url( $url );
-
-               return 'tcp://' . $parsedUrl['host'] . ':' . $parsedUrl['port'];
-       }
-
-       /**
-        * Returns an array with a 'capath' or 'cafile' key
-        * that is suitable to be merged into the 'ssl' sub-array of
-        * a stream context options array.
-        * Uses the 'caInfo' option of the class if it is provided, otherwise uses the system
-        * default CA bundle if PHP supports that, or searches a few standard locations.
-        * @return array
-        * @throws DomainException
-        */
-       protected function getCertOptions() {
-               $certOptions = [];
-               $certLocations = [];
-               if ( $this->caInfo ) {
-                       $certLocations = [ 'manual' => $this->caInfo ];
-               } elseif ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) {
-                       // @codingStandardsIgnoreStart Generic.Files.LineLength
-                       // Default locations, based on
-                       // https://www.happyassassin.net/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/
-                       // PHP 5.5 and older doesn't have any defaults, so we try to guess ourselves.
-                       // PHP 5.6+ gets the CA location from OpenSSL as long as it is not set manually,
-                       // so we should leave capath/cafile empty there.
-                       // @codingStandardsIgnoreEnd
-                       $certLocations = array_filter( [
-                               getenv( 'SSL_CERT_DIR' ),
-                               getenv( 'SSL_CERT_PATH' ),
-                               '/etc/pki/tls/certs/ca-bundle.crt', # Fedora et al
-                               '/etc/ssl/certs',  # Debian et al
-                               '/etc/pki/tls/certs/ca-bundle.trust.crt',
-                               '/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem',
-                               '/System/Library/OpenSSL', # OSX
-                       ] );
-               }
-
-               foreach ( $certLocations as $key => $cert ) {
-                       if ( is_dir( $cert ) ) {
-                               $certOptions['capath'] = $cert;
-                               break;
-                       } elseif ( is_file( $cert ) ) {
-                               $certOptions['cafile'] = $cert;
-                               break;
-                       } elseif ( $key === 'manual' ) {
-                               // fail more loudly if a cert path was manually configured and it is not valid
-                               throw new DomainException( "Invalid CA info passed: $cert" );
-                       }
-               }
-
-               return $certOptions;
-       }
-
-       /**
-        * Custom error handler for dealing with fopen() errors.
-        * fopen() tends to fire multiple errors in succession, and the last one
-        * is completely useless (something like "fopen: failed to open stream")
-        * so normal methods of handling errors programmatically
-        * like get_last_error() don't work.
-        */
-       public function errorHandler( $errno, $errstr ) {
-               $n = count( $this->fopenErrors ) + 1;
-               $this->fopenErrors += [ "errno$n" => $errno, "errstr$n" => $errstr ];
-       }
-
-       public function execute() {
-
-               parent::execute();
-
-               if ( is_array( $this->postData ) ) {
-                       $this->postData = wfArrayToCgi( $this->postData );
-               }
-
-               if ( $this->parsedUrl['scheme'] != 'http'
-                       && $this->parsedUrl['scheme'] != 'https' ) {
-                       $this->status->fatal( 'http-invalid-scheme', $this->parsedUrl['scheme'] );
-               }
-
-               $this->reqHeaders['Accept'] = "*/*";
-               $this->reqHeaders['Connection'] = 'Close';
-               if ( $this->method == 'POST' ) {
-                       // Required for HTTP 1.0 POSTs
-                       $this->reqHeaders['Content-Length'] = strlen( $this->postData );
-                       if ( !isset( $this->reqHeaders['Content-Type'] ) ) {
-                               $this->reqHeaders['Content-Type'] = "application/x-www-form-urlencoded";
-                       }
-               }
-
-               // Set up PHP stream context
-               $options = [
-                       'http' => [
-                               'method' => $this->method,
-                               'header' => implode( "\r\n", $this->getHeaderList() ),
-                               'protocol_version' => '1.1',
-                               'max_redirects' => $this->followRedirects ? $this->maxRedirects : 0,
-                               'ignore_errors' => true,
-                               'timeout' => $this->timeout,
-                               // Curl options in case curlwrappers are installed
-                               'curl_verify_ssl_host' => $this->sslVerifyHost ? 2 : 0,
-                               'curl_verify_ssl_peer' => $this->sslVerifyCert,
-                       ],
-                       'ssl' => [
-                               'verify_peer' => $this->sslVerifyCert,
-                               'SNI_enabled' => true,
-                               'ciphers' => 'HIGH:!SSLv2:!SSLv3:-ADH:-kDH:-kECDH:-DSS',
-                               'disable_compression' => true,
-                       ],
-               ];
-
-               if ( $this->proxy ) {
-                       $options['http']['proxy'] = $this->urlToTcp( $this->proxy );
-                       $options['http']['request_fulluri'] = true;
-               }
-
-               if ( $this->postData ) {
-                       $options['http']['content'] = $this->postData;
-               }
-
-               if ( $this->sslVerifyHost ) {
-                       // PHP 5.6.0 deprecates CN_match, in favour of peer_name which
-                       // actually checks SubjectAltName properly.
-                       if ( version_compare( PHP_VERSION, '5.6.0', '>=' ) ) {
-                               $options['ssl']['peer_name'] = $this->parsedUrl['host'];
-                       } else {
-                               $options['ssl']['CN_match'] = $this->parsedUrl['host'];
-                       }
-               }
-
-               $options['ssl'] += $this->getCertOptions();
-
-               $context = stream_context_create( $options );
-
-               $this->headerList = [];
-               $reqCount = 0;
-               $url = $this->url;
-
-               $result = [];
-
-               if ( $this->profiler ) {
-                       $profileSection = $this->profiler->scopedProfileIn(
-                               __METHOD__ . '-' . $this->profileName
-                       );
-               }
-               do {
-                       $reqCount++;
-                       $this->fopenErrors = [];
-                       set_error_handler( [ $this, 'errorHandler' ] );
-                       $fh = fopen( $url, "r", false, $context );
-                       restore_error_handler();
-
-                       if ( !$fh ) {
-                               // HACK for instant commons.
-                               // If we are contacting (commons|upload).wikimedia.org
-                               // try again with CN_match for en.wikipedia.org
-                               // as php does not handle SubjectAltName properly
-                               // prior to "peer_name" option in php 5.6
-                               if ( isset( $options['ssl']['CN_match'] )
-                                       && ( $options['ssl']['CN_match'] === 'commons.wikimedia.org'
-                                               || $options['ssl']['CN_match'] === 'upload.wikimedia.org' )
-                               ) {
-                                       $options['ssl']['CN_match'] = 'en.wikipedia.org';
-                                       $context = stream_context_create( $options );
-                                       continue;
-                               }
-                               break;
-                       }
-
-                       $result = stream_get_meta_data( $fh );
-                       $this->headerList = $result['wrapper_data'];
-                       $this->parseHeader();
-
-                       if ( !$this->followRedirects ) {
-                               break;
-                       }
-
-                       # Handle manual redirection
-                       if ( !$this->isRedirect() || $reqCount > $this->maxRedirects ) {
-                               break;
-                       }
-                       # Check security of URL
-                       $url = $this->getResponseHeader( "Location" );
-
-                       if ( !Http::isValidURI( $url ) ) {
-                               wfDebug( __METHOD__ . ": insecure redirection\n" );
-                               break;
-                       }
-               } while ( true );
-               if ( $this->profiler ) {
-                       $this->profiler->scopedProfileOut( $profileSection );
-               }
-
-               $this->setStatus();
-
-               if ( $fh === false ) {
-                       if ( $this->fopenErrors ) {
-                               LoggerFactory::getInstance( 'http' )->warning( __CLASS__
-                                       . ': error opening connection: {errstr1}', $this->fopenErrors );
-                       }
-                       $this->status->fatal( 'http-request-error' );
-                       return $this->status;
-               }
-
-               if ( $result['timed_out'] ) {
-                       $this->status->fatal( 'http-timed-out', $this->url );
-                       return $this->status;
-               }
-
-               // If everything went OK, or we received some error code
-               // get the response body content.
-               if ( $this->status->isOK() || (int)$this->respStatus >= 300 ) {
-                       while ( !feof( $fh ) ) {
-                               $buf = fread( $fh, 8192 );
-
-                               if ( $buf === false ) {
-                                       $this->status->fatal( 'http-read-error' );
-                                       break;
-                               }
-
-                               if ( strlen( $buf ) ) {
-                                       call_user_func( $this->callback, $fh, $buf );
-                               }
-                       }
-               }
-               fclose( $fh );
-
-               return $this->status;
-       }
-}
index 9011f17..d3d1f38 100644 (file)
@@ -319,7 +319,7 @@ class Linker {
         * @return LinkTarget
         */
        public static function normaliseSpecialPage( LinkTarget $target ) {
-               if ( $target->getNamespace() == NS_SPECIAL ) {
+               if ( $target->getNamespace() == NS_SPECIAL && !$target->isExternal() ) {
                        list( $name, $subpage ) = SpecialPageFactory::resolveAlias( $target->getDBkey() );
                        if ( !$name ) {
                                return $target;
diff --git a/includes/MWGrants.php b/includes/MWGrants.php
new file mode 100644 (file)
index 0000000..58efdc7
--- /dev/null
@@ -0,0 +1,214 @@
+<?php
+/**
+ * Functions and constants to deal with grants
+ *
+ * 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
+ */
+
+/**
+ * A collection of public static functions to deal with grants.
+ */
+class MWGrants {
+
+       /**
+        * List all known grants.
+        * @return array
+        */
+       public static function getValidGrants() {
+               global $wgGrantPermissions;
+
+               return array_keys( $wgGrantPermissions );
+       }
+
+       /**
+        * Map all grants to corresponding user rights.
+        * @return array grant => array of rights
+        */
+       public static function getRightsByGrant() {
+               global $wgGrantPermissions;
+
+               $res = [];
+               foreach ( $wgGrantPermissions as $grant => $rights ) {
+                       $res[$grant] = array_keys( array_filter( $rights ) );
+               }
+               return $res;
+       }
+
+       /**
+        * Fetch the display name of the grant
+        * @param string $grant
+        * @param Language|string|null $lang
+        * @return string Grant description
+        */
+       public static function grantName( $grant, $lang = null ) {
+               // Give grep a chance to find the usages:
+               // grant-blockusers, grant-createeditmovepage, grant-delete,
+               // grant-editinterface, grant-editmycssjs, grant-editmywatchlist,
+               // grant-editpage, grant-editprotected, grant-highvolume,
+               // grant-oversight, grant-patrol, grant-protect, grant-rollback,
+               // grant-sendemail, grant-uploadeditmovefile, grant-uploadfile,
+               // grant-basic, grant-viewdeleted, grant-viewmywatchlist,
+               // grant-createaccount
+               $msg = wfMessage( "grant-$grant" );
+               if ( $lang !== null ) {
+                       if ( is_string( $lang ) ) {
+                               $lang = Language::factory( $lang );
+                       }
+                       $msg->inLanguage( $lang );
+               }
+               if ( !$msg->exists() ) {
+                       $msg = wfMessage( 'grant-generic', $grant );
+                       if ( $lang ) {
+                               $msg->inLanguage( $lang );
+                       }
+               }
+               return $msg->text();
+       }
+
+       /**
+        * Fetch the display names for the grants.
+        * @param string[] $grants
+        * @param Language|string|null $lang
+        * @return string[] Corresponding grant descriptions
+        */
+       public static function grantNames( array $grants, $lang = null ) {
+               if ( $lang !== null ) {
+                       if ( is_string( $lang ) ) {
+                               $lang = Language::factory( $lang );
+                       }
+               }
+
+               $ret = [];
+               foreach ( $grants as $grant ) {
+                       $ret[] = self::grantName( $grant, $lang );
+               }
+               return $ret;
+       }
+
+       /**
+        * Fetch the rights allowed by a set of grants.
+        * @param string[]|string $grants
+        * @return string[]
+        */
+       public static function getGrantRights( $grants ) {
+               global $wgGrantPermissions;
+
+               $rights = [];
+               foreach ( (array)$grants as $grant ) {
+                       if ( isset( $wgGrantPermissions[$grant] ) ) {
+                               $rights = array_merge( $rights, array_keys( array_filter( $wgGrantPermissions[$grant] ) ) );
+                       }
+               }
+               return array_unique( $rights );
+       }
+
+       /**
+        * Test that all grants in the list are known.
+        * @param string[] $grants
+        * @return bool
+        */
+       public static function grantsAreValid( array $grants ) {
+               return array_diff( $grants, self::getValidGrants() ) === [];
+       }
+
+       /**
+        * Divide the grants into groups.
+        * @param string[]|null $grantsFilter
+        * @return array Map of (group => (grant list))
+        */
+       public static function getGrantGroups( $grantsFilter = null ) {
+               global $wgGrantPermissions, $wgGrantPermissionGroups;
+
+               if ( is_array( $grantsFilter ) ) {
+                       $grantsFilter = array_flip( $grantsFilter );
+               }
+
+               $groups = [];
+               foreach ( $wgGrantPermissions as $grant => $rights ) {
+                       if ( $grantsFilter !== null && !isset( $grantsFilter[$grant] ) ) {
+                               continue;
+                       }
+                       if ( isset( $wgGrantPermissionGroups[$grant] ) ) {
+                               $groups[$wgGrantPermissionGroups[$grant]][] = $grant;
+                       } else {
+                               $groups['other'][] = $grant;
+                       }
+               }
+
+               return $groups;
+       }
+
+       /**
+        * Get the list of grants that are hidden and should always be granted
+        * @return string[]
+        */
+       public static function getHiddenGrants() {
+               global $wgGrantPermissionGroups;
+
+               $grants = [];
+               foreach ( $wgGrantPermissionGroups as $grant => $group ) {
+                       if ( $group === 'hidden' ) {
+                               $grants[] = $grant;
+                       }
+               }
+               return $grants;
+       }
+
+       /**
+        * Generate a link to Special:ListGrants for a particular grant name.
+        *
+        * This should be used to link end users to a full description of what
+        * rights they are giving when they authorize a grant.
+        *
+        * @param string $grant the grant name
+        * @param Language|string|null $lang
+        * @return string (proto-relative) HTML link
+        */
+       public static function getGrantsLink( $grant, $lang = null ) {
+               return \Linker::linkKnown(
+                       \SpecialPage::getTitleFor( 'Listgrants', false, $grant ),
+                       htmlspecialchars( self::grantName( $grant, $lang ) )
+               );
+       }
+
+       /**
+        * Generate wikitext to display a list of grants
+        * @param string[]|null $grantsFilter If non-null, only display these grants.
+        * @param Language|string|null $lang
+        * @return string Wikitext
+        */
+       public static function getGrantsWikiText( $grantsFilter, $lang = null ) {
+               global $wgContLang;
+
+               if ( is_string( $lang ) ) {
+                       $lang = Language::factory( $lang );
+               } elseif ( $lang === null ) {
+                       $lang = $wgContLang;
+               }
+
+               $s = '';
+               foreach ( self::getGrantGroups( $grantsFilter ) as $group => $grants ) {
+                       if ( $group === 'hidden' ) {
+                               continue; // implicitly granted
+                       }
+                       $s .= "*<span class=\"mw-grantgroup\">" .
+                               wfMessage( "grant-group-$group" )->inLanguage( $lang )->text() . "</span>\n";
+                       $s .= ":" . $lang->semicolonList( self::grantNames( $grants, $lang ) ) . "\n";
+               }
+               return "$s\n";
+       }
+
+}
index 8cf009f..eaa1c99 100644 (file)
@@ -313,8 +313,6 @@ class MediaWiki {
         * - Normalise empty title:
         *   /wiki/ -> /wiki/Main
         *   /w/index.php?title= -> /wiki/Main
-        * - Normalise non-standard title urls:
-        *   /w/index.php?title=Foo_Bar -> /wiki/Foo_Bar
         * - Don't redirect anything with query parameters other than 'title' or 'action=view'.
         *
         * @param Title $title
@@ -327,6 +325,8 @@ class MediaWiki {
 
                if ( $request->getVal( 'action', 'view' ) != 'view'
                        || $request->wasPosted()
+                       || ( $request->getVal( 'title' ) !== null
+                               && $title->getPrefixedDBkey() == $request->getVal( 'title' ) )
                        || count( $request->getValueNames( [ 'action', 'title' ] ) )
                        || !Hooks::run( 'TestCanonicalRedirect', [ $request, $title, $output ] )
                ) {
@@ -341,19 +341,7 @@ class MediaWiki {
                }
                // Redirect to canonical url, make it a 301 to allow caching
                $targetUrl = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
-
-               if ( $targetUrl != $request->getFullRequestURL() ) {
-                       $output->setCdnMaxage( 1200 );
-                       $output->redirect( $targetUrl, '301' );
-                       return true;
-               }
-
-               // If there is no title, or the title is in a non-standard encoding, we demand
-               // a redirect. If cgi somehow changed the 'title' query to be non-standard while
-               // the url is standard, the server is misconfigured.
-               if ( $request->getVal( 'title' ) === null
-                       || $title->getPrefixedDBkey() != $request->getVal( 'title' )
-               ) {
+               if ( $targetUrl == $request->getFullRequestURL() ) {
                        $message = "Redirect loop detected!\n\n" .
                                "This means the wiki got confused about what page was " .
                                "requested; this sometimes happens when moving a wiki " .
@@ -375,7 +363,9 @@ class MediaWiki {
                        }
                        throw new HttpError( 500, $message );
                }
-               return false;
+               $output->setSquidMaxage( 1200 );
+               $output->redirect( $targetUrl, '301' );
+               return true;
        }
 
        /**
@@ -676,14 +666,14 @@ class MediaWiki {
        /**
         * @param string $url
         * @param IContextSource $context
-        * @return string|bool Either "local" or "remote" if in the farm, false otherwise
+        * @return string Either "local", "remote" if in the farm, "external" otherwise
         */
-       private function getUrlDomainDistance( $url, IContextSource $context ) {
+       private static function getUrlDomainDistance( $url, IContextSource $context ) {
                static $relevantKeys = [ 'host' => true, 'port' => true ];
 
                $infoCandidate = wfParseUrl( $url );
                if ( $infoCandidate === false ) {
-                       return false;
+                       return 'external';
                }
 
                $infoCandidate = array_intersect_key( $infoCandidate, $relevantKeys );
@@ -705,7 +695,7 @@ class MediaWiki {
                        }
                }
 
-               return false;
+               return 'external';
        }
 
        /**
@@ -899,6 +889,7 @@ class MediaWiki {
 
                // Do any deferred jobs
                DeferredUpdates::doUpdates( 'enqueue' );
+               DeferredUpdates::setImmediateMode( true );
 
                // Make sure any lazy jobs are pushed
                JobQueueGroup::pushLazyJobs();
index b16044e..7c9363c 100644 (file)
@@ -3,6 +3,8 @@ namespace MediaWiki;
 
 use Config;
 use ConfigFactory;
+use CryptHKDF;
+use CryptRand;
 use EventRelayerGroup;
 use GenderCache;
 use GlobalVarConfig;
@@ -18,7 +20,9 @@ use MediaWiki\Services\SalvageableService;
 use MediaWiki\Services\ServiceContainer;
 use MediaWiki\Services\NoSuchServiceException;
 use MWException;
+use MimeAnalyzer;
 use ObjectCache;
+use Parser;
 use ProxyLookup;
 use SearchEngine;
 use SearchEngineConfig;
@@ -180,7 +184,7 @@ class MediaWikiServices extends ServiceContainer {
 
                $oldInstance = self::$instance;
 
-               self::$instance = self::newInstance( $bootstrapConfig );
+               self::$instance = self::newInstance( $bootstrapConfig, 'load' );
                self::$instance->importWiring( $oldInstance, [ 'BootstrapConfig' ] );
 
                if ( $quick === 'quick' ) {
@@ -188,7 +192,6 @@ class MediaWikiServices extends ServiceContainer {
                } else {
                        $oldInstance->destroy();
                }
-
        }
 
        /**
@@ -294,7 +297,7 @@ class MediaWikiServices extends ServiceContainer {
                self::resetGlobalInstance();
 
                // Child, reseed because there is no bug in PHP:
-               // http://bugs.php.net/bug.php?id=42465
+               // https://bugs.php.net/bug.php?id=42465
                mt_srand( getmypid() );
        }
 
@@ -522,6 +525,22 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'WatchedItemQueryService' );
        }
 
+       /**
+        * @since 1.28
+        * @return CryptRand
+        */
+       public function getCryptRand() {
+               return $this->getService( 'CryptRand' );
+       }
+
+       /**
+        * @since 1.28
+        * @return CryptHKDF
+        */
+       public function getCryptHKDF() {
+               return $this->getService( 'CryptHKDF' );
+       }
+
        /**
         * @since 1.28
         * @return MediaHandlerFactory
@@ -530,6 +549,14 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'MediaHandlerFactory' );
        }
 
+       /**
+        * @since 1.28
+        * @return MimeAnalyzer
+        */
+       public function getMimeAnalyzer() {
+               return $this->getService( 'MimeAnalyzer' );
+       }
+
        /**
         * @since 1.28
         * @return ProxyLookup
@@ -538,6 +565,14 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'ProxyLookup' );
        }
 
+       /**
+        * @since 1.29
+        * @return Parser
+        */
+       public function getParser() {
+               return $this->getService( 'Parser' );
+       }
+
        /**
         * @since 1.28
         * @return GenderCache
@@ -589,6 +624,30 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'TitleParser' );
        }
 
+       /**
+        * @since 1.28
+        * @return \BagOStuff
+        */
+       public function getMainObjectStash() {
+               return $this->getService( 'MainObjectStash' );
+       }
+
+       /**
+        * @since 1.28
+        * @return \WANObjectCache
+        */
+       public function getMainWANObjectCache() {
+               return $this->getService( 'MainWANObjectCache' );
+       }
+
+       /**
+        * @since 1.28
+        * @return \BagOStuff
+        */
+       public function getLocalServerObjectCache() {
+               return $this->getService( 'LocalServerObjectCache' );
+       }
+
        /**
         * @since 1.28
         * @return VirtualRESTServiceClient
index f797fe3..e57f880 100644 (file)
@@ -90,7 +90,8 @@ class MergeHistory {
                                        'revision',
                                        'MAX(rev_timestamp)',
                                        [
-                                               'rev_timestamp <= ' . $this->dbw->timestamp( $mwTimestamp ),
+                                               'rev_timestamp <= ' .
+                                                       $this->dbw->addQuotes( $this->dbw->timestamp( $mwTimestamp ) ),
                                                'rev_page' => $this->source->getArticleID()
                                        ],
                                        __METHOD__
@@ -118,7 +119,8 @@ class MergeHistory {
                                $this->timestampLimit = $lasttimestamp;
                        }
 
-                       $this->timeWhere = "rev_timestamp <= {$this->dbw->timestamp( $timeInsert )}";
+                       $this->timeWhere = "rev_timestamp <= " .
+                               $this->dbw->addQuotes( $this->dbw->timestamp( $timeInsert ) );
                } catch ( TimestampException $ex ) {
                        // The timestamp we got is screwed up and merge cannot continue
                        // This should be detected by $this->isValidMerge()
index c1a12aa..7d86d07 100644 (file)
  * @since 1.17
  */
 class Message implements MessageSpecifier, Serializable {
+       /** Use message text as-is */
+       const FORMAT_PLAIN = 'plain';
+       /** Use normal wikitext -> HTML parsing (the result will be wrapped in a block-level HTML tag) */
+       const FORMAT_BLOCK_PARSE = 'block-parse';
+       /** Use normal wikitext -> HTML parsing but strip the block-level wrapper */
+       const FORMAT_PARSE = 'parse';
+       /** Transform {{..}} constructs but don't transform to HTML */
+       const FORMAT_TEXT = 'text';
+       /** Transform {{..}} constructs, HTML-escape the result */
+       const FORMAT_ESCAPED = 'escaped';
 
        /**
         * In which language to get this message. True, which is the default,
@@ -190,15 +200,8 @@ class Message implements MessageSpecifier, Serializable {
        protected $parameters = [];
 
        /**
-        * Format for the message.
-        * Supported formats are:
-        * * text (transform)
-        * * escaped (transform+htmlspecialchars)
-        * * block-parse
-        * * parse (default)
-        * * plain
-        *
         * @var string
+        * @deprecated
         */
        protected $format = 'parse';
 
@@ -347,8 +350,10 @@ class Message implements MessageSpecifier, Serializable {
         * @since 1.21
         *
         * @return string
+        * @deprecated since 1.29 formatting is not stateful
         */
        public function getFormat() {
+               wfDeprecated( __METHOD__, '1.29' );
                return $this->format;
        }
 
@@ -796,9 +801,18 @@ class Message implements MessageSpecifier, Serializable {
         *
         * @since 1.17
         *
+        * @param string|null $format One of the FORMAT_* constants. Null means use whatever was used
+        *   the last time (this is for B/C and should be avoided).
+        *
         * @return string HTML
         */
-       public function toString() {
+       public function toString( $format = null ) {
+               if ( $format === null ) {
+                       $ex = new LogicException( __METHOD__ . ' using implicit format: ' . $this->format );
+                       \MediaWiki\Logger\LoggerFactory::getInstance( 'message-format' )->warning(
+                               $ex->getMessage(), [ 'exception' => $ex, 'format' => $this->format, 'key' => $this->key ] );
+                       $format = $this->format;
+               }
                $string = $this->fetchMessage();
 
                if ( $string === false ) {
@@ -808,6 +822,7 @@ class Message implements MessageSpecifier, Serializable {
                        // message key is user-controlled.
                        // '⧼' is used instead of '<' to side-step any
                        // double-escaping issues.
+                       // (Keep synchronised with mw.Message#toString in JS.)
                        return '⧼' . htmlspecialchars( $this->key ) . '⧽';
                }
 
@@ -821,23 +836,23 @@ class Message implements MessageSpecifier, Serializable {
                }
 
                # Replace parameters before text parsing
-               $string = $this->replaceParameters( $string, 'before' );
+               $string = $this->replaceParameters( $string, 'before', $format );
 
                # Maybe transform using the full parser
-               if ( $this->format === 'parse' ) {
+               if ( $format === self::FORMAT_PARSE ) {
                        $string = $this->parseText( $string );
                        $string = Parser::stripOuterParagraph( $string );
-               } elseif ( $this->format === 'block-parse' ) {
+               } elseif ( $format === self::FORMAT_BLOCK_PARSE ) {
                        $string = $this->parseText( $string );
-               } elseif ( $this->format === 'text' ) {
+               } elseif ( $format === self::FORMAT_TEXT ) {
                        $string = $this->transformText( $string );
-               } elseif ( $this->format === 'escaped' ) {
+               } elseif ( $format === self::FORMAT_ESCAPED ) {
                        $string = $this->transformText( $string );
                        $string = htmlspecialchars( $string, ENT_QUOTES, 'UTF-8', false );
                }
 
                # Raw parameter replacement
-               $string = $this->replaceParameters( $string, 'after' );
+               $string = $this->replaceParameters( $string, 'after', $format );
 
                return $string;
        }
@@ -852,17 +867,11 @@ class Message implements MessageSpecifier, Serializable {
         * @return string
         */
        public function __toString() {
-               if ( $this->format !== 'parse' ) {
-                       $ex = new LogicException( __METHOD__ . ' using implicit format: ' . $this->format );
-                       \MediaWiki\Logger\LoggerFactory::getInstance( 'message-format' )->warning(
-                               $ex->getMessage(), [ 'exception' => $ex, 'format' => $this->format, 'key' => $this->key ] );
-               }
-
                // PHP doesn't allow __toString to throw exceptions and will
                // trigger a fatal error if it does. So, catch any exceptions.
 
                try {
-                       return $this->toString();
+                       return $this->toString( self::FORMAT_PARSE );
                } catch ( Exception $ex ) {
                        try {
                                trigger_error( "Exception caught in " . __METHOD__ . " (message " . $this->key . "): "
@@ -871,10 +880,7 @@ class Message implements MessageSpecifier, Serializable {
                                // Doh! Cause a fatal error after all?
                        }
 
-                       if ( $this->format === 'plain' || $this->format === 'text' ) {
-                               return '<' . $this->key . '>';
-                       }
-                       return '&lt;' . htmlspecialchars( $this->key ) . '&gt;';
+                       return '⧼' . htmlspecialchars( $this->key ) . '⧽';
                }
        }
 
@@ -886,8 +892,8 @@ class Message implements MessageSpecifier, Serializable {
         * @return string Parsed HTML.
         */
        public function parse() {
-               $this->format = 'parse';
-               return $this->toString();
+               $this->format = self::FORMAT_PARSE;
+               return $this->toString( self::FORMAT_PARSE );
        }
 
        /**
@@ -898,8 +904,8 @@ class Message implements MessageSpecifier, Serializable {
         * @return string Unescaped message text.
         */
        public function text() {
-               $this->format = 'text';
-               return $this->toString();
+               $this->format = self::FORMAT_TEXT;
+               return $this->toString( self::FORMAT_TEXT );
        }
 
        /**
@@ -910,8 +916,8 @@ class Message implements MessageSpecifier, Serializable {
         * @return string Unescaped untransformed message text.
         */
        public function plain() {
-               $this->format = 'plain';
-               return $this->toString();
+               $this->format = self::FORMAT_PLAIN;
+               return $this->toString( self::FORMAT_PLAIN );
        }
 
        /**
@@ -922,8 +928,8 @@ class Message implements MessageSpecifier, Serializable {
         * @return string HTML
         */
        public function parseAsBlock() {
-               $this->format = 'block-parse';
-               return $this->toString();
+               $this->format = self::FORMAT_BLOCK_PARSE;
+               return $this->toString( self::FORMAT_BLOCK_PARSE );
        }
 
        /**
@@ -935,8 +941,8 @@ class Message implements MessageSpecifier, Serializable {
         * @return string Escaped message text.
         */
        public function escaped() {
-               $this->format = 'escaped';
-               return $this->toString();
+               $this->format = self::FORMAT_ESCAPED;
+               return $this->toString( self::FORMAT_ESCAPED );
        }
 
        /**
@@ -1070,13 +1076,14 @@ class Message implements MessageSpecifier, Serializable {
         *
         * @param string $message The message text.
         * @param string $type Either "before" or "after".
+        * @param string $format One of the FORMAT_* constants.
         *
         * @return string
         */
-       protected function replaceParameters( $message, $type = 'before' ) {
+       protected function replaceParameters( $message, $type = 'before', $format ) {
                $replacementKeys = [];
                foreach ( $this->parameters as $n => $param ) {
-                       list( $paramType, $value ) = $this->extractParam( $param );
+                       list( $paramType, $value ) = $this->extractParam( $param, $format );
                        if ( $type === $paramType ) {
                                $replacementKeys['$' . ( $n + 1 )] = $value;
                        }
@@ -1091,10 +1098,11 @@ class Message implements MessageSpecifier, Serializable {
         * @since 1.18
         *
         * @param mixed $param Parameter as defined in this class.
+        * @param string $format One of the FORMAT_* constants.
         *
         * @return array Array with the parameter type (either "before" or "after") and the value.
         */
-       protected function extractParam( $param ) {
+       protected function extractParam( $param, $format ) {
                if ( is_array( $param ) ) {
                        if ( isset( $param['raw'] ) ) {
                                return [ 'after', $param['raw'] ];
@@ -1113,7 +1121,7 @@ class Message implements MessageSpecifier, Serializable {
                        } elseif ( isset( $param['bitrate'] ) ) {
                                return [ 'before', $this->getLanguage()->formatBitrate( $param['bitrate'] ) ];
                        } elseif ( isset( $param['plaintext'] ) ) {
-                               return [ 'after', $this->formatPlaintext( $param['plaintext'] ) ];
+                               return [ 'after', $this->formatPlaintext( $param['plaintext'], $format ) ];
                        } else {
                                $warning = 'Invalid parameter for message "' . $this->getKey() . '": ' .
                                        htmlspecialchars( serialize( $param ) );
@@ -1127,7 +1135,7 @@ class Message implements MessageSpecifier, Serializable {
                        // Message objects should not be before parameters because
                        // then they'll get double escaped. If the message needs to be
                        // escaped, it'll happen right here when we call toString().
-                       return [ 'after', $param->toString() ];
+                       return [ 'after', $param->toString( $format ) ];
                } else {
                        return [ 'before', $param ];
                }
@@ -1207,18 +1215,19 @@ class Message implements MessageSpecifier, Serializable {
         * @since 1.25
         *
         * @param string $plaintext String to ensure plaintext output of
+        * @param string $format One of the FORMAT_* constants.
         *
-        * @return string Input plaintext encoded for output to $this->format
+        * @return string Input plaintext encoded for output to $format
         */
-       protected function formatPlaintext( $plaintext ) {
-               switch ( $this->format ) {
-               case 'text':
-               case 'plain':
+       protected function formatPlaintext( $plaintext, $format ) {
+               switch ( $format ) {
+               case self::FORMAT_TEXT:
+               case self::FORMAT_PLAIN:
                        return $plaintext;
 
-               case 'parse':
-               case 'block-parse':
-               case 'escaped':
+               case self::FORMAT_PARSE:
+               case self::FORMAT_BLOCK_PARSE:
+               case self::FORMAT_ESCAPED:
                default:
                        return htmlspecialchars( $plaintext, ENT_QUOTES );
 
index 54d58d2..c03bce7 100644 (file)
@@ -1,7 +1,5 @@
 <?php
 /**
- * Module defining helper functions for detecting and dealing with MIME types.
- *
  * 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
  *
  * @file
  */
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Logger\LoggerFactory;
 
-/**
- * Defines a set of well known MIME types
- * This is used as a fallback to mime.types files.
- * An extensive list of well known MIME types is provided by
- * the file mime.types in the includes directory.
- *
- * This list concatenated with mime.types is used to create a MIME <-> ext
- * map. Each line contains a MIME type followed by a space separated list of
- * extensions. If multiple extensions for a single MIME type exist or if
- * multiple MIME types exist for a single extension then in most cases
- * MediaWiki assumes that the first extension following the MIME type is the
- * canonical extension, and the first time a MIME type appears for a certain
- * extension is considered the canonical MIME type.
- *
- * (Note that appending $wgMimeTypeFile to the end of MM_WELL_KNOWN_MIME_TYPES
- * sucks because you can't redefine canonical types. This could be fixed by
- * appending MM_WELL_KNOWN_MIME_TYPES behind $wgMimeTypeFile, but who knows
- * what will break? In practice this probably isn't a problem anyway -- Bryan)
- */
-define( 'MM_WELL_KNOWN_MIME_TYPES', <<<END_STRING
-application/ogg ogx ogg ogm ogv oga spx
-application/pdf pdf
-application/vnd.oasis.opendocument.chart odc
-application/vnd.oasis.opendocument.chart-template otc
-application/vnd.oasis.opendocument.database odb
-application/vnd.oasis.opendocument.formula odf
-application/vnd.oasis.opendocument.formula-template otf
-application/vnd.oasis.opendocument.graphics odg
-application/vnd.oasis.opendocument.graphics-template otg
-application/vnd.oasis.opendocument.image odi
-application/vnd.oasis.opendocument.image-template oti
-application/vnd.oasis.opendocument.presentation odp
-application/vnd.oasis.opendocument.presentation-template otp
-application/vnd.oasis.opendocument.spreadsheet ods
-application/vnd.oasis.opendocument.spreadsheet-template ots
-application/vnd.oasis.opendocument.text odt
-application/vnd.oasis.opendocument.text-master otm
-application/vnd.oasis.opendocument.text-template ott
-application/vnd.oasis.opendocument.text-web oth
-application/javascript js
-application/x-shockwave-flash swf
-audio/midi mid midi kar
-audio/mpeg mpga mpa mp2 mp3
-audio/x-aiff aif aiff aifc
-audio/x-wav wav
-audio/ogg oga spx ogg
-image/x-bmp bmp
-image/gif gif
-image/jpeg jpeg jpg jpe
-image/png png
-image/svg+xml svg
-image/svg svg
-image/tiff tiff tif
-image/vnd.djvu djvu
-image/x.djvu djvu
-image/x-djvu djvu
-image/x-portable-pixmap ppm
-image/x-xcf xcf
-text/plain txt
-text/html html htm
-video/ogg ogv ogm ogg
-video/mpeg mpg mpeg
-END_STRING
-);
-
-/**
- * Defines a set of well known MIME info entries
- * This is used as a fallback to mime.info files.
- * An extensive list of well known MIME types is provided by
- * the file mime.info in the includes directory.
- */
-define( 'MM_WELL_KNOWN_MIME_INFO', <<<END_STRING
-application/pdf [OFFICE]
-application/vnd.oasis.opendocument.chart [OFFICE]
-application/vnd.oasis.opendocument.chart-template [OFFICE]
-application/vnd.oasis.opendocument.database [OFFICE]
-application/vnd.oasis.opendocument.formula [OFFICE]
-application/vnd.oasis.opendocument.formula-template [OFFICE]
-application/vnd.oasis.opendocument.graphics [OFFICE]
-application/vnd.oasis.opendocument.graphics-template [OFFICE]
-application/vnd.oasis.opendocument.image [OFFICE]
-application/vnd.oasis.opendocument.image-template [OFFICE]
-application/vnd.oasis.opendocument.presentation [OFFICE]
-application/vnd.oasis.opendocument.presentation-template [OFFICE]
-application/vnd.oasis.opendocument.spreadsheet [OFFICE]
-application/vnd.oasis.opendocument.spreadsheet-template [OFFICE]
-application/vnd.oasis.opendocument.text [OFFICE]
-application/vnd.oasis.opendocument.text-template [OFFICE]
-application/vnd.oasis.opendocument.text-master [OFFICE]
-application/vnd.oasis.opendocument.text-web [OFFICE]
-application/javascript text/javascript application/x-javascript [EXECUTABLE]
-application/x-shockwave-flash [MULTIMEDIA]
-audio/midi [AUDIO]
-audio/x-aiff [AUDIO]
-audio/x-wav [AUDIO]
-audio/mp3 audio/mpeg [AUDIO]
-application/ogg audio/ogg video/ogg [MULTIMEDIA]
-image/x-bmp image/x-ms-bmp image/bmp [BITMAP]
-image/gif [BITMAP]
-image/jpeg [BITMAP]
-image/png [BITMAP]
-image/svg+xml [DRAWING]
-image/tiff [BITMAP]
-image/vnd.djvu [BITMAP]
-image/x-xcf [BITMAP]
-image/x-portable-pixmap [BITMAP]
-text/plain [TEXT]
-text/html [TEXT]
-video/ogg [VIDEO]
-video/mpeg [VIDEO]
-unknown/unknown application/octet-stream application/x-empty [UNKNOWN]
-END_STRING
-);
-
-/**
- * Implements functions related to MIME types such as detection and mapping to
- * file extension.
- *
- * Instances of this class are stateless, there only needs to be one global instance
- * of MimeMagic. Please use MimeMagic::singleton() to get that instance.
- */
-class MimeMagic {
-       /**
-        * @var array Mapping of media types to arrays of MIME types.
-        * This is used by findMediaType and getMediaType, respectively
-        */
-       protected $mMediaTypes = null;
-
-       /** @var array Map of MIME type aliases
-        */
-       protected $mMimeTypeAliases = null;
-
-       /** @var array Map of MIME types to file extensions (as a space separated list)
-        */
-       protected $mMimeToExt = null;
-
-       /** @var array Map of file extensions types to MIME types (as a space separated list)
-        */
-       public $mExtToMime = null;
-
-       /** @var IEContentAnalyzer
-        */
-       protected $mIEAnalyzer;
-
-       /** @var string Extra MIME types, set for example by media handling extensions
-        */
-       private $mExtraTypes = '';
-
-       /** @var string Extra MIME info, set for example by media handling extensions
-        */
-       private $mExtraInfo = '';
-
-       /** @var Config */
-       private $mConfig;
-
-       /** @var MimeMagic The singleton instance
-        */
-       private static $instance = null;
-
-       /** Initializes the MimeMagic object. This is called by MimeMagic::singleton().
-        *
-        * This constructor parses the mime.types and mime.info files and build internal mappings.
-        *
-        * @todo Make this constructor private once everything uses the singleton instance
-        * @param Config $config
-        */
-       function __construct( Config $config = null ) {
-               if ( !$config ) {
-                       wfDebug( __METHOD__ . ' called with no Config instance passed to it' );
-                       $config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
-               }
-               $this->mConfig = $config;
-
-               /**
-                *   --- load mime.types ---
-                */
-
-               global $IP;
-
-               # Allow media handling extensions adding MIME-types and MIME-info
-               Hooks::run( 'MimeMagicInit', [ $this ] );
-
-               $types = MM_WELL_KNOWN_MIME_TYPES;
-
-               $mimeTypeFile = $this->mConfig->get( 'MimeTypeFile' );
-               if ( $mimeTypeFile == 'includes/mime.types' ) {
-                       $mimeTypeFile = "$IP/$mimeTypeFile";
-               }
-
-               if ( $mimeTypeFile ) {
-                       if ( is_file( $mimeTypeFile ) && is_readable( $mimeTypeFile ) ) {
-                               wfDebug( __METHOD__ . ": loading mime types from $mimeTypeFile\n" );
-                               $types .= "\n";
-                               $types .= file_get_contents( $mimeTypeFile );
-                       } else {
-                               wfDebug( __METHOD__ . ": can't load mime types from $mimeTypeFile\n" );
-                       }
-               } else {
-                       wfDebug( __METHOD__ . ": no mime types file defined, using built-ins only.\n" );
-               }
-
-               $types .= "\n" . $this->mExtraTypes;
-
-               $types = str_replace( [ "\r\n", "\n\r", "\n\n", "\r\r", "\r" ], "\n", $types );
-               $types = str_replace( "\t", " ", $types );
-
-               $this->mMimeToExt = [];
-               $this->mExtToMime = [];
-
-               $lines = explode( "\n", $types );
-               foreach ( $lines as $s ) {
-                       $s = trim( $s );
-                       if ( empty( $s ) ) {
-                               continue;
-                       }
-                       if ( strpos( $s, '#' ) === 0 ) {
-                               continue;
-                       }
-
-                       $s = strtolower( $s );
-                       $i = strpos( $s, ' ' );
-
-                       if ( $i === false ) {
-                               continue;
-                       }
-
-                       $mime = substr( $s, 0, $i );
-                       $ext = trim( substr( $s, $i + 1 ) );
-
-                       if ( empty( $ext ) ) {
-                               continue;
-                       }
-
-                       if ( !empty( $this->mMimeToExt[$mime] ) ) {
-                               $this->mMimeToExt[$mime] .= ' ' . $ext;
-                       } else {
-                               $this->mMimeToExt[$mime] = $ext;
-                       }
-
-                       $extensions = explode( ' ', $ext );
-
-                       foreach ( $extensions as $e ) {
-                               $e = trim( $e );
-                               if ( empty( $e ) ) {
-                                       continue;
-                               }
-
-                               if ( !empty( $this->mExtToMime[$e] ) ) {
-                                       $this->mExtToMime[$e] .= ' ' . $mime;
-                               } else {
-                                       $this->mExtToMime[$e] = $mime;
-                               }
-                       }
-               }
-
-               /**
-                *   --- load mime.info ---
-                */
-
-               $mimeInfoFile = $this->mConfig->get( 'MimeInfoFile' );
-               if ( $mimeInfoFile == 'includes/mime.info' ) {
-                       $mimeInfoFile = "$IP/$mimeInfoFile";
-               }
-
-               $info = MM_WELL_KNOWN_MIME_INFO;
-
-               if ( $mimeInfoFile ) {
-                       if ( is_file( $mimeInfoFile ) && is_readable( $mimeInfoFile ) ) {
-                               wfDebug( __METHOD__ . ": loading mime info from $mimeInfoFile\n" );
-                               $info .= "\n";
-                               $info .= file_get_contents( $mimeInfoFile );
-                       } else {
-                               wfDebug( __METHOD__ . ": can't load mime info from $mimeInfoFile\n" );
-                       }
-               } else {
-                       wfDebug( __METHOD__ . ": no mime info file defined, using built-ins only.\n" );
-               }
-
-               $info .= "\n" . $this->mExtraInfo;
-
-               $info = str_replace( [ "\r\n", "\n\r", "\n\n", "\r\r", "\r" ], "\n", $info );
-               $info = str_replace( "\t", " ", $info );
-
-               $this->mMimeTypeAliases = [];
-               $this->mMediaTypes = [];
-
-               $lines = explode( "\n", $info );
-               foreach ( $lines as $s ) {
-                       $s = trim( $s );
-                       if ( empty( $s ) ) {
-                               continue;
-                       }
-                       if ( strpos( $s, '#' ) === 0 ) {
-                               continue;
-                       }
-
-                       $s = strtolower( $s );
-                       $i = strpos( $s, ' ' );
-
-                       if ( $i === false ) {
-                               continue;
-                       }
-
-                       # print "processing MIME INFO line $s<br>";
-
-                       $match = [];
-                       if ( preg_match( '!\[\s*(\w+)\s*\]!', $s, $match ) ) {
-                               $s = preg_replace( '!\[\s*(\w+)\s*\]!', '', $s );
-                               $mtype = trim( strtoupper( $match[1] ) );
-                       } else {
-                               $mtype = MEDIATYPE_UNKNOWN;
-                       }
-
-                       $m = explode( ' ', $s );
-
-                       if ( !isset( $this->mMediaTypes[$mtype] ) ) {
-                               $this->mMediaTypes[$mtype] = [];
-                       }
-
-                       foreach ( $m as $mime ) {
-                               $mime = trim( $mime );
-                               if ( empty( $mime ) ) {
-                                       continue;
-                               }
-
-                               $this->mMediaTypes[$mtype][] = $mime;
-                       }
-
-                       if ( count( $m ) > 1 ) {
-                               $main = $m[0];
-                               $mCount = count( $m );
-                               for ( $i = 1; $i < $mCount; $i += 1 ) {
-                                       $mime = $m[$i];
-                                       $this->mMimeTypeAliases[$mime] = $main;
-                               }
-                       }
-               }
-       }
-
+class MimeMagic extends MimeAnalyzer {
        /**
         * Get an instance of this class
         * @return MimeMagic
+        * @deprecated since 1.28
         */
        public static function singleton() {
-               if ( self::$instance === null ) {
-                       self::$instance = new MimeMagic(
-                               ConfigFactory::getDefaultInstance()->makeConfig( 'main' )
-                       );
-               }
-               return self::$instance;
-       }
-
-       /**
-        * Adds to the list mapping MIME to file extensions.
-        * As an extension author, you are encouraged to submit patches to
-        * MediaWiki's core to add new MIME types to mime.types.
-        * @param string $types
-        */
-       public function addExtraTypes( $types ) {
-               $this->mExtraTypes .= "\n" . $types;
-       }
-
-       /**
-        * Adds to the list mapping MIME to media type.
-        * As an extension author, you are encouraged to submit patches to
-        * MediaWiki's core to add new MIME info to mime.info.
-        * @param string $info
-        */
-       public function addExtraInfo( $info ) {
-               $this->mExtraInfo .= "\n" . $info;
-       }
-
-       /**
-        * Returns a list of file extensions for a given MIME type as a space
-        * separated string or null if the MIME type was unrecognized. Resolves
-        * MIME type aliases.
-        *
-        * @param string $mime
-        * @return string|null
-        */
-       public function getExtensionsForType( $mime ) {
-               $mime = strtolower( $mime );
-
-               // Check the mime-to-ext map
-               if ( isset( $this->mMimeToExt[$mime] ) ) {
-                       return $this->mMimeToExt[$mime];
-               }
-
-               // Resolve the MIME type to the canonical type
-               if ( isset( $this->mMimeTypeAliases[$mime] ) ) {
-                       $mime = $this->mMimeTypeAliases[$mime];
-                       if ( isset( $this->mMimeToExt[$mime] ) ) {
-                               return $this->mMimeToExt[$mime];
-                       }
-               }
-
-               return null;
+               return MediaWikiServices::getInstance()->getMIMEAnalyzer();
        }
 
        /**
-        * Returns a list of MIME types for a given file extension as a space
-        * separated string or null if the extension was unrecognized.
-        *
-        * @param string $ext
-        * @return string|null
-        */
-       public function getTypesForExtension( $ext ) {
-               $ext = strtolower( $ext );
-
-               $r = isset( $this->mExtToMime[$ext] ) ? $this->mExtToMime[$ext] : null;
-               return $r;
-       }
-
-       /**
-        * Returns a single MIME type for a given file extension or null if unknown.
-        * This is always the first type from the list returned by getTypesForExtension($ext).
-        *
-        * @param string $ext
-        * @return string|null
-        */
-       public function guessTypesForExtension( $ext ) {
-               $m = $this->getTypesForExtension( $ext );
-               if ( is_null( $m ) ) {
-                       return null;
-               }
-
-               // TODO: Check if this is needed; strtok( $m, ' ' ) should be sufficient
-               $m = trim( $m );
-               $m = preg_replace( '/\s.*$/', '', $m );
-
-               return $m;
-       }
-
-       /**
-        * Tests if the extension matches the given MIME type. Returns true if a
-        * match was found, null if the MIME type is unknown, and false if the
-        * MIME type is known but no matches where found.
-        *
-        * @param string $extension
-        * @param string $mime
-        * @return bool|null
-        */
-       public function isMatchingExtension( $extension, $mime ) {
-               $ext = $this->getExtensionsForType( $mime );
-
-               if ( !$ext ) {
-                       return null; // Unknown MIME type
-               }
-
-               $ext = explode( ' ', $ext );
-
-               $extension = strtolower( $extension );
-               return in_array( $extension, $ext );
-       }
-
-       /**
-        * Returns true if the MIME type is known to represent an image format
-        * supported by the PHP GD library.
-        *
-        * @param string $mime
-        *
-        * @return bool
-        */
-       public function isPHPImageType( $mime ) {
-               // As defined by imagegetsize and image_type_to_mime
-               static $types = [
-                       'image/gif', 'image/jpeg', 'image/png',
-                       'image/x-bmp', 'image/xbm', 'image/tiff',
-                       'image/jp2', 'image/jpeg2000', 'image/iff',
-                       'image/xbm', 'image/x-xbitmap',
-                       'image/vnd.wap.wbmp', 'image/vnd.xiff',
-                       'image/x-photoshop',
-                       'application/x-shockwave-flash',
-               ];
-
-               return in_array( $mime, $types );
-       }
-
-       /**
-        * Returns true if the extension represents a type which can
-        * be reliably detected from its content. Use this to determine
-        * whether strict content checks should be applied to reject
-        * invalid uploads; if we can't identify the type we won't
-        * be able to say if it's invalid.
-        *
-        * @todo Be more accurate when using fancy MIME detector plugins;
-        *       right now this is the bare minimum getimagesize() list.
-        * @param string $extension
-        * @return bool
-        */
-       function isRecognizableExtension( $extension ) {
-               static $types = [
-                       // Types recognized by getimagesize()
-                       'gif', 'jpeg', 'jpg', 'png', 'swf', 'psd',
-                       'bmp', 'tiff', 'tif', 'jpc', 'jp2',
-                       'jpx', 'jb2', 'swc', 'iff', 'wbmp',
-                       'xbm',
-
-                       // Formats we recognize magic numbers for
-                       'djvu', 'ogx', 'ogg', 'ogv', 'oga', 'spx',
-                       'mid', 'pdf', 'wmf', 'xcf', 'webm', 'mkv', 'mka',
-                       'webp',
-
-                       // XML formats we sure hope we recognize reliably
-                       'svg',
-               ];
-               return in_array( strtolower( $extension ), $types );
-       }
-
-       /**
-        * Improves a MIME type using the file extension. Some file formats are very generic,
-        * so their MIME type is not very meaningful. A more useful MIME type can be derived
-        * by looking at the file extension. Typically, this method would be called on the
-        * result of guessMimeType().
-        *
-        * @param string $mime The MIME type, typically guessed from a file's content.
-        * @param string $ext The file extension, as taken from the file name
-        *
-        * @return string The MIME type
-        */
-       public function improveTypeFromExtension( $mime, $ext ) {
-               if ( $mime === 'unknown/unknown' ) {
-                       if ( $this->isRecognizableExtension( $ext ) ) {
-                               wfDebug( __METHOD__ . ': refusing to guess mime type for .' .
-                                       "$ext file, we should have recognized it\n" );
-                       } else {
-                               // Not something we can detect, so simply
-                               // trust the file extension
-                               $mime = $this->guessTypesForExtension( $ext );
-                       }
-               } elseif ( $mime === 'application/x-opc+zip' ) {
-                       if ( $this->isMatchingExtension( $ext, $mime ) ) {
-                               // A known file extension for an OPC file,
-                               // find the proper MIME type for that file extension
-                               $mime = $this->guessTypesForExtension( $ext );
-                       } else {
-                               wfDebug( __METHOD__ . ": refusing to guess better type for $mime file, " .
-                                       ".$ext is not a known OPC extension.\n" );
-                               $mime = 'application/zip';
-                       }
-               } elseif ( $mime === 'text/plain' && $this->findMediaType( ".$ext" ) === MEDIATYPE_TEXT ) {
-                       // Textual types are sometimes not recognized properly.
-                       // If detected as text/plain, and has an extension which is textual
-                       // improve to the extension's type. For example, csv and json are often
-                       // misdetected as text/plain.
-                       $mime = $this->guessTypesForExtension( $ext );
-               }
-
-               # Media handling extensions can improve the MIME detected
-               Hooks::run( 'MimeMagicImproveFromExtension', [ $this, $ext, &$mime ] );
-
-               if ( isset( $this->mMimeTypeAliases[$mime] ) ) {
-                       $mime = $this->mMimeTypeAliases[$mime];
-               }
-
-               wfDebug( __METHOD__ . ": improved mime type for .$ext: $mime\n" );
-               return $mime;
-       }
-
-       /**
-        * MIME type detection. This uses detectMimeType to detect the MIME type
-        * of the file, but applies additional checks to determine some well known
-        * file formats that may be missed or misinterpreted by the default MIME
-        * detection (namely XML based formats like XHTML or SVG, as well as ZIP
-        * based formats like OPC/ODF files).
-        *
-        * @param string $file The file to check
-        * @param string|bool $ext The file extension, or true (default) to extract it from the filename.
-        *   Set it to false to ignore the extension. DEPRECATED! Set to false, use
-        *   improveTypeFromExtension($mime, $ext) later to improve MIME type.
-        *
-        * @return string The MIME type of $file
-        */
-       public function guessMimeType( $file, $ext = true ) {
-               if ( $ext ) { // TODO: make $ext default to false. Or better, remove it.
-                       wfDebug( __METHOD__ . ": WARNING: use of the \$ext parameter is deprecated. " .
-                               "Use improveTypeFromExtension(\$mime, \$ext) instead.\n" );
-               }
-
-               $mime = $this->doGuessMimeType( $file, $ext );
-
-               if ( !$mime ) {
-                       wfDebug( __METHOD__ . ": internal type detection failed for $file (.$ext)...\n" );
-                       $mime = $this->detectMimeType( $file, $ext );
-               }
-
-               if ( isset( $this->mMimeTypeAliases[$mime] ) ) {
-                       $mime = $this->mMimeTypeAliases[$mime];
-               }
-
-               wfDebug( __METHOD__ . ": guessed mime type of $file: $mime\n" );
-               return $mime;
-       }
-
-       /**
-        * Guess the MIME type from the file contents.
-        *
-        * @todo Remove $ext param
-        *
-        * @param string $file
-        * @param mixed $ext
-        * @return bool|string
-        * @throws MWException
+        * @param array $params
+        * @param Config $mainConfig
+        * @return array
         */
-       private function doGuessMimeType( $file, $ext ) {
-               // Read a chunk of the file
-               MediaWiki\suppressWarnings();
-               $f = fopen( $file, 'rb' );
-               MediaWiki\restoreWarnings();
-
-               if ( !$f ) {
-                       return 'unknown/unknown';
-               }
-
-               $fsize = filesize( $file );
-               if ( $fsize === false ) {
-                       return 'unknown/unknown';
-               }
-
-               $head = fread( $f, 1024 );
-               $tailLength = min( 65558, $fsize ); // 65558 = maximum size of a zip EOCDR
-               if ( fseek( $f, -1 * $tailLength, SEEK_END ) === -1 ) {
-                       throw new MWException(
-                               "Seeking $tailLength bytes from EOF failed in " . __METHOD__ );
-               }
-               $tail = $tailLength ? fread( $f, $tailLength ) : '';
-               fclose( $f );
-
-               wfDebug( __METHOD__ . ": analyzing head and tail of $file for magic numbers.\n" );
-
-               // Hardcode a few magic number checks...
-               $headers = [
-                       // Multimedia...
-                       'MThd'             => 'audio/midi',
-                       'OggS'             => 'application/ogg',
-
-                       // Image formats...
-                       // Note that WMF may have a bare header, no magic number.
-                       "\x01\x00\x09\x00" => 'application/x-msmetafile', // Possibly prone to false positives?
-                       "\xd7\xcd\xc6\x9a" => 'application/x-msmetafile',
-                       '%PDF'             => 'application/pdf',
-                       'gimp xcf'         => 'image/x-xcf',
-
-                       // Some forbidden fruit...
-                       'MZ'               => 'application/octet-stream', // DOS/Windows executable
-                       "\xca\xfe\xba\xbe" => 'application/octet-stream', // Mach-O binary
-                       "\x7fELF"          => 'application/octet-stream', // ELF binary
-               ];
-
-               foreach ( $headers as $magic => $candidate ) {
-                       if ( strncmp( $head, $magic, strlen( $magic ) ) == 0 ) {
-                               wfDebug( __METHOD__ . ": magic header in $file recognized as $candidate\n" );
-                               return $candidate;
-                       }
-               }
-
-               /* Look for WebM and Matroska files */
-               if ( strncmp( $head, pack( "C4", 0x1a, 0x45, 0xdf, 0xa3 ), 4 ) == 0 ) {
-                       $doctype = strpos( $head, "\x42\x82" );
-                       if ( $doctype ) {
-                               // Next byte is datasize, then data (sizes larger than 1 byte are very stupid muxers)
-                               $data = substr( $head, $doctype + 3, 8 );
-                               if ( strncmp( $data, "matroska", 8 ) == 0 ) {
-                                       wfDebug( __METHOD__ . ": recognized file as video/x-matroska\n" );
-                                       return "video/x-matroska";
-                               } elseif ( strncmp( $data, "webm", 4 ) == 0 ) {
-                                       wfDebug( __METHOD__ . ": recognized file as video/webm\n" );
-                                       return "video/webm";
-                               }
-                       }
-                       wfDebug( __METHOD__ . ": unknown EBML file\n" );
-                       return "unknown/unknown";
-               }
-
-               /* Look for WebP */
-               if ( strncmp( $head, "RIFF", 4 ) == 0 && strncmp( substr( $head, 8, 7 ), "WEBPVP8", 7 ) == 0 ) {
-                       wfDebug( __METHOD__ . ": recognized file as image/webp\n" );
-                       return "image/webp";
-               }
-
-               /**
-                * Look for PHP.  Check for this before HTML/XML...  Warning: this is a
-                * heuristic, and won't match a file with a lot of non-PHP before.  It
-                * will also match text files which could be PHP. :)
-                *
-                * @todo FIXME: For this reason, the check is probably useless -- an attacker
-                * could almost certainly just pad the file with a lot of nonsense to
-                * circumvent the check in any case where it would be a security
-                * problem.  On the other hand, it causes harmful false positives (bug
-                * 16583).  The heuristic has been cut down to exclude three-character
-                * strings like "<? ", but should it be axed completely?
-                */
-               if ( ( strpos( $head, '<?php' ) !== false ) ||
-                       ( strpos( $head, "<\x00?\x00p\x00h\x00p" ) !== false ) ||
-                       ( strpos( $head, "<\x00?\x00 " ) !== false ) ||
-                       ( strpos( $head, "<\x00?\x00\n" ) !== false ) ||
-                       ( strpos( $head, "<\x00?\x00\t" ) !== false ) ||
-                       ( strpos( $head, "<\x00?\x00=" ) !== false ) ) {
-
-                       wfDebug( __METHOD__ . ": recognized $file as application/x-php\n" );
-                       return 'application/x-php';
-               }
-
-               /**
-                * look for XML formats (XHTML and SVG)
-                */
-               $xml = new XmlTypeCheck( $file );
-               if ( $xml->wellFormed ) {
-                       $xmlMimeTypes = $this->mConfig->get( 'XMLMimeTypes' );
-                       if ( isset( $xmlMimeTypes[$xml->getRootElement()] ) ) {
-                               return $xmlMimeTypes[$xml->getRootElement()];
-                       } else {
-                               return 'application/xml';
-                       }
-               }
-
-               /**
-                * look for shell scripts
-                */
-               $script_type = null;
-
-               # detect by shebang
-               if ( substr( $head, 0, 2 ) == "#!" ) {
-                       $script_type = "ASCII";
-               } elseif ( substr( $head, 0, 5 ) == "\xef\xbb\xbf#!" ) {
-                       $script_type = "UTF-8";
-               } elseif ( substr( $head, 0, 7 ) == "\xfe\xff\x00#\x00!" ) {
-                       $script_type = "UTF-16BE";
-               } elseif ( substr( $head, 0, 7 ) == "\xff\xfe#\x00!" ) {
-                       $script_type = "UTF-16LE";
-               }
-
-               if ( $script_type ) {
-                       if ( $script_type !== "UTF-8" && $script_type !== "ASCII" ) {
-                               // Quick and dirty fold down to ASCII!
-                               $pack = [ 'UTF-16BE' => 'n*', 'UTF-16LE' => 'v*' ];
-                               $chars = unpack( $pack[$script_type], substr( $head, 2 ) );
-                               $head = '';
-                               foreach ( $chars as $codepoint ) {
-                                       if ( $codepoint < 128 ) {
-                                               $head .= chr( $codepoint );
-                                       } else {
-                                               $head .= '?';
+       public static function applyDefaultParameters( array $params, Config $mainConfig ) {
+               $logger = LoggerFactory::getInstance( 'Mime' );
+               $params += [
+                       'typeFile' => $mainConfig->get( 'MimeTypeFile' ),
+                       'infoFile' => $mainConfig->get( 'MimeInfoFile' ),
+                       'xmlTypes' => $mainConfig->get( 'XMLMimeTypes' ),
+                       'guessCallback' =>
+                               function ( $mimeAnalyzer, &$head, &$tail, $file, &$mime ) use ( $logger ) {
+                                       // Also test DjVu
+                                       $deja = new DjVuImage( $file );
+                                       if ( $deja->isValid() ) {
+                                               $logger->info( __METHOD__ . ": detected $file as image/vnd.djvu\n" );
+                                               $mime = 'image/vnd.djvu';
+
+                                               return;
                                        }
-                               }
-                       }
-
-                       $match = [];
-
-                       if ( preg_match( '%/?([^\s]+/)(\w+)%', $head, $match ) ) {
-                               $mime = "application/x-{$match[2]}";
-                               wfDebug( __METHOD__ . ": shell script recognized as $mime\n" );
-                               return $mime;
-                       }
-               }
-
-               // Check for ZIP variants (before getimagesize)
-               if ( strpos( $tail, "PK\x05\x06" ) !== false ) {
-                       wfDebug( __METHOD__ . ": ZIP header present in $file\n" );
-                       return $this->detectZipType( $head, $tail, $ext );
-               }
-
-               MediaWiki\suppressWarnings();
-               $gis = getimagesize( $file );
-               MediaWiki\restoreWarnings();
-
-               if ( $gis && isset( $gis['mime'] ) ) {
-                       $mime = $gis['mime'];
-                       wfDebug( __METHOD__ . ": getimagesize detected $file as $mime\n" );
-                       return $mime;
-               }
-
-               // Also test DjVu
-               $deja = new DjVuImage( $file );
-               if ( $deja->isValid() ) {
-                       wfDebug( __METHOD__ . ": detected $file as image/vnd.djvu\n" );
-                       return 'image/vnd.djvu';
-               }
-
-               # Media handling extensions can guess the MIME by content
-               # It's intentionally here so that if core is wrong about a type (false positive),
-               # people will hopefully nag and submit patches :)
-               $mime = false;
-               # Some strings by reference for performance - assuming well-behaved hooks
-               Hooks::run(
-                       'MimeMagicGuessFromContent',
-                       [ $this, &$head, &$tail, $file, &$mime ]
-               );
-
-               return $mime;
-       }
-
-       /**
-        * Detect application-specific file type of a given ZIP file from its
-        * header data.  Currently works for OpenDocument and OpenXML types...
-        * If can't tell, returns 'application/zip'.
-        *
-        * @param string $header Some reasonably-sized chunk of file header
-        * @param string|null $tail The tail of the file
-        * @param string|bool $ext The file extension, or true to extract it from the filename.
-        *   Set it to false (default) to ignore the extension. DEPRECATED! Set to false,
-        *   use improveTypeFromExtension($mime, $ext) later to improve MIME type.
-        *
-        * @return string
-        */
-       function detectZipType( $header, $tail = null, $ext = false ) {
-               if ( $ext ) { # TODO: remove $ext param
-                       wfDebug( __METHOD__ . ": WARNING: use of the \$ext parameter is deprecated. " .
-                               "Use improveTypeFromExtension(\$mime, \$ext) instead.\n" );
-               }
-
-               $mime = 'application/zip';
-               $opendocTypes = [
-                       'chart-template',
-                       'chart',
-                       'formula-template',
-                       'formula',
-                       'graphics-template',
-                       'graphics',
-                       'image-template',
-                       'image',
-                       'presentation-template',
-                       'presentation',
-                       'spreadsheet-template',
-                       'spreadsheet',
-                       'text-template',
-                       'text-master',
-                       'text-web',
-                       'text' ];
-
-               // http://lists.oasis-open.org/archives/office/200505/msg00006.html
-               $types = '(?:' . implode( '|', $opendocTypes ) . ')';
-               $opendocRegex = "/^mimetype(application\/vnd\.oasis\.opendocument\.$types)/";
-
-               $openxmlRegex = "/^\[Content_Types\].xml/";
-
-               if ( preg_match( $opendocRegex, substr( $header, 30 ), $matches ) ) {
-                       $mime = $matches[1];
-                       wfDebug( __METHOD__ . ": detected $mime from ZIP archive\n" );
-               } elseif ( preg_match( $openxmlRegex, substr( $header, 30 ) ) ) {
-                       $mime = "application/x-opc+zip";
-                       # TODO: remove the block below, as soon as improveTypeFromExtension is used everywhere
-                       if ( $ext !== true && $ext !== false ) {
-                               // These MIME's are stored in the database, where we don't really want
-                               // x-opc+zip, because we use it only for internal purposes
-                               if ( $this->isMatchingExtension( $ext, $mime ) ) {
-                                       /* A known file extension for an OPC file,
-                                        * find the proper mime type for that file extension
-                                        */
-                                       $mime = $this->guessTypesForExtension( $ext );
-                               } else {
-                                       $mime = "application/zip";
-                               }
-                       }
-                       wfDebug( __METHOD__ . ": detected an Open Packaging Conventions archive: $mime\n" );
-               } elseif ( substr( $header, 0, 8 ) == "\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1" &&
-                               ( $headerpos = strpos( $tail, "PK\x03\x04" ) ) !== false &&
-                               preg_match( $openxmlRegex, substr( $tail, $headerpos + 30 ) ) ) {
-                       if ( substr( $header, 512, 4 ) == "\xEC\xA5\xC1\x00" ) {
-                               $mime = "application/msword";
-                       }
-                       switch ( substr( $header, 512, 6 ) ) {
-                               case "\xEC\xA5\xC1\x00\x0E\x00":
-                               case "\xEC\xA5\xC1\x00\x1C\x00":
-                               case "\xEC\xA5\xC1\x00\x43\x00":
-                                       $mime = "application/vnd.ms-powerpoint";
-                                       break;
-                               case "\xFD\xFF\xFF\xFF\x10\x00":
-                               case "\xFD\xFF\xFF\xFF\x1F\x00":
-                               case "\xFD\xFF\xFF\xFF\x22\x00":
-                               case "\xFD\xFF\xFF\xFF\x23\x00":
-                               case "\xFD\xFF\xFF\xFF\x28\x00":
-                               case "\xFD\xFF\xFF\xFF\x29\x00":
-                               case "\xFD\xFF\xFF\xFF\x10\x02":
-                               case "\xFD\xFF\xFF\xFF\x1F\x02":
-                               case "\xFD\xFF\xFF\xFF\x22\x02":
-                               case "\xFD\xFF\xFF\xFF\x23\x02":
-                               case "\xFD\xFF\xFF\xFF\x28\x02":
-                               case "\xFD\xFF\xFF\xFF\x29\x02":
-                                       $mime = "application/vnd.msexcel";
-                                       break;
-                       }
-
-                       wfDebug( __METHOD__ . ": detected a MS Office document with OPC trailer\n" );
-               } else {
-                       wfDebug( __METHOD__ . ": unable to identify type of ZIP archive\n" );
-               }
-               return $mime;
-       }
-
-       /**
-        * Internal MIME type detection. Detection is done using an external
-        * program, if $wgMimeDetectorCommand is set. Otherwise, the fileinfo
-        * extension is tried if it is available. If detection fails and $ext
-        * is not false, the MIME type is guessed from the file extension,
-        * using guessTypesForExtension.
-        *
-        * If the MIME type is still unknown, getimagesize is used to detect the
-        * MIME type if the file is an image. If no MIME type can be determined,
-        * this function returns 'unknown/unknown'.
-        *
-        * @param string $file The file to check
-        * @param string|bool $ext The file extension, or true (default) to extract it from the filename.
-        *   Set it to false to ignore the extension. DEPRECATED! Set to false, use
-        *   improveTypeFromExtension($mime, $ext) later to improve MIME type.
-        *
-        * @return string The MIME type of $file
-        */
-       private function detectMimeType( $file, $ext = true ) {
-               /** @todo Make $ext default to false. Or better, remove it. */
-               if ( $ext ) {
-                       wfDebug( __METHOD__ . ": WARNING: use of the \$ext parameter is deprecated. "
-                               . "Use improveTypeFromExtension(\$mime, \$ext) instead.\n" );
-               }
-
-               $mimeDetectorCommand = $this->mConfig->get( 'MimeDetectorCommand' );
-               $m = null;
-               if ( $mimeDetectorCommand ) {
-                       $args = wfEscapeShellArg( $file );
-                       $m = wfShellExec( "$mimeDetectorCommand $args" );
-               } elseif ( function_exists( "finfo_open" ) && function_exists( "finfo_file" ) ) {
-                       $mime_magic_resource = finfo_open( FILEINFO_MIME );
-
-                       if ( $mime_magic_resource ) {
-                               $m = finfo_file( $mime_magic_resource, $file );
-                               finfo_close( $mime_magic_resource );
-                       } else {
-                               wfDebug( __METHOD__ . ": finfo_open failed on " . FILEINFO_MIME . "!\n" );
-                       }
-               } else {
-                       wfDebug( __METHOD__ . ": no magic mime detector found!\n" );
-               }
-
-               if ( $m ) {
-                       # normalize
-                       $m = preg_replace( '![;, ].*$!', '', $m ); # strip charset, etc
-                       $m = trim( $m );
-                       $m = strtolower( $m );
-
-                       if ( strpos( $m, 'unknown' ) !== false ) {
-                               $m = null;
-                       } else {
-                               wfDebug( __METHOD__ . ": magic mime type of $file: $m\n" );
-                               return $m;
-                       }
-               }
-
-               // If desired, look at extension as a fallback.
-               if ( $ext === true ) {
-                       $i = strrpos( $file, '.' );
-                       $ext = strtolower( $i ? substr( $file, $i + 1 ) : '' );
-               }
-               if ( $ext ) {
-                       if ( $this->isRecognizableExtension( $ext ) ) {
-                               wfDebug( __METHOD__ . ": refusing to guess mime type for .$ext file, "
-                                       . "we should have recognized it\n" );
-                       } else {
-                               $m = $this->guessTypesForExtension( $ext );
-                               if ( $m ) {
-                                       wfDebug( __METHOD__ . ": extension mime type of $file: $m\n" );
-                                       return $m;
-                               }
-                       }
-               }
-
-               // Unknown type
-               wfDebug( __METHOD__ . ": failed to guess mime type for $file!\n" );
-               return 'unknown/unknown';
-       }
-
-       /**
-        * Determine the media type code for a file, using its MIME type, name and
-        * possibly its contents.
-        *
-        * This function relies on the findMediaType(), mapping extensions and MIME
-        * types to media types.
-        *
-        * @todo analyse file if need be
-        * @todo look at multiple extension, separately and together.
-        *
-        * @param string $path Full path to the image file, in case we have to look at the contents
-        *        (if null, only the MIME type is used to determine the media type code).
-        * @param string $mime MIME type. If null it will be guessed using guessMimeType.
-        *
-        * @return string A value to be used with the MEDIATYPE_xxx constants.
-        */
-       function getMediaType( $path = null, $mime = null ) {
-               if ( !$mime && !$path ) {
-                       return MEDIATYPE_UNKNOWN;
-               }
-
-               // If MIME type is unknown, guess it
-               if ( !$mime ) {
-                       $mime = $this->guessMimeType( $path, false );
-               }
-
-               // Special code for ogg - detect if it's video (theora),
-               // else label it as sound.
-               if ( $mime == 'application/ogg' && file_exists( $path ) ) {
-
-                       // Read a chunk of the file
-                       $f = fopen( $path, "rt" );
-                       if ( !$f ) {
-                               return MEDIATYPE_UNKNOWN;
-                       }
-                       $head = fread( $f, 256 );
-                       fclose( $f );
-
-                       $head = str_replace( 'ffmpeg2theora', '', strtolower( $head ) );
-
-                       // This is an UGLY HACK, file should be parsed correctly
-                       if ( strpos( $head, 'theora' ) !== false ) {
-                               return MEDIATYPE_VIDEO;
-                       } elseif ( strpos( $head, 'vorbis' ) !== false ) {
-                               return MEDIATYPE_AUDIO;
-                       } elseif ( strpos( $head, 'flac' ) !== false ) {
-                               return MEDIATYPE_AUDIO;
-                       } elseif ( strpos( $head, 'speex' ) !== false ) {
-                               return MEDIATYPE_AUDIO;
-                       } else {
-                               return MEDIATYPE_MULTIMEDIA;
-                       }
-               }
-
-               $type = null;
-               // Check for entry for full MIME type
-               if ( $mime ) {
-                       $type = $this->findMediaType( $mime );
-                       if ( $type !== MEDIATYPE_UNKNOWN ) {
-                               return $type;
-                       }
-               }
-
-               // Check for entry for file extension
-               if ( $path ) {
-                       $i = strrpos( $path, '.' );
-                       $e = strtolower( $i ? substr( $path, $i + 1 ) : '' );
-
-                       // TODO: look at multi-extension if this fails, parse from full path
-                       $type = $this->findMediaType( '.' . $e );
-                       if ( $type !== MEDIATYPE_UNKNOWN ) {
-                               return $type;
-                       }
-               }
-
-               // Check major MIME type
-               if ( $mime ) {
-                       $i = strpos( $mime, '/' );
-                       if ( $i !== false ) {
-                               $major = substr( $mime, 0, $i );
-                               $type = $this->findMediaType( $major );
-                               if ( $type !== MEDIATYPE_UNKNOWN ) {
-                                       return $type;
-                               }
-                       }
-               }
+                                       // Some strings by reference for performance - assuming well-behaved hooks
+                                       Hooks::run(
+                                               'MimeMagicGuessFromContent',
+                                               [ $mimeAnalyzer, &$head, &$tail, $file, &$mime ]
+                                       );
+                               },
+                       'extCallback' => function ( $mimeAnalyzer, $ext, &$mime ) {
+                               // Media handling extensions can improve the MIME detected
+                               Hooks::run( 'MimeMagicImproveFromExtension', [ $mimeAnalyzer, $ext, &$mime ] );
+                       },
+                       'initCallback' => function ( $mimeAnalyzer ) {
+                               // Allow media handling extensions adding MIME-types and MIME-info
+                               Hooks::run( 'MimeMagicInit', [ $mimeAnalyzer ] );
+                       },
+                       'logger' => $logger
+               ];
 
-               if ( !$type ) {
-                       $type = MEDIATYPE_UNKNOWN;
+               if ( $params['infoFile'] === 'includes/mime.info' ) {
+                       $params['infoFile'] = __DIR__ . "/libs/mime/mime.info";
                }
 
-               return $type;
-       }
-
-       /**
-        * Returns a media code matching the given MIME type or file extension.
-        * File extensions are represented by a string starting with a dot (.) to
-        * distinguish them from MIME types.
-        *
-        * This function relies on the mapping defined by $this->mMediaTypes
-        * @access private
-        * @param string $extMime
-        * @return int|string
-        */
-       function findMediaType( $extMime ) {
-               if ( strpos( $extMime, '.' ) === 0 ) {
-                       // If it's an extension, look up the MIME types
-                       $m = $this->getTypesForExtension( substr( $extMime, 1 ) );
-                       if ( !$m ) {
-                               return MEDIATYPE_UNKNOWN;
-                       }
-
-                       $m = explode( ' ', $m );
-               } else {
-                       // Normalize MIME type
-                       if ( isset( $this->mMimeTypeAliases[$extMime] ) ) {
-                               $extMime = $this->mMimeTypeAliases[$extMime];
-                       }
-
-                       $m = [ $extMime ];
+               if ( $params['typeFile'] === 'includes/mime.types' ) {
+                       $params['typeFile'] = __DIR__ . "/libs/mime/mime.types";
                }
 
-               foreach ( $m as $mime ) {
-                       foreach ( $this->mMediaTypes as $type => $codes ) {
-                               if ( in_array( $mime, $codes, true ) ) {
-                                       return $type;
-                               }
-                       }
+               $detectorCmd = $mainConfig->get( 'MimeDetectorCommand' );
+               if ( $detectorCmd ) {
+                       $params['detectCallback'] = function ( $file ) use ( $detectorCmd ) {
+                               return wfShellExec( "$detectorCmd " . wfEscapeShellArg( $file ) );
+                       };
                }
 
-               return MEDIATYPE_UNKNOWN;
-       }
-
-       /**
-        * Get the MIME types that various versions of Internet Explorer would
-        * detect from a chunk of the content.
-        *
-        * @param string $fileName The file name (unused at present)
-        * @param string $chunk The first 256 bytes of the file
-        * @param string $proposed The MIME type proposed by the server
-        * @return array
-        */
-       public function getIEMimeTypes( $fileName, $chunk, $proposed ) {
-               $ca = $this->getIEContentAnalyzer();
-               return $ca->getRealMimesFromData( $fileName, $chunk, $proposed );
-       }
-
-       /**
-        * Get a cached instance of IEContentAnalyzer
-        *
-        * @return IEContentAnalyzer
-        */
-       protected function getIEContentAnalyzer() {
-               if ( is_null( $this->mIEAnalyzer ) ) {
-                       $this->mIEAnalyzer = new IEContentAnalyzer;
-               }
-               return $this->mIEAnalyzer;
+               return $params;
        }
 }
index 5f1dd3f..a8f6f8e 100644 (file)
@@ -131,6 +131,14 @@ class MovePage {
                                ContentHandler::getLocalizedName( $this->oldTitle->getContentModel() ),
                                ContentHandler::getLocalizedName( $this->newTitle->getContentModel() )
                        );
+               } elseif (
+                       !ContentHandler::getForTitle( $this->oldTitle )->canBeUsedOn( $this->newTitle )
+               ) {
+                       $status->fatal(
+                               'content-not-allowed-here',
+                               ContentHandler::getLocalizedName( $this->oldTitle->getContentModel() ),
+                               $this->newTitle->getPrefixedText()
+                       );
                }
 
                // Image-specific checks
@@ -531,8 +539,8 @@ class MovePage {
                        __METHOD__
                );
 
-               // clean up the old title before reset article id - bug 45348
                if ( !$redirectContent ) {
+                       // Clean up the old title *before* reset article id - bug 45348
                        WikiPage::onArticleDelete( $this->oldTitle );
                }
 
index b2e7d94..50629ba 100644 (file)
@@ -295,9 +295,6 @@ class OutputPage extends ContextSource {
         */
        private $copyrightUrl;
 
-       /** @var array Profiling data */
-       private $limitReportData = [];
-
        /**
         * Constructor for OutputPage. This should not be called directly.
         * Instead a new RequestContext should be created and it will implicitly create
@@ -1214,8 +1211,8 @@ class OutputPage extends ContextSource {
        /**
         * Add new language links
         *
-        * @param array $newLinkArray Associative array mapping language code to the page
-        *                      name
+        * @param string[] $newLinkArray Array of interwiki-prefixed (non DB key) titles
+        *                               (e.g. 'fr:Test page')
         */
        public function addLanguageLinks( array $newLinkArray ) {
                $this->mLanguageLinks += $newLinkArray;
@@ -1224,8 +1221,8 @@ class OutputPage extends ContextSource {
        /**
         * Reset the language links and add new language links
         *
-        * @param array $newLinkArray Associative array mapping language code to the page
-        *                      name
+        * @param string[] $newLinkArray Array of interwiki-prefixed (non DB key) titles
+        *                               (e.g. 'fr:Test page')
         */
        public function setLanguageLinks( array $newLinkArray ) {
                $this->mLanguageLinks = $newLinkArray;
@@ -1234,7 +1231,7 @@ class OutputPage extends ContextSource {
        /**
         * Get the list of language links
         *
-        * @return array Array of Interwiki Prefixed (non DB key) Titles (e.g. 'fr:Test page')
+        * @return string[] Array of interwiki-prefixed (non DB key) titles (e.g. 'fr:Test page')
         */
        public function getLanguageLinks() {
                return $this->mLanguageLinks;
@@ -1713,7 +1710,6 @@ class OutputPage extends ContextSource {
                $popts->setTidy( $oldTidy );
 
                $this->addParserOutput( $parserOutput );
-
        }
 
        /**
@@ -1776,14 +1772,11 @@ class OutputPage extends ContextSource {
                        }
                }
 
-               // Enable OOUI if requested via ParserOutput
+               // enable OOUI if requested via ParserOutput
                if ( $parserOutput->getEnableOOUI() ) {
                        $this->enableOOUI();
                }
 
-               // Include profiling data
-               $this->setLimitReportData( $parserOutput->getLimitReportData() );
-
                // Link flags are ignored for now, but may in the future be
                // used to mark individual language links.
                $linkFlags = [];
@@ -1931,6 +1924,36 @@ class OutputPage extends ContextSource {
                $this->setCdnMaxage( $this->mCdnMaxage );
        }
 
+       /**
+        * Get TTL in [$minTTL,$maxTTL] in pass it to lowerCdnMaxage()
+        *
+        * This sets and returns $minTTL if $mtime is false or null. Otherwise,
+        * the TTL is higher the older the $mtime timestamp is. Essentially, the
+        * TTL is 90% of the age of the object, subject to the min and max.
+        *
+        * @param string|integer|float|bool|null $mtime Last-Modified timestamp
+        * @param integer $minTTL Mimimum TTL in seconds [default: 1 minute]
+        * @param integer $maxTTL Maximum TTL in seconds [default: $wgSquidMaxage]
+        * @return integer TTL in seconds
+        * @since 1.28
+        */
+       public function adaptCdnTTL( $mtime, $minTTL = 0, $maxTTL = 0 ) {
+               $minTTL = $minTTL ?: IExpiringStore::TTL_MINUTE;
+               $maxTTL = $maxTTL ?: $this->getConfig()->get( 'SquidMaxage' );
+
+               if ( $mtime === null || $mtime === false ) {
+                       return $minTTL; // entity does not exist
+               }
+
+               $age = time() - wfTimestamp( TS_UNIX, $mtime );
+               $adaptiveTTL = max( .9 * $age, $minTTL );
+               $adaptiveTTL = min( $adaptiveTTL, $maxTTL );
+
+               $this->lowerCdnMaxage( (int)$adaptiveTTL );
+
+               return $adaptiveTTL;
+       }
+
        /**
         * Use enableClientCache(false) to force it to send nocache headers
         *
@@ -2166,22 +2189,26 @@ class OutputPage extends ContextSource {
                                        # We'll purge the proxy cache explicitly, but require end user agents
                                        # to revalidate against the proxy on each visit.
                                        # Surrogate-Control controls our CDN, Cache-Control downstream caches
-                                       wfDebug( __METHOD__ . ": proxy caching with ESI; {$this->mLastModified} **", 'private' );
+                                       wfDebug( __METHOD__ .
+                                               ": proxy caching with ESI; {$this->mLastModified} **", 'private' );
                                        # start with a shorter timeout for initial testing
                                        # header( 'Surrogate-Control: max-age=2678400+2678400, content="ESI/1.0"');
-                                       $response->header( 'Surrogate-Control: max-age=' . $config->get( 'SquidMaxage' )
-                                               . '+' . $this->mCdnMaxage . ', content="ESI/1.0"' );
+                                       $response->header(
+                                               "Surrogate-Control: max-age={$config->get( 'SquidMaxage' )}" .
+                                               "+{$this->mCdnMaxage}, content=\"ESI/1.0\""
+                                       );
                                        $response->header( 'Cache-Control: s-maxage=0, must-revalidate, max-age=0' );
                                } else {
                                        # We'll purge the proxy cache for anons explicitly, but require end user agents
                                        # to revalidate against the proxy on each visit.
                                        # IMPORTANT! The CDN needs to replace the Cache-Control header with
                                        # Cache-Control: s-maxage=0, must-revalidate, max-age=0
-                                       wfDebug( __METHOD__ . ": local proxy caching; {$this->mLastModified} **", 'private' );
+                                       wfDebug( __METHOD__ .
+                                               ": local proxy caching; {$this->mLastModified} **", 'private' );
                                        # start with a shorter timeout for initial testing
                                        # header( "Cache-Control: s-maxage=2678400, must-revalidate, max-age=0" );
-                                       $response->header( 'Cache-Control: s-maxage=' . $this->mCdnMaxage
-                                               . ', must-revalidate, max-age=0' );
+                                       $response->header( "Cache-Control: " .
+                                               "s-maxage={$this->mCdnMaxage}, must-revalidate, max-age=0" );
                                }
                        } else {
                                # We do want clients to cache if they can, but they *must* check for updates
@@ -2215,6 +2242,8 @@ class OutputPage extends ContextSource {
         * @throws MWException
         */
        public function output( $return = false ) {
+               global $wgContLang;
+
                if ( $this->mDoNothing ) {
                        return $return ? '' : null;
                }
@@ -2261,7 +2290,7 @@ class OutputPage extends ContextSource {
                ob_start();
 
                $response->header( 'Content-type: ' . $config->get( 'MimeType' ) . '; charset=UTF-8' );
-               $response->header( 'Content-language: ' . $config->get( 'ContLang' )->getHtmlCode() );
+               $response->header( 'Content-language: ' . $wgContLang->getHtmlCode() );
 
                // Avoid Internet Explorer "compatibility view" in IE 8-10, so that
                // jQuery etc. can work correctly.
@@ -2388,10 +2417,14 @@ class OutputPage extends ContextSource {
        /**
         * Output a standard permission error page
         *
-        * @param array $errors Error message keys
+        * @param array $errors Error message keys or [key, param...] arrays
         * @param string $action Action that was denied or null if unknown
         */
        public function showPermissionsErrorPage( array $errors, $action = null ) {
+               foreach ( $errors as $key => $error ) {
+                       $errors[$key] = (array)$error;
+               }
+
                // For some action (read, edit, create and upload), display a "login to do this action"
                // error if all of the following conditions are met:
                // 1. the user is not logged in
@@ -2684,15 +2717,13 @@ class OutputPage extends ContextSource {
                        $exemptStates = [];
                        $moduleStyles = $this->getModuleStyles( /*filter*/ true );
 
-                       // Batch preload getTitleInfo for isKnownEmpty() calls below
-                       $exemptModules = array_filter( $moduleStyles,
-                               function ( $name ) use ( $rl, &$exemptGroups ) {
-                                       $module = $rl->getModule( $name );
-                                       return $module && isset( $exemptGroups[ $module->getGroup() ] );
-                               }
-                       );
-                       ResourceLoaderWikiModule::preloadTitleInfo(
-                               $context, wfGetDB( DB_REPLICA ), $exemptModules );
+                       // Preload getTitleInfo for isKnownEmpty calls below and in ResourceLoaderClientHtml
+                       // Separate user-specific batch for improved cache-hit ratio.
+                       $userBatch = [ 'user.styles', 'user' ];
+                       $siteBatch = array_diff( $moduleStyles, $userBatch );
+                       $dbr = wfGetDB( DB_REPLICA );
+                       ResourceLoaderWikiModule::preloadTitleInfo( $context, $dbr, $siteBatch );
+                       ResourceLoaderWikiModule::preloadTitleInfo( $context, $dbr, $userBatch );
 
                        // Filter out modules handled by buildExemptModules()
                        $moduleStyles = array_filter( $moduleStyles,
@@ -2771,8 +2802,8 @@ class OutputPage extends ContextSource {
                        // The spec recommends defining XHTML5's charset using the XML declaration
                        // instead of meta.
                        // Our XML declaration is output by Html::htmlHeader.
-                       // http://www.whatwg.org/html/semantics.html#attr-meta-http-equiv-content-type
-                       // http://www.whatwg.org/html/semantics.html#charset
+                       // https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-content-type
+                       // https://html.spec.whatwg.org/multipage/semantics.html#charset
                        $pieces[] = Html::element( 'meta', [ 'charset' => 'UTF-8' ] );
                }
 
@@ -2927,13 +2958,6 @@ class OutputPage extends ContextSource {
                        }
                }
 
-               $chunks[] = ResourceLoader::makeInlineScript(
-                       ResourceLoader::makeConfigSetScript(
-                               [ 'wgPageParseReport' => $this->limitReportData ],
-                               true
-                       )
-               );
-
                return self::combineWrappedStrings( $chunks );
        }
 
@@ -3654,7 +3678,7 @@ class OutputPage extends ContextSource {
        public static function transformCssMedia( $media ) {
                global $wgRequest;
 
-               // http://www.w3.org/TR/css3-mediaqueries/#syntax
+               // https://www.w3.org/TR/css3-mediaqueries/#syntax
                $screenMediaQueryRegex = '/^(?:only\s+)?screen\b/i';
 
                // Switch in on-screen display for media testing
@@ -3835,12 +3859,4 @@ class OutputPage extends ContextSource {
                        'mediawiki.widgets.styles',
                ] );
        }
-
-       /**
-        * @param array $data Data from ParserOutput::getLimitReportData()
-        * @since 1.28
-        */
-       public function setLimitReportData( array $data ) {
-               $this->limitReportData = $data;
-       }
 }
index 018c6f8..e6e96c7 100644 (file)
@@ -1,4 +1,7 @@
 <?php
+// @codingStandardsIgnoreFile Generic.Arrays.DisallowLongArraySyntax
+// @codingStandardsIgnoreFile Generic.Files.LineLength
+// @codingStandardsIgnoreFile MediaWiki.Usage.DirUsage.FunctionFound
 /**
  * Check PHP Version, as well as for composer dependencies in entry points,
  * and display something vaguely comprehensible in the event of a totally
  *
  * @file
  */
-
-/**
- * Check php version and that external dependencies are installed, and
- * display an informative error if either condition is not satisfied.
- *
- * @note Since we can't rely on anything, the minimum PHP versions and MW current
- * version are hardcoded here
- */
-function wfEntryPointCheck( $entryPoint ) {
-       $mwVersion = '1.28';
-       $minimumVersionPHP = '5.5.9';
-       $phpVersion = PHP_VERSION;
-
-       if ( !function_exists( 'version_compare' )
-               || version_compare( $phpVersion, $minimumVersionPHP ) < 0
-       ) {
-               wfPHPVersionError( $entryPoint, $mwVersion, $minimumVersionPHP, $phpVersion );
-       }
-
-       // @codingStandardsIgnoreStart MediaWiki.Usage.DirUsage.FunctionFound
-       if ( !file_exists( dirname( __FILE__ ) . '/../vendor/autoload.php' ) ) {
-               // @codingStandardsIgnoreEnd
-               wfMissingVendorError( $entryPoint, $mwVersion );
-       }
-
-       // List of functions and their associated PHP extension to check for
-       // @codingStandardsIgnoreStart Generic.Arrays.DisallowLongArraySyntax
-       $extensions = array(
+class PHPVersionCheck {
+       /* @var string The number of the MediaWiki version used */
+       var $mwVersion = '1.29';
+       /* @var string The minimum php version for MediaWiki to run */
+       var $minimumVersionPHP = '5.5.9';
+       var $functionsExtensionsMapping = array(
                'mb_substr'   => 'mbstring',
                'utf8_encode' => 'xml',
                'ctype_digit' => 'ctype',
                'json_decode' => 'json',
                'iconv'       => 'iconv',
        );
-       // List of extensions we're missing
-       $missingExtensions = array();
-       // @codingStandardsIgnoreEnd
 
-       foreach ( $extensions as $function => $extension ) {
-               if ( !function_exists( $function ) ) {
-                       $missingExtensions[] = $extension;
+       /**
+        * @var string Which entry point we are protecting. One of:
+        *   - index.php
+        *   - load.php
+        *   - api.php
+        *   - mw-config/index.php
+        *   - cli
+        */
+       var $entryPoint = null;
+
+       /**
+        * @param string $entryPoint Which entry point we are protecting. One of:
+        *   - index.php
+        *   - load.php
+        *   - api.php
+        *   - mw-config/index.php
+        *   - cli
+        * @return $this
+        */
+       function setEntryPoint( $entryPoint ) {
+               $this->entryPoint = $entryPoint;
+       }
+
+       /**
+        * Returns the version of the installed php implementation.
+        *
+        * @return string
+        */
+       function getPHPImplVersion() {
+               return PHP_VERSION;
+       }
+
+       /**
+        * Displays an error, if the installed php version does not meet the minimum requirement.
+        *
+        * @return $this
+        */
+       function checkRequiredPHPVersion() {
+               if ( !function_exists( 'version_compare' )
+                    || version_compare( $this->getPHPImplVersion(), $this->minimumVersionPHP ) < 0
+               ) {
+                       $shortText = "MediaWiki $this->mwVersion requires at least PHP version"
+                                    . " $this->minimumVersionPHP, you are using PHP {$this->getPHPImplVersion()}.";
+
+                       $longText = "Error: You might be using on older PHP version. \n"
+                                   . "MediaWiki $this->mwVersion needs PHP $this->minimumVersionPHP or higher.\n\n"
+                                   . "Check if you have a newer php executable with a different name, "
+                                   . "such as php5.\n\n";
+
+                       $longHtml = <<<HTML
+                       Please consider <a href="http://www.php.net/downloads.php">upgrading your copy of PHP</a>.
+                       PHP versions less than 5.5.0 are no longer supported by the PHP Group and will not receive
+                       security or bugfix updates.
+               </p>
+               <p>
+                       If for some reason you are unable to upgrade your PHP version, you will need to
+                       <a href="https://www.mediawiki.org/wiki/Download">download</a> an older version
+                       of MediaWiki from our website.  See our
+                       <a href="https://www.mediawiki.org/wiki/Compatibility#PHP">compatibility page</a>
+                       for details of which versions are compatible with prior versions of PHP.
+HTML;
+                       $this->triggerError( 'Supported PHP versions', $shortText, $longText, $longHtml );
                }
        }
 
-       if ( $missingExtensions ) {
-               wfMissingExtensions( $entryPoint, $mwVersion, $missingExtensions );
+       /**
+        * Displays an error, if the vendor/autoload.php file could not be found.
+        *
+        * @return $this
+        */
+       function checkVendorExistence() {
+               if ( !file_exists( dirname( __FILE__ ) . '/../vendor/autoload.php' ) ) {
+                       $shortText = "Installing some external dependencies (e.g. via composer) is required.";
+
+                       $longText = "Error: You are missing some external dependencies. \n"
+                                   . "MediaWiki now also has some external dependencies that need to be installed\n"
+                                   . "via composer or from a separate git repo. Please see\n"
+                                   . "https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries\n"
+                                   . "for help on installing the required components.";
+
+                       $longHtml = <<<HTML
+               MediaWiki now also has some external dependencies that need to be installed via
+               composer or from a separate git repo. Please see
+               <a href="https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries">mediawiki.org</a>
+               for help on installing the required components.
+HTML;
+
+                       $this->triggerError( 'External dependencies', $shortText, $longText, $longHtml );
+               }
        }
-}
 
-/**
- * Display something vaguely comprehensible in the event of a totally unrecoverable error.
- * Does not assume access to *anything*; no globals, no autoloader, no database, no localisation.
- * Safe for PHP4 (and putting this here means that WebStart.php and GlobalSettings.php
- * no longer need to be).
- *
- * Calling this function kills execution immediately.
- *
- * @param string $type Which entry point we are protecting. One of:
- *   - index.php
- *   - load.php
- *   - api.php
- *   - mw-config/index.php
- *   - cli
- * @param string $mwVersion The number of the MediaWiki version used
- * @param string $title HTML code to be put within an <h2> tag
- * @param string $shortText
- * @param string $longText
- * @param string $longHtml
- */
-function wfGenericError( $type, $mwVersion, $title, $shortText, $longText, $longHtml ) {
-       $protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
+       /**
+        * Displays an error, if a PHP extension does not exist.
+        *
+        * @return $this
+        */
+       function checkExtensionExistence() {
+               $missingExtensions = array();
+               foreach ( $this->functionsExtensionsMapping as $function => $extension ) {
+                       if ( !function_exists( $function ) ) {
+                               $missingExtensions[] = $extension;
+                       }
+               }
+
+               if ( $missingExtensions ) {
+                       $shortText = "Installing some PHP extensions is required.";
+
+                       $missingExtText = '';
+                       $missingExtHtml = '';
+                       $baseUrl = 'https://secure.php.net';
+                       foreach ( $missingExtensions as $ext ) {
+                               $missingExtText .= " * $ext <$baseUrl/$ext>\n";
+                               $missingExtHtml .= "<li><b>$ext</b> "
+                                                  . "(<a href=\"$baseUrl/$ext\">more information</a>)</li>";
+                       }
+
+                       $cliText = "Error: Missing one or more required components of PHP.\n"
+                                  . "You are missing a required extension to PHP that MediaWiki needs.\n"
+                                  . "Please install:\n" . $missingExtText;
+
+                       $longHtml = <<<HTML
+               You are missing a required extension to PHP that MediaWiki
+               requires to run. Please install:
+               <ul>
+               $missingExtHtml
+               </ul>
+HTML;
+
+                       $this->triggerError( 'Required components', $shortText, $cliText, $longHtml );
+               }
+       }
+
+       /**
+        * Output headers that prevents error pages to be cached.
+        */
+       function outputHTMLHeader() {
+               $protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
 
-       if ( $type == 'cli' ) {
-               $finalOutput = $longText;
-       } else {
                header( "$protocol 500 MediaWiki configuration Error" );
                // Don't cache error pages!  They cause no end of trouble...
                header( 'Cache-control: none' );
                header( 'Pragma: no-cache' );
+       }
 
-               if ( $type == 'index.php' || $type == 'mw-config/index.php' ) {
-                       $pathinfo = pathinfo( $_SERVER['SCRIPT_NAME'] );
-                       if ( $type == 'mw-config/index.php' ) {
-                               $dirname = dirname( $pathinfo['dirname'] );
-                       } else {
-                               $dirname = $pathinfo['dirname'];
-                       }
-                       $encLogo = htmlspecialchars(
-                               str_replace( '//', '/', $dirname . '/' ) .
-                               'resources/assets/mediawiki.png'
-                       );
-                       $shortHtml = htmlspecialchars( $shortText );
+       /**
+        * Returns an error page, which is suitable for output to the end user via a web browser.
+        *
+        * @param $title
+        * @param $longHtml
+        * @param $shortText
+        * @return string
+        */
+       function getIndexErrorOutput( $title, $longHtml, $shortText ) {
+               $pathinfo = pathinfo( $_SERVER['SCRIPT_NAME'] );
+               if ( $this->entryPoint == 'mw-config/index.php' ) {
+                       $dirname = dirname( $pathinfo['dirname'] );
+               } else {
+                       $dirname = $pathinfo['dirname'];
+               }
+               $encLogo =
+                       htmlspecialchars( str_replace( '//', '/', $dirname . '/' ) .
+                                         'resources/assets/mediawiki.png' );
+               $shortHtml = htmlspecialchars( $shortText );
 
-                       header( 'Content-type: text/html; charset=UTF-8' );
+               header( 'Content-type: text/html; charset=UTF-8' );
 
-                       $finalOutput = <<<HTML
+               $finalOutput = <<<HTML
 <!DOCTYPE html>
 <html lang="en" dir="ltr">
        <head>
                <meta charset="UTF-8" />
-               <title>MediaWiki {$mwVersion}</title>
+               <title>MediaWiki {$this->mwVersion}</title>
                <style media='screen'>
                        body {
                                color: #000;
@@ -144,7 +231,7 @@ function wfGenericError( $type, $mwVersion, $title, $shortText, $longText, $long
        </head>
        <body>
                <img src="{$encLogo}" alt='The MediaWiki logo' />
-               <h1>MediaWiki {$mwVersion} internal error</h1>
+               <h1>MediaWiki {$this->mwVersion} internal error</h1>
                <div class='error'>
                <p>
                        {$shortHtml}
@@ -157,105 +244,59 @@ function wfGenericError( $type, $mwVersion, $title, $shortText, $longText, $long
        </body>
 </html>
 HTML;
-               // Handle everything that's not index.php
-               } else {
-                       // So nothing thinks this is JS or CSS
-                       $finalOutput = ( $type == 'load.php' ) ? "/* $shortText */" : $shortText;
-               }
-       }
-       echo "$finalOutput\n";
-       die( 1 );
-}
-
-/**
- * Display an error for the minimum PHP version requirement not being satisfied.
- *
- * @param string $type See wfGenericError
- * @param string $mwVersion See wfGenericError
- * @param string $minimumVersionPHP The minimum PHP version supported by MediaWiki
- * @param string $phpVersion The current PHP version
- */
-function wfPHPVersionError( $type, $mwVersion, $minimumVersionPHP, $phpVersion ) {
-       $shortText = "MediaWiki $mwVersion requires at least "
-               . "PHP version $minimumVersionPHP, you are using PHP $phpVersion.";
-
-       $longText = "Error: You might be using on older PHP version. \n"
-               . "MediaWiki $mwVersion needs PHP $minimumVersionPHP or higher.\n\n"
-               . "Check if you have a newer php executable with a different name, such as php5.\n\n";
-
-       $longHtml = <<<HTML
-                       Please consider <a href="http://www.php.net/downloads.php">upgrading your copy of PHP</a>.
-                       PHP versions less than 5.5.0 are no longer supported by the PHP Group and will not receive
-                       security or bugfix updates.
-               </p>
-               <p>
-                       If for some reason you are unable to upgrade your PHP version, you will need to
-                       <a href="https://www.mediawiki.org/wiki/Download">download</a> an older version
-                       of MediaWiki from our website.  See our
-                       <a href="https://www.mediawiki.org/wiki/Compatibility#PHP">compatibility page</a>
-                       for details of which versions are compatible with prior versions of PHP.
-HTML;
-       wfGenericError( $type, $mwVersion, 'Supported PHP versions', $shortText, $longText, $longHtml );
-}
-
-/**
- * Display an error for the vendor/autoload.php file not being found.
- *
- * @param string $type See wfGenericError
- * @param string $mwVersion See wfGenericError
- */
-function wfMissingVendorError( $type, $mwVersion ) {
-       $shortText = "Installing some external dependencies (e.g. via composer) is required.";
 
-       $longText = "Error: You are missing some external dependencies. \n"
-               . "MediaWiki now also has some external dependencies that need to be installed\n"
-               . "via composer or from a separate git repo. Please see\n"
-               . "https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries\n"
-               . "for help on installing the required components.";
+               return $finalOutput;
+       }
 
-       // @codingStandardsIgnoreStart Generic.Files.LineLength
-       $longHtml = <<<HTML
-               MediaWiki now also has some external dependencies that need to be installed via
-               composer or from a separate git repo. Please see
-               <a href="https://www.mediawiki.org/wiki/Download_from_Git#Fetch_external_libraries">mediawiki.org</a>
-               for help on installing the required components.
-HTML;
-       // @codingStandardsIgnoreEnd
+       /**
+        * Display something vaguely comprehensible in the event of a totally unrecoverable error.
+        * Does not assume access to *anything*; no globals, no autoloader, no database, no localisation.
+        * Safe for PHP4 (and putting this here means that WebStart.php and GlobalSettings.php
+        * no longer need to be).
+        *
+        * Calling this function kills execution immediately.
+        *
+        * @param string $title HTML code to be put within an <h2> tag
+        * @param string $shortText
+        * @param string $longText
+        * @param string $longHtml
+        */
+       function triggerError( $title, $shortText, $longText, $longHtml ) {
+               switch ( $this->entryPoint ) {
+                       case 'cli':
+                               $finalOutput = $longText;
+                               break;
+                       case 'index.php':
+                       case 'mw-config/index.php':
+                               $this->outputHTMLHeader();
+                               $finalOutput = $this->getIndexErrorOutput( $title, $longHtml, $shortText );
+                               break;
+                       case 'load.php':
+                               $this->outputHTMLHeader();
+                               $finalOutput = "/* $shortText */";
+                               break;
+                       default:
+                               $this->outputHTMLHeader();
+                               // Handle everything that's not index.php
+                               $finalOutput = $shortText;
+               }
 
-       wfGenericError( $type, $mwVersion, 'External dependencies', $shortText, $longText, $longHtml );
+               echo "$finalOutput\n";
+               die( 1 );
+       }
 }
 
 /**
- * Display an error for a PHP extension not existing.
+ * Check php version and that external dependencies are installed, and
+ * display an informative error if either condition is not satisfied.
  *
- * @param string $type See wfGenericError
- * @param string $mwVersion See wfGenericError
- * @param array $missingExts The extensions we're missing
+ * @note Since we can't rely on anything, the minimum PHP versions and MW current
+ * version are hardcoded here
  */
-function wfMissingExtensions( $type, $mwVersion, $missingExts ) {
-       $shortText = "Installing some PHP extensions is required.";
-
-       $missingExtText = '';
-       $missingExtHtml = '';
-       $baseUrl = 'https://secure.php.net';
-       foreach ( $missingExts as $ext ) {
-               $missingExtText .= " * $ext <$baseUrl/$ext>\n";
-               $missingExtHtml .= "<li><b>$ext</b> "
-                       . "(<a href=\"$baseUrl/$ext\">more information</a>)</li>";
-       }
-
-       $cliText = "Error: Missing one or more required components of PHP.\n"
-               . "You are missing a required extension to PHP that MediaWiki needs.\n"
-               . "Please install:\n" . $missingExtText;
-
-       $longHtml = <<<HTML
-               You are missing a required extension to PHP that MediaWiki
-               requires to run. Please install:
-               <ul>
-               $missingExtHtml
-               </ul>
-HTML;
-
-       wfGenericError( $type, $mwVersion, 'Required components', $shortText,
-               $cliText, $longHtml );
+function wfEntryPointCheck( $entryPoint ) {
+       $phpVersionCheck = new PHPVersionCheck();
+       $phpVersionCheck->setEntryPoint( $entryPoint );
+       $phpVersionCheck->checkRequiredPHPVersion();
+       $phpVersionCheck->checkVendorExistence();
+       $phpVersionCheck->checkExtensionExistence();
 }
index ed06935..d09e1fb 100644 (file)
@@ -19,6 +19,7 @@
  *
  * @file
  */
+use Wikimedia\ScopedCallback;
 
 /**
  * Gives access to properties of a page.
index 9f8c06b..d86b19a 100644 (file)
@@ -861,7 +861,6 @@ class Preferences {
                        'section' => 'editing/preview',
                        'label-message' => 'tog-uselivepreview',
                ];
-
        }
 
        /**
@@ -1614,7 +1613,6 @@ class PreferencesForm extends HTMLForm {
         * @return string
         */
        function getButtons() {
-
                $attrs = [ 'id' => 'mw-prefs-restoreprefs' ];
 
                if ( !$this->getModifiedUser()->isAllowedAny( 'editmyprivateinfo', 'editmyoptions' ) ) {
index 98bc885..f6c4147 100644 (file)
@@ -182,12 +182,20 @@ abstract class PrefixSearch {
                ) ) {
                        return $this->titles( $this->defaultSearchBackend( $namespaces, $search, $limit, $offset ) );
                }
-               return $this->strings( $this->handleResultFromHook( $srchres, $namespaces, $search, $limit ) );
+               return $this->strings(
+                       $this->handleResultFromHook( $srchres, $namespaces, $search, $limit, $offset ) );
        }
 
-       private function handleResultFromHook( $srchres, $namespaces, $search, $limit ) {
-               $rescorer = new SearchExactMatchRescorer();
-               return $rescorer->rescore( $search, $namespaces, $srchres, $limit );
+       private function handleResultFromHook( $srchres, $namespaces, $search, $limit, $offset ) {
+               if ( $offset === 0 ) {
+                       // Only perform exact db match if offset === 0
+                       // This is still far from perfect but at least we avoid returning the
+                       // same title afain and again when the user is scrolling with a query
+                       // that matches a title in the db.
+                       $rescorer = new SearchExactMatchRescorer();
+                       $srchres = $rescorer->rescore( $search, $namespaces, $srchres, $limit );
+               }
+               return $srchres;
        }
 
        /**
index 6acc528..b812191 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  */
 use MediaWiki\Linker\LinkTarget;
+use MediaWiki\MediaWikiServices;
 
 /**
  * @todo document
@@ -86,6 +87,7 @@ class Revision implements IDBAccessObject {
        const DELETED_USER = 4;
        const DELETED_RESTRICTED = 8;
        const SUPPRESSED_USER = 12; // convenience
+       const SUPPRESSED_ALL = 15; // convenience
 
        // Audience options for accessors
        const FOR_PUBLIC = 1;
@@ -1046,11 +1048,10 @@ class Revision implements IDBAccessObject {
         *   to the $audience parameter
         *
         * @deprecated since 1.21, use getContent() instead
-        * @todo Replace usage in core
         * @return string
         */
        public function getText( $audience = self::FOR_PUBLIC, User $user = null ) {
-               ContentHandler::deprecated( __METHOD__, '1.21' );
+               wfDeprecated( __METHOD__, '1.21' );
 
                $content = $this->getContent( $audience, $user );
                return ContentHandler::getContentText( $content ); # returns the raw content text, if applicable
@@ -1396,6 +1397,11 @@ class Revision implements IDBAccessObject {
        public function insertOn( $dbw ) {
                global $wgDefaultExternalStore, $wgContentHandlerUseDB;
 
+               // We're inserting a new revision, so we have to use master anyway.
+               // If it's a null revision, it may have references to rows that
+               // are not in the replica yet (the text row).
+               $this->mQueryFlags |= self::READ_LATEST;
+
                // Not allowed to have rev_page equal to 0, false, etc.
                if ( !$this->mPage ) {
                        $title = $this->getTitle();
@@ -1898,7 +1904,7 @@ class Revision implements IDBAccessObject {
         * @since 1.28
         */
        public static function newKnownCurrent( IDatabase $db, $pageId, $revId ) {
-               $cache = ObjectCache::getMainWANInstance();
+               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
                return $cache->getWithSetCallback(
                        // Page/rev IDs passed in from DB to reflect history merges
                        $cache->makeGlobalKey( 'revision', $db->getWikiID(), $pageId, $revId ),
index 8f1fc99..44e4e3e 100644 (file)
@@ -41,7 +41,7 @@ class Sanitizer {
 
        /**
         * Acceptable tag name charset from HTML5 parsing spec
-        * http://www.w3.org/TR/html5/syntax.html#tag-open-state
+        * https://www.w3.org/TR/html5/syntax.html#tag-open-state
         */
        const ELEMENT_BITS_REGEX = '!^(/?)([A-Za-z][^\t\n\v />\0]*+)([^>]*?)(/?>)([^<]*)$!';
 
@@ -58,7 +58,7 @@ class Sanitizer {
 
        /**
         * List of all named character entities defined in HTML 4.01
-        * http://www.w3.org/TR/html4/sgml/entities.html
+        * https://www.w3.org/TR/html4/sgml/entities.html
         * As well as &apos; which is only defined starting in XHTML1.
         */
        private static $htmlEntities = [
@@ -333,7 +333,7 @@ class Sanitizer {
        /**
         * Regular expression to match HTML/XML attribute pairs within a tag.
         * Allows some... latitude. Based on,
-        * http://www.w3.org/TR/html5/syntax.html#before-attribute-value-state
+        * https://www.w3.org/TR/html5/syntax.html#before-attribute-value-state
         * Used in Sanitizer::fixTagAttributes and Sanitizer::decodeTagAttributes
         * @return string
         */
@@ -1015,6 +1015,7 @@ class Sanitizer {
                                | url\s*\(
                                | image\s*\(
                                | image-set\s*\(
+                               | attr\s*\([^)]+[\s,]+url
                        !ix', $value ) ) {
                        return '/* insecure input */';
                }
@@ -1148,11 +1149,11 @@ class Sanitizer {
         * ambiguous if it's part of something that looks like a percent escape
         * (which don't work reliably in fragments cross-browser).
         *
-        * @see http://www.w3.org/TR/html401/types.html#type-name Valid characters
+        * @see https://www.w3.org/TR/html401/types.html#type-name Valid characters
         *   in the id and name attributes
-        * @see http://www.w3.org/TR/html401/struct/links.html#h-12.2.3 Anchors with
+        * @see https://www.w3.org/TR/html401/struct/links.html#h-12.2.3 Anchors with
         *   the id attribute
-        * @see http://www.whatwg.org/html/elements.html#the-id-attribute
+        * @see https://www.w3.org/TR/html5/dom.html#the-id-attribute
         *   HTML5 definition of id attribute
         *
         * @param string $id Id to escape
@@ -1238,7 +1239,7 @@ class Sanitizer {
         *
         * @todo For extra validity, input should be validated UTF-8.
         *
-        * @see http://www.w3.org/TR/CSS21/syndata.html Valid characters/format
+        * @see https://www.w3.org/TR/CSS21/syndata.html Valid characters/format
         *
         * @param string $class
         * @return string
@@ -1351,7 +1352,7 @@ class Sanitizer {
                } elseif ( !isset( $set[2] ) ) {
                        # In XHTML, attributes must have a value so return an empty string.
                        # See "Empty attribute syntax",
-                       # http://www.w3.org/TR/html5/syntax.html#syntax-attribute-name
+                       # https://www.w3.org/TR/html5/syntax.html#syntax-attribute-name
                        return "";
                } else {
                        throw new MWException( "Tag conditions not met. This should never happen and is a bug." );
@@ -1621,7 +1622,7 @@ class Sanitizer {
 
                        # RDFa
                        # These attributes are specified in section 9 of
-                       # http://www.w3.org/TR/2008/REC-rdfa-syntax-20081014
+                       # https://www.w3.org/TR/2008/REC-rdfa-syntax-20081014
                        'about',
                        'property',
                        'resource',
@@ -1629,7 +1630,7 @@ class Sanitizer {
                        'typeof',
 
                        # Microdata. These are specified by
-                       # http://www.whatwg.org/html/microdata.html#the-microdata-model
+                       # https://html.spec.whatwg.org/multipage/microdata.html#the-microdata-model
                        'itemid',
                        'itemprop',
                        'itemref',
@@ -1653,7 +1654,7 @@ class Sanitizer {
                ];
 
                # Numbers refer to sections in HTML 4.01 standard describing the element.
-               # See: http://www.w3.org/TR/html4/
+               # See: https://www.w3.org/TR/html4/
                $whitelist = [
                        # 7.5.4
                        'div'        => $block,
@@ -1700,7 +1701,7 @@ class Sanitizer {
                        # 9.3.2
                        'br'         => array_merge( $common, [ 'clear' ] ),
 
-                       # http://www.whatwg.org/html/text-level-semantics.html#the-wbr-element
+                       # https://www.w3.org/TR/html5/text-level-semantics.html#the-wbr-element
                        'wbr'        => $common,
 
                        # 9.3.4
@@ -1775,7 +1776,7 @@ class Sanitizer {
                        'hr'         => array_merge( $common, [ 'width' ] ),
 
                        # HTML Ruby annotation text module, simple ruby only.
-                       # http://www.whatwg.org/html/text-level-semantics.html#the-ruby-element
+                       # https://www.w3.org/TR/html5/text-level-semantics.html#the-ruby-element
                        'ruby'       => $common,
                        # rbc
                        'rb'         => $common,
@@ -1785,14 +1786,14 @@ class Sanitizer {
 
                        # MathML root element, where used for extensions
                        # 'title' may not be 100% valid here; it's XHTML
-                       # http://www.w3.org/TR/REC-MathML/
+                       # https://www.w3.org/TR/REC-MathML/
                        'math'       => [ 'class', 'style', 'id', 'title' ],
 
                        # HTML 5 section 4.6
                        'bdi' => $common,
 
                        # HTML5 elements, defined by:
-                       # http://www.whatwg.org/html/
+                       # https://html.spec.whatwg.org/multipage/semantics.html#the-data-element
                        'data' => array_merge( $common, [ 'value' ] ),
                        'time' => array_merge( $common, [ 'datetime' ] ),
                        'mark' => $common,
@@ -1867,7 +1868,7 @@ class Sanitizer {
                        list( /* $whole */, $protocol, $host, $rest ) = $matches;
 
                        // Characters that will be ignored in IDNs.
-                       // http://tools.ietf.org/html/3454#section-3.1
+                       // https://tools.ietf.org/html/rfc3454#section-3.1
                        // Strip them before further processing so blacklists and such work.
                        $strip = "/
                                \\s|          # general whitespace
index 6044911..c2197a6 100644 (file)
 
 use MediaWiki\Interwiki\ClassicInterwikiLookup;
 use MediaWiki\Linker\LinkRendererFactory;
+use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
 
 return [
        'DBLoadBalancerFactory' => function( MediaWikiServices $services ) {
                $mainConfig = $services->getMainConfig();
 
-               $lbConf = LBFactoryMW::applyDefaultConfig(
+               $lbConf = MWLBFactory::applyDefaultConfig(
                        $mainConfig->get( 'LBFactoryConf' ),
                        $mainConfig
                );
-               $class = LBFactoryMW::getLBFactoryClass( $lbConf );
+               $class = MWLBFactory::getLBFactoryClass( $lbConf );
 
                return new $class( $lbConf );
        },
@@ -158,12 +159,69 @@ return [
                return new WatchedItemQueryService( $services->getDBLoadBalancer() );
        },
 
+       'CryptRand' => function( MediaWikiServices $services ) {
+               $secretKey = $services->getMainConfig()->get( 'SecretKey' );
+               return new CryptRand(
+                       [
+                               // To try vary the system information of the state a bit more
+                               // by including the system's hostname into the state
+                               'wfHostname',
+                               // It's mostly worthless but throw the wiki's id into the data
+                               // for a little more variance
+                               'wfWikiID',
+                               // If we have a secret key set then throw it into the state as well
+                               function() use ( $secretKey ) {
+                                       return $secretKey ?: '';
+                               }
+                       ],
+                       // The config file is likely the most often edited file we know should
+                       // be around so include its stat info into the state.
+                       // The constant with its location will almost always be defined, as
+                       // WebStart.php defines MW_CONFIG_FILE to $IP/LocalSettings.php unless
+                       // being configured with MW_CONFIG_CALLBACK (e.g. the installer).
+                       defined( 'MW_CONFIG_FILE' ) ? [ MW_CONFIG_FILE ] : [],
+                       LoggerFactory::getInstance( 'CryptRand' )
+               );
+       },
+
+       'CryptHKDF' => function( MediaWikiServices $services ) {
+               $config = $services->getMainConfig();
+
+               $secret = $config->get( 'HKDFSecret' ) ?: $config->get( 'SecretKey' );
+               if ( !$secret ) {
+                       throw new RuntimeException( "Cannot use MWCryptHKDF without a secret." );
+               }
+
+               // In HKDF, the context can be known to the attacker, but this will
+               // keep simultaneous runs from producing the same output.
+               $context = [ microtime(), getmypid(), gethostname() ];
+
+               // Setup salt cache. Use APC, or fallback to the main cache if it isn't setup
+               $cache = $services->getLocalServerObjectCache();
+               if ( $cache instanceof EmptyBagOStuff ) {
+                       $cache = ObjectCache::getLocalClusterInstance();
+               }
+
+               return new CryptHKDF( $secret, $config->get( 'HKDFAlgorithm' ),
+                       $cache, $context, $services->getCryptRand()
+               );
+       },
+
        'MediaHandlerFactory' => function( MediaWikiServices $services ) {
                return new MediaHandlerFactory(
                        $services->getMainConfig()->get( 'MediaHandlers' )
                );
        },
 
+       'MimeAnalyzer' => function( MediaWikiServices $services ) {
+               return new MimeMagic(
+                       MimeMagic::applyDefaultParameters(
+                               [],
+                               $services->getMainConfig()
+                       )
+               );
+       },
+
        'ProxyLookup' => function( MediaWikiServices $services ) {
                $mainConfig = $services->getMainConfig();
                return new ProxyLookup(
@@ -172,6 +230,11 @@ return [
                );
        },
 
+       'Parser' => function( MediaWikiServices $services ) {
+               $conf = $services->getMainConfig()->get( 'ParserConf' );
+               return ObjectFactory::constructClassInstance( $conf['class'], [ $conf ] );
+       },
+
        'LinkCache' => function( MediaWikiServices $services ) {
                return new LinkCache(
                        $services->getTitleFormatter(),
@@ -218,6 +281,61 @@ return [
                return $services->getService( '_MediaWikiTitleCodec' );
        },
 
+       'MainObjectStash' => function( MediaWikiServices $services ) {
+               $mainConfig = $services->getMainConfig();
+
+               $id = $mainConfig->get( 'MainStash' );
+               if ( !isset( $mainConfig->get( 'ObjectCaches' )[$id] ) ) {
+                       throw new UnexpectedValueException(
+                               "Cache type \"$id\" is not present in \$wgObjectCaches." );
+               }
+
+               return \ObjectCache::newFromParams( $mainConfig->get( 'ObjectCaches' )[$id] );
+       },
+
+       'MainWANObjectCache' => function( MediaWikiServices $services ) {
+               $mainConfig = $services->getMainConfig();
+
+               $id = $mainConfig->get( 'MainWANCache' );
+               if ( !isset( $mainConfig->get( 'WANObjectCaches' )[$id] ) ) {
+                       throw new UnexpectedValueException(
+                               "WAN cache type \"$id\" is not present in \$wgWANObjectCaches." );
+               }
+
+               $params = $mainConfig->get( 'WANObjectCaches' )[$id];
+               $objectCacheId = $params['cacheId'];
+               if ( !isset( $mainConfig->get( 'ObjectCaches' )[$objectCacheId] ) ) {
+                       throw new UnexpectedValueException(
+                               "Cache type \"$objectCacheId\" is not present in \$wgObjectCaches." );
+               }
+               $params['store'] = $mainConfig->get( 'ObjectCaches' )[$objectCacheId];
+
+               return \ObjectCache::newWANCacheFromParams( $params );
+       },
+
+       'LocalServerObjectCache' => function( MediaWikiServices $services ) {
+               $mainConfig = $services->getMainConfig();
+
+               if ( function_exists( 'apc_fetch' ) ) {
+                       $id = 'apc';
+               } elseif ( function_exists( 'apcu_fetch' ) ) {
+                       $id = 'apcu';
+               } elseif ( function_exists( 'xcache_get' ) && wfIniGetBool( 'xcache.var_size' ) ) {
+                       $id = 'xcache';
+               } elseif ( function_exists( 'wincache_ucache_get' ) ) {
+                       $id = 'wincache';
+               } else {
+                       $id = CACHE_NONE;
+               }
+
+               if ( !isset( $mainConfig->get( 'ObjectCaches' )[$id] ) ) {
+                       throw new UnexpectedValueException(
+                               "Cache type \"$id\" is not present in \$wgObjectCaches." );
+               }
+
+               return \ObjectCache::newFromParams( $mainConfig->get( 'ObjectCaches' )[$id] );
+       },
+
        'VirtualRESTServiceClient' => function( MediaWikiServices $services ) {
                $config = $services->getMainConfig()->get( 'VirtualRestConfig' );
 
index 7cda14c..357c76d 100644 (file)
@@ -818,7 +818,9 @@ $wgOut = RequestContext::getMain()->getOutput(); // BackCompat
 /**
  * @var Parser $wgParser
  */
-$wgParser = new StubObject( 'wgParser', $wgParserConf['class'], [ $wgParserConf ] );
+$wgParser = new StubObject( 'wgParser', function () {
+       return MediaWikiServices::getInstance()->getParser();
+} );
 
 /**
  * @var Title $wgTitle
index 07828fe..a35af6e 100644 (file)
@@ -113,7 +113,7 @@ class Status extends StatusValue {
         *     1 => object(Status) # The Status with warning messages, only
         * ]
         *
-        * @return array
+        * @return Status[]
         */
        public function splitByErrorType() {
                list( $errorsOnlyStatus, $warningsOnlyStatus ) = parent::splitByErrorType();
index c0ae374..494c7bf 100644 (file)
@@ -93,11 +93,11 @@ class TemplatesOnThisPageFormatter {
                }
 
                if ( $more instanceof LinkTarget ) {
-                       $outText .= Html::rawElement( 'li', $this->linkRenderer->makeLink(
+                       $outText .= Html::rawElement( 'li', [], $this->linkRenderer->makeLink(
                                $more, $this->context->msg( 'moredotdotdot' )->text() ) );
                } elseif ( $more ) {
                        // Documented as should already be escaped
-                       $outText .= Html::rawElement( 'li', $more );
+                       $outText .= Html::rawElement( 'li', [], $more );
                }
 
                $outText .= '</ul>';
index 5e1e8c6..3c51bae 100644 (file)
@@ -1412,7 +1412,6 @@ class Title implements LinkTarget {
                        $fragment,
                        $this->getInterwiki()
                );
-
        }
 
        /**
@@ -2926,7 +2925,6 @@ class Title implements LinkTarget {
 
                        # Cycle through all the restrictions.
                        foreach ( $rows as $row ) {
-
                                // Don't take care of restrictions types that aren't allowed
                                if ( !in_array( $row->pr_type, $restrictionTypes ) ) {
                                        continue;
@@ -4391,16 +4389,19 @@ class Title implements LinkTarget {
        public function invalidateCache( $purgeTime = null ) {
                if ( wfReadOnly() ) {
                        return false;
-               }
-
-               if ( $this->mArticleID === 0 ) {
+               } elseif ( $this->mArticleID === 0 ) {
                        return true; // avoid gap locking if we know it's not there
                }
 
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->onTransactionPreCommitOrIdle( function () {
+                       ResourceLoaderWikiModule::invalidateModuleCache( $this, null, null, wfWikiID() );
+               } );
+
                $conds = $this->pageCond();
                DeferredUpdates::addUpdate(
                        new AutoCommitUpdate(
-                               wfGetDB( DB_MASTER ),
+                               $dbw,
                                __METHOD__,
                                function ( IDatabase $dbw, $fname ) use ( $conds, $purgeTime ) {
                                        $dbTimestamp = $dbw->timestamp( $purgeTime ?: time() );
@@ -4597,7 +4598,6 @@ class Title implements LinkTarget {
                        : $wgExemptFromUserRobotsControl;
 
                return !in_array( $this->mNamespace, $bannedNamespaces );
-
        }
 
        /**
index c040fb1..0c3d52a 100644 (file)
@@ -50,24 +50,30 @@ class WatchedItemQueryService {
         */
        private $loadBalancer;
 
+       /** @var WatchedItemQueryServiceExtension[]|null */
+       private $extensions = null;
+
        public function __construct( LoadBalancer $loadBalancer ) {
                $this->loadBalancer = $loadBalancer;
        }
 
        /**
-        * @return DatabaseBase
-        * @throws MWException
+        * @return WatchedItemQueryServiceExtension[]
         */
-       private function getConnection() {
-               return $this->loadBalancer->getConnection( DB_REPLICA, [ 'watchlist' ] );
+       private function getExtensions() {
+               if ( $this->extensions === null ) {
+                       $this->extensions = [];
+                       Hooks::run( 'WatchedItemQueryServiceExtensions', [ &$this->extensions, $this ] );
+               }
+               return $this->extensions;
        }
 
        /**
-        * @param Database $connection
+        * @return IDatabase
         * @throws MWException
         */
-       private function reuseConnection( Database $connection ) {
-               $this->loadBalancer->reuseConnection( $connection );
+       private function getConnection() {
+               return $this->loadBalancer->getConnectionRef( DB_REPLICA, [ 'watchlist' ] );
        }
 
        /**
@@ -92,9 +98,6 @@ class WatchedItemQueryService {
         *                                 timestamp to start enumerating from
         *        'end'                 => string (format accepted by wfTimestamp) requires 'dir' option,
         *                                 timestamp to end enumerating
-        *        'startFrom'           => [ string $rcTimestamp, int $rcId ] requires 'dir' option,
-        *                                 return items starting from the RecentChange specified by this,
-        *                                 $rcTimestamp should be in the format accepted by wfTimestamp
         *        'watchlistOwner'      => User user whose watchlist items should be listed if different
         *                                 than the one specified with $user param,
         *                                 requires 'watchlistOwnerToken' option
@@ -105,6 +108,7 @@ class WatchedItemQueryService {
         *                                 generator ('rc_cur_id' or 'rc_this_oldid') if true, or all
         *                                 id fields ('rc_cur_id', 'rc_this_oldid', 'rc_last_oldid')
         *                                 if false (default)
+        * @param array|null &$startFrom Continuation value: [ string $rcTimestamp, int $rcId ]
         * @return array of pairs ( WatchedItem $watchedItem, string[] $recentChangeInfo ),
         *         where $recentChangeInfo contains the following keys:
         *         - 'rc_id',
@@ -115,7 +119,9 @@ class WatchedItemQueryService {
         *         - 'rc_deleted',
         *         Additional keys could be added by specifying the 'includeFields' option
         */
-       public function getWatchedItemsWithRecentChangeInfo( User $user, array $options = [] ) {
+       public function getWatchedItemsWithRecentChangeInfo(
+               User $user, array $options = [], &$startFrom = null
+       ) {
                $options += [
                        'includeFields' => [],
                        'namespaceIds' => [],
@@ -136,15 +142,19 @@ class WatchedItemQueryService {
                        'must be DIR_OLDER or DIR_NEWER'
                );
                Assert::parameter(
-                       !isset( $options['start'] ) && !isset( $options['end'] ) && !isset( $options['startFrom'] )
+                       !isset( $options['start'] ) && !isset( $options['end'] ) && $startFrom === null
                                || isset( $options['dir'] ),
                        '$options[\'dir\']',
-                       'must be provided when providing any of options: start, end, startFrom'
+                       'must be provided when providing the "start" or "end" options or the $startFrom parameter'
                );
                Assert::parameter(
-                       !isset( $options['startFrom'] )
-                               || ( is_array( $options['startFrom'] ) && count( $options['startFrom'] ) === 2 ),
+                       !isset( $options['startFrom'] ),
                        '$options[\'startFrom\']',
+                       'must not be provided, use $startFrom instead'
+               );
+               Assert::parameter(
+                       !isset( $startFrom ) || ( is_array( $startFrom ) && count( $startFrom ) === 2 ),
+                       '$startFrom',
                        'must be a two-element array'
                );
                if ( array_key_exists( 'watchlistOwner', $options ) ) {
@@ -172,6 +182,21 @@ class WatchedItemQueryService {
                $dbOptions = $this->getWatchedItemsWithRCInfoQueryDbOptions( $options );
                $joinConds = $this->getWatchedItemsWithRCInfoQueryJoinConds( $options );
 
+               if ( $startFrom !== null ) {
+                       $conds[] = $this->getStartFromConds( $db, $options, $startFrom );
+               }
+
+               foreach ( $this->getExtensions() as $extension ) {
+                       $extension->modifyWatchedItemsWithRCInfoQuery(
+                               $user, $options, $db,
+                               $tables,
+                               $fields,
+                               $conds,
+                               $dbOptions,
+                               $joinConds
+                       );
+               }
+
                $res = $db->select(
                        $tables,
                        $fields,
@@ -181,10 +206,15 @@ class WatchedItemQueryService {
                        $joinConds
                );
 
-               $this->reuseConnection( $db );
-
+               $limit = isset( $dbOptions['LIMIT'] ) ? $dbOptions['LIMIT'] : INF;
                $items = [];
+               $startFrom = null;
                foreach ( $res as $row ) {
+                       if ( --$limit <= 0 ) {
+                               $startFrom = [ $row->rc_timestamp, $row->rc_id ];
+                               break;
+                       }
+
                        $items[] = [
                                new WatchedItem(
                                        $user,
@@ -195,6 +225,10 @@ class WatchedItemQueryService {
                        ];
                }
 
+               foreach ( $this->getExtensions() as $extension ) {
+                       $extension->modifyWatchedItemsWithRCInfo( $user, $options, $db, $items, $res, $startFrom );
+               }
+
                return $items;
        }
 
@@ -258,8 +292,6 @@ class WatchedItemQueryService {
                        $dbOptions
                );
 
-               $this->reuseConnection( $db );
-
                $watchedItems = [];
                foreach ( $res as $row ) {
                        // todo these could all be cached at some point?
@@ -337,7 +369,7 @@ class WatchedItemQueryService {
        }
 
        private function getWatchedItemsWithRCInfoQueryConds(
-               Database $db,
+               IDatabase $db,
                User $user,
                array $options
        ) {
@@ -380,10 +412,6 @@ class WatchedItemQueryService {
                        $conds[] = $deletedPageLogCond;
                }
 
-               if ( array_key_exists( 'startFrom', $options ) ) {
-                       $conds[] = $this->getStartFromConds( $db, $options );
-               }
-
                return $conds;
        }
 
@@ -445,7 +473,7 @@ class WatchedItemQueryService {
                return $conds;
        }
 
-       private function getStartEndConds( Database $db, array $options ) {
+       private function getStartEndConds( IDatabase $db, array $options ) {
                if ( !isset( $options['start'] ) && ! isset( $options['end'] ) ) {
                        return [];
                }
@@ -454,17 +482,19 @@ class WatchedItemQueryService {
 
                if ( isset( $options['start'] ) ) {
                        $after = $options['dir'] === self::DIR_OLDER ? '<=' : '>=';
-                       $conds[] = 'rc_timestamp ' . $after . ' ' . $db->addQuotes( $options['start'] );
+                       $conds[] = 'rc_timestamp ' . $after . ' ' .
+                               $db->addQuotes( $db->timestamp( $options['start'] ) );
                }
                if ( isset( $options['end'] ) ) {
                        $before = $options['dir'] === self::DIR_OLDER ? '>=' : '<=';
-                       $conds[] = 'rc_timestamp ' . $before . ' ' . $db->addQuotes( $options['end'] );
+                       $conds[] = 'rc_timestamp ' . $before . ' ' .
+                               $db->addQuotes( $db->timestamp( $options['end'] ) );
                }
 
                return $conds;
        }
 
-       private function getUserRelatedConds( Database $db, User $user, array $options ) {
+       private function getUserRelatedConds( IDatabase $db, User $user, array $options ) {
                if ( !array_key_exists( 'onlyByUser', $options ) && !array_key_exists( 'notByUser', $options ) ) {
                        return [];
                }
@@ -491,7 +521,7 @@ class WatchedItemQueryService {
                return $conds;
        }
 
-       private function getExtraDeletedPageLogEntryRelatedCond( Database $db, User $user ) {
+       private function getExtraDeletedPageLogEntryRelatedCond( IDatabase $db, User $user ) {
                // LogPage::DELETED_ACTION hides the affected page, too. So hide those
                // entirely from the watchlist, or someone could guess the title.
                $bitmask = 0;
@@ -509,9 +539,9 @@ class WatchedItemQueryService {
                return '';
        }
 
-       private function getStartFromConds( Database $db, array $options ) {
+       private function getStartFromConds( IDatabase $db, array $options, array $startFrom ) {
                $op = $options['dir'] === self::DIR_OLDER ? '<' : '>';
-               list( $rcTimestamp, $rcId ) = $options['startFrom'];
+               list( $rcTimestamp, $rcId ) = $startFrom;
                $rcTimestamp = $db->addQuotes( $db->timestamp( $rcTimestamp ) );
                $rcId = (int)$rcId;
                return $db->makeList(
@@ -529,7 +559,7 @@ class WatchedItemQueryService {
                );
        }
 
-       private function getWatchedItemsForUserQueryConds( Database $db, User $user, array $options ) {
+       private function getWatchedItemsForUserQueryConds( IDatabase $db, User $user, array $options ) {
                $conds = [ 'wl_user' => $user->getId() ];
                if ( $options['namespaceIds'] ) {
                        $conds['wl_namespace'] = array_map( 'intval', $options['namespaceIds'] );
@@ -563,12 +593,12 @@ class WatchedItemQueryService {
         * Creates a query condition part for getting only items before or after the given link target
         * (while ordering using $sort mode)
         *
-        * @param Database $db
+        * @param IDatabase $db
         * @param LinkTarget $target
         * @param string $op comparison operator to use in the conditions
         * @return string
         */
-       private function getFromUntilTargetConds( Database $db, LinkTarget $target, $op ) {
+       private function getFromUntilTargetConds( IDatabase $db, LinkTarget $target, $op ) {
                return $db->makeList(
                        [
                                "wl_namespace $op " . $target->getNamespace(),
@@ -593,7 +623,7 @@ class WatchedItemQueryService {
                }
 
                if ( array_key_exists( 'limit', $options ) ) {
-                       $dbOptions['LIMIT'] = (int)$options['limit'];
+                       $dbOptions['LIMIT'] = (int)$options['limit'] + 1;
                }
 
                return $dbOptions;
diff --git a/includes/WatchedItemQueryServiceExtension.php b/includes/WatchedItemQueryServiceExtension.php
new file mode 100644 (file)
index 0000000..8fcf131
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * Extension mechanism for WatchedItemQueryService
+ *
+ * @since 1.29
+ *
+ * @file
+ * @ingroup Watchlist
+ *
+ * @license GNU GPL v2+
+ */
+interface WatchedItemQueryServiceExtension {
+
+       /**
+        * Modify the WatchedItemQueryService::getWatchedItemsWithRecentChangeInfo()
+        * query before it's made.
+        *
+        * @warning Any joins added *must* join on a unique key of the target table
+        *  unless you really know what you're doing.
+        * @param User $user
+        * @param array $options Options from
+        *  WatchedItemQueryService::getWatchedItemsWithRecentChangeInfo()
+        * @param IDatabase $db Database connection being used for the query
+        * @param array &$tables Tables for Database::select()
+        * @param array &$fields Fields for Database::select()
+        * @param array &$conds Conditions for Database::select()
+        * @param array &$dbOptions Options for Database::select()
+        * @param array &$joinConds Join conditions for Database::select()
+        */
+       public function modifyWatchedItemsWithRCInfoQuery( User $user, array $options, IDatabase $db,
+               array &$tables, array &$fields, array &$conds, array &$dbOptions, array &$joinConds
+       );
+
+       /**
+        * Modify the results from WatchedItemQueryService::getWatchedItemsWithRecentChangeInfo()
+        * before they're returned.
+        *
+        * @param User $user
+        * @param array $options Options from
+        *  WatchedItemQueryService::getWatchedItemsWithRecentChangeInfo()
+        * @param IDatabase $db Database connection being used for the query
+        * @param array &$items array of pairs ( WatchedItem $watchedItem, string[] $recentChangeInfo ).
+        *  May be truncated if necessary, in which case $startFrom must be updated.
+        * @param ResultWrapper|bool $res Database query result
+        * @param array|null &$startFrom Continuation value. If you truncate $items, set this to
+        *  [ $recentChangeInfo['rc_timestamp'], $recentChangeInfo['rc_id'] ] from the first item
+        *  removed.
+        */
+       public function modifyWatchedItemsWithRCInfo( User $user, array $options, IDatabase $db,
+               array &$items, $res, &$startFrom
+       );
+
+}
index 478cc5f..cc4779e 100644 (file)
@@ -3,6 +3,7 @@
 use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
 use MediaWiki\Linker\LinkTarget;
 use Wikimedia\Assert\Assert;
+use Wikimedia\ScopedCallback;
 
 /**
  * Storage layer class for WatchedItems.
@@ -166,7 +167,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @param User $user
         * @param LinkTarget $target
         *
-        * @return WatchedItem|null
+        * @return WatchedItem|false
         */
        private function getCached( User $user, LinkTarget $target ) {
                return $this->cache->get( $this->getCacheKey( $user, $target ) );
@@ -192,20 +193,11 @@ class WatchedItemStore implements StatsdAwareInterface {
        /**
         * @param int $dbIndex DB_MASTER or DB_REPLICA
         *
-        * @return DatabaseBase
-        * @throws MWException
-        */
-       private function getConnection( $dbIndex ) {
-               return $this->loadBalancer->getConnection( $dbIndex, [ 'watchlist' ] );
-       }
-
-       /**
-        * @param Database $connection
-        *
+        * @return IDatabase
         * @throws MWException
         */
-       private function reuseConnection( $connection ) {
-               $this->loadBalancer->reuseConnection( $connection );
+       private function getConnectionRef( $dbIndex ) {
+               return $this->loadBalancer->getConnectionRef( $dbIndex, [ 'watchlist' ] );
        }
 
        /**
@@ -217,7 +209,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @return int
         */
        public function countWatchedItems( User $user ) {
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
                $return = (int)$dbr->selectField(
                        'watchlist',
                        'COUNT(*)',
@@ -226,7 +218,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        ],
                        __METHOD__
                );
-               $this->reuseConnection( $dbr );
 
                return $return;
        }
@@ -237,7 +228,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @return int
         */
        public function countWatchers( LinkTarget $target ) {
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
                $return = (int)$dbr->selectField(
                        'watchlist',
                        'COUNT(*)',
@@ -247,7 +238,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        ],
                        __METHOD__
                );
-               $this->reuseConnection( $dbr );
 
                return $return;
        }
@@ -263,7 +253,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @throws MWException
         */
        public function countVisitingWatchers( LinkTarget $target, $threshold ) {
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
                $visitingWatchers = (int)$dbr->selectField(
                        'watchlist',
                        'COUNT(*)',
@@ -276,7 +266,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        ],
                        __METHOD__
                );
-               $this->reuseConnection( $dbr );
 
                return $visitingWatchers;
        }
@@ -293,7 +282,7 @@ class WatchedItemStore implements StatsdAwareInterface {
        public function countWatchersMultiple( array $targets, array $options = [] ) {
                $dbOptions = [ 'GROUP BY' => [ 'wl_namespace', 'wl_title' ] ];
 
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
 
                if ( array_key_exists( 'minimumWatchers', $options ) ) {
                        $dbOptions['HAVING'] = 'COUNT(*) >= ' . (int)$options['minimumWatchers'];
@@ -308,8 +297,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        $dbOptions
                );
 
-               $this->reuseConnection( $dbr );
-
                $watchCounts = [];
                foreach ( $targets as $linkTarget ) {
                        $watchCounts[$linkTarget->getNamespace()][$linkTarget->getDBkey()] = 0;
@@ -341,7 +328,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                array $targetsWithVisitThresholds,
                $minimumWatchers = null
        ) {
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
 
                $conds = $this->getVisitingWatchersCondition( $dbr, $targetsWithVisitThresholds );
 
@@ -357,8 +344,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        $dbOptions
                );
 
-               $this->reuseConnection( $dbr );
-
                $watcherCounts = [];
                foreach ( $targetsWithVisitThresholds as list( $target ) ) {
                        /* @var LinkTarget $target */
@@ -452,14 +437,13 @@ class WatchedItemStore implements StatsdAwareInterface {
                        return false;
                }
 
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
                $row = $dbr->selectRow(
                        'watchlist',
                        'wl_notificationtimestamp',
                        $this->dbCond( $user, $target ),
                        __METHOD__
                );
-               $this->reuseConnection( $dbr );
 
                if ( !$row ) {
                        return false;
@@ -499,7 +483,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                                "wl_title {$options['sort']}"
                        ];
                }
-               $db = $this->getConnection( $options['forWrite'] ? DB_MASTER : DB_REPLICA );
+               $db = $this->getConnectionRef( $options['forWrite'] ? DB_MASTER : DB_REPLICA );
 
                $res = $db->select(
                        'watchlist',
@@ -508,11 +492,10 @@ class WatchedItemStore implements StatsdAwareInterface {
                        __METHOD__,
                        $dbOptions
                );
-               $this->reuseConnection( $db );
 
                $watchedItems = [];
                foreach ( $res as $row ) {
-                       // todo these could all be cached at some point?
+                       // @todo: Should we add these to the process cache?
                        $watchedItems[] = new WatchedItem(
                                $user,
                                new TitleValue( (int)$row->wl_namespace, $row->wl_title ),
@@ -569,7 +552,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                        return $timestamps;
                }
 
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
 
                $lb = new LinkBatch( $targetsToLoad );
                $res = $dbr->select(
@@ -581,7 +564,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        ],
                        __METHOD__
                );
-               $this->reuseConnection( $dbr );
 
                foreach ( $res as $row ) {
                        $timestamps[$row->wl_namespace][$row->wl_title] = $row->wl_notificationtimestamp;
@@ -620,6 +602,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                }
 
                $rows = [];
+               $items = [];
                foreach ( $targets as $target ) {
                        $rows[] = [
                                'wl_user' => $user->getId(),
@@ -627,16 +610,26 @@ class WatchedItemStore implements StatsdAwareInterface {
                                'wl_title' => $target->getDBkey(),
                                'wl_notificationtimestamp' => null,
                        ];
+                       $items[] = new WatchedItem(
+                               $user,
+                               $target,
+                               null
+                       );
                        $this->uncache( $user, $target );
                }
 
-               $dbw = $this->getConnection( DB_MASTER );
+               $dbw = $this->getConnectionRef( DB_MASTER );
                foreach ( array_chunk( $rows, 100 ) as $toInsert ) {
                        // Use INSERT IGNORE to avoid overwriting the notification timestamp
                        // if there's already an entry for this page
                        $dbw->insert( 'watchlist', $toInsert, __METHOD__, 'IGNORE' );
                }
-               $this->reuseConnection( $dbw );
+               // Update process cache to ensure skin doesn't claim that the current
+               // page is unwatched in the response of action=watch itself (T28292).
+               // This would otherwise be re-queried from a slave by isWatched().
+               foreach ( $items as $item ) {
+                       $this->cache( $item );
+               }
 
                return true;
        }
@@ -660,7 +653,7 @@ class WatchedItemStore implements StatsdAwareInterface {
 
                $this->uncache( $user, $target );
 
-               $dbw = $this->getConnection( DB_MASTER );
+               $dbw = $this->getConnectionRef( DB_MASTER );
                $dbw->delete( 'watchlist',
                        [
                                'wl_user' => $user->getId(),
@@ -669,7 +662,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        ], __METHOD__
                );
                $success = (bool)$dbw->affectedRows();
-               $this->reuseConnection( $dbw );
 
                return $success;
        }
@@ -687,7 +679,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                        return false;
                }
 
-               $dbw = $this->getConnection( DB_MASTER );
+               $dbw = $this->getConnectionRef( DB_MASTER );
 
                $conds = [ 'wl_user' => $user->getId() ];
                if ( $targets ) {
@@ -702,8 +694,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        __METHOD__
                );
 
-               $this->reuseConnection( $dbw );
-
                $this->uncacheUser( $user );
 
                return $success;
@@ -718,7 +708,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @return int[] Array of user IDs the timestamp has been updated for
         */
        public function updateNotificationTimestamp( User $editor, LinkTarget $target, $timestamp ) {
-               $dbw = $this->getConnection( DB_MASTER );
+               $dbw = $this->getConnectionRef( DB_MASTER );
                $uids = $dbw->selectFieldValues(
                        'watchlist',
                        'wl_user',
@@ -730,7 +720,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        ],
                        __METHOD__
                );
-               $this->reuseConnection( $dbw );
 
                $watchers = array_map( 'intval', $uids );
                if ( $watchers ) {
@@ -740,7 +729,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                                function () use ( $timestamp, $watchers, $target, $fname ) {
                                        global $wgUpdateRowsPerQuery;
 
-                                       $dbw = $this->getConnection( DB_MASTER );
+                                       $dbw = $this->getConnectionRef( DB_MASTER );
                                        $factory = wfGetLBFactory();
                                        $ticket = $factory->getEmptyTransactionTicket( __METHOD__ );
 
@@ -762,8 +751,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                                                }
                                        }
                                        $this->uncacheLinkTarget( $target );
-
-                                       $this->reuseConnection( $dbw );
                                },
                                DeferredUpdates::POSTSEND,
                                $dbw
@@ -885,7 +872,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                        $queryOptions['LIMIT'] = $unreadLimit;
                }
 
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
                $rowCount = $dbr->selectRowCount(
                        'watchlist',
                        '1',
@@ -896,7 +883,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        __METHOD__,
                        $queryOptions
                );
-               $this->reuseConnection( $dbr );
 
                if ( !isset( $unreadLimit ) ) {
                        return $rowCount;
@@ -937,7 +923,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @param LinkTarget $newTarget
         */
        public function duplicateEntry( LinkTarget $oldTarget, LinkTarget $newTarget ) {
-               $dbw = $this->getConnection( DB_MASTER );
+               $dbw = $this->getConnectionRef( DB_MASTER );
 
                $result = $dbw->select(
                        'watchlist',
@@ -975,8 +961,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                                __METHOD__
                        );
                }
-
-               $this->reuseConnection( $dbw );
        }
 
 }
index 0065135..3ef3bc1 100644 (file)
@@ -113,7 +113,7 @@ class WebRequest {
         */
        public static function getPathInfo( $want = 'all' ) {
                global $wgUsePathInfo;
-               // PATH_INFO is mangled due to http://bugs.php.net/bug.php?id=31892
+               // PATH_INFO is mangled due to https://bugs.php.net/bug.php?id=31892
                // And also by Apache 2.x, double slashes are converted to single slashes.
                // So we will use REQUEST_URI if possible.
                $matches = [];
@@ -175,7 +175,7 @@ class WebRequest {
                } elseif ( $wgUsePathInfo ) {
                        if ( isset( $_SERVER['ORIG_PATH_INFO'] ) && $_SERVER['ORIG_PATH_INFO'] != '' ) {
                                // Mangled PATH_INFO
-                               // http://bugs.php.net/bug.php?id=31892
+                               // https://bugs.php.net/bug.php?id=31892
                                // Also reported when ini_get('cgi.fix_pathinfo')==false
                                $matches['title'] = substr( $_SERVER['ORIG_PATH_INFO'], 1 );
 
@@ -379,7 +379,7 @@ class WebRequest {
         */
        private function getGPCVal( $arr, $name, $default ) {
                # PHP is so nice to not touch input data, except sometimes:
-               # http://us2.php.net/variables.external#language.variables.external.dot-in-names
+               # https://secure.php.net/variables.external#language.variables.external.dot-in-names
                # Work around PHP *feature* to avoid *bugs* elsewhere.
                $name = strtr( $name, '.', '_' );
                if ( isset( $arr[$name] ) ) {
index c741907..916a10c 100644 (file)
@@ -102,7 +102,7 @@ class WebRequestUpload {
 
        /**
         * Return the upload error. See link for explanation
-        * http://www.php.net/manual/en/features.file-upload.errors.php
+        * https://secure.php.net/manual/en/features.file-upload.errors.php
         *
         * @return int One of the UPLOAD_ constants, 0 if non-existent
         */
index 43f7217..4c6b071 100644 (file)
@@ -238,7 +238,6 @@ class Xml {
                        Xml::label( $msg->text(), $attrs['id'] ),
                        Xml::tags( 'select', $attrs, $options )
                ];
-
        }
 
        /**
@@ -452,7 +451,7 @@ class Xml {
 
        /**
         * Convenience function to build an HTML submit button
-        * When $wgUseMediaWikiUIEverywhere is true it will default to a constructive button
+        * When $wgUseMediaWikiUIEverywhere is true it will default to a progressive button
         * @param string $value Label text for the button
         * @param array $attribs Optional custom attributes
         * @return string HTML
@@ -467,7 +466,7 @@ class Xml {
                // some submit forms
                // might need to be mw-ui-destructive (e.g. delete a page)
                if ( $wgUseMediaWikiUIEverywhere ) {
-                       $baseAttrs['class'] = 'mw-ui-button mw-ui-constructive';
+                       $baseAttrs['class'] = 'mw-ui-button mw-ui-progressive';
                }
                // Any custom attributes will take precendence of anything in baseAttrs e.g. override the class
                $attribs = $attribs + $baseAttrs;
index f3ef3b3..c1763fa 100644 (file)
@@ -139,6 +139,10 @@ class HistoryAction extends FormlessAction {
 
                // Fail nicely if article doesn't exist.
                if ( !$this->page->exists() ) {
+                       global $wgSend404Code;
+                       if ( $wgSend404Code ) {
+                               $out->setStatusCode( 404 );
+                       }
                        $out->addWikiMsg( 'nohistory' );
                        # show deletion/move log if there is an entry
                        LogEventsList::showLogExtract(
@@ -214,7 +218,6 @@ class HistoryAction extends FormlessAction {
                        $pager->getNavigationBar()
                );
                $out->preventClickjacking( $pager->getPreventClickjacking() );
-
        }
 
        /**
index 4d80a1c..be3be85 100644 (file)
@@ -294,6 +294,16 @@ class InfoAction extends FormlessAction {
                        $modelHtml
                ];
 
+               if ( $title->inNamespace( NS_USER ) ) {
+                       $pageUser = User::newFromName( $title->getRootText() );
+                       if ( $pageUser && $pageUser->getId() && !$pageUser->isHidden() ) {
+                               $pageInfo['header-basic'][] = [
+                                       $this->msg( 'pageinfo-user-id' ),
+                                       $pageUser->getId()
+                               ];
+                       }
+               }
+
                // Search engine status
                $pOutput = new ParserOutput();
                if ( isset( $pageProperties['noindex'] ) ) {
@@ -690,7 +700,6 @@ class InfoAction extends FormlessAction {
 
                                $dbr = wfGetDB( DB_REPLICA );
                                $dbrWatchlist = wfGetDB( DB_REPLICA, 'watchlist' );
-
                                $setOpts += Database::getCacheSetOptions( $dbr, $dbrWatchlist );
 
                                $watchedItemStore = MediaWikiServices::getInstance()->getWatchedItemStore();
index 85ea87c..8df6044 100644 (file)
@@ -1,7 +1,5 @@
 <?php
 /**
- * Mark a revision as patrolled on a page
- *
  * Copyright © 2011 Alexandre Emsenhuber
  *
  * This program is free software; you can redistribute it and/or modify
  *
  * @ingroup Actions
  */
-class MarkpatrolledAction extends FormlessAction {
+class MarkpatrolledAction extends FormAction {
 
        public function getName() {
                return 'markpatrolled';
        }
 
        protected function getDescription() {
+               // Disable default header "subtitle"
                return '';
        }
 
-       public function onView() {
-               $request = $this->getRequest();
+       public function getRestriction() {
+               return 'patrol';
+       }
 
-               $rcId = $request->getInt( 'rcid' );
-               $rc = RecentChange::newFromId( $rcId );
-               if ( is_null( $rc ) ) {
+       protected function getRecentChange( $data = null ) {
+               $rc = null;
+               // Note: This works both on initial GET url and after submitting the form
+               $rcId = $data ? intval( $data['rcid'] ) : $this->getRequest()->getInt( 'rcid' );
+               if ( $rcId ) {
+                       $rc = RecentChange::newFromId( $rcId );
+               }
+               if ( !$rc ) {
                        throw new ErrorPageError( 'markedaspatrollederror', 'markedaspatrollederrortext' );
                }
+               return $rc;
+       }
 
-               $user = $this->getUser();
-               if ( !$user->matchEditToken( $request->getVal( 'token' ), $rcId ) ) {
-                       throw new ErrorPageError( 'sessionfailure-title', 'sessionfailure' );
-               }
+       protected function preText() {
+               $rc = $this->getRecentChange();
+               $title = $rc->getTitle();
+
+               // Based on logentry-patrol-patrol (see PatrolLogFormatter)
+               $revId = $rc->getAttribute( 'rc_this_oldid' );
+               $query = [
+                       'curid' => $rc->getAttribute( 'rc_cur_id' ),
+                       'diff' => $revId,
+                       'oldid' => $rc->getAttribute( 'rc_last_oldid' )
+               ];
+               $revlink = Linker::link( $title, htmlspecialchars( $revId ), [], $query );
+               $pagelink = Linker::link( $title, htmlspecialchars( $title->getPrefixedText() ) );
 
+               return $this->msg( 'confirm-markpatrolled-top' )->params(
+                       $title->getPrefixedText(),
+                       // Provide pre-rendered link as parser would render [[:$1]] as bold non-link
+                       Message::rawParam( $pagelink ),
+                       Message::rawParam( $revlink )
+               )->parse();
+       }
+
+       protected function alterForm( HTMLForm $form ) {
+               $form->addHiddenField( 'rcid', $this->getRequest()->getInt( 'rcid' ) );
+               $form->setTokenSalt( 'patrol' );
+               $form->setSubmitTextMsg( 'confirm-markpatrolled-button' );
+       }
+
+       /**
+        * @return bool|array True for success, false for didn't-try, array of errors on failure
+        */
+       public function onSubmit( $data ) {
+               $user = $this->getUser();
+               $rc = $this->getRecentChange( $data );
                $errors = $rc->doMarkPatrolled( $user );
 
                if ( in_array( [ 'rcpatroldisabled' ], $errors ) ) {
                        throw new ErrorPageError( 'rcpatroldisabled', 'rcpatroldisabledtext' );
                }
 
-               if ( in_array( [ 'hookaborted' ], $errors ) ) {
-                       // The hook itself has handled any output
-                       return;
-               }
-
-               # It would be nice to see where the user had actually come from, but for now just guess
+               // Guess where the user came from
+               // TODO: Would be nice to see where the user actually came from
                if ( $rc->getAttribute( 'rc_type' ) == RC_NEW ) {
                        $returnTo = 'Newpages';
                } elseif ( $rc->getAttribute( 'rc_log_type' ) == 'upload' ) {
@@ -76,18 +108,25 @@ class MarkpatrolledAction extends FormlessAction {
                        $this->getOutput()->setPageTitle( $this->msg( 'markedaspatrollederror' ) );
                        $this->getOutput()->addWikiMsg( 'markedaspatrollederror-noautopatrol' );
                        $this->getOutput()->returnToMain( null, $return );
-
-                       return;
+                       return true;
                }
 
-               if ( count( $errors ) ) {
-                       throw new PermissionsError( 'patrol', $errors );
+               if ( $errors ) {
+                       if ( !in_array( [ 'hookaborted' ], $errors ) ) {
+                               throw new PermissionsError( 'patrol', $errors );
+                       }
+                       // The hook itself has handled any output
+                       return $errors;
                }
 
-               # Inform the user
                $this->getOutput()->setPageTitle( $this->msg( 'markedaspatrolled' ) );
                $this->getOutput()->addWikiMsg( 'markedaspatrolledtext', $rc->getTitle()->getPrefixedText() );
                $this->getOutput()->returnToMain( null, $return );
+               return true;
+       }
+
+       public function onSuccess() {
+               // Required by parent class. Redundant as our onSubmit handles output already.
        }
 
        public function doesWrites() {
index 1a42ccc..6fafebf 100644 (file)
@@ -173,13 +173,7 @@ class ApiAuthManagerHelper {
                $this->module->getMain()->markParamsUsed( array_keys( $data ) );
 
                if ( $sensitive ) {
-                       try {
-                               $this->module->requirePostedParameters( array_keys( $sensitive ), 'noprefix' );
-                       } catch ( UsageException $ex ) {
-                               // Make this a warning for now, upgrade to an error in 1.29.
-                               $this->module->setWarning( $ex->getMessage() );
-                               $this->module->logFeatureUsage( $this->module->getModuleName() . '-params-in-query-string' );
-                       }
+                       $this->module->requirePostedParameters( array_keys( $sensitive ), 'noprefix' );
                }
 
                return AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data );
index 809d567..506ff73 100644 (file)
@@ -600,7 +600,7 @@ abstract class ApiBase extends ContextSource {
 
        /**
         * Gets a default replica DB connection object
-        * @return DatabaseBase
+        * @return Database
         */
        protected function getDB() {
                if ( !isset( $this->mSlaveDB ) ) {
@@ -2745,16 +2745,6 @@ abstract class ApiBase extends ContextSource {
                return 0;
        }
 
-       /**
-        * Get the result data array (read-only)
-        * @deprecated since 1.25, use $this->getResult() methods instead
-        * @return array
-        */
-       public function getResultData() {
-               wfDeprecated( __METHOD__, '1.25' );
-               return $this->getResult()->getData();
-       }
-
        /**
         * Call wfTransactionalTimeLimit() if this request was POSTed
         * @since 1.26
index 4ddbd04..13b3577 100644 (file)
 class ApiClearHasMsg extends ApiBase {
        public function execute() {
                $user = $this->getUser();
-               $user->setNewtalk( false );
+               if ( $this->getRequest()->wasPosted() ) {
+                       $user->setNewtalk( false );
+               } else {
+                       DeferredUpdates::addCallableUpdate( function () use ( $user ) {
+                               $user->setNewtalk( false );
+                       } );
+               }
                $this->getResult()->addValue( null, $this->getModuleName(), 'success' );
        }
 
index 6601fb7..19e2453 100644 (file)
@@ -31,6 +31,7 @@ class ApiContinuationManager {
 
        private $continuationData = [];
        private $generatorContinuationData = [];
+       private $generatorNonContinuationData = [];
 
        private $generatorParams = [];
        private $generatorDone = false;
@@ -142,6 +143,26 @@ class ApiContinuationManager {
                $this->continuationData[$name][$paramName] = $paramValue;
        }
 
+       /**
+        * Set the non-continuation parameter for the generator module
+        *
+        * In case the generator isn't going to be continued, this sets the fields
+        * to return.
+        *
+        * @since 1.28
+        * @param ApiBase $module
+        * @param string $paramName
+        * @param string|array $paramValue
+        */
+       public function addGeneratorNonContinueParam( ApiBase $module, $paramName, $paramValue ) {
+               $name = $module->getModuleName();
+               $paramName = $module->encodeParamName( $paramName );
+               if ( is_array( $paramValue ) ) {
+                       $paramValue = implode( '|', $paramValue );
+               }
+               $this->generatorNonContinuationData[$name][$paramName] = $paramValue;
+       }
+
        /**
         * Set the continuation parameter for the generator module
         * @param ApiBase $module
@@ -165,6 +186,15 @@ class ApiContinuationManager {
                return array_merge_recursive( $this->continuationData, $this->generatorContinuationData );
        }
 
+       /**
+        * Fetch raw non-continuation data
+        * @since 1.28
+        * @return array
+        */
+       public function getRawNonContinuation() {
+               return $this->generatorNonContinuationData;
+       }
+
        /**
         * Fetch continuation result data
         * @return array [ (array)$data, (bool)$batchcomplete ]
@@ -192,8 +222,13 @@ class ApiContinuationManager {
                        foreach ( $continuationData as $module => $kvp ) {
                                $data += $kvp;
                        }
-                       $data += $this->generatorParams;
-                       $generatorKeys = implode( '|', array_keys( $this->generatorParams ) );
+                       $generatorParams = [];
+                       foreach ( $this->generatorNonContinuationData as $kvp ) {
+                               $generatorParams += $kvp;
+                       }
+                       $generatorParams += $this->generatorParams;
+                       $data += $generatorParams;
+                       $generatorKeys = implode( '|', array_keys( $generatorParams ) );
                } elseif ( $this->generatorContinuationData ) {
                        // All the generator-using modules are complete, but the
                        // generator isn't. Continue the generator and restart the
index 5011f48..67f54a8 100644 (file)
@@ -33,6 +33,7 @@ abstract class ApiFormatBase extends ApiBase {
        private $mIsHtml, $mFormat, $mUnescapeAmps, $mHelp;
        private $mBuffer, $mDisabled = false;
        private $mIsWrappedHtml = false;
+       private $mHttpStatus = false;
        protected $mForceDefaultParams = false;
 
        /**
@@ -147,6 +148,23 @@ abstract class ApiFormatBase extends ApiBase {
                }
        }
 
+       /**
+        * Set the HTTP status code to be used for the response
+        * @since 1.29
+        * @param int $code
+        */
+       public function setHttpStatus( $code ) {
+               if ( $this->mDisabled ) {
+                       return;
+               }
+
+               if ( $this->getIsHtml() ) {
+                       $this->mHttpStatus = $code;
+               } else {
+                       $this->getMain()->getRequest()->response()->statusHeader( $code );
+               }
+       }
+
        /**
         * Initialize the printer function and prepare the output headers.
         * @param bool $unused Always false since 1.25
@@ -212,6 +230,18 @@ abstract class ApiFormatBase extends ApiBase {
                                                ApiHelp::fixHelpLinks( $header )
                                        )
                                );
+
+                               if ( $this->mHttpStatus && $this->mHttpStatus !== 200 ) {
+                                       $out->addHTML(
+                                               Html::rawElement( 'div', [ 'class' => 'api-pretty-header api-pretty-status' ],
+                                                       $this->msg(
+                                                               'api-format-prettyprint-status',
+                                                               $this->mHttpStatus,
+                                                               HttpStatus::getMessage( $this->mHttpStatus )
+                                                       )->parse()
+                                               )
+                                       );
+                               }
                        }
 
                        if ( Hooks::run( 'ApiFormatHighlight', [ $context, $result, $mime, $format ] ) ) {
@@ -225,12 +255,15 @@ abstract class ApiFormatBase extends ApiBase {
                                $time = microtime( true ) - $this->getConfig()->get( 'RequestTime' );
                                $json = FormatJson::encode(
                                        [
+                                               'status' => (int)( $this->mHttpStatus ?: 200 ),
+                                               'statustext' => HttpStatus::getMessage( $this->mHttpStatus ?: 200 ),
                                                'html' => $out->getHTML(),
                                                'modules' => array_values( array_unique( array_merge(
                                                        $out->getModules(),
                                                        $out->getModuleScripts(),
                                                        $out->getModuleStyles()
                                                ) ) ),
+                                               'continue' => $this->getResult()->getResultData( 'continue' ),
                                                'time' => round( $time * 1000 ),
                                        ],
                                        false, FormatJson::ALL_OK
index a3bb6a2..02efd7b 100644 (file)
@@ -311,11 +311,11 @@ class ApiHelp extends ApiBase {
                                if ( count( $modules ) === 1 && $m === $modules[0] &&
                                        !( !empty( $options['submodules'] ) && $m->getModuleManager() )
                                ) {
-                                       $link = Html::element( 'b', null, $name );
+                                       $link = Html::element( 'b', [ 'dir' => 'ltr', 'lang' => 'en' ], $name );
                                } else {
                                        $link = SpecialPage::getTitleFor( 'ApiHelp', $m->getModulePath() )->getLocalURL();
                                        $link = Html::element( 'a',
-                                               [ 'href' => $link, 'class' => 'apihelp-linktrail' ],
+                                               [ 'href' => $link, 'class' => 'apihelp-linktrail', 'dir' => 'ltr', 'lang' => 'en' ],
                                                $name
                                        );
                                        $any = true;
@@ -350,7 +350,8 @@ class ApiHelp extends ApiBase {
                                if ( isset( $sourceInfo['namemsg'] ) ) {
                                        $extname = $context->msg( $sourceInfo['namemsg'] )->text();
                                } else {
-                                       $extname = $sourceInfo['name'];
+                                       // Probably English, so wrap it.
+                                       $extname = Html::element( 'span', [ 'dir' => 'ltr', 'lang' => 'en' ], $sourceInfo['name'] );
                                }
                                $help['flags'] .= Html::rawElement( 'li', null,
                                        self::wrap(
@@ -361,7 +362,9 @@ class ApiHelp extends ApiBase {
 
                                $link = SpecialPage::getTitleFor( 'Version', 'License/' . $sourceInfo['name'] );
                                if ( isset( $sourceInfo['license-name'] ) ) {
-                                       $msg = $context->msg( 'api-help-license', $link, $sourceInfo['license-name'] );
+                                       $msg = $context->msg( 'api-help-license', $link,
+                                               Html::element( 'span', [ 'dir' => 'ltr', 'lang' => 'en' ], $sourceInfo['license-name'] )
+                                       );
                                } elseif ( SpecialVersion::getExtLicenseFileName( dirname( $sourceInfo['path'] ) ) ) {
                                        $msg = $context->msg( 'api-help-license-noname', $link );
                                } else {
@@ -403,7 +406,7 @@ class ApiHelp extends ApiBase {
                                $help['help-urls'] .= Html::openElement( 'ul' );
                                foreach ( $urls as $url ) {
                                        $help['help-urls'] .= Html::rawElement( 'li', null,
-                                               Html::element( 'a', [ 'href' => $url ], $url )
+                                               Html::element( 'a', [ 'href' => $url, 'dir' => 'ltr' ], $url )
                                        );
                                }
                                $help['help-urls'] .= Html::closeElement( 'ul' );
@@ -432,8 +435,9 @@ class ApiHelp extends ApiBase {
                                                $settings = [ ApiBase::PARAM_DFLT => $settings ];
                                        }
 
-                                       $help['parameters'] .= Html::element( 'dt', null,
-                                               $module->encodeParamName( $name ) );
+                                       $help['parameters'] .= Html::rawElement( 'dt', null,
+                                               Html::element( 'span', [ 'dir' => 'ltr', 'lang' => 'en' ], $module->encodeParamName( $name ) )
+                                       );
 
                                        // Add description
                                        $description = [];
@@ -488,8 +492,9 @@ class ApiHelp extends ApiBase {
                                                        $links = isset( $settings[ApiBase::PARAM_VALUE_LINKS] )
                                                                ? $settings[ApiBase::PARAM_VALUE_LINKS]
                                                                : [];
-                                                       $type = array_map( function ( $v ) use ( $links ) {
-                                                               $ret = wfEscapeWikiText( $v );
+                                                       $values = array_map( function ( $v ) use ( $links ) {
+                                                               // We can't know whether this contains LTR or RTL text.
+                                                               $ret = $v === '' ? $v : Html::element( 'span', [ 'dir' => 'auto' ], $v );
                                                                if ( isset( $links[$v] ) ) {
                                                                        $ret = "[[{$links[$v]}|$ret]]";
                                                                }
@@ -497,17 +502,17 @@ class ApiHelp extends ApiBase {
                                                        }, $type );
                                                        $i = array_search( '', $type, true );
                                                        if ( $i === false ) {
-                                                               $type = $context->getLanguage()->commaList( $type );
+                                                               $values = $context->getLanguage()->commaList( $values );
                                                        } else {
-                                                               unset( $type[$i] );
-                                                               $type = $context->msg( 'api-help-param-list-can-be-empty' )
-                                                                       ->numParams( count( $type ) )
-                                                                       ->params( $context->getLanguage()->commaList( $type ) )
+                                                               unset( $values[$i] );
+                                                               $values = $context->msg( 'api-help-param-list-can-be-empty' )
+                                                                       ->numParams( count( $values ) )
+                                                                       ->params( $context->getLanguage()->commaList( $values ) )
                                                                        ->parse();
                                                        }
                                                        $info[] = $context->msg( 'api-help-param-list' )
                                                                ->params( $multi ? 2 : 1 )
-                                                               ->params( $type )
+                                                               ->params( $values )
                                                                ->parse();
                                                        $hintPipeSeparated = false;
                                                } else {
@@ -527,7 +532,8 @@ class ApiHelp extends ApiBase {
                                                                                $prefix = $module->isMain()
                                                                                        ? '' : ( $module->getModulePath() . '+' );
                                                                                $submodules = array_map( function ( $name ) use ( $prefix ) {
-                                                                                       return "[[Special:ApiHelp/{$prefix}{$name}|{$name}]]";
+                                                                                       $text = Html::element( 'span', [ 'dir' => 'ltr', 'lang' => 'en' ], $name );
+                                                                                       return "[[Special:ApiHelp/{$prefix}{$name}|{$text}]]";
                                                                                }, $submodules );
                                                                        }
                                                                        $count = count( $submodules );
@@ -650,8 +656,9 @@ class ApiHelp extends ApiBase {
                                                $info[] = $context->msg( 'api-help-param-default-empty' )
                                                        ->parse();
                                        } elseif ( $default !== null && $default !== false ) {
+                                               // We can't know whether this contains LTR or RTL text.
                                                $info[] = $context->msg( 'api-help-param-default' )
-                                                       ->params( wfEscapeWikiText( $default ) )
+                                                       ->params( Html::element( 'span', [ 'dir' => 'auto' ], $default ) )
                                                        ->parse();
                                        }
 
@@ -723,7 +730,7 @@ class ApiHelp extends ApiBase {
                                        $sandbox = SpecialPage::getTitleFor( 'ApiSandbox' )->getLocalURL() . '#' . $qs;
                                        $help['examples'] .= Html::rawElement( 'dt', null, $msg->parse() );
                                        $help['examples'] .= Html::rawElement( 'dd', null,
-                                               Html::element( 'a', [ 'href' => $link ], "api.php?$qs" ) . ' ' .
+                                               Html::element( 'a', [ 'href' => $link, 'dir' => 'ltr' ], "api.php?$qs" ) . ' ' .
                                                Html::rawElement( 'a', [ 'href' => $sandbox ],
                                                        $context->msg( 'api-help-open-in-apisandbox' )->parse() )
                                        );
index 573524a..45378ee 100644 (file)
@@ -64,7 +64,8 @@ class ApiHelpParamValueMessage extends Message {
         */
        public function fetchMessage() {
                if ( $this->message === null ) {
-                       $this->message = ";{$this->paramValue}:" . parent::fetchMessage();
+                       $this->message = ";<span dir=\"ltr\" lang=\"en\">{$this->paramValue}</span>:"
+                               . parent::fetchMessage();
                }
                return $this->message;
        }
index 966bcbf..37cb80a 100644 (file)
 class ApiImageRotate extends ApiBase {
        private $mPageSet = null;
 
-       /**
-        * Add all items from $values into the result
-        * @param array $result Output
-        * @param array $values Values to add
-        * @param string $flag The name of the boolean flag to mark this element
-        * @param string $name If given, name of the value
-        */
-       private static function addValues( array &$result, $values, $flag = null, $name = null ) {
-               foreach ( $values as $val ) {
-                       if ( $val instanceof Title ) {
-                               $v = [];
-                               ApiQueryBase::addTitleInfo( $v, $val );
-                       } elseif ( $name !== null ) {
-                               $v = [ $name => $val ];
-                       } else {
-                               $v = $val;
-                       }
-                       if ( $flag !== null ) {
-                               $v[$flag] = true;
-                       }
-                       $result[] = $v;
-               }
-       }
-
        public function execute() {
                $this->useTransactionalTimeLimit();
 
@@ -62,11 +38,9 @@ class ApiImageRotate extends ApiBase {
 
                $result = [];
 
-               self::addValues( $result, $pageSet->getInvalidTitlesAndReasons(), 'invalid' );
-               self::addValues( $result, $pageSet->getSpecialTitles(), 'special', 'title' );
-               self::addValues( $result, $pageSet->getMissingPageIDs(), 'missing', 'pageid' );
-               self::addValues( $result, $pageSet->getMissingRevisionIDs(), 'missing', 'revid' );
-               self::addValues( $result, $pageSet->getInterwikiTitlesAsResult() );
+               $result = $pageSet->getInvalidTitlesAndRevisions( [
+                       'invalidTitles', 'special', 'missingIds', 'missingRevIds', 'interwikiTitles',
+               ] );
 
                foreach ( $pageSet->getTitles() as $title ) {
                        $r = [];
@@ -74,6 +48,9 @@ class ApiImageRotate extends ApiBase {
                        ApiQueryBase::addTitleInfo( $r, $title );
                        if ( !$title->exists() ) {
                                $r['missing'] = true;
+                               if ( $title->isKnown() ) {
+                                       $r['known'] = true;
+                               }
                        }
 
                        $file = wfFindFile( $title, [ 'latest' => true ] );
index 55edd99..6ac261d 100644 (file)
@@ -190,15 +190,6 @@ class ApiLogin extends ApiBase {
 
                                $result['lguserid'] = intval( $user->getId() );
                                $result['lgusername'] = $user->getName();
-
-                               // @todo: These are deprecated, and should be removed at some
-                               // point (1.28 at the earliest, and see T121527). They were ok
-                               // when the core cookie-based login was the only thing, but
-                               // CentralAuth broke that a while back and
-                               // SessionManager/AuthManager *really* break it.
-                               $result['lgtoken'] = $user->getToken();
-                               $result['cookieprefix'] = $this->getConfig()->get( 'CookiePrefix' );
-                               $result['sessionid'] = $session->getId();
                                break;
 
                        case 'NeedToken':
@@ -206,10 +197,6 @@ class ApiLogin extends ApiBase {
                                $this->setWarning( 'Fetching a token via action=login is deprecated. ' .
                                   'Use action=query&meta=tokens&type=login instead.' );
                                $this->logFeatureUsage( 'action=login&!lgtoken' );
-
-                               // @todo: See above about deprecation
-                               $result['cookieprefix'] = $this->getConfig()->get( 'CookiePrefix' );
-                               $result['sessionid'] = $session->getId();
                                break;
 
                        case 'WrongToken':
index 8d5af59..38299b4 100644 (file)
@@ -572,11 +572,7 @@ class ApiMain extends ApiBase {
 
                $response = $this->getRequest()->response();
                $headerStr = 'MediaWiki-API-Error: ' . $errCode;
-               if ( $e->getCode() === 0 ) {
-                       $response->header( $headerStr );
-               } else {
-                       $response->header( $headerStr, true, $e->getCode() );
-               }
+               $response->header( $headerStr );
 
                // Reset and print just the error message
                ob_clean();
@@ -585,7 +581,7 @@ class ApiMain extends ApiBase {
                $this->createErrorPrinter();
 
                try {
-                       $this->printResult( true );
+                       $this->printResult( $e->getCode() );
                } catch ( UsageException $ex ) {
                        // The error printer itself is failing. Try suppressing its request
                        // parameters and redo.
@@ -595,7 +591,10 @@ class ApiMain extends ApiBase {
                        $this->mPrinter = null;
                        $this->createErrorPrinter();
                        $this->mPrinter->forceDefaultParams();
-                       $this->printResult( true );
+                       if ( $e->getCode() ) {
+                               $response->statusHeader( 200 ); // Reset in case the fallback doesn't want a non-200
+                       }
+                       $this->printResult( $e->getCode() );
                }
        }
 
@@ -636,8 +635,8 @@ class ApiMain extends ApiBase {
         * If the parameter and the header do match, the header is checked against $wgCrossSiteAJAXdomains
         * and $wgCrossSiteAJAXdomainExceptions, and if the origin qualifies, the appropriate CORS
         * headers are set.
-        * http://www.w3.org/TR/cors/#resource-requests
-        * http://www.w3.org/TR/cors/#resource-preflight-requests
+        * https://www.w3.org/TR/cors/#resource-requests
+        * https://www.w3.org/TR/cors/#resource-preflight-requests
         *
         * @return bool False if the caller should abort (403 case), true otherwise (all other cases)
         */
@@ -719,7 +718,7 @@ class ApiMain extends ApiBase {
 
                        $response->header( "Access-Control-Allow-Origin: $allowOrigin" );
                        $response->header( "Access-Control-Allow-Credentials: $allowCredentials" );
-                       // http://www.w3.org/TR/resource-timing/#timing-allow-origin
+                       // https://www.w3.org/TR/resource-timing/#timing-allow-origin
                        if ( $allowTiming !== false ) {
                                $response->header( "Timing-Allow-Origin: $allowTiming" );
                        }
@@ -1361,6 +1360,15 @@ class ApiMain extends ApiBase {
                                        break;
                        }
                }
+               if ( isset( $params['assertuser'] ) ) {
+                       $assertUser = User::newFromName( $params['assertuser'], false );
+                       if ( !$assertUser || !$this->getUser()->equals( $assertUser ) ) {
+                               $this->dieUsage(
+                                       'Assertion that the user is "' . $params['assertuser'] . '" failed',
+                                       'assertnameduserfailed'
+                               );
+                       }
+               }
        }
 
        /**
@@ -1432,7 +1440,7 @@ class ApiMain extends ApiBase {
                        MWDebug::appendDebugInfoToApiResult( $this->getContext(), $this->getResult() );
 
                        // Print result data
-                       $this->printResult( false );
+                       $this->printResult();
                }
        }
 
@@ -1466,7 +1474,7 @@ class ApiMain extends ApiBase {
                        'ip' => $request->getIP(),
                        'userAgent' => $this->getUserAgent(),
                        'wiki' => wfWikiID(),
-                       'timeSpentBackend' => (int) round( $time * 1000 ),
+                       'timeSpentBackend' => (int)round( $time * 1000 ),
                        'hadError' => $e !== null,
                        'errorCodes' => [],
                        'params' => [],
@@ -1612,15 +1620,18 @@ class ApiMain extends ApiBase {
        /**
         * Print results using the current printer
         *
-        * @param bool $isError
+        * @param int $httpCode HTTP status code, or 0 to not change
         */
-       protected function printResult( $isError ) {
+       protected function printResult( $httpCode = 0 ) {
                if ( $this->getConfig()->get( 'DebugAPI' ) !== false ) {
                        $this->setWarning( 'SECURITY WARNING: $wgDebugAPI is enabled' );
                }
 
                $printer = $this->mPrinter;
                $printer->initPrinter( false );
+               if ( $httpCode ) {
+                       $printer->setHttpStatus( $httpCode );
+               }
                $printer->execute();
                $printer->closePrinter();
        }
@@ -1661,6 +1672,9 @@ class ApiMain extends ApiBase {
                        'assert' => [
                                ApiBase::PARAM_TYPE => [ 'user', 'bot' ]
                        ],
+                       'assertuser' => [
+                               ApiBase::PARAM_TYPE => 'user',
+                       ],
                        'requestid' => null,
                        'servedby' => false,
                        'curtimestamp' => false,
index ed229cb..46c57b8 100644 (file)
@@ -86,10 +86,10 @@ class ApiPageSet extends ApiBase {
         * Add all items from $values into the result
         * @param array $result Output
         * @param array $values Values to add
-        * @param string $flag The name of the boolean flag to mark this element
+        * @param string[] $flags The names of boolean flags to mark this element
         * @param string $name If given, name of the value
         */
-       private static function addValues( array &$result, $values, $flag = null, $name = null ) {
+       private static function addValues( array &$result, $values, $flags = [], $name = null ) {
                foreach ( $values as $val ) {
                        if ( $val instanceof Title ) {
                                $v = [];
@@ -99,7 +99,7 @@ class ApiPageSet extends ApiBase {
                        } else {
                                $v = $val;
                        }
-                       if ( $flag !== null ) {
+                       foreach ( $flags as $flag ) {
                                $v[$flag] = true;
                        }
                        $result[] = $v;
@@ -309,8 +309,9 @@ class ApiPageSet extends ApiBase {
                        $pageFlds['page_lang'] = null;
                }
 
-               // only store non-default fields
-               $this->mRequestedPageFields = array_diff_key( $this->mRequestedPageFields, $pageFlds );
+               foreach ( LinkCache::getSelectFields() as $field ) {
+                       $pageFlds[$field] = null;
+               }
 
                $pageFlds = array_merge( $pageFlds, $this->mRequestedPageFields );
 
@@ -600,19 +601,39 @@ class ApiPageSet extends ApiBase {
        ) {
                $result = [];
                if ( in_array( 'invalidTitles', $invalidChecks ) ) {
-                       self::addValues( $result, $this->getInvalidTitlesAndReasons(), 'invalid' );
+                       self::addValues( $result, $this->getInvalidTitlesAndReasons(), [ 'invalid' ] );
                }
                if ( in_array( 'special', $invalidChecks ) ) {
-                       self::addValues( $result, $this->getSpecialTitles(), 'special', 'title' );
+                       $known = [];
+                       $unknown = [];
+                       foreach ( $this->getSpecialTitles() as $title ) {
+                               if ( $title->isKnown() ) {
+                                       $known[] = $title;
+                               } else {
+                                       $unknown[] = $title;
+                               }
+                       }
+                       self::addValues( $result, $unknown, [ 'special', 'missing' ] );
+                       self::addValues( $result, $known, [ 'special' ] );
                }
                if ( in_array( 'missingIds', $invalidChecks ) ) {
-                       self::addValues( $result, $this->getMissingPageIDs(), 'missing', 'pageid' );
+                       self::addValues( $result, $this->getMissingPageIDs(), [ 'missing' ], 'pageid' );
                }
                if ( in_array( 'missingRevIds', $invalidChecks ) ) {
-                       self::addValues( $result, $this->getMissingRevisionIDs(), 'missing', 'revid' );
+                       self::addValues( $result, $this->getMissingRevisionIDs(), [ 'missing' ], 'revid' );
                }
                if ( in_array( 'missingTitles', $invalidChecks ) ) {
-                       self::addValues( $result, $this->getMissingTitles(), 'missing' );
+                       $known = [];
+                       $unknown = [];
+                       foreach ( $this->getMissingTitles() as $title ) {
+                               if ( $title->isKnown() ) {
+                                       $known[] = $title;
+                               } else {
+                                       $unknown[] = $title;
+                               }
+                       }
+                       self::addValues( $result, $unknown, [ 'missing' ] );
+                       self::addValues( $result, $known, [ 'missing', 'known' ] );
                }
                if ( in_array( 'interwikiTitles', $invalidChecks ) ) {
                        self::addValues( $result, $this->getInterwikiTitlesAsResult() );
@@ -734,6 +755,8 @@ class ApiPageSet extends ApiBase {
                // Store Title object in various data structures
                $title = Title::newFromRow( $row );
 
+               LinkCache::singleton()->addGoodLinkObjFromRow( $title, $row );
+
                $pageId = intval( $row->page_id );
                $this->mAllPages[$row->page_namespace][$row->page_title] = $pageId;
                $this->mTitles[] = $title;
@@ -863,9 +886,11 @@ class ApiPageSet extends ApiBase {
                        // Any items left in the $remaining list are added as missing
                        if ( $processTitles ) {
                                // The remaining titles in $remaining are non-existent pages
+                               $linkCache = LinkCache::singleton();
                                foreach ( $remaining as $ns => $dbkeys ) {
                                        foreach ( array_keys( $dbkeys ) as $dbkey ) {
                                                $title = Title::makeTitle( $ns, $dbkey );
+                                               $linkCache->addBadLinkObj( $title );
                                                $this->mAllPages[$ns][$dbkey] = $this->mFakePageId;
                                                $this->mMissingPages[$ns][$dbkey] = $this->mFakePageId;
                                                $this->mGoodAndMissingPages[$ns][$dbkey] = $this->mFakePageId;
@@ -1330,7 +1355,7 @@ class ApiPageSet extends ApiBase {
 
        /**
         * Get the database connection (read-only)
-        * @return DatabaseBase
+        * @return Database
         */
        protected function getDB() {
                return $this->mDbSource->getDB();
index 83b5d93..0cad5de 100644 (file)
@@ -641,6 +641,8 @@ class ApiParse extends ApiBase {
                        $hiddencats[$row->page_title] = isset( $row->pp_propname );
                }
 
+               $linkCache = LinkCache::singleton();
+
                foreach ( $links as $link => $sortkey ) {
                        $entry = [];
                        $entry['sortkey'] = $sortkey;
@@ -648,6 +650,14 @@ class ApiParse extends ApiBase {
                        ApiResult::setContentValue( $entry, 'category', (string)$link );
                        if ( !isset( $hiddencats[$link] ) ) {
                                $entry['missing'] = true;
+
+                               // We already know the link doesn't exist in the database, so
+                               // tell LinkCache that before calling $title->isKnown().
+                               $title = Title::makeTitle( NS_CATEGORY, $link );
+                               $linkCache->addBadLinkObj( $title );
+                               if ( $title->isKnown() ) {
+                                       $entry['known'] = true;
+                               }
                        } elseif ( $hiddencats[$link] ) {
                                $entry['hidden'] = true;
                        }
index 5e3c709..16bd725 100644 (file)
@@ -168,7 +168,7 @@ class ApiQuery extends ApiBase {
         * @param string $name Name to assign to the database connection
         * @param int $db One of the DB_* constants
         * @param array $groups Query groups
-        * @return DatabaseBase
+        * @return Database
         */
        public function getNamedDB( $name, $db, $groups ) {
                if ( !array_key_exists( $name, $this->mNamedDB ) ) {
@@ -258,6 +258,11 @@ class ApiQuery extends ApiBase {
                // Write the continuation data into the result
                $this->setContinuationManager( null );
                if ( $this->mParams['rawcontinue'] ) {
+                       $data = $continuationManager->getRawNonContinuation();
+                       if ( $data ) {
+                               $this->getResult()->addValue( null, 'query-noncontinue', $data,
+                                       ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
+                       }
                        $data = $continuationManager->getRawContinuation();
                        if ( $data ) {
                                $this->getResult()->addValue( null, 'query-continue', $data,
@@ -357,6 +362,9 @@ class ApiQuery extends ApiBase {
                        $vals = [];
                        ApiQueryBase::addTitleInfo( $vals, $title );
                        $vals['missing'] = true;
+                       if ( $title->isKnown() ) {
+                               $vals['known'] = true;
+                       }
                        $pages[$fakeId] = $vals;
                }
                // Report any invalid titles
@@ -367,7 +375,7 @@ class ApiQuery extends ApiBase {
                foreach ( $pageSet->getMissingPageIDs() as $pageid ) {
                        $pages[$pageid] = [
                                'pageid' => $pageid,
-                               'missing' => true
+                               'missing' => true,
                        ];
                }
                // Report special pages
@@ -376,13 +384,7 @@ class ApiQuery extends ApiBase {
                        $vals = [];
                        ApiQueryBase::addTitleInfo( $vals, $title );
                        $vals['special'] = true;
-                       if ( $title->isSpecialPage() &&
-                               !SpecialPageFactory::exists( $title->getDBkey() )
-                       ) {
-                               $vals['missing'] = true;
-                       } elseif ( $title->getNamespace() == NS_MEDIA &&
-                               !wfFindFile( $title )
-                       ) {
+                       if ( !$title->isKnown() ) {
                                $vals['missing'] = true;
                        }
                        $pages[$fakeId] = $vals;
index 6aeee68..8734f38 100644 (file)
@@ -44,10 +44,10 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
         * which may not necessarily be the same as the local DB.
         *
         * TODO: allow querying non-local repos.
-        * @return DatabaseBase
+        * @return IDatabase
         */
        protected function getDB() {
-               return $this->mRepo->getSlaveDB();
+               return $this->mRepo->getReplicaDB();
        }
 
        public function execute() {
index 060e3e1..b64b2c8 100644 (file)
@@ -166,12 +166,20 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
                $orderby[] = "rev_id $sort";
                $this->addOption( 'ORDER BY', $orderby );
 
-               $res = $this->select( __METHOD__ );
+               $hookData = [];
+               $res = $this->select( __METHOD__, [], $hookData );
                $pageMap = []; // Maps rev_page to array index
                $count = 0;
                $nextIndex = 0;
                $generated = [];
                foreach ( $res as $row ) {
+                       if ( $count === 0 && $resultPageSet !== null ) {
+                               // Set the non-continue since the list of all revisions is
+                               // prone to having entries added at the start frequently.
+                               $this->getContinuationManager()->addGeneratorNonContinueParam(
+                                       $this, 'continue', "$row->rev_timestamp|$row->rev_id"
+                               );
+                       }
                        if ( ++$count > $this->limit ) {
                                // We've had enough
                                $this->setContinueEnumParameter( 'continue', "$row->rev_timestamp|$row->rev_id" );
@@ -203,12 +211,12 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
                                        ];
                                        ApiResult::setIndexedTagName( $a['revisions'], 'rev' );
                                        ApiQueryBase::addTitleInfo( $a, $title );
-                                       $fit = $result->addValue( [ 'query', $this->getModuleName() ], $index, $a );
+                                       $fit = $this->processRow( $row, $a['revisions'][0], $hookData ) &&
+                                               $result->addValue( [ 'query', $this->getModuleName() ], $index, $a );
                                } else {
                                        $index = $pageMap[$row->rev_page];
-                                       $fit = $result->addValue(
-                                               [ 'query', $this->getModuleName(), $index, 'revisions' ],
-                                               null, $rev );
+                                       $fit = $this->processRow( $row, $rev, $hookData ) &&
+                                               $result->addValue( [ 'query', $this->getModuleName(), $index, 'revisions' ], null, $rev );
                                }
                                if ( !$fit ) {
                                        $this->setContinueEnumParameter( 'continue', "$row->rev_timestamp|$row->rev_id" );
index b35eec2..bba5375 100644 (file)
@@ -103,7 +103,7 @@ abstract class ApiQueryBase extends ApiBase {
 
        /**
         * Get the Query database connection (read-only)
-        * @return DatabaseBase
+        * @return Database
         */
        protected function getDB() {
                if ( is_null( $this->mDb ) ) {
@@ -119,7 +119,7 @@ abstract class ApiQueryBase extends ApiBase {
         * @param string $name Name to assign to the database connection
         * @param int $db One of the DB_* constants
         * @param array $groups Query groups
-        * @return DatabaseBase
+        * @return Database
         */
        public function selectNamedDB( $name, $db, $groups ) {
                $this->mDb = $this->getQuery()->getNamedDB( $name, $db, $groups );
@@ -347,9 +347,12 @@ abstract class ApiQueryBase extends ApiBase {
         *    'options' => ...,
         *    'join_conds' => ...
         *  ]
+        * @param array|null &$hookData If set, the ApiQueryBaseBeforeQuery and
+        *  ApiQueryBaseAfterQuery hooks will be called, and the
+        *  ApiQueryBaseProcessRow hook will be expected.
         * @return ResultWrapper
         */
-       protected function select( $method, $extraQuery = [] ) {
+       protected function select( $method, $extraQuery = [], array &$hookData = null ) {
 
                $tables = array_merge(
                        $this->tables,
@@ -372,11 +375,38 @@ abstract class ApiQueryBase extends ApiBase {
                        isset( $extraQuery['join_conds'] ) ? (array)$extraQuery['join_conds'] : []
                );
 
+               if ( $hookData !== null ) {
+                       Hooks::run( 'ApiQueryBaseBeforeQuery',
+                               [ $this, &$tables, &$fields, &$where, &$options, &$join_conds, &$hookData ]
+                       );
+               }
+
                $res = $this->getDB()->select( $tables, $fields, $where, $method, $options, $join_conds );
 
+               if ( $hookData !== null ) {
+                       Hooks::run( 'ApiQueryBaseAfterQuery', [ $this, $res, &$hookData ] );
+               }
+
                return $res;
        }
 
+       /**
+        * Call the ApiQueryBaseProcessRow hook
+        *
+        * Generally, a module that passed $hookData to self::select() will call
+        * this just before calling ApiResult::addValue(), and treat a false return
+        * here in the same way it treats a false return from addValue().
+        *
+        * @since 1.28
+        * @param object $row Database row
+        * @param array &$data Data to be added to the result
+        * @param array &$hookData Hook data from ApiQueryBase::select()
+        * @return bool Return false if row processing should end with continuation
+        */
+       protected function processRow( $row, array &$data, array &$hookData ) {
+               return Hooks::run( 'ApiQueryBaseProcessRow', [ $this, $row, &$data, &$hookData ] );
+       }
+
        /**
         * @param string $query
         * @param string $protocol
index 67fe0d6..f7b94c7 100644 (file)
@@ -45,6 +45,15 @@ abstract class ApiQueryGeneratorBase extends ApiQueryBase {
                $this->mGeneratorPageSet = $generatorPageSet;
        }
 
+       /**
+        * Indicate whether the module is in generator mode
+        * @since 1.28
+        * @return bool
+        */
+       public function isInGeneratorMode() {
+               return $this->mGeneratorPageSet !== null;
+       }
+
        /**
         * Get the PageSet object to work on.
         * If this module is generator, the pageSet object is different from other module's
index 9be5849..0c70a8a 100644 (file)
@@ -92,10 +92,10 @@ class ApiQueryMyStashedFiles extends ApiQueryBase {
                        ];
 
                        if ( isset( $prop['size'] ) ) {
-                               $item['size'] = (int) $row->us_size;
-                               $item['width'] = (int) $row->us_image_width;
-                               $item['height'] = (int) $row->us_image_height;
-                               $item['bits'] = (int) $row->us_image_bits;
+                               $item['size'] = (int)$row->us_size;
+                               $item['width'] = (int)$row->us_image_width;
+                               $item['height'] = (int)$row->us_image_height;
+                               $item['bits'] = (int)$row->us_image_bits;
                        }
 
                        if ( isset( $prop['type'] ) ) {
index cc3ca60..8b11dc2 100644 (file)
@@ -361,9 +361,10 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                $this->token = $params['token'];
                $this->addOption( 'LIMIT', $params['limit'] + 1 );
 
+               $hookData = [];
                $count = 0;
                /* Perform the actual query. */
-               $res = $this->select( __METHOD__ );
+               $res = $this->select( __METHOD__, [], $hookData );
 
                $revids = [];
                $titles = [];
@@ -372,6 +373,13 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                /* Iterate through the rows, adding data extracted from them to our query result. */
                foreach ( $res as $row ) {
+                       if ( $count === 0 && $resultPageSet !== null ) {
+                               // Set the non-continue since the list of recentchanges is
+                               // prone to having entries added at the start frequently.
+                               $this->getContinuationManager()->addGeneratorNonContinueParam(
+                                       $this, 'continue', "$row->rc_timestamp|$row->rc_id"
+                               );
+                       }
                        if ( ++$count > $params['limit'] ) {
                                // We've reached the one extra which shows that there are
                                // additional pages to be had. Stop here...
@@ -384,7 +392,8 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                                $vals = $this->extractRowInfo( $row );
 
                                /* Add that row's data to our final output. */
-                               $fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $vals );
+                               $fit = $this->processRow( $row, $vals, $hookData ) &&
+                                       $result->addValue( [ 'query', $this->getModuleName() ], null, $vals );
                                if ( !$fit ) {
                                        $this->setContinueEnumParameter( 'continue', "$row->rc_timestamp|$row->rc_id" );
                                        break;
index b816f43..3259927 100644 (file)
@@ -313,7 +313,8 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
 
                $count = 0;
                $generated = [];
-               $res = $this->select( __METHOD__ );
+               $hookData = [];
+               $res = $this->select( __METHOD__, [], $hookData );
 
                foreach ( $res as $row ) {
                        if ( ++$count > $this->limit ) {
@@ -350,7 +351,8 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
                                        }
                                }
 
-                               $fit = $this->addPageSubItem( $row->rev_page, $rev, 'rev' );
+                               $fit = $this->processRow( $row, $rev, $hookData ) &&
+                                       $this->addPageSubItem( $row->rev_page, $rev, 'rev' );
                                if ( !$fit ) {
                                        if ( $enumRevMode ) {
                                                $this->setContinueEnumParameter( 'continue',
index ba60da9..6be5198 100644 (file)
@@ -75,6 +75,7 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                // Create search engine instance and set options
                $search = $this->buildSearchEngine( $params );
                $search->setFeatureData( 'rewrite', (bool)$params['enablerewrites'] );
+               $search->setFeatureData( 'interwiki', (bool)$interwiki );
 
                $query = $search->transformSearchTerm( $query );
                $query = $search->replacePrefixes( $query );
index 99f722d..0bb7ff8 100644 (file)
@@ -576,7 +576,6 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                ApiResult::setIndexedTagName( $data, 'library' );
 
                return $this->getResult()->addValue( 'query', $property, $data );
-
        }
 
        protected function appendExtensions( $property ) {
index 7a14aac..43eb7e8 100644 (file)
@@ -93,7 +93,7 @@ class ApiQueryTags extends ApiQueryBase {
                        $tag['name'] = $tagName;
 
                        if ( $fld_displayname ) {
-                               $tag['displayname'] = ChangeTags::tagDescription( $tagName );
+                               $tag['displayname'] = ChangeTags::tagDescription( $tagName, $this );
                        }
 
                        if ( $fld_description ) {
index f92a916..b85bec4 100644 (file)
@@ -111,8 +111,9 @@ class ApiQueryContributions extends ApiQueryBase {
 
                $this->prepareQuery();
 
+               $hookData = [];
                // Do the actual query.
-               $res = $this->select( __METHOD__ );
+               $res = $this->select( __METHOD__, [], $hookData );
 
                if ( $this->fld_sizediff ) {
                        $revIds = [];
@@ -139,7 +140,8 @@ class ApiQueryContributions extends ApiQueryBase {
                        }
 
                        $vals = $this->extractRowInfo( $row );
-                       $fit = $this->getResult()->addValue( [ 'query', $this->getModuleName() ], null, $vals );
+                       $fit = $this->processRow( $row, $vals, $hookData ) &&
+                               $this->getResult()->addValue( [ 'query', $this->getModuleName() ], null, $vals );
                        if ( !$fit ) {
                                $this->setContinueEnumParameter( 'continue', $this->continueStr( $row ) );
                                break;
index c30f0cf..42ea55d 100644 (file)
@@ -106,13 +106,14 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                        $options['end'] = $params['end'];
                }
 
+               $startFrom = null;
                if ( !is_null( $params['continue'] ) ) {
                        $cont = explode( '|', $params['continue'] );
                        $this->dieContinueUsageIf( count( $cont ) != 2 );
                        $continueTimestamp = $cont[0];
                        $continueId = (int)$cont[1];
                        $this->dieContinueUsageIf( $continueId != $cont[1] );
-                       $options['startFrom'] = [ $continueTimestamp, $continueId ];
+                       $startFrom = [ $continueTimestamp, $continueId ];
                }
 
                if ( $wlowner !== $user ) {
@@ -169,33 +170,24 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                        $options['notByUser'] = $params['excludeuser'];
                }
 
-               $options['limit'] = $params['limit'] + 1;
+               $options['limit'] = $params['limit'];
+
+               Hooks::run( 'ApiQueryWatchlistPrepareWatchedItemQueryServiceOptions', [
+                       $this, $params, &$options
+               ] );
 
                $ids = [];
                $count = 0;
                $watchedItemQuery = MediaWikiServices::getInstance()->getWatchedItemQueryService();
-               $items = $watchedItemQuery->getWatchedItemsWithRecentChangeInfo( $wlowner, $options );
+               $items = $watchedItemQuery->getWatchedItemsWithRecentChangeInfo( $wlowner, $options, $startFrom );
 
                foreach ( $items as list ( $watchedItem, $recentChangeInfo ) ) {
                        /** @var WatchedItem $watchedItem */
-                       if ( ++$count > $params['limit'] ) {
-                               // We've reached the one extra which shows that there are
-                               // additional pages to be had. Stop here...
-                               $this->setContinueEnumParameter(
-                                       'continue',
-                                       $recentChangeInfo['rc_timestamp'] . '|' . $recentChangeInfo['rc_id']
-                               );
-                               break;
-                       }
-
                        if ( is_null( $resultPageSet ) ) {
                                $vals = $this->extractOutputData( $watchedItem, $recentChangeInfo );
                                $fit = $this->getResult()->addValue( [ 'query', $this->getModuleName() ], null, $vals );
                                if ( !$fit ) {
-                                       $this->setContinueEnumParameter(
-                                               'continue',
-                                               $recentChangeInfo['rc_timestamp'] . '|' . $recentChangeInfo['rc_id']
-                                       );
+                                       $startFrom = [ $recentChangeInfo['rc_timestamp'], $recentChangeInfo['rc_id'] ];
                                        break;
                                }
                        } else {
@@ -207,6 +199,10 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                        }
                }
 
+               if ( $startFrom !== null ) {
+                       $this->setContinueEnumParameter( 'continue', implode( '|', $startFrom ) );
+               }
+
                if ( is_null( $resultPageSet ) ) {
                        $this->getResult()->addIndexedTagName(
                                [ 'query', $this->getModuleName() ],
@@ -396,6 +392,10 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                        $vals['suppressed'] = true;
                }
 
+               Hooks::run( 'ApiQueryWatchlistExtractOutputData', [
+                       $this, $watchedItem, $recentChangeInfo, &$vals
+               ] );
+
                return $vals;
        }
 
index 712217b..4fac37d 100644 (file)
@@ -75,7 +75,7 @@ class ApiRsd extends ApiBase {
         * compatible APIs, by hooking 'ApiRsdServiceApis' and adding more
         * elements to the array.
         *
-        * See http://cyber.law.harvard.edu/blogs/gems/tech/rsd.html for
+        * See https://cyber.harvard.edu/blogs/gems/tech/rsd.html for
         * the base RSD spec, and check WordPress and StatusNet sites for
         * in-production examples listing several blogging and micrblogging
         * APIs.
index f335682..3412f38 100644 (file)
@@ -158,6 +158,9 @@ class ApiSetNotificationTimestamp extends ApiBase {
                                        ];
                                        if ( !$title->exists() ) {
                                                $r['missing'] = true;
+                                               if ( $title->isKnown() ) {
+                                                       $r['known'] = true;
+                                               }
                                        }
                                        if ( isset( $timestamps[$ns] ) && array_key_exists( $dbkey, $timestamps[$ns] ) ) {
                                                $r['notificationtimestamp'] = '';
index 5a2492d..92cbe90 100644 (file)
@@ -21,6 +21,7 @@
 
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
+use Wikimedia\ScopedCallback;
 
 /**
  * Prepare an edit in shared cache so that it can be reused on edit
index d28165d..fccdc0f 100644 (file)
@@ -8,6 +8,11 @@
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentación]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Llista d'alderique]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anuncios de la API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Fallos y solicitúes]\n</div>\n<strong>Estau:</strong> Toles carauterístiques qu'apaecen nesta páxina tendríen de funcionar, pero la API inda ta en desendolcu activu, y puede camudar en cualquier momentu. Suscríbete a la [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ llista de corréu mediawiki-api-announce] p'avisos sobro anovamientos.\n\n<strong>Solicitúes incorreutes:</strong> Cuando s'unvíen solicitúes incorreutes a la API, unvíase una cabecera HTTP cola clave \"MediaWiki-API-Error\" y, darréu, tanto'l valor de la cabecera como'l códigu d'error devueltu pondránse al mesmu valor. Pa más información, consulta [[mw:API:Errors_and_warnings|API: Errores y avisos]].\n\n<strong>Pruebes:</strong> Pa facilitar les pruebes de solicitúes API, consulta [[Special:ApiSandbox]].",
        "apihelp-main-param-action": "Qué aición facer.",
        "apihelp-main-param-format": "El formatu de la salida.",
+       "apihelp-main-param-maxlag": "El retrasu (lag) máximu puede utilizase cuando MediaWiki ta instaláu nun conxuntu de bases de datos replicaes. Pa evitar les aiciones que pudieran causar un retrasu entá mayor na replicación del sitiu, esti parámetru puede causar que'l cliente espere hasta que'l retrasu de replicación sía menor que'l valor especificáu. En casu de retrasu escesivu, devuélvese un códigu d'error <samp>maxlag</samp> con un mensaxe asemeyáu a <samp>Esperando a $host: $lag segundos de retrasu<s/amp>.<br />Ver [[mw:Manual:Maxlag_parameter|Manual:Parámetru maxlag]] pa más información.",
+       "apihelp-main-param-smaxage": "Establez l'encabezáu HTTP <code>s-maxage</code> de control de caché a esta cantidá de segundos. Los errores nunca se guarden na caché.",
+       "apihelp-main-param-maxage": "Establez l'encabezáu HTTP <code>max-age</code> de control de caché a esta cantidá de segundos. Los errores nunca se guarden na caché.",
+       "apihelp-main-param-assert": "Comprobar que l'usuariu tien sesión aniciada si'l valor ye <kbd>user</kbd> o que tien el permisu de bot si ye <kbd>bot</kbd>.",
+       "apihelp-main-param-assertuser": "Comprobar que'l usuariu actual ye l'usuariu nomáu.",
        "apihelp-main-param-servedby": "Incluyir el nome del host que sirvió la solicitú nes resultancies.",
        "apihelp-main-param-curtimestamp": "Incluyir la marca de tiempu actual na resultancia.",
        "apihelp-block-description": "Bloquiar a un usuariu.",
index c7bfb23..3818ce9 100644 (file)
@@ -53,6 +53,7 @@
        "apihelp-createaccount-param-language": "Моўны код, які будзе выстаўлены ўдзельніку па змоўчаньні (неабавязкова, па змоўчаньні мова зьместу).",
        "apihelp-createaccount-example-pass": "Стварэньне ўдзельніка <kbd>testuser</kbd> з паролем <kbd>test123</kbd>.",
        "apihelp-createaccount-example-mail": "Стварэньне ўдзельніка <kbd>testmailuser</kbd> і адпраўка выпадковага паролю электроннай поштай.",
+       "apihelp-edit-param-text": "Зьмест старонкі.",
        "apihelp-query+transcludedin-paramvalue-prop-title": "Назва кожнай старонкі.",
        "apihelp-query+transcludedin-param-limit": "Колькі вяртаць.",
        "apihelp-query+userinfo-paramvalue-prop-acceptlang": "Дублюе загаловак <code>Accept-Language</code>, адасланы кліентам у структураваным фармаце."
index 4156395..29c0605 100644 (file)
@@ -2,7 +2,8 @@
        "@metadata": {
                "authors": [
                        "Vodnokon4e",
-                       "StanProg"
+                       "StanProg",
+                       "Spas.Z.Spasov"
                ]
        },
        "apihelp-main-param-action": "Кое действие да се извърши.",
@@ -30,7 +31,7 @@
        "apihelp-feedcontributions-param-year": "От година (и по-рано).",
        "apihelp-feedcontributions-param-month": "От месец (и по-рано).",
        "apihelp-feedcontributions-param-tagfilter": "Филтриране на приноси, които имат тези етикети.",
-       "apihelp-feedcontributions-param-deletedonly": "Покажи само изтритите редакции.",
+       "apihelp-feedcontributions-param-deletedonly": "Покажи само изтритите приноси.",
        "apihelp-feedcontributions-param-newonly": "Показване само на редакции за създаване на страници.",
        "apihelp-feedcontributions-param-hideminor": "Скриване на малки промени.",
        "apihelp-feedcontributions-param-showsizediff": "Показване на размера на разликите между версиите.",
index c93d8ba..fde631c 100644 (file)
@@ -2,13 +2,24 @@
        "@metadata": {
                "authors": [
                        "Aftabuzzaman",
-                       "Bodhisattwa"
+                       "Bodhisattwa",
+                       "আজিজ"
                ]
        },
+       "apihelp-main-param-format": "আউটপুটের বিন্যাস",
+       "apihelp-main-param-requestid": "এখানে প্রদত্ত যেকোন মান প্রতিক্রিয়ায় অন্তর্ভুক্ত করা হবে। অনুরোধের পার্থক্য করতে ব্যবহার করা যেতে পারে।",
        "apihelp-block-description": "ব্যবহারকারীকে বাধা দিন।",
+       "apihelp-block-param-reason": "বাধার দানের কারণ।",
+       "apihelp-createaccount-description": "নতুন ব্যবহারকারীর অ্যাকাউন্ট তৈরি করুন",
        "apihelp-createaccount-param-name": "ব্যবহারকারী নাম।",
        "apihelp-delete-description": "একটি পাতা মুছে ফেলুন।",
        "apihelp-delete-example-simple": "<kbd>প্রধান পাতা</kbd> মুছে ফেলুন।",
+       "apihelp-edit-param-text": "পাতার বিষয়বস্তু।",
        "apihelp-edit-param-minor": "অনুল্লেখ্য সম্পাদনা।",
+       "apihelp-edit-param-bot": "এই সম্পাদনাটি একটি বট সম্পাদনা হিসাবে চিহ্নিত করে।",
+       "apihelp-edit-param-createonly": "পাতাটি আগেই বিদ্যমান থাকলে সম্পদনা করবেন না।",
+       "apihelp-edit-param-contentmodel": "নতুন বিষয়বস্তুর, বিষয়বস্তু-মডেল।",
+       "apihelp-edit-example-edit": "একটি পাতা সম্পাদনা করুন",
+       "apihelp-edit-example-prepend": "একটি পৃষ্ঠার পূর্বে <kbd>_&#95;NOTOC_&#95;</kbd> লিখুন।",
        "apihelp-login-example-login": "প্রবেশ"
 }
index 41f1ff9..db799e2 100644 (file)
        "apihelp-emailuser-param-text": "E-Mail-Inhalt.",
        "apihelp-emailuser-param-ccme": "Eine Kopie dieser E-Mail an mich senden.",
        "apihelp-emailuser-example-email": "Eine E-Mail an den Benutzer <kbd>WikiSysop</kbd> mit dem Text <kbd>Content</kbd> senden.",
-       "apihelp-expandtemplates-description": "Alle Vorlagen im Wikitext expandieren.",
+       "apihelp-expandtemplates-description": "Alle Vorlagen innerhalb des Wikitextes expandieren.",
        "apihelp-expandtemplates-param-title": "Titel der Seite.",
        "apihelp-expandtemplates-param-text": "Zu konvertierender Wikitext.",
        "apihelp-expandtemplates-param-revid": "Versionsnummer, die für die Anzeige von <nowiki>{{REVISIONID}}</nowiki> und ähnlichen Variablen verwendet wird.",
        "apihelp-options-description": "Die Voreinstellungen des gegenwärtigen Benutzers ändern.",
        "apihelp-options-param-reset": "Setzt die Einstellungen auf Websitestandards zurück.",
        "apihelp-options-param-resetkinds": "Liste von zurückzusetzenden Optionstypen, wenn die <var>$1reset</var>-Option ausgewählt ist.",
-       "apihelp-options-param-change": "Liste von Änderungen, die mit Name=Wert formatiert sind (z.B. skin=vector). Wert darf keine Verkettungszeichen enthalten. Falls kein Wert angegeben wurde (nichtmal ein Gleichheitszeichen), z.B.: optionname|otheroption|..., wird die Option auf ihren Vorgabewert zurückgesetzt.",
-       "apihelp-options-param-optionvalue": "Der Wert für die Option, die durch <var>$1optionname</var> angegeben ist, kann Verkettungszeichen enthalten.",
+       "apihelp-options-param-change": "Liste von Änderungen, die mit name=wert formatiert sind (z.&nbsp;B. skin=vector). Falls kein Wert angegeben wurde (ohne einem Gleichheitszeichen), z.&nbsp;B. Optionname|AndereOption|…, wird die Option auf ihren Standardwert zurückgesetzt. Falls ein übergebener Wert ein Trennzeichen enthält (<kbd>|</kbd>), verwende den [[Special:ApiHelp/main#main/datatypes|alternativen Mehrfachwerttrenner]] zur korrekten Bedienung.",
+       "apihelp-options-param-optionvalue": "Der Wert für die Option, die durch <var>$1optionname</var> angegeben ist.",
        "apihelp-options-example-reset": "Alle Einstellungen zurücksetzen",
        "apihelp-options-example-change": "Ändert die Einstellungen <kbd>skin</kbd> und <kbd>hideminor</kbd>.",
        "apihelp-options-example-complex": "Setzt alle Einstellungen zurück, dann <kbd>skin</kbd> und <kbd>nickname</kbd> festlegen.",
        "apihelp-xmlfm-description": "Daten im XML-Format ausgeben (schöngedruckt in HTML).",
        "api-format-title": "MediaWiki-API-Ergebnis",
        "api-format-prettyprint-header": "Dies ist die HTML-Repräsentation des $1-Formats. HTML ist zur Fehlerbehebung gut, aber unpassend für den Anwendungsgebrauch.\n\nGib den Parameter <var>format</var> an, um das Ausgabeformat zu ändern. Um die Nicht-HTML-Repräsentation des $1-Formats anzusehen, lege <kbd>format=$2</kbd> fest.\n\nSiehe die [[mw:API|vollständige Dokumentation]] oder die [[Special:ApiHelp/main|API-Hilfe]] für weitere Informationen.",
+       "api-format-prettyprint-status": "Diese Antwort wird mit dem HTTP-Status $1 $2 zurückgegeben.",
        "api-pageset-param-titles": "Eine Liste der Titel, an denen gearbeitet werden soll.",
        "api-pageset-param-pageids": "Eine Liste der Seitenkennungen, an denen gearbeitet werden soll.",
        "api-pageset-param-revids": "Eine Liste der Versionskennungen, an denen gearbeitet werden soll.",
index 31bb5fa..b5179bb 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "Gorizon",
                        "Mirzali",
-                       "Kumkumuk"
+                       "Kumkumuk",
+                       "Asmen"
                ]
        },
        "apihelp-main-param-action": "Performansa kamci aksiyon",
@@ -20,7 +21,7 @@
        "apihelp-disabled-description": "Eno modul aktiv niyo.",
        "apihelp-edit-description": "Vıraze û pelan bıvurne.",
        "apihelp-edit-param-text": "Zerreki pele",
-       "apihelp-edit-param-minor": "Vurnayışo qıckek.",
+       "apihelp-edit-param-minor": "Vurriyayışê werdiy",
        "apihelp-edit-param-notminor": "Vurnayışo qıckek niyo.",
        "apihelp-edit-param-bot": "Nê vurnayışi zey boti nişan ke.",
        "apihelp-edit-example-edit": "Şeker bıvurne",
index 40388f9..0f184d9 100644 (file)
@@ -13,6 +13,7 @@
        "apihelp-main-param-smaxage": "Set the <code>s-maxage</code> HTTP cache control header to this many seconds. Errors are never cached.",
        "apihelp-main-param-maxage": "Set the <code>max-age</code> HTTP cache control header to this many seconds. Errors are never cached.",
        "apihelp-main-param-assert": "Verify the user is logged in if set to <kbd>user</kbd>, or has the bot user right if <kbd>bot</kbd>.",
+       "apihelp-main-param-assertuser": "Verify the current user is the named user.",
        "apihelp-main-param-requestid": "Any value given here will be included in the response. May be used to distinguish requests.",
        "apihelp-main-param-servedby": "Include the hostname that served the request in the results.",
        "apihelp-main-param-curtimestamp": "Include the current timestamp in the result.",
        "apihelp-edit-param-tags": "Change tags to apply to the revision.",
        "apihelp-edit-param-minor": "Minor edit.",
        "apihelp-edit-param-notminor": "Non-minor edit.",
-       "apihelp-edit-param-bot": "Mark this edit as bot.",
+       "apihelp-edit-param-bot": "Mark this edit as a bot edit.",
        "apihelp-edit-param-basetimestamp": "Timestamp of the base revision, used to detect edit conflicts. May be obtained through [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
        "apihelp-edit-param-starttimestamp": "Timestamp when the editing process began, used to detect edit conflicts. An appropriate value may be obtained using <var>[[Special:ApiHelp/main|curtimestamp]]</var> when beginning the edit process (e.g. when loading the page content to edit).",
        "apihelp-edit-param-recreate": "Override any errors about the page having been deleted in the meantime.",
        "apihelp-emailuser-param-ccme": "Send a copy of this mail to me.",
        "apihelp-emailuser-example-email": "Send an email to user <kbd>WikiSysop</kbd> with the text <kbd>Content</kbd>.",
 
-       "apihelp-expandtemplates-description": "Expands all templates in wikitext.",
+       "apihelp-expandtemplates-description": "Expands all templates within wikitext.",
        "apihelp-expandtemplates-param-title": "Title of page.",
        "apihelp-expandtemplates-param-text": "Wikitext to convert.",
        "apihelp-expandtemplates-param-revid": "Revision ID, for <nowiki>{{REVISIONID}}</nowiki> and similar variables.",
        "apihelp-feedcontributions-param-month": "From month (and earlier).",
        "apihelp-feedcontributions-param-tagfilter": "Filter contributions that have these tags.",
        "apihelp-feedcontributions-param-deletedonly": "Show only deleted contributions.",
-       "apihelp-feedcontributions-param-toponly": "Only show edits that are latest revisions.",
+       "apihelp-feedcontributions-param-toponly": "Only show edits that are the latest revisions.",
        "apihelp-feedcontributions-param-newonly": "Only show edits that are page creations.",
        "apihelp-feedcontributions-param-hideminor": "Hide minor edits.",
        "apihelp-feedcontributions-param-showsizediff": "Show the size difference between revisions.",
        "apihelp-options-description": "Change preferences of the current user.\n\nOnly options which are registered in core or in one of installed extensions, or options with keys prefixed with <code>userjs-</code> (intended to be used by user scripts), can be set.",
        "apihelp-options-param-reset": "Resets preferences to the site defaults.",
        "apihelp-options-param-resetkinds": "List of types of options to reset when the <var>$1reset</var> option is set.",
-       "apihelp-options-param-change": "List of changes, formatted name=value (e.g. skin=vector). Value cannot contain pipe characters. If no value is given (not even an equals sign), e.g., optionname|otheroption|..., the option will be reset to its default value.",
+       "apihelp-options-param-change": "List of changes, formatted name=value (e.g. skin=vector). If no value is given (not even an equals sign), e.g., optionname|otheroption|..., the option will be reset to its default value. If any value passed contains the pipe character (<kbd>|</kbd>), use the [[Special:ApiHelp/main#main/datatypes|alternative multiple-value separator]] for correct operation.",
        "apihelp-options-param-optionname": "The name of the option that should be set to the value given by <var>$1optionvalue</var>.",
-       "apihelp-options-param-optionvalue": "The value for the option specified by <var>$1optionname</var>, can contain pipe characters.",
+       "apihelp-options-param-optionvalue": "The value for the option specified by <var>$1optionname</var>.",
        "apihelp-options-example-reset": "Reset all preferences.",
        "apihelp-options-example-change": "Change <kbd>skin</kbd> and <kbd>hideminor</kbd> preferences.",
        "apihelp-options-example-complex": "Reset all preferences, then set <kbd>skin</kbd> and <kbd>nickname</kbd>.",
        "api-format-title": "MediaWiki API result",
        "api-format-prettyprint-header": "This is the HTML representation of the $1 format. HTML is good for debugging, but is unsuitable for application use.\n\nSpecify the <var>format</var> parameter to change the output format. To see the non-HTML representation of the $1 format, set <kbd>format=$2</kbd>.\n\nSee the [[mw:API|complete documentation]], or the [[Special:ApiHelp/main|API help]] for more information.",
        "api-format-prettyprint-header-only-html": "This is an HTML representation intended for debugging, and is unsuitable for application use.\n\nSee the [[mw:API|complete documentation]], or the [[Special:ApiHelp/main|API help]] for more information.",
+       "api-format-prettyprint-status": "This response would be returned with HTTP status $1 $2.",
 
        "api-pageset-param-titles": "A list of titles to work on.",
        "api-pageset-param-pageids": "A list of page IDs to work on.",
index 8ed1cf5..1078a6d 100644 (file)
                        "Rubentl134",
                        "2axterix2",
                        "Dgstranz",
-                       "Copper12"
+                       "Copper12",
+                       "Irus",
+                       "Hamilton Abreu",
+                       "Pompilos",
+                       "Igv"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentación]]\n* [[mw:API:FAQ|Preguntas frecuentes]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de correo]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anuncios de la API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Errores y peticiones]\n</div>\n<strong>Estado:</strong> Todas las características que se muestran en esta página deberían funcionar, pero la API aún se encuentra en desarrollo activo y puede cambiar en cualquier momento. Suscríbete a [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la lista de correo de mediawiki-api-announce] para estar al día de las actualizaciones.\n\n<strong>Solicitudes erróneas:</strong> Cuando se envían solicitudes erróneas a la API, se envía una cabecera HTTP con la clave \"MediaWiki-API-Error\". El valor de la cabecera y el código de error devuelto tomarán el mismo valor. Para más información, véase [[mw:API:Errors_and_warnings|API: Errores y advertencias]].\n\n<strong>Pruebas:</strong> para facilitar las pruebas de solicitudes a la API, consulta [[Special:ApiSandbox]].",
@@ -32,6 +36,7 @@
        "apihelp-main-param-smaxage": "Establece el encabezado HTTP <code>s-maxage</code> de control de caché a esta cantidad de segundos. Los errores nunca se almacenan en caché.",
        "apihelp-main-param-maxage": "Establece el encabezado HTTP <code>max-age</code> de control de caché a esta cantidad de segundos. Los errores nunca se almacenan en caché.",
        "apihelp-main-param-assert": "Comprobar que el usuario haya iniciado sesión si el valor es <kbd>user</kbd> o si tiene el permiso de bot si es <kbd>bot</kbd>.",
+       "apihelp-main-param-assertuser": "Verificar el usuario actual es el usuario nombrado.",
        "apihelp-main-param-requestid": "Cualquier valor dado aquí se incluirá en la respuesta. Se puede utilizar para distinguir solicitudes.",
        "apihelp-main-param-servedby": "Incluir el nombre del host que ha servido la solicitud en los resultados.",
        "apihelp-main-param-curtimestamp": "Incluir la marca de tiempo actual en el resultado.",
        "apihelp-edit-param-tags": "Cambia las etiquetas para aplicarlas a la revisión.",
        "apihelp-edit-param-minor": "Edición menor.",
        "apihelp-edit-param-notminor": "Edición no menor.",
-       "apihelp-edit-param-bot": "Marcar esta edición como de bot.",
+       "apihelp-edit-param-bot": "Marcar esta edición como edición de bot.",
        "apihelp-edit-param-basetimestamp": "Marca de tiempo de la revisión base, usada para detectar conflictos de edición. Se puede obtener mediante [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]]",
        "apihelp-edit-param-starttimestamp": "Marca de tiempo de cuando empezó el proceso de edición, usada para detectar conflictos de edición. Se puede obtener un valor apropiado usando <var>[[Special:ApiHelp/main|curtimestamp]]</var> cuando comiences el proceso de edición (por ejemplo, al cargar el contenido de la página por editar).",
        "apihelp-edit-param-recreate": "Reemplazar los errores acerca de la página de haber sido eliminados en el ínterin.",
        "apihelp-options-param-resetkinds": "Lista de tipos de opciones a restablecer cuando la opción <var>$1reset</var> esté establecida.",
        "apihelp-options-param-change": "Lista de cambios con el formato name=value (por ejemplo: skin=vector). El valor no puede contener caracteres de barras verticales. Si no se da ningún valor (ni siquiera un signo de igual), por ejemplo: optionname|otheroption|..., la opción se restablecerá a sus valores predeterminados.",
        "apihelp-options-param-optionname": "El nombre de la opción que debe establecerse en el valor dado por <var>$1optionvalue</var>.",
-       "apihelp-options-param-optionvalue": "El valor de la opción especificada por <var>$1optionname</var>, puede contener barras verticales.",
+       "apihelp-options-param-optionvalue": "El valor de la opción especificada por <var>$1optionname</var>.",
        "apihelp-options-example-reset": "Restablecer todas las preferencias",
        "apihelp-options-example-change": "Cambiar las preferencias <kbd>skin</kbd> y <kbd>hideminor</kbd>.",
        "apihelp-options-example-complex": "Restablecer todas las preferencias y establecer <kbd>skin</kbd> y <kbd>nickname</kbd>.",
        "apihelp-query+alldeletedrevisions-param-user": "Listar solo las revisiones de este usuario.",
        "apihelp-query+alldeletedrevisions-param-excludeuser": "No listar las revisiones de este usuario.",
        "apihelp-query+alldeletedrevisions-param-namespace": "Listar solo las páginas en este espacio de nombres.",
+       "apihelp-query+alldeletedrevisions-param-generatetitles": "Cuando se utiliza como generador, generar títulos en lugar de identificadores de revisión.",
        "apihelp-query+alldeletedrevisions-example-user": "Listar las últimas 50 contribuciones borradas del usuario <kbd>Example</kbd>.",
        "apihelp-query+alldeletedrevisions-example-ns-main": "Listar las primeras 50 revisiones borradas en el espacio de nombres principal.",
        "apihelp-query+allfileusages-description": "Listar todos los usos del archivo, incluyendo los que no existen.",
        "apihelp-query+alltransclusions-param-prefix": "Buscar todos los títulos transcluidos que comiencen con este valor.",
        "apihelp-query+alltransclusions-param-prop": "Qué piezas de información incluir:",
        "apihelp-query+alltransclusions-paramvalue-prop-title": "Añade el título de la transclusión.",
+       "apihelp-query+alltransclusions-param-namespace": "El espacio de nombres que enumerar.",
        "apihelp-query+alltransclusions-param-limit": "Número de elementos que se desea obtener.",
+       "apihelp-query+alltransclusions-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+alltransclusions-example-unique": "Listar títulos transcluidos de forma única.",
        "apihelp-query+alltransclusions-example-unique-generator": "Obtiene todos los títulos transcluidos, marcando los que faltan.",
        "apihelp-query+alltransclusions-example-generator": "Obtiene las páginas que contienen las transclusiones.",
        "apihelp-query+allusers-description": "Enumerar todos los usuarios registrados.",
        "apihelp-query+allusers-param-prefix": "Buscar todos los usuarios que empiecen con este valor.",
+       "apihelp-query+allusers-param-dir": "Dirección de ordenamiento.",
        "apihelp-query+allusers-param-group": "Incluir solo usuarios en los grupos dados.",
+       "apihelp-query+allusers-param-excludegroup": "Excluir a los usuarios en estos grupos",
+       "apihelp-query+allusers-param-rights": "Sólo se incluyen a los usuarios con los derechos cedidos. No incluye los derechos concedidos por la implícita o auto-promoverse grupos como *, usuario, o autoconfirmed.",
        "apihelp-query+allusers-param-prop": "Qué piezas de información incluir:",
        "apihelp-query+allusers-paramvalue-prop-blockinfo": "Añade información sobre un bloque actual al usuario.",
        "apihelp-query+allusers-paramvalue-prop-groups": "Lista los grupos a los que el usuario pertenece. Esto utiliza más recursos del servidor y puede devolver menos resultados que el límite.",
+       "apihelp-query+allusers-paramvalue-prop-implicitgroups": "Lista todos los grupos el usuario es automáticamente en.",
        "apihelp-query+allusers-paramvalue-prop-rights": "Lista los permisos que tiene el usuario.",
        "apihelp-query+allusers-paramvalue-prop-editcount": "Añade el número de ediciones del usuario.",
        "apihelp-query+allusers-paramvalue-prop-registration": "Añade la marca de tiempo del momento en que el usuario se registró, si está disponible (puede estar en blanco).",
+       "apihelp-query+allusers-paramvalue-prop-centralids": "Añade el central IDs y estado de anexo para el usuario.",
        "apihelp-query+allusers-param-limit": "Cuántos nombres de usuario se devolverán.",
+       "apihelp-query+allusers-param-witheditsonly": "Mostrar solo los usuarios que han realizado ediciones.",
        "apihelp-query+allusers-param-activeusers": "Solo listar usuarios activos en {{PLURAL:$1|el último día|los $1 últimos días}}.",
+       "apihelp-query+allusers-param-attachedwiki": "Con <kbd>$1prop=centralids</kbd>, indicar también si el usuario está conectado con el wiki identificado por el ID.",
        "apihelp-query+allusers-example-Y": "Listar usuarios que empiecen por <kbd>Y</kbd>.",
+       "apihelp-query+authmanagerinfo-description": "Recuperar información sobre el estado de autenticación actual.",
        "apihelp-query+authmanagerinfo-example-login": "Captura de las solicitudes que puede ser utilizadas al comienzo de inicio de sesión.",
        "apihelp-query+backlinks-description": "Encuentra todas las páginas que enlazan a la página dada.",
        "apihelp-query+backlinks-param-pageid": "Identificador de página que buscar. No puede usarse junto con <var>$1title</var>",
+       "apihelp-query+backlinks-param-namespace": "El espacio de nombres que enumerar.",
+       "apihelp-query+backlinks-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+backlinks-param-filterredir": "Cómo filtrar redirecciones. Si se establece a <kbd>nonredirects</kbd> cuando está activo <var>$1redirect</var>, esto sólo se aplica al segundo nivel.",
        "apihelp-query+backlinks-param-limit": "Cuántas páginas en total se devolverán. Si está activo <var>$1redirect</var>, el límite aplica a cada nivel por separado (lo que significa que se pueden devolver hasta 2 * <var>$1limit</var> resultados).",
        "apihelp-query+backlinks-example-simple": "Mostrar enlaces a <kbd>Main page</kbd>.",
        "apihelp-query+backlinks-example-generator": "Obtener información acerca de las páginas enlazadas a <kbd>Main page</kbd>.",
        "apihelp-query+blocks-description": "Listar todos los usuarios y direcciones IP bloqueadas.",
+       "apihelp-query+blocks-param-start": "El sello de tiempo para comenzar la enumeración",
+       "apihelp-query+blocks-param-end": "El sello de tiempo para detener la enumeración",
+       "apihelp-query+blocks-param-ids": "Lista de bloquear IDs para listar (opcional).",
        "apihelp-query+blocks-param-users": "Lista de usuarios a buscar (opcional).",
        "apihelp-query+blocks-param-ip": "Obtiene todos los bloqueos que se aplican a esta dirección IP o intervalo CIDR, incluyendo bloqueos de intervalos. No se puede usar en conjunto con <var>$3users</var>. No se aceptan intervalos CIDR mayores que IPv4/$1 o IPv6/$2.",
+       "apihelp-query+blocks-param-limit": "El número máximo de filtros a listar.",
        "apihelp-query+blocks-param-prop": "Qué propiedades se obtendrán:",
+       "apihelp-query+blocks-paramvalue-prop-id": "Agrega el ID del bloque.",
+       "apihelp-query+blocks-paramvalue-prop-user": "Añade el nombre de usuario del usuario bloqueado.",
        "apihelp-query+blocks-paramvalue-prop-userid": "Añade el identificador del usuario bloqueado.",
+       "apihelp-query+blocks-paramvalue-prop-by": "Añade el nombre de usuario del bloqueo de usuario.",
+       "apihelp-query+blocks-paramvalue-prop-byid": "Añade el usuario ID del usuario bloqueador.",
        "apihelp-query+blocks-paramvalue-prop-timestamp": "Añade la fecha y hora de cuando se aplicó el bloque.",
+       "apihelp-query+blocks-paramvalue-prop-expiry": "Añade la marca de tiempo correspondiente a la expiración del bloqueo.",
        "apihelp-query+blocks-paramvalue-prop-reason": "Añade la razón dada para el bloqueo.",
+       "apihelp-query+blocks-paramvalue-prop-range": "Añade la gama de direcciones de IP afectó por el bloque.",
+       "apihelp-query+blocks-paramvalue-prop-flags": "Etiquetas la prohibición con (autoblock, anononly, etc.).",
        "apihelp-query+blocks-example-simple": "Listar bloques.",
        "apihelp-query+categories-param-prop": "Qué propiedades adicionales obtener para cada categoría:",
        "apihelp-query+categories-paramvalue-prop-timestamp": "Añade la marca de tiempo del momento en que se añadió la categoría.",
        "apihelp-query+categories-param-show": "Qué tipo de categorías mostrar.",
        "apihelp-query+categories-param-limit": "Cuántas categorías se devolverán.",
+       "apihelp-query+categories-param-dir": "La dirección en que ordenar la lista.",
+       "apihelp-query+categories-example-simple": "Obtener una lista de categorías a las que pertenece la página <kbd>Albert Einstein</kbd>.",
        "apihelp-query+categories-example-generator": "Obtener información acerca de todas las categorías utilizadas en la página <kbd>Albert Einstein</kbd>.",
        "apihelp-query+categoryinfo-description": "Devuelve información acerca de las categorías dadas.",
        "apihelp-query+categoryinfo-example-simple": "Obtener información acerca de <kbd>Category:Foo</kbd> y <kbd>Category:Bar</kbd>",
        "apihelp-query+deletedrevs-param-limit": "La cantidad máxima de revisiones que listar.",
        "apihelp-query+deletedrevs-example-mode3-talk": "Listar las primeras 50 páginas en el espacio de nombres {{ns:talk}} (modo 3).",
        "apihelp-query+disabled-description": "Se ha desactivado el módulo de consulta.",
+       "apihelp-query+duplicatefiles-param-dir": "La dirección en que ordenar la lista.",
+       "apihelp-query+duplicatefiles-param-localonly": "Buscar solo archivos en el repositorio local.",
        "apihelp-query+duplicatefiles-example-simple": "Buscar duplicados de [[:File:Alber Einstein Head.jpg]].",
        "apihelp-query+duplicatefiles-example-generated": "Buscar duplicados en todos los archivos.",
        "apihelp-query+embeddedin-description": "Encuentra todas las páginas que transcluyen el título dado.",
        "apihelp-query+embeddedin-param-title": "Título a buscar. No puede usarse en conjunto con $1pageid.",
+       "apihelp-query+embeddedin-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+embeddedin-param-filterredir": "Cómo filtrar las redirecciones.",
        "apihelp-query+embeddedin-param-limit": "Cuántas páginas se devolverán.",
        "apihelp-query+extlinks-param-limit": "Cuántos enlaces se devolverán.",
        "apihelp-query+exturlusage-param-prop": "Qué piezas de información incluir:",
        "apihelp-query+exturlusage-paramvalue-prop-ids": "Añade el identificado de la página.",
        "apihelp-query+exturlusage-paramvalue-prop-title": "Agrega el título y el identificador del espacio de nombres de la página.",
+       "apihelp-query+exturlusage-paramvalue-prop-url": "Añade el URL utilizado en la página.",
        "apihelp-query+exturlusage-param-protocol": "Protocolo del URL. Si está vacío y se establece <var>$1query</var>, el protocolo es <kbd>http</kbd>. Deja vacío esto y <var>$1query</var> para listar todos los enlaces externos.",
        "apihelp-query+exturlusage-param-limit": "Cuántas páginas se devolverán.",
        "apihelp-query+exturlusage-example-simple": "Mostrar páginas que enlacen con <kbd>http://www.mediawiki.org</kbd>.",
        "apihelp-query+filearchive-param-from": "El título de imagen para comenzar la enumeración",
        "apihelp-query+filearchive-param-to": "El título de imagen para detener la enumeración.",
        "apihelp-query+filearchive-param-prefix": "Buscar todos los títulos de las imágenes que comiencen con este valor.",
+       "apihelp-query+filearchive-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+filearchive-param-prop": "Qué información de imagen se obtendrá:",
        "apihelp-query+filearchive-paramvalue-prop-timestamp": "Añade la marca de tiempo de la versión subida.",
        "apihelp-query+filearchive-paramvalue-prop-user": "Agrega el usuario que subió la versión de la imagen.",
        "apihelp-query+imageinfo-example-dated": "Obtener información sobre las versiones de [[:File:Test.jpg]] a partir de 2008.",
        "apihelp-query+images-description": "Devuelve todos los archivos contenidos en las páginas dadas.",
        "apihelp-query+images-param-limit": "Cuántos archivos se devolverán.",
+       "apihelp-query+images-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+images-example-simple": "Obtener una lista de los archivos usados en la [[Main Page|Portada]].",
        "apihelp-query+imageusage-param-title": "Título a buscar. No puede usarse en conjunto con $1pageid.",
        "apihelp-query+imageusage-param-pageid": "ID de página a buscar. No puede usarse con $1title.",
        "apihelp-query+imageusage-param-namespace": "El espacio de nombres que enumerar.",
+       "apihelp-query+imageusage-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+imageusage-example-simple": "Mostrar las páginas que usan [[:File:Albert Einstein Head.jpg]].",
        "apihelp-query+imageusage-example-generator": "Obtener información sobre las páginas que empleen [[:File:Albert Einstein Head.jpg]].",
        "apihelp-query+info-description": "Obtener información básica de la página.",
        "apihelp-query+iwbacklinks-param-limit": "Cuántas páginas se devolverán.",
        "apihelp-query+iwbacklinks-param-prop": "Qué propiedades se obtendrán:",
        "apihelp-query+iwbacklinks-paramvalue-prop-iwtitle": "Añade el título del interwiki.",
+       "apihelp-query+iwbacklinks-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+iwbacklinks-example-simple": "Obtener las páginas enlazadas a [[wikibooks:Test]]",
        "apihelp-query+iwlinks-description": "Devuelve todos los enlaces interwiki de las páginas dadas.",
        "apihelp-query+iwlinks-param-prop": "Qué propiedades adicionales obtener para cada enlace interlingüe:",
        "apihelp-query+iwlinks-paramvalue-prop-url": "Añade el URL completo.",
        "apihelp-query+iwlinks-param-limit": "Cuántos enlaces interwiki se desea devolver.",
        "apihelp-query+iwlinks-param-prefix": "Devolver únicamente enlaces interwiki con este prefijo.",
+       "apihelp-query+iwlinks-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+langbacklinks-param-lang": "Idioma del enlace de idioma.",
        "apihelp-query+langbacklinks-param-limit": "Cuántas páginas en total se devolverán.",
        "apihelp-query+langbacklinks-param-prop": "Qué propiedades se obtendrán:",
        "apihelp-query+langbacklinks-paramvalue-prop-lllang": "Agrega el código de idioma del enlace de idioma.",
        "apihelp-query+langbacklinks-paramvalue-prop-lltitle": "Añade el título del enlace de idioma.",
+       "apihelp-query+langbacklinks-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+langbacklinks-example-simple": "Obtener las páginas enlazadas a [[:fr:Test]]",
        "apihelp-query+langbacklinks-example-generator": "Obtener información acerca de las páginas enlazadas a [[:fr:Test]].",
        "apihelp-query+langlinks-param-url": "Obtener la URL completa o no (no se puede usar con <var>$1prop</var>).",
        "apihelp-query+langlinks-param-prop": "Qué propiedades adicionales obtener para cada enlace interlingüe:",
        "apihelp-query+langlinks-paramvalue-prop-url": "Añade el URL completo.",
-       "apihelp-query+langlinks-paramvalue-prop-autonym": "Añade el nombre del idioma nativo.",
+       "apihelp-query+langlinks-paramvalue-prop-autonym": "Añade el nombre nativo del idioma.",
        "apihelp-query+langlinks-param-lang": "Devolver solo enlaces de idioma con este código de idioma.",
+       "apihelp-query+langlinks-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+links-param-limit": "Cuántos enlaces se devolverán.",
+       "apihelp-query+links-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+linkshere-param-prop": "Qué propiedades se obtendrán:",
        "apihelp-query+linkshere-paramvalue-prop-pageid": "Identificador de cada página.",
        "apihelp-query+linkshere-paramvalue-prop-title": "Título de cada página.",
        "apihelp-query+tags-paramvalue-prop-active": "Si la etiqueta aún se sigue aplicando.",
        "apihelp-query+templates-description": "Devuelve todas las páginas transcluidas en las páginas dadas.",
        "apihelp-query+templates-param-limit": "Cuántas plantillas se devolverán.",
+       "apihelp-query+templates-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+transcludedin-description": "Encuentra todas las páginas que transcluyan las páginas dadas.",
        "apihelp-query+transcludedin-param-prop": "Qué propiedades se obtendrán:",
        "apihelp-query+transcludedin-paramvalue-prop-pageid": "Identificador de cada página.",
        "apihelp-query+userinfo-paramvalue-prop-editcount": "Añade el número de ediciones del usuario actual.",
        "apihelp-query+userinfo-paramvalue-prop-ratelimits": "Lista todos los límites de velocidad aplicados al usuario actual.",
        "apihelp-query+userinfo-paramvalue-prop-realname": "Añade el nombre real del usuario.",
+       "apihelp-query+userinfo-paramvalue-prop-email": "Añade la dirección de correo electrónico del usuario y la fecha de autenticación por correo.",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "Añade la fecha de registro del usuario.",
        "apihelp-query+userinfo-example-simple": "Obtener información sobre el usuario actual.",
        "apihelp-query+userinfo-example-data": "Obtener información adicional sobre el usuario actual.",
        "apihelp-tag-example-rev": "Añadir la etiqueta <kbd>vandalism</kbd> al identificador de revisión 123 sin especificar un motivo",
        "apihelp-tag-example-log": "Eliminar la etiqueta <kbd>spam</kbd> de la entrada del registro con identificador 123 con el motivo <kbd>Wrongly applied</kbd>",
        "apihelp-unblock-description": "Desbloquear un usuario.",
-       "apihelp-unblock-param-user": "Nombre de usuario, dirección IP o rango de direcciones IP para desbloquear. No se puede utilizar junto con <var>$1id</var>.",
+       "apihelp-unblock-param-user": "Nombre de usuario, dirección IP o intervalo de direcciones IP para desbloquear. No se puede utilizar junto con <var>$1id</var>.",
        "apihelp-unblock-param-reason": "Motivo del desbloqueo.",
        "apihelp-unblock-example-id": "Desbloquear el bloqueo de ID #<kbd>105</kbd>",
        "apihelp-unblock-example-user": "Desbloquear al usuario <kbd>Bob</kbd> con el motivo <kbd>Sorry Bob</kbd>",
index 5f09064..be2f9a0 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "Subi",
                        "Sator",
-                       "An13sa"
+                       "An13sa",
+                       "Gorkaazk"
                ]
        },
        "apihelp-main-param-action": "Zein ekintza burutuko da.",
@@ -48,7 +49,7 @@
        "apihelp-login-param-name": "Erabiltzaile izena.",
        "apihelp-login-param-password": "Pasahitza.",
        "apihelp-login-param-domain": "Domeinua (hautazkoa).",
-       "apihelp-login-example-login": "Saioa hasi",
+       "apihelp-login-example-login": "Hasi saioa",
        "apihelp-move-description": "Orrialde bat mugitu",
        "apihelp-move-param-reason": "Berrizenpenaren arrazoia.",
        "apihelp-move-param-noredirect": "Birzuzenketarik ez sortu.",
index ef9d7d1..5d2f396 100644 (file)
@@ -37,6 +37,7 @@
        "apihelp-main-param-smaxage": "Fixer l’entête HTTP de contrôle de cache <code>s-maxage</code> à ce nombre de secondes. Les erreurs ne sont jamais mises en cache.",
        "apihelp-main-param-maxage": "Fixer l’entête HTTP de contrôle de cache <code>max-age</code> à ce nombre de secondes. Les erreurs ne sont jamais mises en cache.",
        "apihelp-main-param-assert": "Vérifier si l’utilisateur est connecté si positionné à <kbd>user</kbd>, ou s'il a le droit d'un utilisateur robot si positionné à <kbd>bot</kbd>.",
+       "apihelp-main-param-assertuser": "Vérifier que l’utilisateur actuel est l’utilisateur nommé.",
        "apihelp-main-param-requestid": "Toute valeur fournie ici sera incluse dans la réponse. Peut être utilisé pour distinguer des demandes.",
        "apihelp-main-param-servedby": "Inclure le nom d’hôte qui a renvoyé la requête dans les résultats.",
        "apihelp-main-param-curtimestamp": "Inclure l’horodatage actuel dans le résultat.",
@@ -49,7 +50,7 @@
        "apihelp-block-param-anononly": "Bloquer uniquement les utilisateurs anonymes (c’est-à-dire désactiver les modifications anonymes pour cette adresse IP).",
        "apihelp-block-param-nocreate": "Empêcher la création de compte.",
        "apihelp-block-param-autoblock": "Bloquer automatiquement la dernière adresse IP utilisée, et toute les adresses IP subséquentes depuis lesquelles ils ont essayé de se connecter.",
-       "apihelp-block-param-noemail": "Empêcher l’utilisateur d’envoyer des courriels via le wiki (nécessite le doit <code>blockemail</code>).",
+       "apihelp-block-param-noemail": "Empêcher l’utilisateur d’envoyer des courriels via le wiki (nécessite le droit <code>blockemail</code>).",
        "apihelp-block-param-hidename": "Masque le nom de l’utilisateur dans le journal des blocages (nécessite le droit <code>hideuser</code>).",
        "apihelp-block-param-allowusertalk": "Autoriser les utilisateurs à modifier leur propre page de discussion (dépend de <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
        "apihelp-block-param-reblock": "Si l’utilisateur est déjà bloqué, écraser le blocage existant.",
@@ -61,7 +62,7 @@
        "apihelp-checktoken-description": "Vérifier la validité d'un jeton de <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
        "apihelp-checktoken-param-type": "Type de jeton testé",
        "apihelp-checktoken-param-token": "Jeton à tester.",
-       "apihelp-checktoken-param-maxtokenage": "Temps maximum autorisé pour le jeton, en secondes",
+       "apihelp-checktoken-param-maxtokenage": "Temps maximum autorisé pour l'utilisation du jeton, en secondes",
        "apihelp-checktoken-example-simple": "Tester la validité d'un jeton de <kbd>csrf</kbd>.",
        "apihelp-clearhasmsg-description": "Efface le drapeau <code>hasmsg</code> pour l’utilisateur courant.",
        "apihelp-clearhasmsg-example-1": "Effacer le drapeau <code>hasmsg</code> pour l’utilisateur courant",
@@ -83,7 +84,7 @@
        "apihelp-createaccount-param-password": "Mot de passe (ignoré si <var>$1mailpassword</var> est défini).",
        "apihelp-createaccount-param-domain": "Domaine pour l’authentification externe (facultatif).",
        "apihelp-createaccount-param-token": "Jeton de création de compte obtenu à la première requête.",
-       "apihelp-createaccount-param-email": "Adresse de courriel de l’utilisateur (facultatif).",
+       "apihelp-createaccount-param-email": "Adresse courriel de l’utilisateur (facultatif).",
        "apihelp-createaccount-param-realname": "Vrai nom de l’utilisateur (facultatif).",
        "apihelp-createaccount-param-mailpassword": "S’il est fixé à une valeur quelconque, un mot de passe aléatoire sera envoyé par courriel à l’utilisateur.",
        "apihelp-createaccount-param-reason": "Motif facultatif de création du compte à mettre dans les journaux.",
        "apihelp-edit-param-tags": "Modifier les balises à appliquer à la version.",
        "apihelp-edit-param-minor": "Modification mineure.",
        "apihelp-edit-param-notminor": "Modification non mineure.",
-       "apihelp-edit-param-bot": "Marquer cette modification comme robot.",
+       "apihelp-edit-param-bot": "Marquer cette modification comme effectuée par un robot.",
        "apihelp-edit-param-basetimestamp": "Horodatage de la révision de base, utilisé pour détecter les conflits de modification. Peut être obtenu via [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
        "apihelp-edit-param-starttimestamp": "L'horodatage, lorsque le processus d'édition est démarré, est utilisé pour détecter les conflits de modification. Une valeur appropriée peut être obtenue en utilisant <var>[[Special:ApiHelp/main|curtimestamp]]</var> lors du démarrage du processus d'édition (par ex. en chargeant le contenu de la page à modifier).",
        "apihelp-edit-param-recreate": "Ignorer toutes les erreurs concernant la page \nqui a été supprimée entre-temps.",
        "apihelp-emailuser-param-text": "Corps du courriel.",
        "apihelp-emailuser-param-ccme": "M’envoyer une copie de ce courriel.",
        "apihelp-emailuser-example-email": "Envoyer un courriel à l’utilisateur <kbd>WikiSysop</kbd> avec le texte <kbd>Content</kbd>.",
-       "apihelp-expandtemplates-description": "Développe tous les modèles en wikitexte.",
+       "apihelp-expandtemplates-description": "Développe tous les modèles avec du wikitexte.",
        "apihelp-expandtemplates-param-title": "Titre de la page.",
        "apihelp-expandtemplates-param-text": "Wikitexte à convertir.",
        "apihelp-expandtemplates-param-revid": "ID de révision, pour <nowiki>{{REVISIONID}}</nowiki> et les variables semblables.",
        "apihelp-import-example-import": "Importer [[meta:Help:ParserFunctions]] vers l’espace de noms 100 avec tout l’historique.",
        "apihelp-linkaccount-description": "Lier un compte d’un fournisseur tiers à l’utilisateur actuel.",
        "apihelp-linkaccount-example-link": "Commencer le processus de liaison d’un compte depuis <kbd>Exemple</kbd>.",
-       "apihelp-login-description": "Se connecter et obtenir les cookies d’authentification.\n\nCette action ne devrait être utilisée qu’en lien avec [[Special:BotPasswords]] ; l’utiliser pour la connexion du compte principal est obsolète et peut échouer sans avertissement. Pour se connecter sans problème au compte principal, utiliser <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd>.",
-       "apihelp-login-description-nobotpasswords": "Se connecter et obtenir les cookies d’authentification.\n\nCette action est obsolète et peut échouer sans prévenir. Pour se connecter sans problème, utiliser <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd>.",
+       "apihelp-login-description": "Se connecter et obtenir les témoins d’authentification.\n\nCette action ne devrait être utilisée qu’en lien avec [[Special:BotPasswords]] ; l’utiliser pour la connexion du compte principal est désuet et peut échouer sans avertissement. Pour se connecter sans problème au compte principal, utiliser <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd>.",
+       "apihelp-login-description-nobotpasswords": "Se connecter et obtenir les témoins d’authentification.\n\nCette action est désuète et peut échouer sans prévenir. Pour se connecter sans problème, utiliser <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd>.",
        "apihelp-login-param-name": "Nom d’utilisateur.",
        "apihelp-login-param-password": "Mot de passe.",
        "apihelp-login-param-domain": "Domaine (facultatif).",
        "apihelp-options-description": "Modifier les préférences de l’utilisateur courant.\n\nSeules les options enregistrées dans le cœur ou dans l’une des extensions installées, ou les options avec des clés préfixées par <code>userjs-</code> (devant être utilisées dans les scripts utilisateur), peuvent être définies.",
        "apihelp-options-param-reset": "Réinitialise les préférences aux valeurs par défaut du site.",
        "apihelp-options-param-resetkinds": "Liste des types d’option à réinitialiser quand l’option <var>$1reset</var> est définie.",
-       "apihelp-options-param-change": "Liste des modifications, au format nom=valeur (par ex. skin=vector). La valeur ne peut pas contenir de caractère barre verticale. Si aucune valeur n’est fournie (pas même un signe égal), par ex., nomoption|autreoption|…, l’option sera réinitialisée à sa valeur par défaut.",
+       "apihelp-options-param-change": "Liste des modifications, au format nom=valeur (par ex. skin=vector). Si aucune valeur n’est fournie (pas même un signe égal), par ex., nomoption|autreoption|…, l’option sera réinitialisée à sa valeur par défaut. Pour toute valeur passée contenant une barre verticale (<kbd>|</kbd>), utiliser le [[Special:ApiHelp/main#main/datatypes|séparateur alternatif de valeur multiple]] pour que l'opération soit correcte.",
        "apihelp-options-param-optionname": "Un nom d’option qui doit être fixé à la valeur fournie par <var>$1optionvalue</var>.",
-       "apihelp-options-param-optionvalue": "La valeur d’une option spécifiée par <var>$1optionname</var> peut contenir des caractères barre verticale.",
+       "apihelp-options-param-optionvalue": "La valeur de l'option spécifiée par <var>$1optionname</var>.",
        "apihelp-options-example-reset": "Réinitialiser toutes les préférences",
        "apihelp-options-example-change": "Modifier les préférences <kbd>skin</kbd> et <kbd>hideminor</kbd>.",
        "apihelp-options-example-complex": "Réinitialiser toutes les préférences, puis définir <kbd>skin</kbd> et <kbd>nickname</kbd>.",
        "api-format-title": "Résultat de l’API de MediaWiki",
        "api-format-prettyprint-header": "Voici la représentation HTML du format $1. HTML est utile pour le débogage, mais inapproprié pour être utilisé dans une application.\n\nSpécifiez le paramètre <var>format</var> pour modifier le format de sortie. Pour voir la représentation non HTML du format $1, mettez <kbd>format=$2</kbd>.\n\nVoyez la [[mw:API|documentation complète]], ou l’[[Special:ApiHelp/main|aide de l’API]] pour plus d’information.",
        "api-format-prettyprint-header-only-html": "Ceci est une représentation HTML à des fins de déboguage, et n’est pas approprié à une utilisation applicative.\n\nVoir la [[mw:API|documentation complète]], ou l’[[Special:ApiHelp/main|aide de l’API]] pour plus d’information.",
+       "api-format-prettyprint-status": "Cette réponse serait retournée avec l'état HTTP $1 $2.",
        "api-pageset-param-titles": "Une liste des titres sur lesquels travailler.",
        "api-pageset-param-pageids": "Une liste des IDs de page sur lesquelles travailler.",
        "api-pageset-param-revids": "Une liste des IDs de révision sur lesquelles travailler.",
index 79e36cf..bd8d4a2 100644 (file)
@@ -10,7 +10,8 @@
                        "Toliño",
                        "Umherirrender",
                        "Amire80",
-                       "Macofe"
+                       "Macofe",
+                       "Hamilton Abreu"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentación]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discusión]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anuncios da API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Erros e solicitudes]\n</div>\n<strong>Estado:</strong> Tódalas funcionalidades mostradas nesta páxina deberían estar funcionanado, pero a API aínda está desenrolo, e pode ser modificada en calquera momento. Apúntese na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discusión mediawiki-api-announce] para estar informado acerca das actualizacións.\n\n<strong>Solicitudes incorrectas:</strong> Cando se envían solicitudes incorrectas á API, envíase unha cabeceira HTTP coa chave \"MediaWiki-API-Error\" e, a seguir, tanto o valor da cabeceira como o código de erro retornado serán definidos co mesmo valor. Para máis información, consulte [[mw:API:Errors_and_warnings|API: Erros e avisos]].\n\n<strong>Test:</strong> Para facilitar as probas das peticións da API, consulte [[Special:ApiSandbox]].",
@@ -20,6 +21,7 @@
        "apihelp-main-param-smaxage": "Fixar a cabeceira HTTP de control de caché <code>s-maxage</code> a esos segundos. Os erros nunca se gardan na caché.",
        "apihelp-main-param-maxage": "Fixar a cabeceira HTTP de control de caché <code>max-age</code> a esos segundos. Os erros nunca se gardan na caché.",
        "apihelp-main-param-assert": "Verificar se o usuario está conectado como <kbd>usuario</kbd> ou ten a marca de <kbd>bot</kbd>.",
+       "apihelp-main-param-assertuser": "Verificar que o usuario actual é o usuario nomeado.",
        "apihelp-main-param-requestid": "Calquera valor dado aquí será incluído na resposta. Pode usarse para distingir peticións.",
        "apihelp-main-param-servedby": "Inclúa o nome do servidor que servía a solicitude nos resultados.",
        "apihelp-main-param-curtimestamp": "Incluir a marca de tempo actual no resultado.",
        "apihelp-emailuser-param-text": "Corpo do correo.",
        "apihelp-emailuser-param-ccme": "Enviarme unha copia deste correo.",
        "apihelp-emailuser-example-email": "Enviar un correo electrónico ó usuario <kbd>WikiSysop</kbd> co texto <kbd>Content</kbd>.",
-       "apihelp-expandtemplates-description": "Expandir tódolos modelos en wikitexto.",
+       "apihelp-expandtemplates-description": "Expandir tódolos modelos dentro do wikitexto.",
        "apihelp-expandtemplates-param-title": "Título da páxina.",
        "apihelp-expandtemplates-param-text": "Sintaxis wiki a converter.",
        "apihelp-expandtemplates-param-revid": "ID de revisión, para <nowiki>{{REVISIONID}}</nowiki> e variables similares.",
        "apihelp-options-description": "Cambiar as preferencias do usuario actual.\n\nSó se poden cambiar opcións que estean rexistradas no núcleo ou nunha das extensións instaladas, ou aquelas opcións con claves prefixadas con <code>userjs-</code> (previstas para ser usadas por escrituras de usuario).",
        "apihelp-options-param-reset": "Reinicia as preferencias ás iniciais do sitio.",
        "apihelp-options-param-resetkinds": "Lista de tipos de opcións a reinicializar cando a opción <var>$1reset</var> está definida.",
-       "apihelp-options-param-change": "Lista de cambios, con formato nome=valor (p. ex. skin=vector). O valor non pode ter caracteres de barra vertical. Se non se indica un valor (sen u signo igual), p. ex. nomeopcion|outraopcion|..., a opción será gardada co seu valor por defecto.",
+       "apihelp-options-param-change": "Lista de cambios, con formato nome=valor (p. ex. skin=vector). Se non se da un valor (sen un símbolo de igual), p.ex. optionname|otheroption|..., a opción pasará ó valor por defecto. Para calquera valor que conteña o carácter (<kbd>|</kbd>), use o [[Special:ApiHelp/main#main/datatypes|separador alternativo para valores múltiples]] para unha operación correcta.",
        "apihelp-options-param-optionname": "O nome da opción que debe fixarse no valor dado por <var>$1optionvalue</var>.",
-       "apihelp-options-param-optionvalue": "O valor para a opción especificada por <var>$1optionname</var>. Pode conter barras verticais.",
+       "apihelp-options-param-optionvalue": "O valor para a opción especificada por <var>$1optionname</var>, pode conter barras verticais.",
        "apihelp-options-example-reset": "Restablecer todas as preferencias.",
        "apihelp-options-example-change": "Cambiar as preferencias <kbd>skin</kbd> and <kbd>hideminor</kbd>.",
        "apihelp-options-example-complex": "Restaurar todas as preferencias, logo fixar <kbd>skin</kbd> e <kbd>nickname</kbd>.",
        "apihelp-query+allfileusages-param-dir": "Dirección na cal listar.",
        "apihelp-query+allfileusages-example-B": "Lista títulos de ficheiro, incluíndo os   eliminados, cos IDs de páxina dos que proveñen, comezando en <kbd>B</kbd>.",
        "apihelp-query+allfileusages-example-unique": "Listar títulos únicos de ficheiros.",
-       "apihelp-query+allfileusages-example-unique-generator": "Obter todos os títulos de ficheiro, marcando os eliminados.",
+       "apihelp-query+allfileusages-example-unique-generator": "Obter todos os títulos de ficheiro, marcando os que faltan.",
        "apihelp-query+allfileusages-example-generator": "Obtén as páxinas que conteñen os ficheiros.",
        "apihelp-query+allimages-description": "Enumerar tódalas imaxes secuencialmente.",
        "apihelp-query+allimages-param-sort": "Propiedade pola que ordenar.",
        "apihelp-query+tags-paramvalue-prop-active": "Se a etiqueta aínda está a ser usada.",
        "apihelp-query+tags-example-simple": "Listar as marcas dispoñibles",
        "apihelp-query+templates-description": "Devolve todas as páxinas incluídas na páxina indicada.",
-       "apihelp-query+templates-param-namespace": "Mostrar modelos só neste espazo de nomes.",
+       "apihelp-query+templates-param-namespace": "Mostrar os modelos só nestes espazos de nomes.",
        "apihelp-query+templates-param-limit": "Número de modelos a devolver.",
        "apihelp-query+templates-param-templates": "Listar só eses modelos. Útil para verificar se unha páxina concreta ten un modelo determinado.",
        "apihelp-query+templates-param-dir": "Dirección na cal listar.",
        "api-format-title": "Resultado de API de MediaWiki",
        "api-format-prettyprint-header": "Esta é a representación HTML do formato $1. HTML é bó para depurar, pero non é axeitado para usar nunha aplicación.\n\nEspecifique o parámetro <var>format</var> para cambiar o formato de saída. Para ver a representación non-HTML do formato $1, fixe <kbd>format=$2</kbd>.\n\n\nRevise a [[mw:API|documentación completa]], ou a [[Special:ApiHelp/main|axuda da API]] para obter máis información.",
        "api-format-prettyprint-header-only-html": "Esta é unha representación HTML empregada para a depuración de erros, e non é axeitada para o uso de aplicacións.\n\nVexa a [[mw:API|documentación completa]], ou a [[Special:ApiHelp/main|axuda da API]] para máis información.",
+       "api-format-prettyprint-status": "Esta resposta será devolta co estado de HTTP $1 $2.",
        "api-pageset-param-titles": "Lista de títulos nos que traballar.",
        "api-pageset-param-pageids": "Lista de identificadores de páxina nos que traballar.",
        "api-pageset-param-revids": "Unha lista de IDs de modificacións sobre as que traballar.",
index dd0d07b..c1dd0fa 100644 (file)
@@ -21,6 +21,7 @@
        "apihelp-main-param-smaxage": "הגדרת כותרת בקרת מטמון HTTP‏ <code>s-maxage</code> למספר כזה של שניות.",
        "apihelp-main-param-maxage": "הגדרת כותרת בקרת מטמון HTTP‏ <code>max-age</code> למספר כזה של שניות.",
        "apihelp-main-param-assert": "לוודא שהמשתמש נכנס אם זה מוגדר ל־<kbd>user</kbd>, או שיש לו הרשאת בוט אם זה <kbd>bot</kbd>.",
+       "apihelp-main-param-assertuser": "לוודא שהמשתמש הנוכחי הוא המשתמש ששמו ניתן.",
        "apihelp-main-param-requestid": "כל ערך שיינתן כאן ייכלל בתשובה. אפשר להשתמש בזה כדי להבדיל בין בקשות.",
        "apihelp-main-param-servedby": "לכלול את שם המארח ששירת את הבקשה בתוצאות.",
        "apihelp-main-param-curtimestamp": "הכללת חותם־הזמן הנוכחי בתוצאה.",
        "apihelp-edit-param-tags": "אילו תגי שינוי להחיל על הגרסה.",
        "apihelp-edit-param-minor": "עריכה משנית.",
        "apihelp-edit-param-notminor": "שינוי לא משני.",
-       "apihelp-edit-param-bot": "סימון עריכה זו כבוט.",
+       "apihelp-edit-param-bot": "ס×\99×\9e×\95×\9f ×¢×¨×\99×\9b×\94 ×\96×\95 ×\9bער×\99×\9bת ×\91×\95×\98.",
        "apihelp-edit-param-basetimestamp": "חותם־זמן של גרסת הבסיס, משמש לזיהוי התנגשויות עריכה. אפשר לקבל אותו באמצעות [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
        "apihelp-edit-param-starttimestamp": "חותם־הזמן של תחילת תהליך העריכה, משמש לזיהוי התנגשויות. אפשר לקבל ערך מתאים באמצעות <var>[[Special:ApiHelp/main|curtimestamp]]</var> בעת תחילת תהליך העריכה (למשל בזמן טעינת תוכן הדף לעריכה).",
        "apihelp-edit-param-recreate": "לעקוב את כל הטעויות על כך שהדף נמחק בינתיים.",
        "apihelp-emailuser-param-text": "גוף הדואר.",
        "apihelp-emailuser-param-ccme": "שליחת עותק של הדואר הזה אליי.",
        "apihelp-emailuser-example-email": "שליחת דוא\"ל למשתמש <kbd>WikiSysop</kbd> עם הטקסט <kbd>Content</kbd>.",
-       "apihelp-expandtemplates-description": "הרחבת כל התבניות בקוד הוויקי.",
+       "apihelp-expandtemplates-description": "×\94ר×\97×\91ת ×\9b×\9c ×\94ת×\91× ×\99×\95ת ×\91ת×\95×\9a ×§×\95×\93 ×\94×\95×\95×\99ק×\99.",
        "apihelp-expandtemplates-param-title": "כותרת הדף.",
        "apihelp-expandtemplates-param-text": "איזה קוד ויקי להמיר.",
        "apihelp-expandtemplates-param-revid": "מזהה גרסה, עבור <nowiki>{{REVISIONID}}</nowiki> ומשתנים דומים.",
        "apihelp-options-description": "שינוי העדפות של המשתמש הנוכחי.\n\nרק אפשרויות שמוגדרות בליבה או באחת מההרחבות המותקנות, או אפשרויות עם מפתחות עם התחילית \"<code dir=\"ltr\">userjs-</code>\" (שמיועדות לשימוש תסריטי משתמשים) יכולות להיות מוגדרות.",
        "apihelp-options-param-reset": "אתחול ההעדפות לבררות המחדל של האתר.",
        "apihelp-options-param-resetkinds": "רשימת סוגי אפשרויות לאתחל כאשר מוגדרת האפשרות <var>$1reset</var>.",
-       "apihelp-options-param-change": "רש×\99×\9eת ×©×\99× ×\95×\99×\99×\9d, ×\91תס×\93×\99ר name=value (×\9c×\9eש×\9c skin=vector). ×\94ער×\9a ×\90×\99× ×\95 ×\99×\9b×\95×\9c ×\9c×\94×\9b×\99×\9c ×ª×\95×\95×\99 ×\9eק×\9c (|). ×\90×\9d ×\9c×\90 × ×\99ת×\9f ×¢×¨×\9a, ×\90פ×\99×\9c×\95 ×\9c×\90 ×¡×\99×\9e×\9f ×©×\95×\95×\94, ×\9c×\9eש×\9c optionname|otheroption|...â\80\8e, ×\94×\90פשר×\95ת ×ª×\90×\95פס ×\9cער×\9a ×\91ררת ×\94×\9e×\97×\93×\9c ×©×\9cה.",
+       "apihelp-options-param-change": "רש×\99×\9eת ×©×\99× ×\95×\99×\99×\9d, ×\91תס×\93×\99ר name=value (×\9c×\9eש×\9c skin=vector). ×\90×\9d ×\9c×\90 × ×\99ת×\9f ×¢×¨×\9a, ×\90פ×\99×\9c×\95 ×\9c×\90 ×¡×\99×\9e×\9f ×©×\95×\95×\94, ×\9c×\9eש×\9c optionname|otheroption|...â\80\8e, ×\94×\90פשר×\95ת ×ª×\90×\95פס ×\9cער×\9a ×\91ררת ×\94×\9e×\97×\93×\9c ×©×\9c×\94. ×\90×\9d ×¢×¨×\9a ×\9e×\95×¢×\91ר ×\9b×\9cש×\94×\95 ×\9e×\9b×\99×\9c ×\90ת ×ª×\95 ×\94×\9eק×\9c (<kbd>|</kbd>), ×\99ש ×\9c×\94שת×\9eש ×\91[[Special:ApiHelp/main#main/datatypes|×\9eפר×\99×\93 ×¢×¨×\9b×\99×\9d ×\9eר×\95×\91×\99×\9d ×\97×\9c×\95פ×\99]] ×\91ש×\91×\99×\9c ×¤×¢×\95×\9c×\94 × ×\9b×\95× ה.",
        "apihelp-options-param-optionname": "שם האפשרות שצריך להגדיר לערך שניתן ב־<var>$1optionvalue</var>.",
-       "apihelp-options-param-optionvalue": "ערך האפשרות שצוין ב־<var>$1optionname</var>, יכול להכיל תווי מקל.",
+       "apihelp-options-param-optionvalue": "ערך האפשרות שצוין ב־<var>$1optionname</var>.",
        "apihelp-options-example-reset": "אתחול כל ההעדפות.",
        "apihelp-options-example-change": "לשנות את ההעדפות <kbd>skin</kbd> ו־<kbd>hideminor</kbd>.",
        "apihelp-options-example-complex": "לאתחל את כל ההעדפות ואז להגדיר את <kbd>skin</kbd> ואת <kbd>nickname</kbd>.",
        "api-format-title": "תוצאה של API של מדיה־ויקי",
        "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]] למידע נוסף.",
        "api-format-prettyprint-header-only-html": "זה ייצוג HTML שמיועד לניפוי שגיאות ואינו מתאים לשימוש ביישומים.\n\nר' את [[mw:API|התיעוד המלא]] או את [[Special:ApiHelp/main|העזרה של API]] למידע נוסף.",
+       "api-format-prettyprint-status": "התשובה הזאת הייתה מוחזרת עם סטטוס ה־HTTP מס' $1 עם הטקסט $2.",
        "api-pageset-param-titles": "רשימת כותרות.",
        "api-pageset-param-pageids": "רשימת מזהי דף לעבוד עליהם.",
        "api-pageset-param-revids": "רשימת מזהי גרסה לעבוד עליהם.",
index d93dc23..b585885 100644 (file)
@@ -4,7 +4,8 @@
                        "WongKentir",
                        "Beeyan",
                        "Rachmat.Wahidi",
-                       "Kenrick95"
+                       "Kenrick95",
+                       "Presidenvolksraad"
                ]
        },
        "apihelp-main-param-action": "Tindakan manakah yang akan dilakukan.",
@@ -94,5 +95,6 @@
        "apihelp-login-example-login": "Masuk log.",
        "apihelp-query+prefixsearch-param-profile": "Cari profil untuk digunakan.",
        "apihelp-query+search-param-qiprofile": "Meminta profil independen untuk digunakan (berefek pada algoritma peringkat).",
-       "apihelp-revisiondelete-param-ids": "Penanda untuk perubahan yang akan dihapus"
+       "apihelp-revisiondelete-param-ids": "Penanda untuk perubahan yang akan dihapus",
+       "api-format-prettyprint-status": "Tanggapan ini akan dikembalikan dengan status $1 $2 HTTP."
 }
index 9786543..48521a1 100644 (file)
@@ -90,7 +90,7 @@
        "apihelp-edit-param-tags": "Cambia i tag da applicare alla revisione.",
        "apihelp-edit-param-minor": "Modifica minore.",
        "apihelp-edit-param-notminor": "Modifica non minore.",
-       "apihelp-edit-param-bot": "Contrassegna questa modifica come bot.",
+       "apihelp-edit-param-bot": "Contrassegna questa modifica come eseguita da un bot.",
        "apihelp-edit-param-createonly": "Non modificare la pagina se già esiste.",
        "apihelp-edit-param-nocreate": "Genera un errore se la pagina non esiste.",
        "apihelp-edit-param-watch": "Aggiunge la pagina agli osservati speciali dell'utente attuale.",
        "apihelp-emailuser-param-text": "Testo dell'e-mail.",
        "apihelp-emailuser-param-ccme": "Mandami una copia di questa mail.",
        "apihelp-emailuser-example-email": "Manda una e-mail all'utente <kbd>WikiSysop</kbd> con il testo <kbd>Content</kbd>.",
-       "apihelp-expandtemplates-description": "Espandi tutti i template nel wikitesto.",
+       "apihelp-expandtemplates-description": "Espande tutti i template all'interno del wikitesto.",
        "apihelp-expandtemplates-param-title": "Titolo della pagina.",
        "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-opensearch-param-suggest": "Non fare nulla se <var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> è falso.",
        "apihelp-opensearch-param-format": "Il formato dell'output.",
        "apihelp-opensearch-example-te": "Trova le pagine che iniziano con <kbd>Te</kbd>.",
+       "apihelp-options-param-optionvalue": "Il valore per l'opzione specificata da <var>$1optionname</var>.",
        "apihelp-options-example-reset": "Reimposta tutte le preferenze.",
        "apihelp-paraminfo-description": "Ottieni informazioni sui moduli API.",
        "apihelp-paraminfo-param-helpformat": "Formato delle stringhe di aiuto.",
index f3beff6..d9d079b 100644 (file)
@@ -9,7 +9,9 @@
                        "Otokoume",
                        "Sujiniku",
                        "Macofe",
-                       "Suchichi02"
+                       "Suchichi02",
+                       "Kkairri",
+                       "ネイ"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|説明文書]]\n* [[mw:API: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/ the mediawiki-api-announce メーリングリスト]に参加してください。\n\n<strong>誤ったリクエスト:</strong> 誤ったリクエストが API に送られた場合、\"MediaWiki-API-Error\" HTTP ヘッダーが送信され、そのヘッダーの値と送り返されるエラーコードは同じ値にセットされます。より詳しい情報は [[mw:API:Errors_and_warnings|API: Errors and warnings]] を参照してください。\n\n<strong>テスト:</strong> API のリクエストのテストは、[[Special:ApiSandbox]]で簡単に行えます。",
@@ -85,7 +87,7 @@
        "apihelp-edit-param-tags": "この版に適用する変更タグ。",
        "apihelp-edit-param-minor": "細部の編集",
        "apihelp-edit-param-notminor": "細部の編集ではない。",
-       "apihelp-edit-param-bot": "この編集をボットとしてマークする。",
+       "apihelp-edit-param-bot": "ã\81\93ã\81®ç·¨é\9b\86ã\82\92ã\83\9cã\83\83ã\83\88ã\81®ç·¨é\9b\86ã\81¨ã\81\97ã\81¦ã\83\9eã\83¼ã\82¯ã\81\99ã\82\8bã\80\82",
        "apihelp-edit-param-basetimestamp": "編集前の版のタイムスタンプ。編集競合を検出するために使用されます。\n[[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]] で取得できます。",
        "apihelp-edit-param-starttimestamp": "編集作業を開始したときのタイムスタンプ。編集競合を検出するために使用されます。適切な値は <var>[[Special:ApiHelp/main|curtimestamp]]</var> を使用して編集作業を開始するとき (たとえば、編集するページの本文を読み込んだとき) に取得できます。",
        "apihelp-edit-param-createonly": "すでにそのページが存在する場合は編集を行いません。",
        "apihelp-opensearch-example-te": "<kbd>Te</kbd> から始まるページを検索する。",
        "apihelp-options-param-reset": "個人設定をサイトの既定値にリセットする。",
        "apihelp-options-param-resetkinds": "<var>$1reset</var> が設定されている場合、リセットする設定項目の種類のリスト。",
-       "apihelp-options-param-change": "名前=値 の形式 (例えば skin=vector) で整形された変更のリスト。値はパイプ文字を含むことができません。optionname|otheroption|... のように値が与えられない (イコール記号すら無い) 場合、設定は既定値にリセットされます。",
+       "apihelp-options-param-change": "名前=値 の形式 (例えば skin=vector) で整形された変更のリスト。optionname|otheroption|... のように値が与えられなかった (イコール記号すら無い) 場合、設定は既定値にリセットされます。与えられた値がパイプ(<kbd>|</kbd>)を含む場合、[[Special:ApiHelp/main#main/datatypes|ほかのセパレーター]]をお使いください。",
        "apihelp-options-example-reset": "すべて初期設定に戻す。",
        "apihelp-options-example-change": "<kbd>skin</kbd> および <kbd>hideminor</kbd> の個人設定を変更する。",
        "apihelp-options-example-complex": "すべての個人設定を初期化し、<kbd>skin</kbd> および <kbd> nickname </kbd> を設定する。",
        "apihelp-protect-description": "ページの保護レベルを変更します。",
        "apihelp-protect-param-title": "保護(解除)するページ名です。$1pageid とは同時に使用できません。",
        "apihelp-protect-param-pageid": "保護(解除)するページIDです。$1title とは同時に使用できません。",
-       "apihelp-protect-param-protections": "<kbd>action=level</kbd> の形式 (例えば、<kbd>edit=sysop</kbd>) で整形された、保護レベルの一覧。\n\n<strong>注意: </strong> ここに列挙されなかった操作の制限は解除されます。",
+       "apihelp-protect-param-protections": "<kbd>action=level</kbd> の形式 (例えば、<kbd>edit=sysop</kbd>) で整形された、保護レベルの一覧。レベル <kbd>all</kbd> は誰もが操作できる、言い換えると制限が掛かっていないことを意味します。\n\n<strong>注意: </strong> ここに列挙されなかった操作の制限は解除されます。",
        "apihelp-protect-param-expiry": "有効期限です。タイムスタンプがひとつだけ指定された場合は、それがすべての保護に適用されます。無期限の保護を行う場合は<kbd>infinite</kbd>, <kbd>indefinite</kbd>, <kbd>infinity</kbd>, または <kbd>never</kbd> を指定します。",
        "apihelp-protect-param-reason": "保護(解除)の理由。",
        "apihelp-protect-param-tags": "保護記録の項目に適用する変更タグ。",
        "apihelp-query+exturlusage-param-protocol": "URLのプロトコル。このパラメータが空であり、かつ<var>$1query</var> が設定されている場合, protocol は <kbd>http</kbd> となります。すべての外部リンクを一覧表示するためにはこのパラメータと <var>$1query</var> の両方を空にしてください。",
        "apihelp-query+exturlusage-param-query": "プロトコルを除いた検索文字列。[[Special:LinkSearch]] も参照してください。すべての外部リンクを一覧表示するには空欄にしてください。",
        "apihelp-query+exturlusage-param-namespace": "列挙するページ名前空間。",
+       "apihelp-query+exturlusage-param-limit": "返すページの数。",
        "apihelp-query+exturlusage-example-simple": "<kbd>http://www.mediawiki.org</kbd> にリンクしているページを一覧表示する。",
        "apihelp-query+filearchive-description": "削除されたファイルをすべて順に列挙します。",
        "apihelp-query+filearchive-param-from": "列挙の始点となる画像のページ名。",
        "apihelp-query+fileusage-param-prop": "取得するプロパティ:",
        "apihelp-query+fileusage-paramvalue-prop-pageid": "各ページのページID。",
        "apihelp-query+fileusage-paramvalue-prop-title": "各ページのページ名。",
+       "apihelp-query+fileusage-paramvalue-prop-redirect": "ページがリダイレクトである場合マークします。",
+       "apihelp-query+fileusage-param-namespace": "この名前空間に含まれるページのみを一覧表示します。",
        "apihelp-query+fileusage-example-simple": "[[:File:Example.jpg]] を使用しているページの一覧を取得する。",
        "apihelp-query+fileusage-example-generator": "[[:File:Example.jpg]] を使用しているページの情報を取得する。",
        "apihelp-query+imageinfo-param-prop": "取得するファイル情報:",
        "apihelp-query+siteinfo-paramvalue-prop-general": "システム全体の情報。",
        "apihelp-query+siteinfo-paramvalue-prop-specialpagealiases": "特別ページの別名の一覧。",
        "apihelp-query+siteinfo-paramvalue-prop-magicwords": "マジックワードとこれらの別名の一覧。",
+       "apihelp-query+siteinfo-param-numberingroup": "利用者グループに属する利用者の数を一覧表示します。",
        "apihelp-query+siteinfo-example-simple": "サイト情報を取得する。",
        "apihelp-query+tags-description": "変更タグを一覧表示します。",
        "apihelp-query+tags-param-limit": "一覧表示するタグの最大数。",
        "apihelp-query+usercontribs-param-tag": "このタグが付与された版のみを一覧表示する。",
        "apihelp-query+usercontribs-param-toponly": "最新の版である変更のみを一覧表示する。",
        "apihelp-query+usercontribs-example-user": "利用者 <kbd>Example</kbd> の投稿記録を表示する。",
+       "apihelp-query+usercontribs-example-ipprefix": "<kbd>192.0.2.</kbd> から始まるすべてのIPアドレスからの投稿記録を表示する。",
+       "apihelp-query+userinfo-description": "現在の利用者に関する情報を取得します。",
        "apihelp-query+userinfo-param-prop": "どの情報を結果に含めるか:",
        "apihelp-query+userinfo-paramvalue-prop-realname": "利用者の本名を追加します。",
        "apihelp-query+userinfo-example-simple": "現在の利用者に関する情報を取得します。",
diff --git a/includes/api/i18n/ka.json b/includes/api/i18n/ka.json
new file mode 100644 (file)
index 0000000..a9bc686
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Irus"
+               ]
+       },
+       "apihelp-login-param-name": "მომხმარებლის სახელი",
+       "apihelp-login-param-password": "პაროლი",
+       "apihelp-login-param-domain": "ელ-ფოსტა (არასავალდებულო)",
+       "apihelp-login-example-login": "შესვლა"
+}
index 5ae6c87..d01abe5 100644 (file)
@@ -13,7 +13,8 @@
                        "Yearning",
                        "Priviet",
                        "Ykhwong",
-                       "Jonghaya"
+                       "Jonghaya",
+                       "Jerrykim306"
                ]
        },
        "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에 잘못된 요청이 전송되면 \"MediaWiki-API-Error\" 키가 포함된 HTTP 헤더가 전송되며 반환되는 헤더와 오류 코드의 값은 동일한 값으로 설정됩니다. 자세한 정보에 대해서는 [[mw:API:Errors_and_warnings|API:오류와 경고]]를 참조하십시오.\n\n<strong>테스트하기:</strong> API 요청 테스트를 용이하게 하려면, [[Special:ApiSandbox]]를 보십시오.",
@@ -88,7 +89,7 @@
        "apihelp-edit-param-tags": "이 판에 적용할 태그를 변경합니다.",
        "apihelp-edit-param-minor": "사소한 편집.",
        "apihelp-edit-param-notminor": "사소하지 않은 편집.",
-       "apihelp-edit-param-bot": "이 편집을 봇으로 표시.",
+       "apihelp-edit-param-bot": "이 편집을 봇 편집으로 표시.",
        "apihelp-edit-param-createonly": "이 페이지가 이미 존재하면 편집하지 않습니다.",
        "apihelp-edit-param-nocreate": "페이지가 존재하지 않으면 오류를 출력합니다.",
        "apihelp-edit-param-watch": "문서를 현재 사용자의 주시문서 목록에 추가합니다.",
        "apihelp-emailuser-param-text": "메일 본문.",
        "apihelp-emailuser-param-ccme": "자신에게 메일의 복사본을 보냅니다.",
        "apihelp-emailuser-example-email": "<kbd>WikiSysop</kbd> 사용자에게 텍스트 <kbd>Content</kbd>로 이메일을 보냅니다.",
-       "apihelp-expandtemplates-description": "모든 틀을 위키텍스트로 확장.",
+       "apihelp-expandtemplates-description": "위키텍스트 안에 모든 틀을 확장합니다.",
        "apihelp-expandtemplates-param-title": "문서 제목",
        "apihelp-expandtemplates-param-text": "변환할 위키텍스트.",
        "apihelp-expandtemplates-paramvalue-prop-wikitext": "확장된 위키텍스트.",
        "apihelp-feedwatchlist-param-feedformat": "피드 포맷.",
        "apihelp-feedwatchlist-example-default": "주시문서 목록 피드를 보여줍니다.",
        "apihelp-filerevert-description": "파일을 이전 판으로 되돌립니다.",
+       "apihelp-filerevert-param-comment": "업로드 댓글입니다.",
        "apihelp-filerevert-example-revert": "<kbd>Wiki.png</kbd>를 <kbd>2011-03-05T15:27:40Z</kbd> 판으로 되돌립니다.",
        "apihelp-help-description": "지정된 모듈의 도움말을 보여줍니다.",
        "apihelp-help-param-helpformat": "도움말 출력 포맷.",
        "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "판의 콘텐츠 모델 ID.",
        "apihelp-query+revisions+base-paramvalue-prop-content": "판의 텍스트.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "판의 태그.",
+       "apihelp-query+search-description": "전문 검색을 수행합니다.",
        "apihelp-query+search-param-qiprofile": "쿼리 독립적인 프로파일 사용(순위 알고리즘에 영향있음)",
        "apihelp-query+search-paramvalue-prop-size": "바이트 단위로 문서의 크기를 추가합니다.",
        "apihelp-query+search-paramvalue-prop-wordcount": "문서의 낱말 수를 추가합니다.",
index 041203e..47b79ab 100644 (file)
@@ -5,6 +5,7 @@
                        "Macofe"
                ]
        },
+       "apihelp-main-param-assertuser": "Iwwerpréifen ob den aktuelle Benotzer de Benotzer mat deem Numm ass.",
        "apihelp-main-param-curtimestamp": "Den aktuellen Zäitstempel an d'Resultat integréieren.",
        "apihelp-block-description": "E Benotzer spären.",
        "apihelp-block-param-user": "Benotzernumm, IP-Adress oder IP-Beräich deen Dir späre wëllt.",
@@ -30,7 +31,7 @@
        "apihelp-edit-param-text": "Säiteninhalt.",
        "apihelp-edit-param-minor": "Kleng Ännerung.",
        "apihelp-edit-param-notminor": "Keng kleng Ännerung",
-       "apihelp-edit-param-bot": "Dës Ännerung als Bot-Ännerung markéieren.",
+       "apihelp-edit-param-bot": "Dës Ännerung als eng Bot-Ännerung markéieren.",
        "apihelp-edit-param-createonly": "D'Säit net ännere wann et se scho gëtt.",
        "apihelp-edit-param-watch": "D'Säit op dem aktuelle Benotzer seng Iwwerwaachungslëscht dobäisetzen.",
        "apihelp-edit-example-edit": "Eng Säit änneren",
index 938c098..25012ba 100644 (file)
        "apihelp-block-description": "Blokuoti vartotoją.",
        "apihelp-block-param-reason": "Blokavimo priežastis.",
        "apihelp-block-param-nocreate": "Neleisti kurti paskyrų.",
+       "apihelp-compare-param-fromtitle": "Pirmas pavadinimas palyginimui.",
+       "apihelp-compare-param-fromid": "Pirmojo lyginamo puslapio ID.",
+       "apihelp-compare-param-totitle": "Antrasis pavadinimas palyginimui.",
+       "apihelp-compare-param-toid": "Antrojo lyginamo puslapio ID.",
+       "apihelp-createaccount-description": "Kurti naują vartotojo paskyrą.",
        "apihelp-createaccount-param-name": "Naudotojo vardas.",
+       "apihelp-createaccount-param-email": "Vartotojo el. pašto adresas (nebūtina).",
        "apihelp-createaccount-param-realname": "Vardas (nebūtina).",
        "apihelp-delete-description": "Ištrinti puslapį.",
+       "apihelp-delete-param-watch": "Pridėti puslapį prie dabartinio vartotojo stebimųjų sąrašo.",
+       "apihelp-delete-param-unwatch": "Pašalinti puslapį iš dabartinio vartotojo stebimųjų sąrašo.",
        "apihelp-delete-example-simple": "Ištrinti <kbd>Main Page</kbd>.",
        "apihelp-delete-example-reason": "Ištrinti <kbd>Main Page</kbd> su priežastimi <kbd>Preparing for move</kbd>.",
        "apihelp-disabled-description": "Šis modulis buvo išjungtas.",
        "apihelp-edit-description": "Kurti ir redaguoti puslapius.",
+       "apihelp-edit-param-title": "Redaguotino puslapio pavadinimas. Negali būti naudojamas kartu su <var>$1pageid</var>.",
+       "apihelp-edit-param-pageid": "Redaguotino puslapio ID. Negali būti naudojamas kartu su <var>$1title</var>.",
+       "apihelp-edit-param-section": "Sekcijos numeris. <kbd>0</kbd> - viršutinei sekcijai, <kbd>new</kbd> - naujai sekcijai.",
        "apihelp-edit-param-sectiontitle": "Naujo skyriaus pavadinimas.",
        "apihelp-edit-param-text": "Puslapio turinys.",
+       "apihelp-edit-param-summary": "Keitimo santrauka. Taip pat sekcijos pavadinimas, kai $1section=new ir $1sectiontitle yra nenustatytas.",
        "apihelp-edit-param-minor": "Smulkus pakeitimas.",
        "apihelp-edit-param-notminor": "Nesmulkus pakeitimas.",
+       "apihelp-edit-param-bot": "Pažymėti šį pakeitimą kaip roboto pakeitimą.",
        "apihelp-edit-param-createonly": "Neredaguoti puslapio jei jis jau egzistuoja.",
+       "apihelp-edit-param-nocreate": "Parodyti klaidą, jei puslapis neegzistuoja.",
        "apihelp-edit-param-watch": "Pridėti puslapį į dabartinio vartotojo stebimųjų sąrašą.",
        "apihelp-edit-param-unwatch": "Pašalinti puslapį iš dabartinio vartotojo stebimųjų sąrašo.",
        "apihelp-edit-param-redirect": "Automatiškai išspręsti peradresavimus.",
+       "apihelp-edit-param-contentmodel": "Naujam turiniui taikomas turinio modelis.",
        "apihelp-edit-example-edit": "Redaguoti puslapį.",
        "apihelp-emailuser-description": "Siųsti el. laišką naudotojui.",
        "apihelp-emailuser-param-target": "El. laiško gavėjas.",
+       "apihelp-emailuser-param-subject": "Temos antraštė.",
+       "apihelp-emailuser-param-ccme": "Siųsti šio laiško kopiją man.",
+       "apihelp-emailuser-example-email": "Siųsti el. pašto vartotojui <kbd>WikiSysop</kbd> su tekstu <kbd>Content</kbd>.",
        "apihelp-expandtemplates-param-title": "Puslapio pavadinimas.",
+       "apihelp-feedcontributions-description": "Gražina vartotojo įnašų srautą.",
        "apihelp-feedcontributions-param-feedformat": "Srauto formatas.",
        "apihelp-feedcontributions-param-year": "Nuo metų (ir anksčiau).",
        "apihelp-feedcontributions-param-month": "Nuo mėnesio (ir anksčiau).",
        "apihelp-feedcontributions-param-tagfilter": "Filtruoti įnašus, kurie turi šias žymes.",
        "apihelp-feedcontributions-param-deletedonly": "Rodyti tik ištrintus įnašus.",
+       "apihelp-feedcontributions-param-toponly": "Rodyti tik keitimus, kurie yra paskutiniai pakeitimai.",
+       "apihelp-feedcontributions-param-newonly": "Rodyti tik keitimus, kurie yra puslapio sukūrimai.",
        "apihelp-feedcontributions-param-hideminor": "Slėpti nedidelius pakeitimus.",
+       "apihelp-feedcontributions-param-showsizediff": "Rodyti dydžio skirtumą tarp keitimų.",
+       "apihelp-feedcontributions-example-simple": "Gražinti įnašus vartotojui <kbd>Example</kbd>.",
+       "apihelp-feedrecentchanges-description": "Gražina naujausių pakeitimų srautą.",
        "apihelp-feedrecentchanges-param-feedformat": "Srauto formatas.",
+       "apihelp-feedrecentchanges-param-limit": "Maksimalus grąžinamų rezultatų skaičius.",
        "apihelp-feedrecentchanges-param-from": "Rodyti pakeitimus nuo tada.",
        "apihelp-feedrecentchanges-param-hideminor": "Slėpti smulkius pakeitimus.",
        "apihelp-feedrecentchanges-param-hidebots": "Slėpti robotų pakeitimus.",
        "apihelp-feedrecentchanges-param-hideanons": "Slėpti vartotojų anonimų pakeitimus.",
        "apihelp-feedrecentchanges-param-hideliu": "Slėpti užsiregistravusių vartotojų pakeitimus.",
        "apihelp-feedrecentchanges-param-hidemyself": "Slėpti pakeitimus, atliktus dabartinio vartotojo.",
+       "apihelp-feedrecentchanges-param-hidecategorization": "Slėpti kategorijos narystės pakeitimus.",
        "apihelp-feedrecentchanges-param-tagfilter": "Filtruoti pagal žymę.",
        "apihelp-feedrecentchanges-param-target": "Rodyti tik keitimus puslapiuose, pasiekiamuose iš šio puslapio.",
+       "apihelp-feedrecentchanges-param-showlinkedto": "Vietoj to, rodyti pakeitimus puslapyje, susietame su pasirinktu puslapiu.",
+       "apihelp-feedrecentchanges-param-categories": "Rodyti pakeitimus tik puslapiuose, esančiuose visuose šiuose kategorijose.",
+       "apihelp-feedrecentchanges-param-categories_any": "Vietoj to, rodyti tik pakeitimus puslapiuse, esančiuose bet kurioje iš kategorijų.",
        "apihelp-feedrecentchanges-example-simple": "Parodyti naujausius keitimus.",
+       "apihelp-feedrecentchanges-example-30days": "Rodyti naujausius pakeitimus per 30 dienų.",
+       "apihelp-feedwatchlist-description": "Gražina stebimųjų sąrašo srautą.",
        "apihelp-feedwatchlist-param-feedformat": "Srauto formatas.",
+       "apihelp-feedwatchlist-example-default": "Rodyti stebimųjų sąrašo srautą.",
+       "apihelp-feedwatchlist-example-all6hrs": "Rodyti visus pakeitimus stebimuose puslapiuose per paskutines 6 valandas.",
        "apihelp-filerevert-param-comment": "Įkėlimo komentaras.",
+       "apihelp-help-description": "Rodyti pagalbą pasirinktiems moduliams.",
+       "apihelp-help-example-main": "Pagalba pagrindiniam moduliui.",
        "apihelp-help-example-recursive": "Visa pagalba viename puslapyje.",
        "apihelp-help-example-help": "Pačio pagalbos modulio pagalba.",
        "apihelp-imagerotate-description": "Pasukti viena ar daugiau paveikslėlių.",
        "apihelp-imagerotate-param-rotation": "Kiek laipsnių pasukti paveikslėlį pagal laikrodžio rodyklę.",
+       "apihelp-imagerotate-example-simple": "Pasukti <kbd>File:Example.png</kbd> <kbd>90</kbd> laipsnių.",
        "apihelp-imagerotate-example-generator": "Pasukti visus paveikslėlius <kbd>Category:Flip</kbd> <kbd>180</kbd> laipsnių.",
        "apihelp-import-param-xml": "XML failas įkeltas.",
        "apihelp-login-param-name": "Vartotojo vardas.",
        "apihelp-query+allcategories-param-limit": "Kiek kategorijų gražinti.",
        "apihelp-query+allcategories-paramvalue-prop-size": "Prideda puslapių kategorijoje skaičių.",
        "apihelp-query+alldeletedrevisions-example-user": "Sąrašas paskutinių 50 ištrintų indėlių pagal vartotoją\n<kbd>Pavyzdys</kbd>.",
+       "apihelp-query+allfileusages-paramvalue-prop-title": "Prideda failo pavadinimą.",
+       "apihelp-query+allfileusages-param-limit": "Kiek iš viso gražinti objektų.",
+       "apihelp-query+allfileusages-example-generator": "Gauti puslapius, kuriuose yra failai.",
+       "apihelp-query+allimages-param-limit": "Kiek iš viso gražinti paveikslėlių.",
+       "apihelp-query+allimages-example-B": "Rodyti failų sąrašą, pradedant raide <kbd>B</kbd>.",
+       "apihelp-query+allimages-example-recent": "Rodyti neseniai įkeltų failų sąrašą, panašu į [[Special:NewFiles]].",
+       "apihelp-query+allimages-example-mimetypes": "Rodyti sąrašą failų su MIME tipu <kbd>image/png</kbd> arba <kbd>image/gif</kbd>",
+       "apihelp-query+allimages-example-generator": "Rodyti informaciją apie 4 failus, pradedant raide <kbd>T</kbd>.",
+       "apihelp-query+alllinks-param-prop": "Kokią informaciją įtraukti:",
        "apihelp-query+alllinks-paramvalue-prop-title": "Prideda nuorodos pavadinimą.",
        "apihelp-query+alllinks-param-limit": "Kiek objektų iš viso gražinti.",
        "apihelp-query+allmessages-param-lang": "Gražinti pranešimus šia kalba.",
+       "apihelp-query+allmessages-param-from": "Gražinti pranešimus, pradedant šiuo pranešimu.",
+       "apihelp-query+allmessages-param-to": "Gražinti pranešimus, baigiant šiuo pranešimu.",
        "apihelp-query+allrevisions-param-namespace": "Rodyti puslapius tik šioje vardų srityje.",
+       "apihelp-query+mystashedfiles-param-limit": "Kiek gauti failų.",
+       "apihelp-query+allusers-param-prop": "Kokią informaciją įtraukti:",
+       "apihelp-query+allusers-paramvalue-prop-implicitgroups": "Nurodo visas grupes, kuriuose vartotojas yra automatiškai.",
+       "apihelp-query+allusers-paramvalue-prop-rights": "Nurodo teises, kurias turi vartotojas.",
+       "apihelp-query+allusers-paramvalue-prop-editcount": "Prideda vartotojo pakeitimų skaičių.",
+       "apihelp-query+allusers-paramvalue-prop-registration": "Prideda laiko žymą, nurodančia kada vartotojas prisiregistravo, jei prieinama (gali būti tuščias).",
+       "apihelp-query+allusers-param-limit": "Kiek viso gražinti vartotojų vardų.",
+       "apihelp-query+allusers-param-witheditsonly": "Nurodyti tik vartotojus, kurie atliko keitimus.",
+       "apihelp-query+allusers-param-activeusers": "Nurodyti tik vartotojus, kurie buvo aktyvus per {{PLURAL:$1|paskutinę dieną|paskutines $1 dienas}}.",
+       "apihelp-query+allusers-example-Y": "Nurodyti vartotojus, pradedant nuo <kbd>Y</kbd>.",
+       "apihelp-query+backlinks-description": "Rasti visus puslapius, kurie nukreipia į pateiktą puslapį.",
        "apihelp-query+backlinks-example-simple": "Rodyti nuorodas <kbd>Pagrindinis puslapis</kbd>.",
+       "apihelp-query+blocks-description": "Nurodyti visus užblokuotus vartotojus ir IP adresus.",
+       "apihelp-query+blocks-param-limit": "Maksimalus nurodomų blokavimų skaičius.",
        "apihelp-query+blocks-paramvalue-prop-id": "Prideda bloko ID.",
        "apihelp-query+blocks-paramvalue-prop-user": "Prideda užblokuoto vartotojo vardą.",
        "apihelp-query+blocks-paramvalue-prop-userid": "Prideda užblokuoto vartotojo ID.",
        "apihelp-query+blocks-paramvalue-prop-expiry": "Prideda blokavimo pabaigos laiko žymes.",
        "apihelp-query+blocks-paramvalue-prop-reason": "Prideda blokavimo priežastį.",
        "apihelp-query+blocks-paramvalue-prop-range": "Prideda blokavimo paveiktų IP adresų diapazoną.",
+       "apihelp-query+blocks-example-simple": "Nurodyti blokavimus.",
+       "apihelp-query+blocks-example-users": "Nurodo vartotojų <kbd>Alice</kbd> ir <kbd>Bob</kbd> blokavimus.",
+       "apihelp-query+categories-description": "Nurodo visas kategorijas, kurioms priklauso puslapiai.",
+       "apihelp-query+categories-param-show": "Kokias kategorijas rodyti.",
+       "apihelp-query+categories-param-limit": "Kiek kategorijų gražinti.",
+       "apihelp-query+categories-param-categories": "Nurodyti tik šias kategorijas. Naudinga, kai norima patikrinti ar tam tikras puslapis yra tam tikroje kategorijoje.",
+       "apihelp-query+categories-example-simple": "Gauti sąrašą kategorijų, kurioms priklauso puslapis <kbd>Albert Einstein</kbd>.",
+       "apihelp-query+categories-example-generator": "Gauti informaciją apie visas kategorijas, panaudotas <kbd>Albert Einstein</kbd> puslapyje.",
+       "apihelp-query+categoryinfo-description": "Gražina informaciją apie pateiktas kategorijas.",
+       "apihelp-query+categoryinfo-example-simple": "Gauti informaciją apie <kbd>Category:Foo</kbd> ir <kbd>Category:Bar</kbd>.",
+       "apihelp-query+categorymembers-description": "Nurodyti visus puslapius pateiktoje kategorijoje.",
+       "apihelp-query+categorymembers-paramvalue-prop-ids": "Prideda puslapio ID.",
+       "apihelp-query+categorymembers-param-limit": "Maksimalus grąžinamų puslapių skaičius.",
+       "apihelp-query+categorymembers-param-startsortkey": "Vietoj to, naudoti $1starthexsortkey",
+       "apihelp-query+categorymembers-param-endsortkey": "Vietoj to, naudoti $1endhexsortkey",
+       "apihelp-query+categorymembers-example-simple": "Gauti pirmus 10 puslapiu iš <kbd>Category:Physics</kbd>.",
+       "apihelp-query+categorymembers-example-generator": "Gauti puslapių informaciją apie pirmus 10 puslapių iš <kbd>Category:Physics</kbd>.",
+       "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|Režimas|Režimai}}: $2",
+       "apihelp-query+duplicatefiles-param-limit": "Kiek pasikartojančių failų gražinti.",
+       "apihelp-query+duplicatefiles-example-simple": "Ieškoti [[:File:Albert Einstein Head.jpg]] dublikatų.",
+       "apihelp-query+duplicatefiles-example-generated": "Ieškoti pasikartojančių visuose failuose.",
+       "apihelp-query+embeddedin-param-title": "Pavadinimas paieškai. Negali būti naudojamas kartu su $1pageid.",
+       "apihelp-query+embeddedin-param-pageid": "Puslapio ID paieškai. Negali būti naudojamas kartu su $1title.",
+       "apihelp-query+embeddedin-param-limit": "Kiek puslapių iš viso gražinti.",
+       "apihelp-query+extlinks-param-limit": "Kiek nuorodų grąžinti.",
+       "apihelp-query+extlinks-example-simple": "Gauti sąrašą <kbd>Main Page</kbd> išorinių nuorodų.",
+       "apihelp-query+exturlusage-param-prop": "Kokią informaciją įtraukti:",
+       "apihelp-query+exturlusage-paramvalue-prop-ids": "Prideda puslapio ID.",
+       "apihelp-query+exturlusage-paramvalue-prop-url": "Prideda URL, panaudota puslapyje.",
+       "apihelp-query+exturlusage-param-limit": "Kiek puslapių gražinti.",
+       "apihelp-query+exturlusage-example-simple": "Rodyti puslapius, nurodančius į <kbd>http://www.mediawiki.org</kbd>.",
+       "apihelp-query+filearchive-param-prop": "Kokią paveikslėlio informaciją gauti:",
+       "apihelp-query+filearchive-paramvalue-prop-timestamp": "Prideda laiko žymę įkeltai versijai.",
+       "apihelp-query+filearchive-paramvalue-prop-user": "Prideda vartotoją, kuris įkėlė paveikslėlio versiją.",
+       "apihelp-query+filearchive-paramvalue-prop-size": "Prideda paveikslėlio dydžio informaciją baitais ir aukštį, plotį ir puslapių skaičių (jei taikoma).",
+       "apihelp-query+filearchive-paramvalue-prop-mime": "Prideda paveikslėlio MIME.",
+       "apihelp-query+filearchive-paramvalue-prop-mediatype": "Prideda paveikslėlio medijos tipą.",
+       "apihelp-query+filearchive-example-simple": "Rodyti visų ištrintų failų sąrašą.",
+       "apihelp-query+fileusage-param-prop": "Kurias savybes gauti:",
+       "apihelp-query+fileusage-paramvalue-prop-pageid": "Kiekvieno puslapio ID.",
+       "apihelp-query+fileusage-paramvalue-prop-title": "Kiekvieno puslapio pavadinimas.",
+       "apihelp-query+fileusage-paramvalue-prop-redirect": "Pažymėti jei puslapis yra peradresavimas.",
+       "apihelp-query+fileusage-param-limit": "Kiek gražinti.",
+       "apihelp-query+fileusage-example-simple": "Gauti sąrašą puslapių, kurie naudoja [[:File:Example.jpg]].",
+       "apihelp-query+fileusage-example-generator": "Gauti informaciją apie puslapius, kurie naudoja [[:File:Example.jpg]].",
+       "apihelp-query+imageinfo-description": "Gražina failo informaciją ir įkėlimų istoriją.",
+       "apihelp-query+imageinfo-param-prop": "Kurią failo informaciją gauti:",
+       "apihelp-query+imageinfo-paramvalue-prop-timestamp": "Prideda laiko žymę įkeltai versijai.",
+       "apihelp-query+imageinfo-paramvalue-prop-user": "Prideda vartotoją, kuris įkėlę kiekvieną failo versiją.",
+       "apihelp-query+imageinfo-paramvalue-prop-userid": "Prideda vartotojo ID, kuris įkėlė kiekvieną failo versiją.",
+       "apihelp-query+imageinfo-paramvalue-prop-comment": "Versijos komentaras.",
+       "apihelp-query+imageinfo-paramvalue-prop-mime": "Prideda MIME failo tipą.",
+       "apihelp-query+imageinfo-paramvalue-prop-mediatype": "Prideda failo medijos tipą.",
+       "apihelp-query+imageinfo-param-urlheight": "Panašu į $1urlwidth.",
+       "apihelp-query+images-param-limit": "Kiek failų gražinti.",
+       "apihelp-query+images-param-images": "Nurodyti tik šiuos failus. Naudinga, kai norima patikrinti ar tam tikras puslapis turi tam tikrą failą.",
+       "apihelp-query+images-example-simple": "Gauti sąrašą failų, kurie naudojami [[Main Page]].",
+       "apihelp-query+images-example-generator": "Gauti informaciją apie failus, kurie yra naudojami [[Main Page]].",
+       "apihelp-query+imageusage-description": "Rasti visus puslapius, kurie naudoja duotą paveikslėlio pavadinimą.",
+       "apihelp-query+info-description": "Gauti pagrindinę puslapio informaciją.",
+       "apihelp-query+info-param-prop": "Kokias papildomas savybes gauti:",
+       "apihelp-query+info-paramvalue-prop-protection": "Nurodyti kiekvieno puslapio apsaugos lygį.",
+       "apihelp-query+info-paramvalue-prop-watched": "Kiekvieno puslapio stebėjimo būsena.",
+       "apihelp-query+info-paramvalue-prop-watchers": "Stebėtojų skaičius, jei leidžiama.",
+       "apihelp-query+info-paramvalue-prop-readable": "Ar vartotojas gali skaityti šį puslapį.",
+       "apihelp-query+info-paramvalue-prop-preload": "Pateikia tekstą, gražinta EditFormPreloadText.",
+       "apihelp-query+info-example-simple": "Gauti informaciją apie puslapį <kbd>Main Page</kbd>.",
+       "apihelp-query+info-example-protection": "Gauti bendrą ir apsaugos informaciją apie <kbd>Main Page</kbd> puslapį.",
+       "apihelp-query+iwbacklinks-param-prop": "Kurias savybes gauti:",
+       "apihelp-query+iwbacklinks-example-simple": "Gauti puslapius, nurodančius į [[wikibooks:Test]].",
+       "apihelp-query+iwbacklinks-example-generator": "Gauti informaciją apie puslapius, nurodančius į [[wikibooks:Test]].",
+       "apihelp-query+iwlinks-paramvalue-prop-url": "Prideda visą URL.",
+       "apihelp-query+langbacklinks-param-lang": "Kalbos nuorodos kalba.",
+       "apihelp-query+langbacklinks-param-limit": "Kiek puslapių iš viso gražinti.",
+       "apihelp-query+langbacklinks-param-prop": "Kurias savybes gauti:",
+       "apihelp-query+langbacklinks-example-simple": "Gauti puslapius, nurodančius į [[:fr:Test]].",
+       "apihelp-query+langbacklinks-example-generator": "Gauti informaciją apie puslapius, nurodančius į [[:fr:Test]].",
+       "apihelp-query+langlinks-param-url": "Ar gauti visą URL (negali būti naudojamas su <var>$1prop</var>).",
+       "apihelp-query+langlinks-paramvalue-prop-url": "Prideda visą URL.",
+       "apihelp-query+links-param-limit": "Kiek nuorodų grąžinti.",
+       "apihelp-query+links-example-simple": "Gauti nuorodas iš puslapio <kbd>Main Page</kbd>",
+       "apihelp-query+links-example-generator": "Gauti informaciją apie puslapių nuorodas puslapyje <kbd>Main Page</kbd>.",
+       "apihelp-query+linkshere-description": "Rasti visus puslapius, kurie nurodo į pateiktus puslapius.",
+       "apihelp-query+linkshere-param-prop": "Kurias savybes gauti:",
+       "apihelp-query+linkshere-paramvalue-prop-pageid": "Kiekvieno puslapio ID.",
+       "apihelp-query+linkshere-paramvalue-prop-title": "Kiekvieno puslapio pavadinimas.",
+       "apihelp-query+linkshere-paramvalue-prop-redirect": "Pažymėti jei puslapis yra peradresavimas.",
+       "apihelp-query+linkshere-param-limit": "Kiek gražinti.",
+       "apihelp-query+linkshere-param-show": "Rodyti tik elementus, atitinkančius šiuos kriterijus:\n;redirect:Rodyti tik nukreipimus.\n;!redirect:Rodyti tik ne nukreipimus.",
+       "apihelp-query+linkshere-example-simple": "Gauti sąrašą puslapių, kurie nurodo į [[Main Page]].",
+       "apihelp-query+linkshere-example-generator": "Gauti informaciją apie puslapius, kurie nurodo į [[Main Page]].",
+       "apihelp-query+logevents-description": "Gauti įvykius iš žurnalų.",
+       "apihelp-query+logevents-param-prop": "Kurias savybes gauti:",
+       "apihelp-query+logevents-paramvalue-prop-ids": "Prideda žurnalo įvykio ID.",
+       "apihelp-query+logevents-paramvalue-prop-type": "Prideda žurnalo įvykio tipą.",
        "apihelp-query+watchlist-paramvalue-type-external": "Išoriniai keitimai.",
        "apihelp-query+watchlist-paramvalue-type-new": "Puslapio sukūrimai.",
        "apihelp-stashedit-param-title": "Puslapio pavadinimas buvo redaguotas.",
        "apihelp-stashedit-param-sectiontitle": "Naujo skyriaus pavadinimas.",
-       "apihelp-stashedit-param-text": "Puslapio turinys."
+       "apihelp-stashedit-param-text": "Puslapio turinys.",
+       "api-format-prettyprint-status": "Šis atsakymas būtų gražintas su HTTP statusu $1 $2."
 }
index 03cb2b5..1580fcf 100644 (file)
        "apihelp-delete-description": "पान वगळा",
        "apihelp-edit-param-minor": "छोटे संपादन",
        "apihelp-edit-param-notminor": "छोटे नसलेले संपादन",
+       "apihelp-edit-param-bot": "या संपादनावर सांगकाम्याचे संपादन म्हणून खूण करा.",
        "apihelp-edit-example-edit": "पान संपादा",
+       "apihelp-expandtemplates-description": "विकिमजकूरात सर्व साच्यांचा विस्तार करा.",
+       "apihelp-feedcontributions-param-toponly": "केवळ नवीनतम आवर्तने असलेलीच संपादने दाखवा.",
        "apihelp-feedrecentchanges-param-categories": "या सर्व वर्गात असलेल्या पानांमधील बदलच फक्त  दाखवा.",
        "apihelp-feedrecentchanges-param-categories_any": "त्यापेक्षा,या कोणत्याही वर्गांमधील,पानांना झालेले बदलच फक्त दाखवा.",
        "apihelp-login-param-name": "सदस्य नाव.",
index 4b99320..ac2c8b7 100644 (file)
@@ -13,7 +13,8 @@
                        "Rangekill",
                        "Robin van der Vliet",
                        "Edoderoo",
-                       "Lemondoge"
+                       "Lemondoge",
+                       "Hex"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentatie]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api E-maillijst]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-aankondigingen]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bugs & verzoeken]\n</div>\n<strong>Status:</strong> Alle functies die op deze pagina worden weergegeven horen te werken. Aan de API wordt actief gewerkt, en deze kan gewijzigd worden. Abonneer u op  de [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ e-maillijst mediawiki-api-announce] voor meldingen over aanpassingen.\n\n<strong>Foutieve verzoeken:</strong> als de API foutieve verzoeken ontvangt, wordt er geantwoord met een HTTP-header met de sleutel \"MediaWiki-API-Error\" en daarna worden de waarde van de header en de foutcode op dezelfde waarde ingesteld. Zie [[mw:API:Errors_and_warnings|API: Errors and warnings]] voor meer informatie.\n\n<strong>Testen:</strong> u kunt [[Special:ApiSandbox|eenvoudig API-verzoeken testen]].",
@@ -60,7 +61,7 @@
        "apihelp-edit-param-tags": "Wijzigingslabels om aan de versie toe te voegen.",
        "apihelp-edit-param-minor": "Kleine bewerking.",
        "apihelp-edit-param-notminor": "Geen kleine bewerking.",
-       "apihelp-edit-param-bot": "Deze bewerking als bot markeren.",
+       "apihelp-edit-param-bot": "Deze bewerking markeren als gedaan door een robot.",
        "apihelp-edit-param-createonly": "De pagina niet bewerken als die al bestaat.",
        "apihelp-edit-param-nocreate": "Een foutmelding geven als de pagina niet bestaat.",
        "apihelp-edit-param-watch": "Voeg de pagina toe aan de volglijst van de huidige gebruiker.",
        "apihelp-options-description": "Voorkeuren van de huidige gebruiker wijzigen.\n\nAlleen opties die zijn geregistreerd in core of in een van de geïnstalleerde uitbreidingen, of opties met de toetsen aangeduid met <code>userjs-</code> (bedoeld om te worden gebruikt door gebruikersscripts), kunnen worden ingesteld.",
        "apihelp-options-param-reset": "Zet de voorkeuren terug naar de standaard van de website.",
        "apihelp-options-param-resetkinds": "Lijst van de optiestypes die opnieuw ingesteld worden wanneer de optie <var>$1reset</var> is ingesteld.",
-       "apihelp-options-param-change": "Lijst van wijzigingen, opgemaakt als <kbd>naam=waarde</kbd> (bijvoorbeeld <kbd>skin=vector</kbd>). De waarde kan geen sluistekens bevatten. Als er geen waarde wordt opgegeven (zelfs niet een is-gelijk teken), bijvoorbeeld, <kbd>optienaam|otheroption|...</kbd>, wordt de optie ingesteld op de standaardwaarde.",
+       "apihelp-options-param-change": "Lijst van wijzigingen, opgemaakt als <kbd>naam=waarde</kbd> (bijvoorbeeld <kbd>skin=vector</kbd>). Als er geen waarde wordt opgegeven (zelfs niet een is-gelijk teken), bijvoorbeeld <kbd>optienaam|andereoptie|...</kbd>, dan wordt de optie ingesteld op de standaardwaarde. Als een opgegeven waarde een sluisteken bevat (<kbd>|</kbd>), gebruik dan het [[Special:ApiHelp/main#main/datatypes|alternatieve scheidingsteken tussen meerdere waardes]] voor een juiste werking.",
        "apihelp-options-param-optionname": "De naam van de optie die moet worden ingesteld op de waarde gegeven door <var>$1optiewaarde</var>.",
-       "apihelp-options-param-optionvalue": "De waarde voor de optie opgegeven door <var>$1optienaam</var>, kan sluistekens (verticale streepjes) bevatten.",
+       "apihelp-options-param-optionvalue": "De waarde voor de optie opgegeven door <var>$1optionname</var>.",
        "apihelp-options-example-reset": "Alle voorkeuren opnieuw instellen.",
        "apihelp-options-example-change": "Voorkeuren wijzigen voor <kbd>skin</kbd> en <kbd>hideminor</kbd>.",
        "apihelp-parse-paramvalue-prop-categorieshtml": "Vraagt een HTML-versie van de categorieën op.",
diff --git a/includes/api/i18n/nso.json b/includes/api/i18n/nso.json
new file mode 100644 (file)
index 0000000..42b30bb
--- /dev/null
@@ -0,0 +1,9 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Mohau"
+               ]
+       },
+       "apihelp-createaccount-param-name": "Leina la mošomši.",
+       "apihelp-login-example-login": "Tsena."
+}
index 6e85779..7ecfebe 100644 (file)
@@ -28,7 +28,7 @@
        "apihelp-edit-param-text": "Contengut de la pagina.",
        "apihelp-edit-param-minor": "Modificacion menora.",
        "apihelp-edit-param-notminor": "Modificacion pas menora.",
-       "apihelp-edit-param-bot": "Marcar aquesta modificacion coma robòt.",
+       "apihelp-edit-param-bot": "Marcar aquesta modificacion coma efectuada per un robòt.",
        "apihelp-edit-example-edit": "Modificar una pagina",
        "apihelp-edit-example-prepend": "Prefixar una pagina per <kbd>_&#95;NOTOC_&#95;</kbd>",
        "apihelp-emailuser-description": "Mandar un corrièr electronic un l’utilizaire.",
index 0dfd5f5..4c31ca8 100644 (file)
                        "Darellur",
                        "The Polish",
                        "Matma Rex",
-                       "Sethakill"
+                       "Sethakill",
+                       "Woytecr"
                ]
        },
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Dokumentacja]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista dyskusyjna]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Ogłoszenia dotyczące API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Błędy i propozycje]\n</div>\n<strong>Stan:</strong> Wszystkie funkcje opisane na tej stronie powinny działać, ale API nadal jest aktywnie rozwijane i mogą się zmienić w dowolnym czasie. Subskrybuj [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ listę dyskusyjną mediawiki-api-announce], aby móc na bieżąco dowiadywać się o aktualizacjach.\n\n<strong>Błędne żądania:</strong> Gdy zostanie wysłane błędne żądanie do API, zostanie wysłany w odpowiedzi nagłówek HTTP z kluczem \"MediaWiki-API-Error\" i zarówno jego wartość jak i wartość kodu błędu wysłanego w odpowiedzi będą miały taką samą wartość. Aby uzyskać więcej informacji, zobacz [[mw:API:Errors_and_warnings|API: Błędy i ostrzeżenia]].\n\n<strong>Testowanie:</strong> Aby łatwo testować żądania API, zobacz [[Special:ApiSandbox]].",
        "apihelp-main-param-action": "Wybierz akcję do wykonania.",
        "apihelp-main-param-format": "Format danych wyjściowych.",
        "apihelp-main-param-maxlag": "Maksymalne opóźnienie mogą być używane kiedy MediaWiki jest zainstalowana w klastrze zreplikowanej bazy danych. By zapisać działania powodujące większe opóźnienie replikacji, ten parametr może wymusić czekanie u klienta, dopóki opóźnienie replikacji jest mniejsze niż określona wartość. W przypadku nadmiernego opóźnienia, kod błędu <samp>maxlag</samp> jest zwracany z wiadomością jak <samp>Oczekiwanie na $host: $lag sekund opóźnienia</samp>.<br />Zobacz [[mw:Manual:Maxlag_parameter|Podręcznik:Parametr Maxlag]] by uzyskać więcej informacji.",
+       "apihelp-main-param-smaxage": "Ustaw nagłówek HTTP kontrolujący pamięć podręczną <code>s-maxage</code> na taką ilość sekund. Błędy nie będą nigdy przechowywane w pamięci podręcznej.",
+       "apihelp-main-param-maxage": "Ustaw nagłówek HTTP kontrolujący pamięć podręczną <code>maxage</code> na taką ilość sekund. Błędy nie będą nigdy przechowywane w pamięci podręcznej.",
        "apihelp-main-param-assert": "Zweryfikuj, czy użytkownik jest zalogowany, jeżeli wybrano <kbd>user</kbd>, lub czy ma uprawnienia bota, jeżeli wybrano <kbd>bot</kbd>.",
+       "apihelp-main-param-assertuser": "Sprawdź, czy bieżący użytkownik posiada nazwę.",
+       "apihelp-main-param-requestid": "Każda wartość tu podana będzie dołączana do odpowiedzi. Może być użyta do rozróżniania żądań.",
+       "apihelp-main-param-servedby": "Dołącz do odpowiedzi nazwę hosta, który obsłużył żądanie.",
        "apihelp-main-param-curtimestamp": "Dołącz obecny znacznik czasu do wyniku.",
+       "apihelp-main-param-uselang": "Język, w którym mają być pokazywane tłumaczenia wiadomości. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> z <kbd>siprop=languages</kbd> zwróci listę języków lub ustaw jako <kbd>user</kbd>, aby pobrać z preferencji zalogowanego użytkownika lub <kbd>content</kbd>, aby wykorzystać język zawartości tej wiki.",
        "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-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>.",
-       "apihelp-block-example-user-complex": "Zablokuj użytkownika <kbd>Vandal</kbd> na zawsze za <kbd>Vandalism</kbd> i uniemożliwij utworzenie nowego konta oraz wysyłanie emaili.",
+       "apihelp-block-example-ip-simple": "Zablokuj IP <kbd>192.0.2.5</kbd> na 3 dni z powodem <kbd>First strike</kbd>.",
+       "apihelp-block-example-user-complex": "Zablokuj użytkownika <kbd>Vandal</kbd> na zawsze z powodem <kbd>Vandalism</kbd> i uniemożliw utworzenie nowego konta oraz wysyłanie emaili.",
+       "apihelp-changeauthenticationdata-description": "Zmień dane logowania bieżącego użytkownika.",
+       "apihelp-changeauthenticationdata-example-password": "Spróbuj zmienić hasło bieżącego użytkownika na <kbd>ExamplePassword</kbd>.",
+       "apihelp-checktoken-description": "Sprawdź poprawność tokenu z <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
        "apihelp-checktoken-param-type": "Typ tokenu do przetestowania.",
        "apihelp-checktoken-param-token": "Token do przetestowania.",
        "apihelp-checktoken-param-maxtokenage": "Maksymalny wiek tokenu, w sekundach.",
+       "apihelp-checktoken-example-simple": "Sprawdź poprawność tokenu <kbd>csrf</kbd>.",
+       "apihelp-clearhasmsg-description": "Czyści flagę <code>hasmsg</code> dla bieżącego użytkownika.",
+       "apihelp-clearhasmsg-example-1": "Wyczyść flagę <code>hasmsg</code> dla bieżącego użytkownika.",
        "apihelp-compare-param-fromtitle": "Pierwszy tytuł do porównania.",
        "apihelp-compare-param-fromid": "ID pierwszej strony do porównania.",
        "apihelp-compare-param-fromrev": "Pierwsza wersja do porównania.",
        "apihelp-delete-example-reason": "Usuń <kbd>Main Page</kbd> z powodem <kbd>Preparing for move</kbd>.",
        "apihelp-disabled-description": "Ten moduł został wyłączony.",
        "apihelp-edit-description": "Twórz i edytuj strony.",
+       "apihelp-edit-param-title": "Tytuł strony do edycji. Nie może być użyty równocześnie z <var>$1pageid</var>.",
+       "apihelp-edit-param-pageid": "ID strony do edycji. Nie może być używany równocześnie z <var>$1title</var>.",
        "apihelp-edit-param-section": "Numer sekcji. <kbd>0</kbd> dla górnej sekcji, <kbd>new</kbd> dla nowej sekcji.",
        "apihelp-edit-param-sectiontitle": "Tytuł nowej sekcji.",
        "apihelp-edit-param-text": "Zawartość strony.",
-       "apihelp-edit-param-tags": "Zmień tagi do przypisania do tej edycji.",
+       "apihelp-edit-param-summary": "Opis edycji. Także tytuł sekcji gdy użyto $1section=new, a nie ustawiono $1sectiontitle.",
+       "apihelp-edit-param-tags": "Znaczniki zmian do zastosowania w tej edycji.",
        "apihelp-edit-param-minor": "Drobna zmiana.",
-       "apihelp-edit-param-notminor": "Nie drobna zmiana.",
+       "apihelp-edit-param-notminor": "Nie oznaczaj tej zmiany jako drobną.",
        "apihelp-edit-param-bot": "Oznacz tę edycję jako edycję bota.",
+       "apihelp-edit-param-basetimestamp": "Czas wersji, która jest edytowana. Służy do wykrywania konfliktów edycji. Można pobrać poprzez [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
+       "apihelp-edit-param-starttimestamp": "Czas rozpoczęcia procesu edycji. Służy do wykrywania konfliktów edycji. Odpowiednia wartość może być pobrana za pomocą <var>[[Special:ApiHelp/main|curtimestamp]]</var> podczas rozpoczynania procesu edycji (np. podczas ładowania zawartości strony do edycji).",
+       "apihelp-edit-param-recreate": "Ignoruj błędy o usunięciu strony w międzyczasie.",
        "apihelp-edit-param-createonly": "Nie edytuj strony, jesli już istnieje.",
        "apihelp-edit-param-nocreate": "Zwróć błąd, jeśli strona nie istnieje.",
-       "apihelp-edit-param-watch": "Dodaj stronę do aktualnej listy obserwacji użytkownika.",
-       "apihelp-edit-param-unwatch": "Usuń stronę z aktualnej listy obserwacji użytkownika.",
+       "apihelp-edit-param-watch": "Dodaj stronę do listy obserwowanych bieżącego użytkownika.",
+       "apihelp-edit-param-unwatch": "Usuń stronę z listy obserwowanych bieżącego użytkownika.",
+       "apihelp-edit-param-md5": "Hash MD5 parametru $1text lub złączonych parametrów $1prependtext i $1appendtext. Jeżeli ustawiony, edycja nie zostanie zapisana dopóki hash nie będzie się zgadzać.",
+       "apihelp-edit-param-prependtext": "Tekst do dodania na początku strony. Zastępuje $1text.",
+       "apihelp-edit-param-appendtext": "Tekst do dodania na końcu strony. Zastępuje $1text.\n\nUżyj $1section=new zamiast tego parametru aby dodać nową sekcję.",
+       "apihelp-edit-param-undo": "Wycofaj tę wersję. Zastępuje $1text, $1prependtext i $1appendtext.",
+       "apihelp-edit-param-undoafter": "Wycofaj wszystkie wersje od $1undo do tej. Jeżeli nie ustawiono, wycofaj tylko jedną wersję.",
        "apihelp-edit-param-redirect": "Automatycznie rozwiązuj przekierowania.",
-       "apihelp-edit-example-edit": "Edytuj stronę",
+       "apihelp-edit-param-contentformat": "Format serializacji zawartości wprowadzonego tekstu.",
+       "apihelp-edit-param-contentmodel": "Model zawartości nowego tekstu.",
+       "apihelp-edit-param-token": "Token powinien być wysyłany jako ostatni parametr albo przynajmniej po parametrze $1text.",
+       "apihelp-edit-example-edit": "Edytuj stronę.",
+       "apihelp-edit-example-prepend": "Dopisz <kbd>_&#95;NOTOC_&#95;</kbd> na początku strony.",
        "apihelp-emailuser-description": "Wyślij e‐mail do użytkownika.",
        "apihelp-emailuser-param-target": "Użytkownik, do którego wysyłany jest e-mail.",
        "apihelp-emailuser-param-subject": "Nagłówek tematu.",
        "apihelp-mergehistory-description": "Łączenie historii edycji.",
        "apihelp-mergehistory-param-reason": "Powód łączenia historii.",
        "apihelp-move-description": "Przenieś stronę.",
+       "apihelp-move-param-to": "Tytuł na jaki zmienić nazwę strony.",
        "apihelp-move-param-reason": "Powód zmiany nazwy.",
        "apihelp-move-param-movetalk": "Zmień nazwę strony dyskusji, jeśli istnieje.",
        "apihelp-move-param-movesubpages": "Zmień nazwy podstron, jeśli możliwe.",
        "apihelp-move-param-noredirect": "Nie twórz przekierowania.",
+       "apihelp-move-param-watch": "Dodaj stronę i przekierowanie do listy obserwowanych bieżącego użytkownika.",
+       "apihelp-move-param-unwatch": "Usuń stronę i przekierowanie z listy obserwowanych bieżącego użytkownika.",
        "apihelp-move-param-ignorewarnings": "Ignoruj wszystkie ostrzeżenia.",
+       "apihelp-move-example-move": "Przenieś <kbd>Badtitle</kbd> na <kbd>Goodtitle</kbd> bez pozostawienia przekierowania.",
+       "apihelp-opensearch-description": "Przeszukaj wiki przy użyciu protokołu OpenSearch.",
        "apihelp-opensearch-param-search": "Wyszukaj tekst.",
        "apihelp-opensearch-param-limit": "Maksymalna liczba zwracanych wyników.",
        "apihelp-opensearch-param-namespace": "Przestrzenie nazw do przeszukania.",
+       "apihelp-opensearch-param-suggest": "Nie działa jeżeli <var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> ustawiono na false.",
+       "apihelp-opensearch-param-redirects": "Jak obsługiwać przekierowania:\n;return:Zwróć samo przekierowanie.\n;resolve:Zwróć stronę docelową. Może zwrócić mniej niż wyników określonych w $1limit.\nZ powodów historycznych, domyślnie jest to \"return\" dla $1format=json, a \"resolve\" dla innych formatów.",
        "apihelp-opensearch-param-format": "Format danych wyjściowych.",
+       "apihelp-opensearch-param-warningsaserror": "Jeżeli pojawią się ostrzeżenia związane z <kbd>format=json</kbd>, zwróć błąd API zamiast ignorowania ich.",
        "apihelp-opensearch-example-te": "Znajdź strony zaczynające się od <kbd>Te</kbd>.",
+       "apihelp-options-description": "Zmienia preferencje bieżącego użytkownika.\n\nMożna ustawiać tylko opcje zarejestrowane w rdzeniu, w zainstalowanych rozszerzeniach lub z kluczami o prefiksie <code>userjs-</code> (do wykorzystywania przez skrypty użytkowników).",
        "apihelp-options-param-reset": "Resetuj preferencje do domyślnych.",
+       "apihelp-options-param-resetkinds": "Lista typów opcji do zresetowania, jeżeli ustawiono opcję <var>$1reset</var>.",
+       "apihelp-options-param-change": "Lista zmian, w formacie nazwa=wartość (np. skin=vector).  Jeżeli nie zostanie podana wartość (nawet znak równości), np., optionname|otheroption|..., to opcja zostanie zresetowana do jej wartości domyślnej. Jeżeli jakakolwiek podawana wartość zawiera znak pionowej kreski (<kbd>|</kbd>), użyj [[Special:ApiHelp/main#main/datatypes|alternatywnego separatora wielu wartości]] aby operacja się powiodła.",
        "apihelp-options-param-optionname": "Nazwa opcji, która powinna być ustawiona na wartość <var>$1optionvalue</var>.",
-       "apihelp-options-param-optionvalue": "Wartość opcji, określona w <var>$1optionname</var>, może zawierać znaki pionowej kreski.",
+       "apihelp-options-param-optionvalue": "Wartość opcji, określona w <var>$1optionname</var>.",
        "apihelp-options-example-reset": "Resetuj wszystkie preferencje.",
+       "apihelp-options-example-change": "Zmień preferencje <kbd>skin</kbd> (skórka) i <kbd>hideminor</kbd> (ukryj drobne edycje).",
+       "apihelp-options-example-complex": "Zresetuj wszystkie preferencje, a następnie ustaw <kbd>skin</kbd> i <kbd>nickname</kbd>.",
        "apihelp-paraminfo-description": "Zdobądź informacje o modułach API.",
+       "apihelp-paraminfo-param-modules": "Lista nazw modułów (wartości parametrów <var>action</var> i <var>format</var> lub <kbd>main</kbd>). Można określić podmoduły za pomocą <kbd>+</kbd> lub wszystkie podmoduły, wpisując <kbd>+*</kbd>, lub wszystkie podmoduły rekursywnie <kbd>+**</kbd>.",
        "apihelp-paraminfo-param-helpformat": "Format tekstów pomocnicznych.",
+       "apihelp-paraminfo-param-querymodules": "Lista nazw modułów zapytań (wartość parametrów <var>prop</var>, <var>meta</var> lub <var>list</var>). Użyj <kbd>$1modules=query+foo</kbd> zamiast <kbd>$1querymodules=foo</kbd>.",
        "apihelp-parse-param-summary": "Powód do analizy.",
+       "apihelp-parse-param-prop": "Jakie porcje informacji otrzymać:",
+       "apihelp-parse-paramvalue-prop-text": "Przetworzony tekst z wikitekstu.",
+       "apihelp-parse-paramvalue-prop-langlinks": "Linki językowe z przetworzonego wikitekstu.",
+       "apihelp-parse-paramvalue-prop-categories": "Kategorie z przetworzonego wikitekstu.",
+       "apihelp-parse-paramvalue-prop-categorieshtml": "Wersja HTML listy kategorii.",
+       "apihelp-parse-paramvalue-prop-links": "Linki wewnętrzne z przetworzonego wikitekstu.",
+       "apihelp-parse-paramvalue-prop-templates": "Szablony z przetworzonego wikitekstu.",
+       "apihelp-parse-paramvalue-prop-images": "Zdjęcia z przetworzonego wikitekstu.",
+       "apihelp-parse-paramvalue-prop-externallinks": "Linki zewnętrzne z przetworzonego wikitekstu.",
+       "apihelp-parse-paramvalue-prop-sections": "Sekcje z przetworzonego wikitekstu.",
        "apihelp-parse-paramvalue-prop-wikitext": "Zwróć oryginalny wikitext, który został przeanalizowany.",
        "apihelp-parse-param-preview": "Analizuj w trybie podglądu.",
        "apihelp-parse-param-disabletoc": "Pomiń spis treści na wyjściu.",
        "apihelp-protect-example-protect": "Zabezpiecz stronę",
        "apihelp-protect-example-unprotect": "Odbezpiecz stronę ustawiając ograniczenia na <kbd>all</kbd> (czyli każdy może wykonać działanie).",
        "apihelp-protect-example-unprotect2": "Odbezpiecz stronę ustawiając brak ograniczeń.",
+       "apihelp-purge-description": "Wyczyść pamięć podręczną dla stron o podanych tytułach.\n\nWymaga wysłania jako żądanie POST jeżeli użytkownik jest niezalogowany.",
        "apihelp-purge-param-forcelinkupdate": "Uaktualnij tabele linków.",
+       "apihelp-purge-param-forcerecursivelinkupdate": "Uaktualnij tabele linków włącznie z linkami dotyczącymi każdej strony wykorzystywanej jako szablon na tej stronie.",
+       "apihelp-purge-example-simple": "Wyczyść strony <kbd>Main Page</kbd> i <kbd>API</kbd>.",
        "apihelp-purge-example-generator": "Przeczyść pierwsze 10 stron w przestrzeni głównej.",
        "apihelp-query+allcategories-description": "Emuluj wszystkie kategorie.",
+       "apihelp-query+allcategories-param-from": "Kategoria, od której rozpocząć wyliczanie.",
+       "apihelp-query+allcategories-param-to": "Kategoria, na której zakończyć wyliczanie.",
        "apihelp-query+allcategories-param-dir": "Kierunek sortowania.",
        "apihelp-query+allcategories-param-limit": "Liczba kategorii do zwórcenia.",
+       "apihelp-query+allcategories-param-prop": "Jakie właściwości otrzymać:",
+       "apihelp-query+allcategories-paramvalue-prop-size": "Dodaje liczbę stron w kategorii.",
+       "apihelp-query+allcategories-paramvalue-prop-hidden": "Oznacza kategorie ukryte za pomocą <code>_&#95;HIDDENCAT_&#95;</code>.",
+       "apihelp-query+allcategories-example-size": "Wymień kategorie z informacjami o liczbie stron w każdej z nich.",
+       "apihelp-query+alldeletedrevisions-description": "Wymień wszystkie usunięte wersje użytkownika lub z przestrzeni nazw.",
        "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Może być użyte tylko z <var>$3user</var>.",
        "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "Nie może być używane z <var>$3user</var>.",
+       "apihelp-query+alldeletedrevisions-param-start": "Znacznik czasu, od którego rozpocząć wyliczanie.",
+       "apihelp-query+alldeletedrevisions-param-end": "Znacznik czasu, na którym zakończyć wyliczanie.",
        "apihelp-query+alldeletedrevisions-param-from": "Zacznij nasłuchiwanie na tym tytule.",
        "apihelp-query+alldeletedrevisions-param-to": "Skończ nasłuchiwanie na tym tytule.",
+       "apihelp-query+alldeletedrevisions-param-prefix": "Szukaj tytułów stron zaczynających się na tę wartość.",
        "apihelp-query+alldeletedrevisions-param-tag": "Pokazuj tylko zmiany oznaczone tym znacznikiem.",
        "apihelp-query+alldeletedrevisions-param-user": "Pokazuj tylko zmiany dokonane przez tego użytkownika.",
        "apihelp-query+alldeletedrevisions-param-excludeuser": "Nie pokazuj zmian dokonanych przez tego użytkownika.",
        "apihelp-query+alldeletedrevisions-param-namespace": "Listuj tylko strony z tej przestrzeni nazw.",
+       "apihelp-query+alldeletedrevisions-example-user": "Wymień ostatnie 50 usuniętych edycji przez użytkownika <kbd>Example</kbd>.",
+       "apihelp-query+alldeletedrevisions-example-ns-main": "Wymień ostatnie 50 usuniętych edycji z przestrzeni głównej.",
+       "apihelp-query+allfileusages-description": "Lista wykorzystania pliku, także dla nieistniejących.",
+       "apihelp-query+allfileusages-param-from": "Nazwa pliku, od którego rozpocząć wyliczanie.",
+       "apihelp-query+allfileusages-param-to": "Nazwa pliku, na którym zakończyć wyliczanie.",
+       "apihelp-query+allfileusages-param-prop": "Jakie informacje dołączyć:",
+       "apihelp-query+allfileusages-paramvalue-prop-title": "Dodaje tytuł pliku.",
        "apihelp-query+allfileusages-param-limit": "Łączna liczba obiektów do zwrócenia.",
        "apihelp-query+allfileusages-example-unique": "Lista unikatowych tytułów plików.",
        "apihelp-query+allimages-param-sort": "Sortowanie według właściwości.",
+       "apihelp-query+allimages-param-minsize": "Ogranicz do obrazków, mających co najmniej taką liczbę bajtów.",
+       "apihelp-query+allimages-param-maxsize": "Ogranicz do obrazków, mających co najwyżej taką liczbę bajtów.",
+       "apihelp-query+allimages-example-B": "Pokaz listę plików rozpoczynających się na literę <kbd>B</kbd>.",
        "apihelp-query+allimages-example-recent": "Pokaż listę ostatnio przesłanych plików, podobnie do [[Special:NewFiles]].",
        "apihelp-query+allimages-example-mimetypes": "Pokaż listę plików z typem MIME <kbd>image/png</kbd> lub <kbd>image/gif</kbd>",
+       "apihelp-query+allimages-example-generator": "Pokaż informacje o 4 plikach rozpoczynających się na literę <kbd>T</kbd>.",
+       "apihelp-query+alllinks-param-from": "Nazwa linku, od którego rozpocząć wyliczanie.",
+       "apihelp-query+alllinks-param-to": "Nazwa linku, na którym zakończyć wyliczanie.",
+       "apihelp-query+alllinks-param-prop": "Jakie informacje dołączyć:",
+       "apihelp-query+alllinks-paramvalue-prop-title": "Dodaje tytuł linku.",
        "apihelp-query+alllinks-param-namespace": "Przestrzeń nazw do emulacji.",
        "apihelp-query+alllinks-param-limit": "Łączna liczba obiektów do zwrócenia.",
        "apihelp-query+alllinks-example-unique": "Lista unikatowych tytułów plików.",
        "apihelp-query+allmessages-param-prop": "Właściwości do odczytu.",
        "apihelp-query+allmessages-param-prefix": "Zwróć wiadomości z tym prefixem.",
+       "apihelp-query+allmessages-example-ipb": "Pokaż wiadomości rozpoczynające się od <kbd>ipb-</kbd>.",
+       "apihelp-query+allmessages-example-de": "Pokaż wiadomości <kbd>august</kbd> i <kbd>mainpage</kbd> w języku niemieckim.",
+       "apihelp-query+allpages-param-from": "Tytuł strony, od której rozpocząć wyliczanie.",
+       "apihelp-query+allpages-param-to": "Tytuł strony, na której zakończyć wyliczanie.",
+       "apihelp-query+allpages-param-minsize": "Ogranicz do stron, mających co najmniej taką liczbę bajtów.",
+       "apihelp-query+allpages-param-maxsize": "Ogranicz do stron, mających co najwyżej taką liczbę bajtów.",
        "apihelp-query+allpages-param-prtype": "Ogranicz tylko do zabezpieczonych stron.",
        "apihelp-query+allpages-param-limit": "Liczba stron do zwrócenia.",
        "apihelp-query+allpages-example-B": "Pokaż listę stron rozpoczynających się na literę <kbd>B</kbd>.",
+       "apihelp-query+allpages-example-generator": "Pokaż informacje o 4 stronach rozpoczynających się na literę <kbd>T</kbd>.",
+       "apihelp-query+allpages-example-generator-revisions": "Pokaż zawartość pierwszych dwóch nieprzekierowujących stron, zaczynających się na <kbd>Re</kbd>.",
        "apihelp-query+allredirects-description": "Lista wszystkich przekierowań do przestrzeni nazw.",
+       "apihelp-query+allredirects-param-from": "Nazwa przekierowania, od którego rozpocząć wyliczanie.",
+       "apihelp-query+allredirects-param-to": "Nazwa przekierowania, na którym zakończyć wyliczanie.",
+       "apihelp-query+allredirects-param-prop": "Jakie informacje dołączyć:",
+       "apihelp-query+allredirects-paramvalue-prop-title": "Dodaje tytuł przekierowania.",
        "apihelp-query+allredirects-param-namespace": "Przestrzeń nazw do emulacji.",
        "apihelp-query+allredirects-param-limit": "Łączna liczba obiektów do zwrócenia.",
        "apihelp-query+allrevisions-description": "Wyświetl wszystkie wersje.",
+       "apihelp-query+allrevisions-param-start": "Znacznik czasu, od którego rozpocząć wyliczanie.",
+       "apihelp-query+allrevisions-param-end": "Znacznik czasu, na którym zakończyć wyliczanie.",
        "apihelp-query+allrevisions-param-user": "Wyświetl wersje tylko tego użytkownika.",
        "apihelp-query+allrevisions-param-excludeuser": "Nie wyświetlaj wersji tego użytkownika.",
        "apihelp-query+allrevisions-param-namespace": "Wyświetl tylko strony w przestrzeni głównej.",
        "apihelp-query+allrevisions-example-ns-main": "Wyświetl pierwsze 50 wersji w przestrzeni głównej.",
+       "apihelp-query+mystashedfiles-param-limit": "Liczba plików do pobrania.",
+       "apihelp-query+alltransclusions-param-prop": "Jakie informacje dołączyć:",
        "apihelp-query+alltransclusions-param-namespace": "Przestrzeń nazw do emulacji.",
+       "apihelp-query+alltransclusions-param-limit": "Łączna liczba elementów do zwrócenia.",
+       "apihelp-query+allusers-param-from": "Nazwa użytkownika, od którego rozpocząć wyliczanie.",
+       "apihelp-query+allusers-param-to": "Nazwa użytkownika, na którym zakończyć wyliczanie.",
+       "apihelp-query+allusers-param-prefix": "Wyszukaj wszystkich użytkowników, których nazwy zaczynają się od tej wartości.",
+       "apihelp-query+allusers-param-dir": "Kierunek sortowania.",
+       "apihelp-query+allusers-param-prop": "Jakie informacje dołączyć:",
+       "apihelp-query+allusers-paramvalue-prop-rights": "Wyświetla uprawnienia, które posiada użytkownik.",
+       "apihelp-query+allusers-paramvalue-prop-editcount": "Dodaje liczbę edycji użytkownika.",
+       "apihelp-query+allusers-param-limit": "Łączna liczba nazw użytkowników do zwrócenia.",
        "apihelp-query+allusers-param-witheditsonly": "Tylko użytkownicy, którzy edytowali.",
+       "apihelp-query+allusers-param-activeusers": "Wyświetl tylko użytkowników, aktywnych w ciągu {{PLURAL:$1|ostatniego dnia|ostatnich $1 dni}}.",
+       "apihelp-query+allusers-example-Y": "Wyświetl użytkowników zaczynających się na <kbd>Y</kbd>.",
+       "apihelp-query+backlinks-description": "Znajdź wszystkie strony, które linkują do danej strony.",
        "apihelp-query+backlinks-param-namespace": "Przestrzeń nazw do emulacji.",
        "apihelp-query+backlinks-example-simple": "Pokazuj linki do <kbd>Main page</kbd>.",
+       "apihelp-query+blocks-param-start": "Znacznik czasu, od którego rozpocząć wyliczanie.",
+       "apihelp-query+blocks-param-end": "Znacznik czasu, na którym zakończyć wyliczanie.",
        "apihelp-query+blocks-param-ids": "Lista zablokowanych ID do wylistowania (opcjonalne).",
        "apihelp-query+blocks-param-users": "Lista użytkowników do wyszukania (opcjonalne).",
        "apihelp-query+blocks-param-limit": "Maksymalna liczba blokad do wylistowania.",
+       "apihelp-query+blocks-paramvalue-prop-reason": "Dodaje powód zablokowania.",
        "apihelp-query+blocks-example-simple": "Listuj blokady.",
        "apihelp-query+categories-param-limit": "Liczba kategorii do zwrócenia.",
        "apihelp-query+categorymembers-description": "Wszystkie strony w danej kategorii.",
+       "apihelp-query+categorymembers-param-title": "Kategoria, której zawartość wymienić (wymagane). Musi zawierać prefiks <kbd>{{ns:category}}:</kbd>. Nie może być używany równocześnie z <var>$1pageid</var>.",
+       "apihelp-query+categorymembers-param-pageid": "ID strony kategorii, z której wymienić strony. Nie może być użyty równocześnie z <var>$1title</var>.",
+       "apihelp-query+categorymembers-param-prop": "Jakie informacje dołączyć:",
+       "apihelp-query+categorymembers-paramvalue-prop-ids": "Doda ID strony.",
+       "apihelp-query+categorymembers-paramvalue-prop-title": "Doda tytuł i identyfikator przestrzeni nazw strony.",
+       "apihelp-query+categorymembers-paramvalue-prop-sortkey": "Doda klucz sortowania obowiązujący w danej kategorii (ciąg szesnastkowy).",
+       "apihelp-query+categorymembers-paramvalue-prop-sortkeyprefix": "Doda klucz sortowania obowiązujący w danej kategorii (czytelna przez człowieka część klucza sortowania).",
+       "apihelp-query+categorymembers-paramvalue-prop-type": "Doda informacje o typie strony w kategorii (<samp>page</samp> (strona), <samp>subcat</samp> (podkategoria) lub <samp>file</samp> (plik)).",
        "apihelp-query+categorymembers-param-limit": "Maksymalna liczba zwracanych wyników.",
        "apihelp-query+categorymembers-param-sort": "Sortowanie według właściwości.",
+       "apihelp-query+categorymembers-param-dir": "W jakim kierunku sortować.",
        "apihelp-query+deletedrevisions-param-tag": "Pokazuj tylko zmiany oznaczone tym tagiem.",
        "apihelp-query+deletedrevisions-param-user": "Pokazuj tylko zmiany dokonane przez tego użytkownika.",
        "apihelp-query+deletedrevisions-param-excludeuser": "Nie pokazuj zmian dokonanych przez tego użytkownika.",
        "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|Tryb|Tryby}}: $2",
+       "apihelp-query+deletedrevs-param-start": "Znacznik czasu, od którego rozpocząć wyliczanie.",
+       "apihelp-query+deletedrevs-param-end": "Znacznik czasu, na którym zakończyć wyliczanie.",
        "apihelp-query+deletedrevs-param-unique": "Liatuj tylko jedną edycję dla każdej strony.",
        "apihelp-query+deletedrevs-param-tag": "Pokazuj tylko zmiany oznaczone tym tagiem.",
        "apihelp-query+deletedrevs-param-user": "Listuj tylko zmiany dokonane przez tego użytkownika.",
        "apihelp-query+deletedrevs-param-excludeuser": "Nie listuj zmian dokonanych przez tego użytkownika.",
        "apihelp-query+deletedrevs-param-namespace": "Listuj tylko strony z tej przestrzeni nazw.",
        "apihelp-query+deletedrevs-param-limit": "Maksymalna liczba zmian do wylistowania.",
+       "apihelp-query+disabled-description": "Ten moduł zapytań został wyłączony.",
        "apihelp-query+duplicatefiles-example-generated": "Szukaj duplikatów wszystkich plików.",
        "apihelp-query+embeddedin-param-filterredir": "Jaki filtrować przekierowania.",
+       "apihelp-query+embeddedin-param-limit": "Łączna liczba stron do zwrócenia.",
        "apihelp-query+extlinks-param-limit": "Liczba linków do zwrócenia.",
+       "apihelp-query+exturlusage-param-prop": "Jakie informacje dołączyć:",
+       "apihelp-query+exturlusage-paramvalue-prop-ids": "Dodaje ID strony.",
+       "apihelp-query+exturlusage-paramvalue-prop-title": "Dodaje tytuł i identyfikator przestrzeni nazw strony.",
+       "apihelp-query+exturlusage-paramvalue-prop-url": "Dodaje adres URL, używany na stronie.",
        "apihelp-query+exturlusage-param-limit": "Liczba stron do zwrócenia.",
        "apihelp-query+filearchive-paramvalue-prop-dimensions": "Alias rozmiaru.",
+       "apihelp-query+filearchive-paramvalue-prop-description": "Dodaje opis wersji obrazka.",
        "apihelp-query+filearchive-example-simple": "Pokaż listę wszystkich usuniętych plików.",
        "apihelp-query+filerepoinfo-example-simple": "Uzyskaj informacje na temat repozytoriów plików.",
+       "apihelp-query+fileusage-description": "Znajdź wszystkie strony, które używają danych plików.",
        "apihelp-query+fileusage-paramvalue-prop-title": "Nazwa każdej strony.",
+       "apihelp-query+fileusage-paramvalue-prop-redirect": "Oznacz, jeśli strona jest przekierowaniem.",
        "apihelp-query+fileusage-param-limit": "Ilość do zwrócenia.",
+       "apihelp-query+imageinfo-description": "Zwraca informacje o pliku i historię przesyłania.",
        "apihelp-query+imageinfo-paramvalue-prop-canonicaltitle": "Dodaje kanoniczny tytuł pliku.",
        "apihelp-query+imageinfo-paramvalue-prop-dimensions": "Alias rozmiaru.",
        "apihelp-query+imageinfo-paramvalue-prop-sha1": "Dodaj sumę kontrolną SHA-1 dla tego pliku.",
        "apihelp-query+imageinfo-paramvalue-prop-mime": "Dodaje typ MIME pliku.",
        "apihelp-query+imageinfo-param-urlheight": "Podobne do $1urlwidth.",
        "apihelp-query+images-param-limit": "Liczba plików do zwrócenia.",
+       "apihelp-query+imageusage-example-simple": "Pokaż strony, które korzystają z [[:File:Albert Einstein Head.jpg]].",
        "apihelp-query+info-description": "Pokaż podstawowe informacje o stronie.",
        "apihelp-query+info-paramvalue-prop-watchers": "Liczba obserwujących, jeśli jest to dozwolone.",
        "apihelp-query+info-paramvalue-prop-readable": "Czy użytkownik może przeczytać tę stronę.",
        "apihelp-query+iwbacklinks-param-prefix": "Prefix interwiki.",
        "apihelp-query+iwbacklinks-param-limit": "Łączna liczba stron do zwrócenia.",
+       "apihelp-query+iwbacklinks-paramvalue-prop-iwprefix": "Dodaje prefiks interwiki.",
+       "apihelp-query+iwbacklinks-paramvalue-prop-iwtitle": "Dodaje tytuł interwiki.",
        "apihelp-query+iwlinks-paramvalue-prop-url": "Dodaje pełny adres URL.",
+       "apihelp-query+iwlinks-param-limit": "Łączna liczba linków interwiki do zwrócenia.",
+       "apihelp-query+langbacklinks-param-limit": "Łączna liczba stron do zwrócenia.",
+       "apihelp-query+langbacklinks-paramvalue-prop-lllang": "Dodaje kod języka linku językowego.",
+       "apihelp-query+langbacklinks-paramvalue-prop-lltitle": "Dodaje tytuł linku językowego.",
+       "apihelp-query+langlinks-paramvalue-prop-url": "Dodaje pełny adres URL.",
        "apihelp-query+links-param-limit": "Liczba linków do zwrócenia.",
+       "apihelp-query+linkshere-description": "Znajdź wszystkie strony, które linkują do danych stron.",
        "apihelp-query+linkshere-paramvalue-prop-title": "Nazwa każdej strony.",
+       "apihelp-query+linkshere-paramvalue-prop-redirect": "Oznacz, jeśli strona jest przekierowaniem.",
        "apihelp-query+linkshere-param-limit": "Liczba do zwrócenia.",
        "apihelp-query+logevents-description": "Pobierz eventy z logu.",
        "apihelp-query+logevents-example-simple": "Lista ostatnich zarejestrowanych zdarzeń.",
+       "apihelp-query+pageswithprop-param-prop": "Jakie informacje dołączyć:",
+       "apihelp-query+pageswithprop-paramvalue-prop-ids": "Doda ID strony.",
        "apihelp-query+pageswithprop-example-generator": "Pobierz dodatkowe informacje o pierwszych 10 stronach wykorzystując <code>_&#95;NOTOC_&#95;</code>.",
        "apihelp-query+prefixsearch-param-search": "Wyszukaj tekst.",
        "apihelp-query+prefixsearch-param-namespace": "Przestrzenie nazw do przeszukania.",
        "apihelp-query+protectedtitles-param-namespace": "Listuj tylko strony z tych przestrzeni nazw.",
        "apihelp-query+protectedtitles-param-limit": "Łączna liczba stron do zwrócenia.",
        "apihelp-query+protectedtitles-example-simple": "Lista chronionych nagłówków",
+       "apihelp-query+querypage-param-limit": "Liczba zwracanych wyników.",
+       "apihelp-query+random-param-namespace": "Zwraca strony tylko w tych przestrzeniach nazw.",
        "apihelp-query+recentchanges-param-user": "Listuj tylko zmiany dokonane przez tego użytkownika.",
        "apihelp-query+recentchanges-param-excludeuser": "Nie listuj zmian dokonanych przez tego użytkownika.",
        "apihelp-query+recentchanges-param-tag": "Pokazuj tylko zmiany oznaczone tym tagiem.",
        "apihelp-query+recentchanges-example-simple": "Lista ostatnich zmian.",
+       "apihelp-query+redirects-description": "Zwraca wszystkie przekierowania do danej strony.",
        "apihelp-query+redirects-paramvalue-prop-title": "Nazwa każdego przekierowania.",
        "apihelp-query+redirects-param-limit": "Ile przekierowań zwrócić.",
        "apihelp-query+revisions+base-paramvalue-prop-ids": "Identyfikator wersji.",
        "apihelp-query+revisions+base-paramvalue-prop-flags": "Znaczniki wersji (drobne).",
        "apihelp-query+revisions+base-paramvalue-prop-timestamp": "Znacznik czasu wersji.",
+       "apihelp-query+revisions+base-paramvalue-prop-size": "Długość wersji (w bajtach).",
        "apihelp-query+revisions+base-paramvalue-prop-sha1": "SHA-1 (base 16) wersji.",
        "apihelp-query+revisions+base-paramvalue-prop-content": "Tekst wersji.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "Znaczniki wersji.",
        "apihelp-query+revisions+base-param-limit": "Ograniczenie na liczbę wersji, które będą zwrócone.",
        "apihelp-query+search-description": "Wykonaj wyszukiwanie pełnotekstowe.",
        "apihelp-query+search-param-info": "Które metadane zwrócić.",
+       "apihelp-query+search-paramvalue-prop-size": "Dodaje rozmiar strony w bajtach.",
+       "apihelp-query+search-paramvalue-prop-wordcount": "Dodaje liczbę słów na stronie.",
+       "apihelp-query+search-paramvalue-prop-redirecttitle": "Dodaje tytuł pasującego przekierowania.",
        "apihelp-query+search-param-limit": "Łączna liczba stron do zwrócenia.",
        "apihelp-query+search-param-interwiki": "Dołączaj wyniki wyszukiwań interwiki w wyszukiwarce, jeśli możliwe.",
        "apihelp-query+search-example-simple": "Szukaj <kbd>meaning</kbd>.",
+       "apihelp-query+siteinfo-paramvalue-prop-general": "Ogólne informacje o systemie.",
        "apihelp-query+siteinfo-paramvalue-prop-namespaces": "Lista zarejestrowanych przestrzeni nazw i ich nazwy kanoniczne.",
        "apihelp-query+siteinfo-paramvalue-prop-namespacealiases": "Lista zarejestrowanych aliasów przestrzeni nazw.",
+       "apihelp-query+siteinfo-param-numberingroup": "Wyświetla liczbę użytkowników w grupach użytkowników.",
        "apihelp-query+siteinfo-example-simple": "Pobierz informacje o stronie.",
+       "apihelp-query+stashimageinfo-param-sessionkey": "Alias dla $1filekey, dla kompatybilności wstecznej.",
        "apihelp-query+tags-description": "Lista zmian tagów.",
        "apihelp-query+tags-param-limit": "Maksymalna liczba tagów do wyświetlenia.",
+       "apihelp-query+tags-paramvalue-prop-name": "Dodaje nazwę znacznika.",
+       "apihelp-query+tags-paramvalue-prop-displayname": "Dodaje komunikat systemowy dla znacznika.",
+       "apihelp-query+tags-paramvalue-prop-description": "Dodaje opis znacznika.",
+       "apihelp-query+tags-paramvalue-prop-active": "Czy znacznik jest nadal stosowany.",
        "apihelp-query+tags-example-simple": "Lista dostęnych tagów.",
+       "apihelp-query+templates-description": "Zwraca wszystkie strony osadzone w danych stronach.",
        "apihelp-query+templates-param-limit": "Ile szablonów zwrócić?",
+       "apihelp-query+transcludedin-paramvalue-prop-title": "Nazwa każdej strony.",
+       "apihelp-query+transcludedin-paramvalue-prop-redirect": "Oznacz, jeśli strona jest przekierowaniem.",
        "apihelp-query+transcludedin-param-limit": "Ile zwrócić.",
+       "apihelp-query+userinfo-description": "Pobierz informacje o aktualnym użytkowniku.",
+       "apihelp-query+userinfo-param-prop": "Jakie informacje dołączyć:",
+       "apihelp-query+userinfo-paramvalue-prop-groups": "Wyświetla wszystkie grupy, do których należy bieżący użytkownik.",
+       "apihelp-query+userinfo-paramvalue-prop-rights": "Wyświetla wszystkie uprawnienia, które ma bieżący użytkownik.",
+       "apihelp-query+userinfo-paramvalue-prop-registrationdate": "Dodaje datę rejestracji użytkownika.",
+       "apihelp-query+userinfo-example-simple": "Pobierz informacje o aktualnym użytkowniku.",
+       "apihelp-query+userinfo-example-data": "Pobierz dodatkowe informacje o aktualnym użytkowniku.",
+       "apihelp-query+users-description": "Pobierz informacje o liście użytkowników.",
+       "apihelp-query+users-param-prop": "Jakie informacje dołączyć:",
+       "apihelp-query+users-paramvalue-prop-groups": "Wyświetla wszystkie grupy, do których należy każdy z użytkowników.",
+       "apihelp-query+users-paramvalue-prop-rights": "Wyświetla wszystkie uprawnienia, które ma każdy z użytkowników.",
+       "apihelp-query+users-param-users": "Lista użytkowników, o których chcesz pobrać informacje.",
        "apihelp-query+watchlist-param-excludeuser": "Nie wyświetlaj zmian wykonanych przez tego użytkownika.",
        "apihelp-query+watchlist-paramvalue-prop-title": "Dodaje tytuł strony.",
        "apihelp-query+watchlist-paramvalue-prop-user": "Dodaje użytkownika, który wykonał edycję.",
        "apihelp-query+watchlist-paramvalue-prop-comment": "Dodaje komentarz do edycji.",
        "apihelp-query+watchlist-paramvalue-prop-timestamp": "Dodaje znacznik czasu edycji.",
        "apihelp-query+watchlist-paramvalue-prop-sizes": "Dodaje starą i nową długość strony.",
+       "apihelp-query+watchlist-paramvalue-type-external": "Zmiany zewnętrzne.",
        "apihelp-resetpassword-description": "Wyślij użytkownikowi e-mail do resetowania hasła.",
        "apihelp-resetpassword-example-email": "Wyślij e-mail do resetowania hasła do wszystkich użytkowników posiadających adres <kbd>user@example.com</kbd>.",
        "apihelp-stashedit-param-title": "Tytuł edytowanej strony.",
        "apihelp-stashedit-param-sectiontitle": "Tytuł nowej sekcji.",
        "apihelp-stashedit-param-text": "Zawartość strony.",
        "apihelp-tag-param-reason": "Powód zmiany.",
+       "apihelp-unblock-description": "Odblokuj użytkownika.",
        "apihelp-unblock-param-reason": "Powód odblokowania.",
        "apihelp-undelete-param-reason": "Powód przywracania.",
        "apihelp-upload-param-filename": "Nazwa pliku docelowego.",
+       "apihelp-upload-param-watch": "Obserwuj stronę.",
+       "apihelp-upload-param-ignorewarnings": "Ignoruj wszystkie ostrzeżenia.",
+       "apihelp-upload-param-file": "Zawartość pliku.",
        "apihelp-userrights-param-user": "Nazwa użytkownika.",
+       "apihelp-userrights-param-add": "Dodaj użytkownika do tych grup.",
        "apihelp-userrights-param-reason": "Powód zmiany.",
        "apihelp-json-description": "Dane wyjściowe w formacie JSON.",
        "apihelp-jsonfm-description": "Dane wyjściowe w formacie JSON (prawidłowo wyświetlane w HTML).",
        "apihelp-xml-param-xslt": "Jeśli określony, dodaje podaną stronę jako arkusz styli XSL. Powinna to być strona wiki w przestrzeni nazw MediaWiki, której nazwa kończy się na <code>.xsl</code>.",
        "apihelp-xmlfm-description": "Dane wyjściowe w formacie XML (prawidłowo wyświetlane w HTML).",
        "api-format-title": "Wynik MediaWiki API",
+       "api-pageset-param-titles": "Lista tytułów, z którymi pracować.",
+       "api-pageset-param-pageids": "Lista identyfikatorów stron, z którymi pracować.",
+       "api-pageset-param-revids": "Lista identyfikatorów wersji, z którymi pracować.",
+       "api-pageset-param-generator": "Pobierz listę stron, z którymi pracować poprzez wykonanie określonego modułu zapytań.\n\n<strong>Uwaga:</strong> Nazwy parametrów generatora musi poprzedzać prefiks „g”. Zobacz przykłady.",
+       "api-pageset-param-redirects-generator": "Automatycznie rozwiązuj przekierowania ze stron podanych w <var>$1titles</var>, <var>$1pageids</var>, oraz <var>$1revids</var>, a także ze stron zwróconych przez <var>$1generator</var>.",
+       "api-pageset-param-converttitles": "Konwertuj tytuły do innych wariantów, jeżeli trzeba. Będzie działać tylko wtedy, gdy język zawartości wiki będzie wspierał konwersje wariantów. Języki, które wspierają konwersję wariantów to m.in. $1.",
        "api-help-title": "Pomoc MediaWiki API",
        "api-help-lead": "To jest automatycznie wygenerowana strona dokumentacji MediaWiki API.\nDokumentacja i przykłady: https://www.mediawiki.org/wiki/API",
        "api-help-main-header": "Moduł główny",
        "api-help-param-deprecated": "Przestarzałe.",
        "api-help-param-required": "Ten parametr jest wymagany.",
        "api-help-datatypes-header": "Typy danych",
+       "api-help-param-type-integer": "Typ: {{PLURAL:$1|1=liczba całkowita|2=lista liczb całkowitych}}",
        "api-help-param-type-boolean": "Typ: wartość logiczna ([[Special:ApiHelp/main#main/datatypes|szczegóły]])",
        "api-help-param-type-timestamp": "Typ: {{PLURAL:$1|1=znacznik czasu|2=lista znaczników czasu}} ([[Special:ApiHelp/main#main/datatypes|dozwolone formaty]])",
        "api-help-param-type-user": "Typ: {{PLURAL:$1|1=nazwa użytkownika|2=lista nazw uzytkowników}}",
-       "api-help-param-list": "{{PLURAL:$1|1=Jedna z następujących wartość|2=Wartości (oddziel za pomocą <kbd>{{!}}</kbd>)}}: $2",
+       "api-help-param-list": "{{PLURAL:$1|1=Jedna z następujących wartości|2=Wartości (oddziel za pomocą <kbd>{{!}}</kbd> lub [[Special:ApiHelp/main#main/datatypes|alternatywy]])}}: $2",
        "api-help-param-limit": "Nie więcej niż $1 dozwolone.",
        "api-help-param-limit2": "Nie więcej niż $1 ($2 dla botów) dozwolone.",
        "api-help-param-integer-min": "{{PLURAL:$1|1=Wartość musi być nie mniejsza|2=Wartości muszą być nie mniejsze}} niż $2.",
        "api-help-param-integer-max": "{{PLURAL:$1|1=Wartość musi być nie większa|2=Wartości muszą być nie większe}} niż $3.",
        "api-help-param-integer-minmax": "{{PLURAL:$1|1=Wartość musi|2=Wartości muszą}} być pomiędzy $2 a $3.",
-       "api-help-param-multi-separate": "Oddziel wartości za pomocą <kbd>|</kbd>.",
+       "api-help-param-multi-separate": "Oddziel wartości za pomocą <kbd>|</kbd> lub [[Special:ApiHelp/main#main/datatypes|alternatywy]].",
        "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-continue": "Gdy będzie dostępnych więcej wyników, użyj tego do kontynuowania.",
        "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}}:",
        "api-help-permissions-granted-to": "{{PLURAL:$1|Przydzielone dla}}: $2",
+       "api-help-right-apihighlimits": "Użyj wyższych limitów w zapytaniach API (dla zapytań powolnych: $1; dla zapytań szbkich: $2). Limity zapytań powolnych są także stosowane dla parametrów z podanymi wieloma wartościami.",
+       "api-help-open-in-apisandbox": "<small>[otwórz w brudnopisie]</small>",
        "api-credits-header": "Twórcy",
        "api-credits": "Deweloperzy API:\n* Roan Kattouw (główny programista wrzesień 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (twórca, główny programista wrzesień 2006–wrzesień 2007)\n* Brad Jorsch (główny programista 2013–obecnie)\n\nProsimy wysyłać komentarze, sugestie i pytania do mediawiki-api@lists.wikimedia.org\nlub zgłoś błąd na https://phabricator.wikimedia.org/."
 }
index 40d5786..709230a 100644 (file)
                        "Vitorvicentevalente",
                        "Fúlvio",
                        "Macofe",
-                       "Jkb8"
+                       "Jkb8",
+                       "Hamilton Abreu",
+                       "Mansil"
                ]
        },
-       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentação]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discussão]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anúncios da API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Erros e solicitações]\n</div>\n<strong>Estado:</strong> Todas as funcionalidades mostradas nesta página deveriam estar a funcionar, mas a API ainda está em activo desenvolvimento, e pode ser alterada a qualquer momento. Inscreva-se na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discussão mediawiki-api-announce] para ser informado acerca das actualizações.\n\n<strong>Solicitações erradas:</strong> Quando solicitações erradas são enviadas à API, um cabeçalho em HTTP será enviado com a chave \"MediaWiki-API-Error\" e, em seguida, tanto o valor do cabeçalho quanto o código de erro retornado serão definidos com o mesmo valor. Para mais informação, consulte [[mw:API:Errors_and_warnings|API: Errors and warnings]].\n\n<strong>Testes:</strong> Para facilitar os testes de solicitações à API, consulte [[Special:ApiSandbox]].",
-       "apihelp-main-param-action": "Qual acção a executar.",
-       "apihelp-main-param-format": "O formato de saída.",
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentação]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discussão]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anúncios da API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Erros e pedidos]\n</div>\n<strong>Estado:</strong> Todas as funcionalidades mostradas nesta página devem ter o comportamento documentado mas a API ainda está em desenvolvimento ativo e pode ser alterada a qualquer momento. Inscreva-se na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discussão mediawiki-api-announce] para ser informado acerca das atualizações.\n\n<strong>Pedidos incorretos:</strong> Quando são enviados pedidos incorretos à API, será devolvido um cabeçalho HTTP com a chave \"MediaWiki-API-Error\" e depois tanto o valor desse cabeçalho como o código de erro devolvido serão definidos com o mesmo valor. Para mais informação, consulte [[mw:API:Errors_and_warnings|API:Erros e avisos]].\n\n<strong>Testes:</strong> Para testar facilmente pedidos à API, visite [[Special:ApiSandbox|Testes da API]].",
+       "apihelp-main-param-action": "A operação a ser realizada.",
+       "apihelp-main-param-format": "O formato do resultado.",
+       "apihelp-main-param-maxlag": "O atraso máximo pode ser usado quando o MediaWiki é instalado num ''cluster'' de bases de dados replicadas. Para impedir que as operações causem ainda mais atrasos de replicação do ''site'', este parâmetro pode fazer o cliente aguardar até que o atraso de replicação seja inferior ao valor especificado. Caso o atraso atual exceda esse valor, o código de erro <samp>maxlag</samp> é devolvido com uma mensagem como <samp>À espera do servidor $host: $lag segundos de atraso</samp>.<br />Consulte [[mw:Manual:Maxlag_parameter|Manual: Parâmetro maxlag]] para mais informações.",
+       "apihelp-main-param-smaxage": "Definir no cabeçalho HTTP <code>s-maxage</code> de controlo da ''cache'' este número de segundos. Os erros nunca são armazenados na ''cache''.",
+       "apihelp-main-param-maxage": "Definir no cabeçalho HTTP <code>max-age</code> de controlo da ''cache'' este número de segundos. Os erros nunca são armazenados na ''cache''.",
+       "apihelp-main-param-assert": "Se definido com o valor <kbd>user</kbd>, verificar que o utilizador está autenticado. Se definido com o valor <kbd>bot</kbd>, verificar que o utilizador tem o privilégio de conta robô.",
+       "apihelp-main-param-assertuser": "Verificar que o utilizador atual é o utilizador nomeado.",
+       "apihelp-main-param-requestid": "Qualquer valor fornecido aqui será incluído na resposta. Pode ser usado para distinguir pedidos.",
+       "apihelp-main-param-servedby": "Incluir nos resultados o nome do servidor que serviu o pedido.",
+       "apihelp-main-param-curtimestamp": "Incluir a data e hora atuais no resultado.",
+       "apihelp-main-param-origin": "Ao aceder à API usando um pedido AJAX entre domínios (CORS), coloque aqui o domínio de origem. Isto tem de ser incluído em todas as verificações prévias e, portanto, tem de fazer parte do URI do pedido (e não do conteúdo do POST).\n\nPara pedidos autenticados, este valor tem de corresponder de forma exata a um dos cabeçalhos <code>Origin</code>, portanto, tem de ser algo como <kbd>https://en.wikipedia.org</kbd> ou <kbd>https://meta.wikimedia.org</kbd>. Se este parâmetro não for igual ao cabeçalho <code>Origin</code>, será devolvida a resposta 403. Se este parâmetro for igual ao cabeçalho <code>Origin</code> e a origem for permitida (''white-listed'') os cabeçalhos <code>Access-Control-Allow-Origin</code> e <code>Access-Control-Allow-Credentials</code> serão preenchidos.\n\nPara pedidos não autenticados, especifique o valor <kbd>*</kbd>. Isto fará com que o cabeçalho <code>Access-Control-Allow-Origin</code>\nseja preenchido, mas <code>Access-Control-Allow-Credentials</code> terá o valor <code>false</code> e o acesso a todos os dados específicos do utilizador está restringido.",
+       "apihelp-main-param-uselang": "Língua a usar nas traduções de mensagens. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> com <kbd>siprop=languages</kbd> devolve uma lista de códigos de língua, ou especifique <kbd>user</kbd> para usar a língua nas preferências do utilizador atual, ou especifique <kbd>content</kbd> para usar a língua de conteúdo desta wiki.",
        "apihelp-block-description": "Bloquear um utilizador.",
-       "apihelp-block-param-user": "Nome de utilizador(a), endereço ou gama de IP que pretende bloquear.",
-       "apihelp-block-param-reason": "Motivo do bloqueio.",
-       "apihelp-block-param-nocreate": "Impedir criação de contas.",
-       "apihelp-createaccount-description": "Criar uma nova conta.",
-       "apihelp-createaccount-param-name": "Nome de utilizador(a).",
+       "apihelp-block-param-user": "O nome de utilizador, endereço IP ou gama de endereços IP a serem bloqueados.",
+       "apihelp-block-param-expiry": "O período de expiração. Pode ser relativo (p. ex. <kbd>5 meses</kbd> ou <kbd>2 semanas</kbd>) ou absoluto (p. ex. <kbd>2014-09-18T12:34:56Z</kbd>). Se definido como <kbd>infinite</kbd>, <kbd>indefinite</kbd> ou <kbd>never</kbd>, o bloqueio nunca expirará.",
+       "apihelp-block-param-reason": "O motivo do bloqueio.",
+       "apihelp-block-param-anononly": "Bloquear só utilizadores anónimos (isto é, impedir edições anónimas a partir deste endereço IP)",
+       "apihelp-block-param-nocreate": "Impedir a criação de contas.",
+       "apihelp-block-param-autoblock": "Bloquear automaticamente o último endereço IP usado e quaisquer outros endereços IP subsequentes a partir do quais o utilizador tente iniciar uma sessão.",
+       "apihelp-block-param-noemail": "Impedir o utilizador de enviar correio eletrónico através da wiki. (Requer o privilégio <code>blockemail</code>).",
+       "apihelp-block-param-hidename": "Ocultar o nome do utilizador do registo de bloqueios. (Requer o privilégio <code>hideuser</code>).",
+       "apihelp-block-param-allowusertalk": "Permitir que o utilizador edite a sua própria página de discussão (depende de <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
+       "apihelp-block-param-reblock": "Se o utilizador já está bloqueado, sobrescrever o bloco existente.",
+       "apihelp-block-param-watchuser": "Vigiar as páginas de utilizador e de discussão, do utilizador ou do endereço IP.",
+       "apihelp-block-example-ip-simple": "Bloquear o endereço IP <kbd>192.0.2.5</kbd> por três dias com o motivo <kbd>First strike</kbd>.",
+       "apihelp-block-example-user-complex": "Bloquear o utilizador <kbd>Vandal</kbd> indefinidamente com o motivo <kbd>Vandalism</kbd>, e impedir a criação de nova conta e o envio de correio eletrónico.",
+       "apihelp-changeauthenticationdata-description": "Alterar os dados de autenticação do utilizador atual.",
+       "apihelp-changeauthenticationdata-example-password": "Tentar alterar a palavra-passe do utilizador atual para <kbd>ExamplePassword</kbd>.",
+       "apihelp-checktoken-description": "Verificar a validade de uma chave a partir de <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
+       "apihelp-checktoken-param-type": "Tipo de chave que está a ser testado.",
+       "apihelp-checktoken-param-token": "Chave a testar.",
+       "apihelp-checktoken-param-maxtokenage": "Validade máxima da chave, em segundos.",
+       "apihelp-checktoken-example-simple": "Testar a validade de uma chave <kbd>csrf</kbd>.",
+       "apihelp-clearhasmsg-description": "Limpa a indicação <code>hasmsg</code> do utilizador atual.",
+       "apihelp-clearhasmsg-example-1": "Limpar a indicação <code>hasmsg</code> do utilizador atual.",
+       "apihelp-clientlogin-description": "Entrar na wiki usando o processo interativo.",
+       "apihelp-clientlogin-example-login": "Inicia o processo de entrada na wiki com o utilizador <kbd>Example</kbd> e a palavra-passe <kbd>ExamplePassword</kbd>.",
+       "apihelp-clientlogin-example-login2": "Continuar o processo de autenticação após uma resposta  <samp>UI</samp> para autenticação de dois fatores, fornecendo uma <var>OATHToken</var> de <kbd>987654</kbd>.",
+       "apihelp-compare-description": "Obter a diferença entre 2 páginas.\n\nTêm de ser passados um número de revisão, um título de página ou um identificador de página para o \"from\" e o \"to\".",
+       "apihelp-compare-param-fromtitle": "Primeiro título a comparar.",
+       "apihelp-compare-param-fromid": "Primeiro identificador de página a comparar.",
+       "apihelp-compare-param-fromrev": "Primeira revisão a comparar.",
+       "apihelp-compare-param-totitle": "Segundo título a comparar.",
+       "apihelp-compare-param-toid": "Segundo identificador de página a comparar.",
+       "apihelp-compare-param-torev": "Segunda revisão a comparar.",
+       "apihelp-compare-example-1": "Criar uma lista de diferenças entre as revisões 1 e 2.",
+       "apihelp-createaccount-description": "Criar uma conta nova.",
+       "apihelp-createaccount-param-preservestate": "Se <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> devolveu o valor verdadeiro para <samp>hasprimarypreservedstate</samp>, pedidos marcados como <samp>primary-required</samp> devem ser omitidos. Se devolveu um valor não vazio em <samp>preservedusername</samp>, esse nome de utilizador tem de ser usado no parâmetro <var>username</var>.",
+       "apihelp-createaccount-example-create": "Iniciar o processo de criação do utilizador <kbd>Example</kbd> com a palavra-passe <kbd>ExamplePassword</kbd>.",
+       "apihelp-createaccount-param-name": "Nome de utilizador.",
+       "apihelp-createaccount-param-password": "Palavra-passe (ignorada se <var>$1mailpassword</var> está definida).",
+       "apihelp-createaccount-param-domain": "Domínio para autenticação externa (opcional).",
+       "apihelp-createaccount-param-token": "Chave de criação da conta, obtida no primeiro pedido.",
        "apihelp-createaccount-param-email": "Endereço de correio eletrónico do utilizador (opcional).",
        "apihelp-createaccount-param-realname": "Nome verdadeiro do utilizador (opcional).",
+       "apihelp-createaccount-param-mailpassword": "Se qualquer valor estiver definido, uma palavra-passe aleatória será enviada por correio eletrónico ao utilizador.",
+       "apihelp-createaccount-param-reason": "Motivo opcional de criação da conta, para ser colocado nos registos.",
+       "apihelp-createaccount-param-language": "Código da língua a definir como padrão para o utilizador (opcional, por omissão é a língua de conteúdo).",
+       "apihelp-createaccount-example-pass": "Criar o utilizador <kbd>testuser</kbd> com a palavra-passe <kbd>test123</kbd>.",
+       "apihelp-createaccount-example-mail": "Criar o utilizador <kbd>testmailuser</kbd> e enviar por correio eletrónico uma palavra-passe gerada aleatoriamente.",
+       "apihelp-cspreport-description": "Usado por '' browsers'' para reportar violações da norma \"Content Security Policy\". Este módulo nunca deve ser usado, exceto quando utilizado automaticamente por um ''browser'' compatível com a CSP.",
+       "apihelp-cspreport-param-reportonly": "Marcar como sendo um relatório vindo de uma norma de monitorização e não de uma norma exigida.",
+       "apihelp-cspreport-param-source": "Aquilo que gerou o cabeçalho CSP que desencadeou este relatório.",
        "apihelp-delete-description": "Eliminar uma página.",
-       "apihelp-delete-param-watch": "Adicionar a página à lista de vigiadas do utilizador atual.",
-       "apihelp-delete-param-unwatch": "Remover a página da lista de vigiadas do utilizador atual.",
-       "apihelp-delete-example-simple": "Eliminar <kbd>Main Page</kbd>.",
-       "apihelp-disabled-description": "O módulo foi desativado.",
+       "apihelp-delete-param-title": "Título da página a eliminar. Não pode ser usado em conjunto com <var>$1pageid</var>.",
+       "apihelp-delete-param-pageid": "Identificador da página a eliminar. Não pode ser usado em conjunto com <var>$1title</var>.",
+       "apihelp-delete-param-reason": "Motivo para a eliminação. Se não for definido, será usado um motivo gerado automaticamente.",
+       "apihelp-delete-param-tags": "Etiquetas de modificação a aplicar à entrada no registo de eliminações.",
+       "apihelp-delete-param-watch": "Adicionar a página às páginas vigiadas do utilizador atual.",
+       "apihelp-delete-param-watchlist": "Adicionar ou remover incondicionalmente a página da lista de páginas vigiadas do utilizador atual, usar as preferências ou não alterar o estado de vigilância.",
+       "apihelp-delete-param-unwatch": "Remover a página das páginas vigiadas do utilizador atual.",
+       "apihelp-delete-param-oldimage": "O nome da imagem antiga a ser eliminada, tal como fornecido por [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]].",
+       "apihelp-delete-example-simple": "Eliminar a página <kbd>Main Page</kbd>.",
+       "apihelp-delete-example-reason": "Eliminar <kbd>Main Page</kbd> com o motivo <kbd>Preparing for move</kbd>.",
+       "apihelp-disabled-description": "Este módulo foi desativado.",
        "apihelp-edit-description": "Criar e editar páginas.",
-       "apihelp-edit-param-sectiontitle": "Título para uma nova seção.",
+       "apihelp-edit-param-title": "Título da página a ser editada. Não pode ser usado em conjunto com <var>$1pageid</var>.",
+       "apihelp-edit-param-pageid": "Identificador da página a ser editada. Não pode ser usado em conjunto com <var>$1title</var>.",
+       "apihelp-edit-param-section": "Número da secção. <kbd>0</kbd> para a secção de topo, <kbd>new</kbd> para uma secção nova.",
+       "apihelp-edit-param-sectiontitle": "Título para uma nova secção.",
        "apihelp-edit-param-text": "Conteúdo da página.",
+       "apihelp-edit-param-summary": "Resumo da edição. Também é o título da secção quando $1section=new e $1sectiontitle não está definido.",
+       "apihelp-edit-param-tags": "Etiquetas de modificação a aplicar à revisão.",
        "apihelp-edit-param-minor": "Edição menor.",
-       "apihelp-edit-param-bot": "Marcar esta edição como robô.",
-       "apihelp-edit-example-edit": "Editar uma página",
-       "apihelp-emailuser-description": "Enviar correio eletrónico a utilizador.",
+       "apihelp-edit-param-notminor": "Edição não menor.",
+       "apihelp-edit-param-bot": "Marcar esta edição como edição de robô.",
+       "apihelp-edit-param-basetimestamp": "Data e hora da revisão de base, usada para detetar conflitos de edição. Pode ser obtida usando [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
+       "apihelp-edit-param-starttimestamp": "Data e hora de início do processo de edição, usada para detetar conflitos de edição. Pode-se obter um valor apropriado usando <var>[[Special:ApiHelp/main|curtimestamp]]</var> ao iniciar o processo de edição (por exemplo, ao carregar o conteúdo da página para edição).",
+       "apihelp-edit-param-recreate": "Ignorar todos os erros acerca da página ter sido eliminada entretanto.",
+       "apihelp-edit-param-createonly": "Não editar a página se ela já existe.",
+       "apihelp-edit-param-nocreate": "Gerar um erro se a página não existe.",
+       "apihelp-edit-param-watch": "Adicionar a página às páginas vigiadas do utilizador atual.",
+       "apihelp-edit-param-unwatch": "Remover a página da lista de páginas vigiadas do utilizador atual.",
+       "apihelp-edit-param-watchlist": "Adicionar ou remover incondicionalmente a página da lista de páginas vigiadas do utilizador atual, usar as preferências ou não alterar o estado de vigilância.",
+       "apihelp-edit-param-md5": "A chave MD5 do parâmetro $1text, ou os parâmetros $1prependtext e $1appendtext concatenados. Se estiver definido, a edição não será realizada a menos que a chave seja correta.",
+       "apihelp-edit-param-prependtext": "Adicionar este texto ao início da página. Tem precedência sobre $1text.",
+       "apihelp-edit-param-appendtext": "Adicionar este texto ao fim da página. Tem precedência sobre $1text.\n\nPara acrescentar uma nova secção no fim da página, usar $1section=new em vez deste parâmetro.",
+       "apihelp-edit-param-undo": "Desfazer esta revisão. Tem precedência sobre $1text, $1prependtext e $1appendtext.",
+       "apihelp-edit-param-undoafter": "Desfazer todas as revisões desde $1undo até esta. Se não for definido, desfazer só uma revisão.",
+       "apihelp-edit-param-redirect": "Resolver automaticamente redirecionamentos.",
+       "apihelp-edit-param-contentformat": "Formato para seriação do conteúdo, usado para o texto de entrada.",
+       "apihelp-edit-param-contentmodel": "Modelo de conteúdo do novo conteúdo.",
+       "apihelp-edit-param-token": "A chave deve ser sempre enviada como último parâmetro, ou pelo menos após o parâmetro $1text.",
+       "apihelp-edit-example-edit": "Editar uma página.",
+       "apihelp-edit-example-prepend": "Acrescentar <kbd>_&#95;NOTOC_&#95;</kbd> ao início de uma página.",
+       "apihelp-edit-example-undo": "Desfazer desde a revisão 13579 até à 13585 com resumo automático.",
+       "apihelp-emailuser-description": "Enviar correio eletrónico a um utilizador.",
+       "apihelp-emailuser-param-target": "Utilizador a quem enviar correio eletrónico.",
        "apihelp-emailuser-param-subject": "Assunto.",
        "apihelp-emailuser-param-text": "Texto.",
+       "apihelp-emailuser-param-ccme": "Enviar-me uma cópia desta mensagem.",
+       "apihelp-emailuser-example-email": "Enviar uma mensagem de correio ao utilizador <kbd>WikiSysop</kbd> com o texto <kbd>Content</kbd>.",
+       "apihelp-expandtemplates-description": "Expande todas as predefinições incluídas num texto em notação wiki.",
        "apihelp-expandtemplates-param-title": "Título da página.",
-       "apihelp-feedcontributions-param-feedformat": "O formato do feed.",
-       "apihelp-feedcontributions-param-deletedonly": "Mostrar apenas contribuições eliminadas.",
+       "apihelp-expandtemplates-param-text": "Texto em notação wiki a converter.",
+       "apihelp-expandtemplates-param-revid": "Identificador da revisão, para <nowiki>{{REVISIONID}}</nowiki> e variáveis semelhantes.",
+       "apihelp-expandtemplates-param-prop": "As informações que devem ser obtidas:\n\nNote que se não for selecionado nenhum valor, o resultado irá conter texto em notação wiki mas a saída estará num formato obsoleto.",
+       "apihelp-expandtemplates-paramvalue-prop-wikitext": "O texto em notação wiki expandido.",
+       "apihelp-expandtemplates-paramvalue-prop-categories": "Quaisquer categorias existentes na entrada que não estão representadas no texto em notação wiki de saída.",
+       "apihelp-expandtemplates-paramvalue-prop-properties": "Propriedades da página, definidas por palavras mágicas expandidas, no texto em notação wiki.",
+       "apihelp-expandtemplates-paramvalue-prop-volatile": "Indica se o resultado é volátil e não deve ser reutilizado noutra parte da página.",
+       "apihelp-expandtemplates-paramvalue-prop-ttl": "O período máximo a partir do qual os armazenamentos do resultado na ''cache'' devem ser invalidados.",
+       "apihelp-expandtemplates-paramvalue-prop-modules": "Quaisquer módulos ResourceLoader que as funções do analisador sintático solicitaram que fossem adicionados ao resultado de saída. Um dos valores <kbd>jsconfigvars</kbd> ou <kbd>encodedjsconfigvars</kbd> tem de ser solicitado em conjunto com o valor <kbd>modules</kbd>.",
+       "apihelp-expandtemplates-paramvalue-prop-jsconfigvars": "Devolve as variáveis de configuração JavaScript específicas desta página.",
+       "apihelp-expandtemplates-paramvalue-prop-encodedjsconfigvars": "Devolve as variáveis de configuração JavaScript específicas da página, no formato de uma ''string'' JSON.",
+       "apihelp-expandtemplates-paramvalue-prop-parsetree": "A árvore de análise sintática em XML do texto de entrada.",
+       "apihelp-expandtemplates-param-includecomments": "Indica se devem ser incluídos comentários HTML no resultado.",
+       "apihelp-expandtemplates-param-generatexml": "Gerar a árvore de análise sintática em XML (substituído por $1prop=parsetree).",
+       "apihelp-expandtemplates-example-simple": "Expandir o texto em notação wiki <kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>.",
+       "apihelp-feedcontributions-description": "Devolve um ''feed'' das contribuições do utilizador.",
+       "apihelp-feedcontributions-param-feedformat": "O formato do ''feed''.",
+       "apihelp-feedcontributions-param-user": "Os utilizadores dos quais serão obtidas as contribuições.",
+       "apihelp-feedcontributions-param-namespace": "O espaço nominal pelo qual as contribuições serão filtradas.",
+       "apihelp-feedcontributions-param-year": "Desde o ano.",
+       "apihelp-feedcontributions-param-month": "Desde o mês.",
+       "apihelp-feedcontributions-param-tagfilter": "Filtrar as contribuições para produzir as que têm estas etiquetas.",
+       "apihelp-feedcontributions-param-deletedonly": "Mostrar apenas as contribuições eliminadas.",
+       "apihelp-feedcontributions-param-toponly": "Mostrar apenas as edições mais recentes.",
+       "apihelp-feedcontributions-param-newonly": "Mostrar apenas as edições que são criações de páginas.",
        "apihelp-feedcontributions-param-hideminor": "Ocultar edições menores.",
        "apihelp-feedcontributions-param-showsizediff": "Mostrar diferença de tamanho entre edições.",
-       "apihelp-feedrecentchanges-param-feedformat": "O formato do feed.",
-       "apihelp-feedrecentchanges-param-limit": "Número máximo de resultados a apresentar.",
+       "apihelp-feedcontributions-example-simple": "Devolver as contribuições do utilizador <kbd>Example</kbd>.",
+       "apihelp-feedrecentchanges-description": "Devolve um ''feed'' das mudanças recentes.",
+       "apihelp-feedrecentchanges-param-feedformat": "O formato do ''feed''.",
+       "apihelp-feedrecentchanges-param-namespace": "O espaço nominal ao qual os resultados serão limitados.",
+       "apihelp-feedrecentchanges-param-invert": "Todos os espaços nominais exceto o selecionado.",
+       "apihelp-feedrecentchanges-param-associated": "Incluir o espaço nominal associado (de discussão ou principal).",
+       "apihelp-feedrecentchanges-param-days": "Dias aos quais limitar os resultados.",
+       "apihelp-feedrecentchanges-param-limit": "O número máximo de resultados a serem devolvidos.",
        "apihelp-feedrecentchanges-param-from": "Mostrar alterações desde então.",
        "apihelp-feedrecentchanges-param-hideminor": "Ocultar edições menores.",
-       "apihelp-feedrecentchanges-param-hidebots": "Ocultar alterações feitas por robôs.",
-       "apihelp-feedrecentchanges-param-hidepatrolled": "Ocultar alterações patrulhadas.",
-       "apihelp-feedrecentchanges-param-hidemyself": "Ocultar alterações feitas pelo utilizador atual.",
+       "apihelp-feedrecentchanges-param-hidebots": "Ocultar mudanças feitas por robôs.",
+       "apihelp-feedrecentchanges-param-hideanons": "Ocultar mudanças feitas por utilizadores anónimos.",
+       "apihelp-feedrecentchanges-param-hideliu": "Ocultar mudanças feitas por utilizadores registados.",
+       "apihelp-feedrecentchanges-param-hidepatrolled": "Ocultar mudanças patrulhadas.",
+       "apihelp-feedrecentchanges-param-hidemyself": "Ocultar mudanças feitas pelo utilizador atual.",
+       "apihelp-feedrecentchanges-param-hidecategorization": "Ocultar mudanças de pertença a categorias.",
+       "apihelp-feedrecentchanges-param-tagfilter": "Filtrar por etiqueta.",
        "apihelp-feedrecentchanges-param-target": "Mostrar apenas mudanças em páginas afluentes a esta.",
-       "apihelp-feedrecentchanges-example-simple": "Mostrar mudanças recentes",
-       "apihelp-help-example-main": "Ajuda para o módulo principal",
-       "apihelp-help-example-recursive": "Toda a ajuda numa página",
-       "apihelp-login-param-name": "Nome de utilizador(a).",
+       "apihelp-feedrecentchanges-param-showlinkedto": "Mostrar mudanças em páginas com ligações para a página selecionada.",
+       "apihelp-feedrecentchanges-param-categories": "Mostrar apenas mudanças nas páginas que estão em todas estas categorias.",
+       "apihelp-feedrecentchanges-param-categories_any": "Mostrar mudanças nas páginas que estão em qualquer uma destas categorias.",
+       "apihelp-feedrecentchanges-example-simple": "Mostrar mudanças recentes.",
+       "apihelp-feedrecentchanges-example-30days": "Mostrar as mudanças recentes de 30 dias.",
+       "apihelp-feedwatchlist-description": "Devolve um ''feed'' das páginas vigiadas.",
+       "apihelp-feedwatchlist-param-feedformat": "O formato do ''feed''.",
+       "apihelp-feedwatchlist-param-hours": "Mostrar as mudanças recentes desde há este número de horas.",
+       "apihelp-feedwatchlist-param-linktosections": "Ligar diretamente às secções alteradas, se possível.",
+       "apihelp-feedwatchlist-example-default": "Mostrar o ''feed'' das páginas vigiadas.",
+       "apihelp-feedwatchlist-example-all6hrs": "Mostrar todas as mudanças às páginas vigiadas nas últimas 6 horas.",
+       "apihelp-filerevert-description": "Reverter um ficheiro para uma versão antiga.",
+       "apihelp-filerevert-param-filename": "Nome do ficheiro de destino, sem o prefixo File:.",
+       "apihelp-filerevert-param-comment": "Comentário do carregamento.",
+       "apihelp-filerevert-param-archivename": "Nome de arquivo da revisão para a qual o ficheiro será revertido.",
+       "apihelp-filerevert-example-revert": "Reverter <kbd>Wiki.png</kbd> para a revisão de <kbd>2011-03-05T15:27:40Z</kbd>.",
+       "apihelp-help-description": "Apresentar ajuda para os módulos especificados.",
+       "apihelp-help-param-modules": "Módulos para os quais apresentar ajuda (valores dos parâmetros <var>action</var> e <var>format</var>, ou <kbd>main</kbd>). Pode-se especificar submódulos com um <kbd>+</kbd>.",
+       "apihelp-help-param-submodules": "Incluir ajuda para submódulos do módulo nomeado.",
+       "apihelp-help-param-recursivesubmodules": "Incluir ajuda para os submódulos de forma recursiva.",
+       "apihelp-help-param-helpformat": "Formato de saída da ajuda.",
+       "apihelp-help-param-wrap": "Envolver a saída numa estrutura padrão de resposta da API.",
+       "apihelp-help-param-toc": "Incluir uma tabela de conteúdo na saída HTML.",
+       "apihelp-help-example-main": "Ajuda para o módulo principal.",
+       "apihelp-help-example-submodules": "Ajuda para <kbd>action=query</kbd> e todos os respetivos submódulos.",
+       "apihelp-help-example-recursive": "Toda a ajuda numa página.",
+       "apihelp-help-example-help": "Ajuda para o próprio módulo de ajuda.",
+       "apihelp-help-example-query": "Ajuda para dois submódulos de consulta.",
+       "apihelp-imagerotate-description": "Rodar uma ou mais imagens.",
+       "apihelp-imagerotate-param-rotation": "Graus de rotação da imagem no sentido horário.",
+       "apihelp-imagerotate-example-simple": "Rodar <kbd>File:Example.png</kbd> <kbd>90</kbd> graus.",
+       "apihelp-imagerotate-example-generator": "Rodar todas as imagens na categoria <kbd>Category:Flip</kbd> em <kbd>180</kbd> graus.",
+       "apihelp-import-description": "Importar uma página de outra wiki ou de um ficheiro XML.\n\nNote que o POST do HTTP tem de ser feito como um carregamento de ficheiro (isto é, com multipart/form-data como Content-Type) ao enviar um ficheiro para o parâmetro <var>xml</var>.",
+       "apihelp-import-param-summary": "Resumo da importação para a entrada do registo.",
+       "apihelp-import-param-xml": "Ficheiro XML carregado.",
+       "apihelp-import-param-interwikisource": "Para importações interwikis: a wiki de onde importar.",
+       "apihelp-import-param-interwikipage": "Para importações interwikis: a página a importar.",
+       "apihelp-import-param-fullhistory": "Para importações interwikis: importar o historial completo, não apenas a versão atual.",
+       "apihelp-import-param-templates": "Para importações interwikis: importar também todas as predefinições incluídas.",
+       "apihelp-import-param-namespace": "Importar para este espaço nominal. Não pode ser usado em conjunto com <var>$1rootpage</var>.",
+       "apihelp-import-param-rootpage": "Importar como subpágina desta página. Não pode ser usado em conjunto com <var>$1namespace</var>.",
+       "apihelp-import-example-import": "Importar [[meta:Help:ParserFunctions]] para o espaço nominal 100 com o historial completo.",
+       "apihelp-linkaccount-description": "Ligar uma conta de um fornecedor terceiro ao utilizador atual.",
+       "apihelp-linkaccount-example-link": "Iniciar o processo de ligação a uma conta do fornecedor <kbd>Example</kbd>.",
+       "apihelp-login-description": "Entrar e obter ''cookies'' de autenticação.\n\nEsta operação só deve ser usada em combinação com [[Special:BotPasswords]]; a sua utilização para entrar com a conta principal é obsoleta e poderá falhar sem aviso. Para entrar com a conta principal de forma segura, use <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd>.",
+       "apihelp-login-description-nobotpasswords": "Entrar e obter ''cookies'' de autenticação.\n\nEsta operação é obsoleta e poderá falhar sem aviso. Para entrar de forma segura, use <kbd>[[Special:ApiHelp/clientlogin|action=clientlogin]]</kbd>.",
+       "apihelp-login-param-name": "Nome de utilizador.",
        "apihelp-login-param-password": "Palavra-passe.",
        "apihelp-login-param-domain": "Domínio (opcional).",
-       "apihelp-login-example-login": "Entrar",
-       "apihelp-logout-description": "Terminar e limpar dados de sessão.",
-       "apihelp-managetags-description": "Executar tarefas de gestão relacionadas com alteração de etiquetas.",
+       "apihelp-login-param-token": "Chave de início de sessão obtida no primeiro pedido.",
+       "apihelp-login-example-gettoken": "Obter uma chave de início de sessão.",
+       "apihelp-login-example-login": "Entrar.",
+       "apihelp-logout-description": "Terminar a sessão e limpar os dados da sessão.",
+       "apihelp-logout-example-logout": "Terminar a sessão do utilizador atual.",
+       "apihelp-managetags-description": "Executar tarefas de gestão relacionadas com etiquetas de modificação.",
+       "apihelp-managetags-param-operation": "A operação que será realizada:\n;create:Criar uma nova etiqueta de modificação para uso manual.\n;delete:Remover da base de dados uma etiqueta de modificação, incluindo remover a etiqueta de todas as revisões, entradas nas mudanças recentes e entradas do registo onde ela é utilizada.\n;activate:Ativar uma etiqueta de modificação, permitindo que os utilizadores a apliquem manualmente.\n;deactivate:Desativar uma etiqueta de modificação, impedindo que os utilizadores a apliquem manualmente.",
+       "apihelp-managetags-param-tag": "Etiqueta a ser criada, eliminada, ativada ou desativada. Para criar uma etiqueta ela não pode existir. Para eliminar uma etiqueta, ela tem de existir. Para ativar uma etiqueta, ela tem de existir e não estar a ser utilizada por nenhuma extensão. Para desativar uma etiqueta, ela tem de estar ativa e definida manualmente.",
        "apihelp-managetags-param-reason": "Um motivo, opcional, para a criação, eliminação, ativação ou desativação da etiqueta.",
+       "apihelp-managetags-param-ignorewarnings": "Indica se devem ser ignorados todos os avisos gerados durante a operação.",
+       "apihelp-managetags-example-create": "Criar uma etiqueta com o nome <kbd>spam</kbd> e o motivo <kbd>For use in edit patrolling</kbd>",
+       "apihelp-managetags-example-delete": "Eliminar a etiqueta <kbd>vandlaism</kbd> com o motivo <kbd>Misspelt</kbd>",
+       "apihelp-managetags-example-activate": "Ativar uma etiqueta com o nome <kbd>spam</kbd> e o motivo <kbd>For use in edit patrolling</kbd>",
+       "apihelp-managetags-example-deactivate": "Desativar uma etiqueta com o nome <kbd>spam</kbd> e o motivo <kbd>No longer required</kbd>",
+       "apihelp-mergehistory-description": "Fundir o historial de páginas.",
+       "apihelp-mergehistory-param-from": "Título da página cujo historial será fundido. Não pode ser usado em conjunto com <var>$1fromid</var>.",
+       "apihelp-mergehistory-param-fromid": "Identificador da página cujo historial será fundido. Não pode ser usado em conjunto com <var>$1from</var>.",
+       "apihelp-mergehistory-param-to": "Título da página à qual o historial será fundido. Não pode ser usado em conjunto com <var>$1toid</var>.",
+       "apihelp-mergehistory-param-toid": "Identificador da página à qual o historial será fundido. Não pode ser usado em conjunto com <var>$1to</var>.",
+       "apihelp-mergehistory-param-timestamp": "Data e hora até a qual as revisões serão movidas do historial da página de origem para o historial das páginas de destino. Se omitido, todo o historial da página de origem será fundido com a página de destino.",
+       "apihelp-mergehistory-param-reason": "Motivo para fundir o historial.",
+       "apihelp-mergehistory-example-merge": "Fundir todo o historial da página <kbd>Oldpage</kbd> com o da página <kbd>Newpage</kbd>.",
+       "apihelp-mergehistory-example-merge-timestamp": "Fundir as revisões de <kbd>Oldpage</kbd> até à data e hora <kbd>2015-12-31T04:37:41Z</kbd> com <kbd>Newpage</kbd>.",
        "apihelp-move-description": "Mover uma página.",
+       "apihelp-move-param-from": "Título da página cujo nome será alterado. Não pode ser usado em conjunto com <var>$1fromid</var>.",
+       "apihelp-move-param-fromid": "Identificador da página cujo nome será alterado. Não pode ser usado em conjunto com <var>$1from</var>.",
+       "apihelp-move-param-to": "Novo título da página.",
+       "apihelp-move-param-reason": "Motivo para a alteração do nome.",
+       "apihelp-move-param-movetalk": "Alterar o nome da página de discussão, se esta existir.",
+       "apihelp-move-param-movesubpages": "Alterar o nome das subpáginas, se estas existirem.",
        "apihelp-move-param-noredirect": "Não criar um redirecionamento.",
+       "apihelp-move-param-watch": "Adicionar a página e o redirecionamento às páginas vigiadas do utilizador atual.",
+       "apihelp-move-param-unwatch": "Remover a página e o redirecionamento das páginas vigiadas do utilizador atual.",
+       "apihelp-move-param-watchlist": "Adicionar ou remover incondicionalmente a página da lista de páginas vigiadas do utilizador atual, usar as preferências ou não alterar o estado de vigilância.",
        "apihelp-move-param-ignorewarnings": "Ignorar quaisquer avisos.",
-       "apihelp-opensearch-param-limit": "Número máximo de resultados a apresentar.",
-       "apihelp-options-param-reset": "Reiniciar preferências para os padrões do sítio.",
-       "apihelp-options-example-reset": "Reiniciar todas as preferências",
-       "apihelp-parse-param-section": "Apenas analisar o conteúdo desta secção.\n\nQuando <kbd>nova</kbd>, analise <var>$1text</var> e <var>$1sectiontitle</var> como se fosse adicionar uma nova secção da página.\n\n<kbd>novo</kbd> só é permitido quando especifica <var>text</var>.",
-       "apihelp-patrol-description": "Patrulhar uma página ou edição.",
-       "apihelp-patrol-example-rcid": "Patrulhar uma mudança recente",
-       "apihelp-patrol-example-revid": "Patrulhar uma edição",
-       "apihelp-protect-example-protect": "Proteger uma página",
+       "apihelp-move-example-move": "Mover <kbd>Badtitle</kbd> para <kbd>Goodtitle</kbd> sem deixar um redirecionamento.",
+       "apihelp-opensearch-description": "Pesquisar a wiki usando o protocolo OpenSearch.",
+       "apihelp-opensearch-param-search": "Texto a pesquisar.",
+       "apihelp-opensearch-param-limit": "O número máximo de resultados a serem devolvidos.",
+       "apihelp-opensearch-param-namespace": "Espaços nominais a pesquisar.",
+       "apihelp-opensearch-param-suggest": "Não fazer nada se <var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> for falso.",
+       "apihelp-opensearch-param-redirects": "Como tratar redirecionamentos:\n;return:Devolver o próprio redirecionamento.\n;resolve:Devolver a página de destino. Pode devolver menos de $1limit resultados.\nPor razões históricas, o valor por omissão é \"return\" para o formato $1format=json e \"resolve\" para outros formatos.",
+       "apihelp-opensearch-param-format": "O formato do resultado.",
+       "apihelp-opensearch-param-warningsaserror": "Se forem gerados avisos com <kbd>format=json</kbd>, devolver um erro da API em vez de ignorá-los.",
+       "apihelp-opensearch-example-te": "Encontrar as páginas que começam por <kbd>Te</kbd>.",
+       "apihelp-options-description": "Alterar as preferências do utilizador atual.\n\nSó podem ser definidas as opções que estão registadas no núcleo do MediaWiki ou numa das extensões instaladas, ou opções cuja chave tem o prefixo <code>userjs-</code> (que são supostas ser usadas por ''scripts'' de utilizador).",
+       "apihelp-options-param-reset": "Reiniciar preferências para os valores por omissão do ''site''.",
+       "apihelp-options-param-resetkinds": "Lista dos tipos de opções a reiniciar quando a opção <var>$1reset</var> está definida.",
+       "apihelp-options-param-change": "Listas das alterações, na forma nome=valor (isto é, skin=vector). Se não for fornecido nenhum valor (nem sequer um sinal de igualdade), por exemplo, nomedaopção|outraopção|..., a opção será reiniciada para o seu valor por omissão. Se qualquer dos valores passados contém uma barra vertical (<kbd>|</kbd>), use um [[Special:ApiHelp/main#main/datatypes|separador alternativo para valores múltiplos]] de forma a obter o comportamento correto.",
+       "apihelp-options-param-optionname": "O nome da opção que deve ser configurada com o valor dado por <var>$1optionvalue</var>.",
+       "apihelp-options-param-optionvalue": "O valor para a opção especificada por <var>$1optionname</var>.",
+       "apihelp-options-example-reset": "Reiniciar todas as preferências.",
+       "apihelp-options-example-change": "Alterar as preferências <kbd>skin</kbd> e <kbd>hideminor</kbd>.",
+       "apihelp-options-example-complex": "Reiniciar todas as preferências e depois definir <kbd>skin</kbd> e <kbd>nickname</kbd>.",
+       "apihelp-paraminfo-description": "Obter informação sobre os módulos da API.",
+       "apihelp-paraminfo-param-modules": "Lista dos nomes dos módulos (valores dos parâmetros <var>action</var> e <var>format</var>, ou <kbd>main</kbd>). Podem ser especificados submódulos com <kbd>+</kbd>, ou todos os submódulos com <kbd>+*</kbd>, ou todos os submódulos de forma recursiva com <kbd>+**</kbd>.",
+       "apihelp-paraminfo-param-helpformat": "Formato dos textos de ajuda.",
+       "apihelp-paraminfo-param-querymodules": "Lista de nomes dos módulos a consultar (valores dos parâmetros <var>prop</var>, <var>meta</var> ou <var>list</var>). Usar <kbd>$1modules=query+foo</kbd> em vez de <kbd>$1querymodules=foo</kbd>.",
+       "apihelp-paraminfo-param-mainmodule": "Obter também informação sobre o módulo principal (do nível de topo). Em vez de usá-lo, usar <kbd>$1modules=main</kbd>.",
+       "apihelp-paraminfo-param-pagesetmodule": "Obter também informação sobre o módulo pageset (fornecendo titles= e restantes).",
+       "apihelp-paraminfo-param-formatmodules": "Lista de nomes de módulos de formato (valor do parâmetro <var>format</var>). Em vez de usá-lo, use <var>$1modules</var>.",
+       "apihelp-paraminfo-example-1": "Mostrar informação para <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>, <kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>, <kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd> e <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>.",
+       "apihelp-paraminfo-example-2": "Mostrar informação de todos os módulos de <kbd>[[Special:ApiHelp/query|action=query]]</kbd>.",
+       "apihelp-parse-description": "Faz a análise sintática do conteúdo e devolve o resultado da análise.\n\nConsulte os vários módulos disponíveis no parâmetro prop de <kbd>[[Special:ApiHelp/query|action=query]]</kbd> para obter informação da versão atual de uma página.\n\nHá várias formas de especificar o texto a analisar:\n# Especificar uma página ou revisão, usando <var>$1page</var>, <var>$1pageid</var> ou <var>$1oldid</var>.\n# Especificar o conteúdo de forma explícita, usando <var>$1text</var>, <var>$1title</var> e <var>$1contentmodel</var>.\n# Especificar só um resumo a analisar. <var>$1prop</var> deve receber o valor vazio.",
+       "apihelp-parse-param-title": "Título da página à qual o texto pertence. Se omitido, é preciso especificar <var>$1contentmodel</var> e deve usar [[API]] como título.",
+       "apihelp-parse-param-text": "Texto a analisar. Usar <var>$1title</var> ou <var>$1contentmodel</var> para controlar o modelo de conteúdo.",
+       "apihelp-parse-param-summary": "Resumo a analisar.",
+       "apihelp-parse-param-page": "Analisar o conteúdo desta página. Não pode ser usado em conjunto com <var>$1text</var> e <var>$1title</var>.",
+       "apihelp-parse-param-pageid": "Analisar o conteúdo desta página. Tem precedência sobre <var>$1page</var>.",
+       "apihelp-parse-param-redirects": "Se <var>$1page</var> ou <var>$1pageid</var> estiverem definidos para um redirecionamento, resolvê-lo.",
+       "apihelp-parse-param-oldid": "Analisar o conteúdo desta revisão. Tem precedência sobre <var>$1page</var> e <var>$1pageid</var>.",
+       "apihelp-parse-param-prop": "As informações que devem ser obtidas:",
+       "apihelp-parse-paramvalue-prop-text": "Fornece o texto analisado, de um texto com notação wiki.",
+       "apihelp-parse-paramvalue-prop-langlinks": "Fornece os links interlínguas do texto analisado.",
+       "apihelp-parse-paramvalue-prop-categories": "Fornece as categorias do texto analisado.",
+       "apihelp-parse-paramvalue-prop-categorieshtml": "Fornece a versão HTML das categorias.",
+       "apihelp-parse-paramvalue-prop-links": "Fornece os links internos do texto analisado.",
+       "apihelp-parse-paramvalue-prop-templates": "Fornece as predefinições do texto analisado.",
+       "apihelp-parse-paramvalue-prop-images": "Fornece as imagens do texto analisado.",
+       "apihelp-parse-paramvalue-prop-externallinks": "Fornece os links externos do texto analisado.",
+       "apihelp-parse-paramvalue-prop-sections": "Fornece as secções do texto analisado.",
+       "apihelp-parse-paramvalue-prop-revid": "Adiciona o identificador de revisão da página analisada.",
+       "apihelp-parse-paramvalue-prop-displaytitle": "Adiciona o título do texto analisado.",
+       "apihelp-parse-paramvalue-prop-headitems": "<span class=\"apihelp-deprecated\">Obsoleto.</span> Fornece os elementos a colocar no <code>&lt;head&gt;</code> da página.",
+       "apihelp-parse-paramvalue-prop-headhtml": "Fornece o <code>&lt;head&gt;</code> analisado da página.",
+       "apihelp-parse-paramvalue-prop-modules": "Fornece os módulos ResourceLoader usados na página. Para carregá-los, usar <code>mw.loader.using()</code>. Uma das variáveis <kbd>jsconfigvars</kbd> ou <kbd>encodedjsconfigvars</kbd> tem de ser pedida em conjunto com <kbd>modules</kbd>.",
+       "apihelp-parse-paramvalue-prop-jsconfigvars": "Fornece as variáveis de configuração JavaScript específicas da página. Para aplicá-las, usar <code>mw.config.set()</code>.",
+       "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "Fornece as variáveis de configuração JavaScript específicas da página, no formato de uma ''string'' JSON.",
+       "apihelp-parse-paramvalue-prop-indicators": "Fornece o HTML dos indicadores de estado de página que são usados na página.",
+       "apihelp-parse-paramvalue-prop-iwlinks": "Fornece os links interwikis do texto analisado.",
+       "apihelp-parse-paramvalue-prop-wikitext": "Fornece o texto original com notação wiki que foi analisado.",
+       "apihelp-parse-paramvalue-prop-properties": "Fornece várias propriedades definidas no texto analisado.",
+       "apihelp-parse-paramvalue-prop-limitreportdata": "Fornece o relatório de limites de forma estruturada. Não fornece dados quando <var>$1disablelimitreport</var> está definido.",
+       "apihelp-parse-paramvalue-prop-limitreporthtml": "Fornece a versão HTML do relatório de limites. Não fornece dados quando <var>$1disablelimitreport</var> está definido.",
+       "apihelp-parse-paramvalue-prop-parsetree": "A árvore de análise XML do conteúdo da revisão (requer o modelo de conteúdo <code>$1</code>).",
+       "apihelp-parse-param-pst": "Fazer uma transformação de pré-gravação ao texto de entrada, antes de analisá-lo. Só é válido quando usado com texto.",
+       "apihelp-parse-param-onlypst": "Fazer uma transformação de pré-gravação (PST, ''pre-save transform'') ao texto de entrada, mas não o analisar. Devolve o mesmo texto após aplicação da PST. Só é válido quando usado com <var>$1text</var>.",
+       "apihelp-parse-param-effectivelanglinks": "Inclui links interlínguas fornecidos por extensões (para ser usado com <kbd>$1prop=langlinks</kbd>).",
+       "apihelp-parse-param-section": "Analisar apenas o conteúdo desta secção.\n\nQuando tiver o valor <kbd>new</kbd>, analisar <var>$1text</var> e <var>$1sectiontitle</var> como se fosse adicionar uma nova secção à página.\n\n<kbd>new</kbd> só é permitido quando se especifica <var>text</var>.",
+       "apihelp-parse-param-sectiontitle": "O novo título da secção quando <var>section</var> tem o valor <kbd>new</kbd>.\n\nAo contrário da edição de páginas, este não toma o valor de <var>summary</var> se for omitido ou estiver vazio.",
+       "apihelp-parse-param-disablelimitreport": "Omitir o relatório de limites (\"NewPP limit report\") do resultado de saída do analisador sintático.",
+       "apihelp-parse-param-disablepp": "Em vez deste, usar <var>$1disablelimitreport</var>.",
+       "apihelp-parse-param-disableeditsection": "Omitir links para edição da secção no resultado da análise sintática.",
+       "apihelp-parse-param-disabletidy": "Não fazer a limpeza do HTML (isto é, o ''tidy'') no resultado da análise sintática.",
+       "apihelp-parse-param-generatexml": "Gerar a árvore de análise XML (requer o modelo de conteúdo <code>$1</code>; substituído por <kbd>$2prop=parsetree</kbd>).",
+       "apihelp-parse-param-preview": "Executar a análise em modo de antevisão.",
+       "apihelp-parse-param-sectionpreview": "Executar a análise em modo de antevisão (também ativa o modo de antevisão).",
+       "apihelp-parse-param-disabletoc": "Omitir a tabela de conteúdo no resultado.",
+       "apihelp-parse-param-contentformat": "O formato da seriação de conteúdo, usado para o texto de entrada. Só é válido quando usado com $1text.",
+       "apihelp-parse-param-contentmodel": "Modelo de conteúdo do texto de entrada. Se omitido, $1title tem de ser especificado e o valor por omissão será o modelo do título especificado. Só é válido quando usado com $1text.",
+       "apihelp-parse-example-page": "Fazer a análise sintática de uma página.",
+       "apihelp-parse-example-text": "Fazer a análise sintática do texto com notação wiki.",
+       "apihelp-parse-example-texttitle": "Fazer a análise sintática do texto com notação wiki, especificando o título da página.",
+       "apihelp-parse-example-summary": "Fazer a análise sintática de um resumo.",
+       "apihelp-patrol-description": "Patrulhar uma página ou revisão.",
+       "apihelp-patrol-param-rcid": "Identificador da mudança recente a patrulhar.",
+       "apihelp-patrol-param-revid": "Identificador da revisão a patrulhar.",
+       "apihelp-patrol-param-tags": "Etiquetas de modificação a aplicar à entrada do registo de patrulha.",
+       "apihelp-patrol-example-rcid": "Patrulhar uma mudança recente.",
+       "apihelp-patrol-example-revid": "Patrulhar uma revisão.",
+       "apihelp-protect-description": "Alterar o nível de proteção de uma página.",
+       "apihelp-protect-param-title": "Título da página a proteger ou desproteger. Não pode ser usado em conjunto com $1pageid.",
+       "apihelp-protect-param-pageid": "Identificador da página a proteger ou desproteger. Não pode ser usado em conjunto com $1title.",
+       "apihelp-protect-param-protections": "Lista de níveis de proteção, na forma <kbd>action=level</kbd> (por exemplo, <kbd>edit=sysop</kbd>). O nível <kbd>all</kbd> significada que todos podem executar a operação, isto é, sem restrição.\n\n<strong>Nota:</strong> Serão removidas as restrições de quaisquer operações não listadas.",
+       "apihelp-protect-param-expiry": "Datas e horas de expiração. Se só uma data e hora for definida, será usada para todas as proteções. Use <kbd>infinite</kbd>, <kbd>indefinite</kbd>, <kbd>infinity</kbd> ou <kbd>never</kbd>, para proteção sem expiração.",
+       "apihelp-protect-param-reason": "Motivo da proteção ou desproteção.",
+       "apihelp-protect-param-tags": "Etiquetas de modificação a aplicar à entrada no registo de proteções.",
+       "apihelp-protect-param-cascade": "Ativar a proteção em cascata (isto é, proteger as predefinições transcluídas e as imagens usadas nesta página). Ignorado se nenhum dos níveis de proteção dados suportam a proteção em cascata.",
+       "apihelp-protect-param-watch": "Se definido, adicionar a página que está a ser protegida ou desprotegida às páginas vigiadas do utilizador atual.",
+       "apihelp-protect-param-watchlist": "Adicionar ou remover incondicionalmente a página da lista de páginas vigiadas do utilizador atual, usar as preferências ou não alterar o estado de vigilância.",
+       "apihelp-protect-example-protect": "Proteger uma página.",
+       "apihelp-protect-example-unprotect": "Desproteger uma página definindo a restrição <kbd>all</kbd> (isto é, todos podem executar a operação).",
+       "apihelp-protect-example-unprotect2": "Desproteger uma página definindo que não há restrições.",
+       "apihelp-purge-description": "Limpar a ''cache'' para os títulos especificados.\n\nRequer um pedido POST se o utilizador não tiver iniciado uma sessão.",
+       "apihelp-purge-param-forcelinkupdate": "Atualizar as tabelas de ligações.",
+       "apihelp-purge-param-forcerecursivelinkupdate": "Atualizar a tabela de ligações, e atualizar as tabelas de ligações de qualquer página que usa esta página como modelo.",
+       "apihelp-purge-example-simple": "Purgar as páginas <kbd>Main Page</kbd> e <kbd>API</kbd>.",
+       "apihelp-purge-example-generator": "Purgar as primeiras 10 páginas no espaço nominal principal.",
+       "apihelp-query-description": "Obter dados do MediaWiki e acerca dele.\n\nTodas as modificações de dados têm primeiro que usar um pedido para adquirir uma chave, de forma a impedir ações abusivas de ''sites'' maliciosos.",
+       "apihelp-query-param-prop": "As propriedades a serem obtidas para as páginas consultadas.",
+       "apihelp-query-param-list": "As listas a serem obtidas.",
+       "apihelp-query-param-meta": "Os metadados a serem obtidos.",
+       "apihelp-query-param-indexpageids": "Incluir uma secção adicional de identificadores de página que lista todos os identificadores de página devolvidos.",
+       "apihelp-query-param-export": "Exportar as revisões atuais de todas as páginas fornecidas ou geradas.",
+       "apihelp-query-param-exportnowrap": "Devolver o XML de exportação sem envolvê-lo num resultado XML (o mesmo formato que [[Special:Export]]). Só pode ser usado com $1export.",
+       "apihelp-query-param-iwurl": "Indica se deve ser obtido o URL completo quando o título é um ''link'' interwikis.",
+       "apihelp-query-param-rawcontinue": "Devolver os dados em bruto de <samp>query-continue</samp> para continuar.",
+       "apihelp-query-example-revisions": "Obter [[Special:ApiHelp/query+siteinfo|informação do ''site'']] e as [[Special:ApiHelp/query+revisions|revisões]] da página <kbd>Main Page</kbd>.",
+       "apihelp-query-example-allpages": "Obter as revisões das páginas que começam por <kbd>API/</kbd>.",
        "apihelp-query+allcategories-description": "Enumerar todas as categorias.",
-       "apihelp-query+alldeletedrevisions-example-user": "Lista das últimas 50 contribuições eliminadas pelo utilizador <kbd>Example</kbd>.",
-       "apihelp-query+allpages-param-prefix": "Pesquisa para todos os títulos de páginas que comecem com este valor.",
-       "apihelp-query+allpages-example-generator": "Mostrar informação sobre 4 páginas que comecem com a letra <kbd>T</kbd>.",
-       "apihelp-query+allusers-example-Y": "Lista de utilizadores que comecem com <kbd>Y</kbd>.",
-       "apihelp-query+backlinks-example-simple": "Mostrar ligações para <kbd>Main page</kbd>.",
-       "apihelp-query+backlinks-example-generator": "Obter informações sobre as páginas com ligação para <kbd>Main page</kbd>.",
+       "apihelp-query+allcategories-param-from": "A categoria a partir da qual será começada a enumeração.",
+       "apihelp-query+allcategories-param-to": "A categoria na qual será terminada a enumeração.",
+       "apihelp-query+allcategories-param-prefix": "Procurar todos os títulos de categorias que começam por este valor.",
+       "apihelp-query+allcategories-param-dir": "A direção da ordenação.",
+       "apihelp-query+allcategories-param-min": "Só devolver as categorias que tenham no mínimo este número de membros.",
+       "apihelp-query+allcategories-param-max": "Só devolver as categorias que tenham no máximo este número de membros.",
+       "apihelp-query+allcategories-param-limit": "O número de categorias a serem devolvidas.",
+       "apihelp-query+allcategories-param-prop": "As propriedades a serem obtidas:",
+       "apihelp-query+allcategories-paramvalue-prop-size": "Adiciona o número de páginas na categoria.",
+       "apihelp-query+allcategories-paramvalue-prop-hidden": "Etiqueta as categorias ocultadas com <code>_&#95;HIDDENCAT_&#95;</code>.",
+       "apihelp-query+allcategories-example-size": "Lista as categorias com informação sobre o número de páginas em cada uma delas.",
+       "apihelp-query+allcategories-example-generator": "Obter informação sobre a própria página de categoria, para as categorias que começam por <kbd>List</kbd>.",
+       "apihelp-query+alldeletedrevisions-description": "Listar todas as revisões eliminadas por um utilizador ou de um espaço nominal.",
+       "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Só pode ser usado com <var>$3user</var>.",
+       "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "Não pode ser usado com <var>$3user</var>.",
+       "apihelp-query+alldeletedrevisions-param-start": "A data e hora da revisão a partir da qual será começada a enumeração.",
+       "apihelp-query+alldeletedrevisions-param-end": "A data e hora na qual será terminada a enumeração.",
+       "apihelp-query+alldeletedrevisions-param-from": "Começar a listagem neste título.",
+       "apihelp-query+alldeletedrevisions-param-to": "Terminar a listagem neste título.",
+       "apihelp-query+alldeletedrevisions-param-prefix": "Procurar todos os títulos de página que começam por este valor.",
+       "apihelp-query+alldeletedrevisions-param-tag": "Listar só as revisões marcadas com esta etiqueta.",
+       "apihelp-query+alldeletedrevisions-param-user": "Listar só as revisões feitas por este utilizador.",
+       "apihelp-query+alldeletedrevisions-param-excludeuser": "Não listar as revisões feitas por este utilizador.",
+       "apihelp-query+alldeletedrevisions-param-namespace": "Listar só as páginas neste espaço nominal.",
+       "apihelp-query+alldeletedrevisions-param-miser-user-namespace": "<strong>Nota:</strong> Devido ao [[mw:Manual:$wgMiserMode|modo avarento]], o uso de <var>$1user</var> e <var>$1namespace</var> em conjunto pode resultar na devolução de menos de <var>$1limit</var> resultados antes de continuar; em casos extremos pode não ser devolvido qualquer resultado.",
+       "apihelp-query+alldeletedrevisions-param-generatetitles": "Ao ser usado como gerador, gerar títulos em vez de identificadores de revisões.",
+       "apihelp-query+alldeletedrevisions-example-user": "Listar as últimas 50 contribuições eliminadas do utilizador <kbd>Example</kbd>.",
+       "apihelp-query+alldeletedrevisions-example-ns-main": "Listar as primeiras 50 revisões eliminadas no espaço nominal principal.",
+       "apihelp-query+allfileusages-description": "Listar todas as utilizações de ficheiros, incluindo ficheiros que não existam.",
+       "apihelp-query+allfileusages-param-from": "O título do ficheiro a partir do qual será começada a enumeração.",
+       "apihelp-query+allfileusages-param-to": "O título do ficheiro no qual será terminada a enumeração.",
+       "apihelp-query+allfileusages-param-prefix": "Procurar todos os títulos de ficheiro que começam por este valor.",
+       "apihelp-query+allfileusages-param-unique": "Mostrar só nomes de ficheiro únicos. Não pode ser usado com <kbd>$1prop=ids</kbd>.\nAo ser usado como gerador, produz páginas de destino em vez de páginas de origem.",
+       "apihelp-query+allfileusages-param-prop": "As informações que devem ser incluídas:",
+       "apihelp-query+allfileusages-paramvalue-prop-ids": "Adiciona os identificadores das páginas que utilizam (não pode ser usado com <var>$1unique</var>).",
+       "apihelp-query+allfileusages-paramvalue-prop-title": "Adiciona o título do ficheiro.",
+       "apihelp-query+allfileusages-param-limit": "O número total de elementos a serem devolvidos.",
+       "apihelp-query+allfileusages-param-dir": "A direção de listagem.",
+       "apihelp-query+allfileusages-example-B": "Listar os títulos de ficheiros, incluindo aqueles em falta, com os identificadores das páginas de onde provêm, começando no <kbd>B</kbd>.",
+       "apihelp-query+allfileusages-example-unique": "Listar os títulos de ficheiro únicos.",
+       "apihelp-query+allfileusages-example-unique-generator": "Obtém todos os títulos de ficheiros, marcando aqueles em falta.",
+       "apihelp-query+allfileusages-example-generator": "Obtém as páginas que contêm os ficheiros.",
+       "apihelp-query+allimages-description": "Enumerar todas as imagens sequencialmente.",
+       "apihelp-query+allimages-param-sort": "Propriedade pela qual fazer a ordenação.",
+       "apihelp-query+allimages-param-dir": "A direção de listagem.",
+       "apihelp-query+allimages-param-from": "O título da imagem a partir do qual será começada a enumeração. Só pode ser usado com $1sort=name.",
+       "apihelp-query+allimages-param-to": "O título da imagem no qual será terminada a enumeração. Só pode ser usado com $1sort=name.",
+       "apihelp-query+allimages-param-start": "A data e hora da imagem a partir da qual será começada a enumeração. Só pode ser usado com $1sort=timestamp.",
+       "apihelp-query+allimages-param-end": "A data e hora da imagem na qual será terminada a enumeração. Só pode ser usado com $1sort=timestamp.",
+       "apihelp-query+allimages-param-prefix": "Procurar todos os títulos de imagem que começam por este valor. Só pode ser usado com $1sort=name.",
+       "apihelp-query+allimages-param-minsize": "Limitar só às imagens com este número mínimo de bytes.",
+       "apihelp-query+allimages-param-maxsize": "Limitar só às imagens com este número máximo de bytes.",
+       "apihelp-query+allimages-param-sha1": "Resumo criptográfico SHA1 da imagem. Tem precedência sobre $1sha1base36.",
+       "apihelp-query+allimages-param-sha1base36": "Resumo criptográfico SHA1 da imagem em base 36 (usado no MediaWiki).",
+       "apihelp-query+allimages-param-user": "Devolver só os ficheiros carregados por este utilizador. Só pode ser usado com $1sort=timestamp. Não pode ser usado em conjunto com $1filterbots.",
+       "apihelp-query+allimages-param-filterbots": "Como filtrar os ficheiros carregados por robôs. Só pode ser usado com $1sort=timestamp. Não pode ser usado em conjunto com $1user.",
+       "apihelp-query+allimages-param-mime": "Tipos MIME a procurar; por exemplo, <kbd>image/jpeg</kbd>.",
+       "apihelp-query+allimages-param-limit": "O número total de imagens a serem devolvidas.",
+       "apihelp-query+allimages-example-B": "Mostrar uma lista dos ficheiros que começam com a letra <kbd>B</kbd>.",
+       "apihelp-query+allimages-example-recent": "Mostrar uma lista dos ficheiros carregados recentemente, semelhante a [[Special:NewFiles]].",
+       "apihelp-query+allimages-example-mimetypes": "Mostrar uma lista dos ficheiros com os tipos MIME <kbd>image/png</kbd> ou <kbd>image/gif</kbd>.",
+       "apihelp-query+allimages-example-generator": "Mostrar informação sobre 4 ficheiros, começando pela letra <kbd>T</kbd>.",
+       "apihelp-query+alllinks-description": "Enumerar todos os ''links'' que apontam para um determinado espaço nominal.",
+       "apihelp-query+alllinks-param-from": "O título do ''link'' a partir do qual será começada a enumeração.",
+       "apihelp-query+alllinks-param-to": "O título do ''link'' no qual será terminada a enumeração.",
+       "apihelp-query+alllinks-param-prefix": "Procurar todos os títulos ligados que começam por este valor.",
+       "apihelp-query+alllinks-param-unique": "Mostrar só títulos ligados únicos. Não pode ser usado com <kbd>$1prop=ids</kbd>.\nAo ser usado como gerador, produz páginas de destino em vez de páginas de origem.",
+       "apihelp-query+alllinks-param-prop": "As informações que devem ser incluídas:",
+       "apihelp-query+alllinks-paramvalue-prop-ids": "Adiciona o identificador da página que contém a ligação (não pode ser usado com <var>$1unique</var>).",
+       "apihelp-query+alllinks-paramvalue-prop-title": "Adiciona o título do ''link''.",
+       "apihelp-query+alllinks-param-namespace": "O espaço nominal a ser enumerado.",
+       "apihelp-query+alllinks-param-limit": "O número total de entradas a serem devolvidas.",
+       "apihelp-query+alllinks-param-dir": "A direção de listagem.",
+       "apihelp-query+alllinks-example-B": "Listar os títulos para os quais existem ligações, incluindo títulos em falta, com os identificadores das páginas que contêm as respetivas ligações, começando pela letra <kbd>B</kbd>.",
+       "apihelp-query+alllinks-example-unique": "Listar os títulos únicos para os quais existem ligações.",
+       "apihelp-query+alllinks-example-unique-generator": "Obtém todos os títulos para os quais existem ligações, marcando aqueles em falta.",
+       "apihelp-query+alllinks-example-generator": "Obtém as páginas que contêm as ligações.",
+       "apihelp-query+allmessages-description": "Devolver as mensagens deste ''site''.",
+       "apihelp-query+allmessages-param-messages": "Mensagens a serem produzidas no resultado. <kbd>*</kbd> (o valor por omissão) significa todas as mensagens.",
+       "apihelp-query+allmessages-param-prop": "As propriedades a serem obtidas:",
+       "apihelp-query+allmessages-param-enableparser": "Definir, para ativar o analisador sintático e pré-processar o texto da mensagem com notação wiki (substituir palavras mágicas, processar predefinições, etc.).",
+       "apihelp-query+allmessages-param-nocontent": "Se definido, não incluir o conteúdo das mensagens no resultado de saída.",
+       "apihelp-query+allmessages-param-includelocal": "Incluir também as mensagens locais, isto é, mensagens que não existem no software mas existem como uma página no espaço nominal MediaWiki:.\nIsto lista todas as páginas do espaço nominal MediaWiki:, portanto, também irá listar aquelas que não são verdadeiramente mensagens, como [[MediaWiki:Common.js|Common.js]].",
+       "apihelp-query+allmessages-param-args": "Os argumentos a serem substituídos na mensagem.",
+       "apihelp-query+allmessages-param-filter": "Devolver só as mensagens cujos nomes contêm este texto.",
+       "apihelp-query+allmessages-param-customised": "Devolver só as mensagens neste estado de personalização.",
+       "apihelp-query+allmessages-param-lang": "Devolver as mensagens nesta língua.",
+       "apihelp-query+allmessages-param-from": "Devolver as mensagens, a partir desta mensagem.",
+       "apihelp-query+allmessages-param-to": "Devolver as mensagens, até esta mensagem.",
+       "apihelp-query+allmessages-param-title": "Nome da página a utilizar como contexto ao fazer a análise sintática da mensagem (para a opção $1enableparser).",
+       "apihelp-query+allmessages-param-prefix": "Devolver as mensagens com este prefixo.",
+       "apihelp-query+allmessages-example-ipb": "Mostrar mensagens que começam por <kbd>ipb-</kbd>.",
+       "apihelp-query+allmessages-example-de": "Mostrar as mensagens <kbd>august</kbd> e <kbd>mainpage</kbd> em Alemão.",
+       "apihelp-query+allpages-description": "Enumerar sequencialmente todas as páginas de um determinado espaço nominal.",
+       "apihelp-query+allpages-param-from": "O título de página a partir do qual será começada a enumeração.",
+       "apihelp-query+allpages-param-to": "O título de página no qual será terminada a enumeração.",
+       "apihelp-query+allpages-param-prefix": "Procurar todos os títulos de páginas que comecem com este valor.",
+       "apihelp-query+allpages-param-namespace": "O espaço nominal a ser enumerado.",
+       "apihelp-query+allpages-param-filterredir": "As páginas a serem listadas.",
+       "apihelp-query+allpages-param-minsize": "Limitar só às páginas com este número mínimo de bytes.",
+       "apihelp-query+allpages-param-maxsize": "Limitar só às páginas com este número máximo de bytes.",
+       "apihelp-query+allpages-param-prtype": "Limitar só às páginas protegidas.",
+       "apihelp-query+allpages-param-prlevel": "Filtrar as proteções com base no nível de proteção (tem de ser usado com o parâmetro $1prtype=).",
+       "apihelp-query+allpages-param-prfiltercascade": "Filtrar as proteções com base na proteção em cascata (ignorado se $1prtype não estiver presente).",
+       "apihelp-query+allpages-param-limit": "O número total de páginas a serem devolvidas.",
+       "apihelp-query+allpages-param-dir": "A direção de listagem.",
+       "apihelp-query+allpages-param-filterlanglinks": "Filtrar dependo de uma página ter ''links'' interlínguas. Note que isto pode não tomar em consideração ''links'' interlínguas adicionados por extensões.",
+       "apihelp-query+allpages-param-prexpiry": "O tipo de expiração pelo qual as páginas serão filtradas:\n;indefinite:Obter só páginas com um período de expiração indefinido.\n;definite:Obter só páginas com um período de expiração definido (específico).\n;all:Obter páginas com qualquer período de expiração.",
+       "apihelp-query+allpages-example-B": "Mostrar uma lista de páginas, começando na letra <kbd>B</kbd>.",
+       "apihelp-query+allpages-example-generator": "Mostrar informação sobre 4 páginas, começando na letra <kbd>T</kbd>.",
+       "apihelp-query+allpages-example-generator-revisions": "Mostrar o conteúdo das primeiras 2 páginas que não sejam redirecionamentos, começando na página <kbd>Re</kbd>.",
+       "apihelp-query+allredirects-description": "Listar todos os redirecionamentos para um espaço nominal.",
+       "apihelp-query+allredirects-param-from": "O título do redirecionamento a partir do qual será começada a enumeração.",
+       "apihelp-query+allredirects-param-to": "O título do redirecionamento no qual será terminada a enumeração.",
+       "apihelp-query+allredirects-param-prefix": "Procurar todas as páginas de destino que começam por este valor.",
+       "apihelp-query+allredirects-param-unique": "Mostrar só páginas de destino únicas. Não pode ser usado com <kbd>$1prop=ids|fragment|interwiki</kbd>.\nAo ser usado como gerador, produz páginas de destino em vez de páginas de origem.",
+       "apihelp-query+allredirects-param-prop": "As informações que devem ser incluídas:",
+       "apihelp-query+allredirects-paramvalue-prop-ids": "Adiciona o identificador da página que contém o redirecionamento (não pode ser usado com <var>$1unique</var>).",
+       "apihelp-query+allredirects-paramvalue-prop-title": "Adiciona o título do redirecionamento.",
+       "apihelp-query+allredirects-paramvalue-prop-fragment": "Adiciona o fragmento do redirecionamento, se existir (não pode ser usado com <var>$1unique</var>).",
+       "apihelp-query+allredirects-paramvalue-prop-interwiki": "Adiciona o prefixo interwikis do redirecionamento, se existir (não pode ser usado em conjunto com <var>$1unique</var>).",
+       "apihelp-query+allredirects-param-namespace": "O espaço nominal a ser enumerado.",
+       "apihelp-query+allredirects-param-limit": "O número total de elementos a serem devolvidos.",
+       "apihelp-query+allredirects-param-dir": "A direção de listagem.",
+       "apihelp-query+allredirects-example-B": "Listar as páginas de destino, incluindo aquelas em falta, com os identificadores da página de origem, começando na <kbd>B</kbd>.",
+       "apihelp-query+allredirects-example-unique": "Listar as páginas de destino únicas.",
+       "apihelp-query+allredirects-example-unique-generator": "Obtém todas as páginas de destino, marcando aquelas em falta.",
+       "apihelp-query+allredirects-example-generator": "Obtém as páginas que contêm os redirecionamentos.",
+       "apihelp-query+allrevisions-description": "Listar todas as revisões.",
+       "apihelp-query+allrevisions-param-start": "A data e hora a partir da qual será começada a enumeração.",
+       "apihelp-query+allrevisions-param-end": "A data e hora na qual será terminada a enumeração.",
+       "apihelp-query+allrevisions-param-user": "Listar só as revisões deste utilizador.",
+       "apihelp-query+allrevisions-param-excludeuser": "Não listar as revisões deste utilizador.",
+       "apihelp-query+allrevisions-param-namespace": "Listar só as páginas neste espaço nominal.",
+       "apihelp-query+allrevisions-param-generatetitles": "Ao ser usado como gerador, gerar títulos em vez de identificadores de revisões.",
+       "apihelp-query+allrevisions-example-user": "Listar as últimas 50 contribuições do utilizador <kbd>Example</kbd>.",
+       "apihelp-query+allrevisions-example-ns-main": "Listar as primeiras 50 revisões no espaço nominal principal.",
+       "apihelp-query+mystashedfiles-description": "Obter uma lista dos ficheiros que estão na área de ficheiros escondidos do utilizador atual.",
+       "apihelp-query+mystashedfiles-param-prop": "As propriedades a serem obtidas para os ficheiros.",
+       "apihelp-query+mystashedfiles-paramvalue-prop-size": "Obter o tamanho do ficheiro e as dimensões da imagem.",
+       "apihelp-query+mystashedfiles-paramvalue-prop-type": "Obter o tipo MIME e o tipo de multimédia do ficheiro.",
+       "apihelp-query+mystashedfiles-param-limit": "Quantos ficheiros a serem obtidos.",
+       "apihelp-query+mystashedfiles-example-simple": "Obter a chave, o tamanho e as dimensões em píxeis dos ficheiros na área de ficheiros escondidos do utilizador.",
+       "apihelp-query+alltransclusions-description": "Listar todas as transclusões (páginas incorporadas utilizando &#123;&#123;x&#125;&#125;), incluindo as que estejam em falta.",
+       "apihelp-query+alltransclusions-param-from": "O título da transclusão a partir do qual será começada a enumeração.",
+       "apihelp-query+alltransclusions-param-to": "O título da transclusão no qual será terminada a enumeração.",
+       "apihelp-query+alltransclusions-param-prefix": "Procurar todos os títulos transcluídos que começam por este valor.",
+       "apihelp-query+alltransclusions-param-unique": "Mostrar só títulos transcluídos únicos. Não pode ser usado com <kbd>$1prop=ids</kbd>.\nAo ser usado como gerador, produz páginas de destino em vez de páginas de origem.",
+       "apihelp-query+alltransclusions-param-prop": "As informações que devem ser incluídas:",
+       "apihelp-query+alltransclusions-paramvalue-prop-ids": "Adiciona o identificador da página onde é feita a transclusão (não pode ser usado com <var>$1unique</var>).",
+       "apihelp-query+alltransclusions-paramvalue-prop-title": "Adiciona o título da transclusão.",
+       "apihelp-query+alltransclusions-param-namespace": "O espaço nominal a enumerar.",
+       "apihelp-query+alltransclusions-param-limit": "O número total de elementos a serem devolvidos.",
+       "apihelp-query+alltransclusions-param-dir": "A direção de listagem.",
+       "apihelp-query+alltransclusions-example-B": "Listar os títulos transcluídos, incluindo aqueles em falta, com os identificadores das páginas de origem, começando no <kbd>B</kbd>.",
+       "apihelp-query+alltransclusions-example-unique": "Listar os títulos transcluídos únicos.",
+       "apihelp-query+alltransclusions-example-unique-generator": "Obtém todos os títulos transcluídos, marcando aqueles em falta.",
+       "apihelp-query+alltransclusions-example-generator": "Obtém as páginas que contêm as transclusões.",
+       "apihelp-query+allusers-description": "Enumerar todos os utilizadores registados.",
+       "apihelp-query+allusers-param-from": "O nome de utilizador a partir do qual será começada a enumeração.",
+       "apihelp-query+allusers-param-to": "O nome de utilizador no qual será terminada a enumeração.",
+       "apihelp-query+allusers-param-prefix": "Procurar todos os nomes de utilizador que começam por este valor.",
+       "apihelp-query+allusers-param-dir": "A direção da ordenação.",
+       "apihelp-query+allusers-param-group": "Incluir só os utilizadores nos grupos indicados.",
+       "apihelp-query+allusers-param-excludegroup": "Excluir os utilizadores nos grupos indicados.",
+       "apihelp-query+allusers-param-rights": "Incluir só os utilizadores com as permissões indicadas. Não inclui as permissões atribuídas por grupos implícitos ou de promoção automática como *, utilizador, ou autoconfirmado.",
+       "apihelp-query+allusers-param-prop": "As informações que devem ser incluídas:",
+       "apihelp-query+allusers-paramvalue-prop-blockinfo": "Adiciona a informação sobre um bloqueio atual do utilizador.",
+       "apihelp-query+allusers-paramvalue-prop-groups": "Lista os grupos a que o utilizador pertence. Isto usa mais recursos do servidor e pode devolver menos resultados do que o limite.",
+       "apihelp-query+allusers-paramvalue-prop-implicitgroups": "Lista todos os grupos a que o utilizador pertence de forma automática.",
+       "apihelp-query+allusers-paramvalue-prop-rights": "Lista as permissões que o utilizador tem.",
+       "apihelp-query+allusers-paramvalue-prop-editcount": "Adiciona a contagem de edições do utilizador.",
+       "apihelp-query+allusers-paramvalue-prop-registration": "Adiciona a data e hora de registo do utilizador, se estiver disponível (pode estar vazia).",
+       "apihelp-query+allusers-paramvalue-prop-centralids": "Adiciona os identificadores centrais e o estado de ligação central (''attachment'') do utilizador.",
+       "apihelp-query+allusers-param-limit": "O número total de nomes de utilizador a serem devolvidos.",
+       "apihelp-query+allusers-param-witheditsonly": "Listar só os utilizadores que realizaram edições.",
+       "apihelp-query+allusers-param-activeusers": "Listar só os utilizadores ativos {{PLURAL:$1|no último dia|nos últimos $1 dias}}.",
+       "apihelp-query+allusers-param-attachedwiki": "Com <kbd>$1prop=centralids</kbd>, indicar também se o utilizador tem ligação com a wiki designada por este identificador.",
+       "apihelp-query+allusers-example-Y": "Listar utilizadores, começando pelo <kbd>Y</kbd>.",
+       "apihelp-query+authmanagerinfo-description": "Obter informação sobre o atual estado de autenticação.",
+       "apihelp-query+authmanagerinfo-param-securitysensitiveoperation": "Testar se o estado atual de autenticação do utilizador é suficiente para a operação especificada, que exige condições seguras.",
+       "apihelp-query+authmanagerinfo-param-requestsfor": "Obter informação sobre os pedidos de autenticação que são necessários para a operação de autenticação especificada.",
+       "apihelp-query+authmanagerinfo-example-login": "Obter os pedidos que podem ser usados ao iniciar uma sessão.",
+       "apihelp-query+authmanagerinfo-example-login-merged": "Obter os pedidos que podem ser usados ao iniciar uma sessão, com os campos combinados.",
+       "apihelp-query+authmanagerinfo-example-securitysensitiveoperation": "Testar se a autenticação é suficiente para a operação <kbd>foo</kbd>.",
+       "apihelp-query+backlinks-description": "Encontrar todas as páginas que contêm ligações para a página indicada.",
+       "apihelp-query+backlinks-param-title": "O título a ser procurado. Não pode ser usado em conjunto com <var>$1pageid</var>.",
+       "apihelp-query+backlinks-param-pageid": "O identificador do título a ser procurado. Não pode ser usado em conjunto com <var>$1title</var>.",
+       "apihelp-query+backlinks-param-namespace": "O espaço nominal a ser enumerado.",
+       "apihelp-query+backlinks-param-dir": "A direção de listagem.",
+       "apihelp-query+backlinks-param-filterredir": "Como filtrar os redirecionamentos. Se definido como <kbd>nonredirects</kbd> quando <var>$1redirect</var> está ativado, isto só é aplicado ao segundo nível.",
+       "apihelp-query+backlinks-param-limit": "O número total de páginas a serem devolvidas. Se <var>$1redirect</var> estiver ativado, o limite aplica-se a cada nível em separado (o que significa que até 2 * <var>$1limit</var> resultados podem ser devolvidos).",
+       "apihelp-query+backlinks-param-redirect": "Se a página que contém a ligação é um redirecionamento, procurar também todas as páginas que contêm ligações para esse redirecionamento. O limite máximo é reduzido para metade.",
+       "apihelp-query+backlinks-example-simple": "Mostrar as ligações para <kbd>Main page</kbd>.",
+       "apihelp-query+backlinks-example-generator": "Obter informações sobre as páginas com ligações para <kbd>Main page</kbd>.",
+       "apihelp-query+blocks-description": "Listar todos os utilizadores e endereços IP bloqueados.",
+       "apihelp-query+blocks-param-start": "A data e hora a partir da qual será começada a enumeração.",
+       "apihelp-query+blocks-param-end": "A data e hora na qual será terminada a enumeração.",
+       "apihelp-query+blocks-param-ids": "Lista dos identificadores de bloqueios a serem listados (opcional).",
+       "apihelp-query+blocks-param-users": "Lista dos utilizadores a serem procurados (opcional).",
+       "apihelp-query+blocks-param-ip": "Obter todos os bloqueios aplicáveis a este endereço IP ou intervalo CIDR, incluindo bloqueios de intervalos. Não pode ser usado em conjunto com <var>$3users</var>. Não são aceites intervalos CIDR maiores que IPv4/$1 ou IPv6/$2.",
        "apihelp-query+blocks-param-limit": "O número máximo de bloqueios a listar.",
-       "apihelp-query+categorymembers-description": "Lista de todas as páginas numa categoria fornecida.",
+       "apihelp-query+blocks-param-prop": "As propriedades a serem obtidas:",
+       "apihelp-query+blocks-paramvalue-prop-id": "Adiciona o identificador do bloqueio.",
+       "apihelp-query+blocks-paramvalue-prop-user": "Adiciona o nome do utilizador bloqueado.",
+       "apihelp-query+blocks-paramvalue-prop-userid": "Adiciona o identificador do utilizador bloqueado.",
+       "apihelp-query+blocks-paramvalue-prop-by": "Adiciona o nome do utilizador que fez o bloqueio.",
+       "apihelp-query+blocks-paramvalue-prop-byid": "Adiciona o identificador do utilizador que fez o bloqueio.",
+       "apihelp-query+blocks-paramvalue-prop-timestamp": "Adiciona a data e hora de realização do bloqueio.",
+       "apihelp-query+blocks-paramvalue-prop-expiry": "Adiciona a data e hora de expiração do bloqueio.",
+       "apihelp-query+blocks-paramvalue-prop-reason": "Adiciona o motivo apresentado para o bloqueio.",
+       "apihelp-query+blocks-paramvalue-prop-range": "Adiciona o intervalo de endereços IP afetado pelo bloqueio.",
+       "apihelp-query+blocks-paramvalue-prop-flags": "Etiqueta o bloqueio com (autoblock, anononly, etc.).",
+       "apihelp-query+blocks-param-show": "Mostrar só os bloqueios que preenchem estes critérios.\nPor exemplo, para ver só bloqueios indefinidos de endereços IP, defina <kbd>$1show=ip|!temp</kbd>.",
+       "apihelp-query+blocks-example-simple": "Listar bloqueios.",
+       "apihelp-query+blocks-example-users": "Listar os bloqueios dos utilizadores <kbd>Alice</kbd> e <kbd>Bob</kbd>.",
+       "apihelp-query+categories-description": "Listar todas as categorias às quais as páginas pertencem.",
+       "apihelp-query+categories-param-prop": "As propriedades adicionais que devem ser obtidas para cada categoria:",
+       "apihelp-query+categories-paramvalue-prop-sortkey": "Adiciona a chave de ordenação (''string'' hexadecimal) e o prefixo da chave de ordenação (parte legível) da categoria.",
+       "apihelp-query+categories-paramvalue-prop-timestamp": "Adiciona a data e hora a que a categoria foi adicionada.",
+       "apihelp-query+categories-paramvalue-prop-hidden": "Etiqueta as categorias que estão ocultadas com <code>_&#95;HIDDENCAT_&#95;</code>.",
+       "apihelp-query+categories-param-show": "Os tipos de categorias que serão mostrados.",
+       "apihelp-query+categories-param-limit": "O número de categorias a serem devolvidas.",
+       "apihelp-query+categories-param-categories": "Listar só estas categorias. Útil para verificar se uma determinada página está numa determinada categoria.",
+       "apihelp-query+categories-param-dir": "A direção de listagem.",
+       "apihelp-query+categories-example-simple": "Obter uma lista das categorias às quais pertence a página <kbd>Albert Einstein</kbd>.",
+       "apihelp-query+categories-example-generator": "Obter informação sobre todas as categorias usadas na página <kbd>Albert Einstein</kbd>.",
+       "apihelp-query+categoryinfo-description": "Devolve informação sobre as categorias indicadas.",
+       "apihelp-query+categoryinfo-example-simple": "Obter informações sobre <kbd>Category:Foo</kbd> e <kbd>Category:Bar</kbd>.",
+       "apihelp-query+categorymembers-description": "Listar todas as páginas numa categoria específica.",
+       "apihelp-query+categorymembers-param-title": "A categoria que será enumerada (obrigatório). Tem de incluir o prefixo <kbd>{{ns:category}}:</kbd>. Não pode ser usado em conjunto com <var>$1pageid</var>.",
+       "apihelp-query+categorymembers-param-pageid": "Identificador da categoria a ser enumerada. Não pode ser usado em conjunto com <var>$1title</var>.",
+       "apihelp-query+categorymembers-param-prop": "As informações que devem ser incluídas:",
+       "apihelp-query+categorymembers-paramvalue-prop-ids": "Adiciona o identificador da página.",
+       "apihelp-query+categorymembers-paramvalue-prop-title": "Adiciona o título e o identificador do espaço nominal da página.",
+       "apihelp-query+categorymembers-paramvalue-prop-sortkey": "Adiciona a chave usada para a ordenação da categoria (''string'' hexadecimal).",
+       "apihelp-query+categorymembers-paramvalue-prop-sortkeyprefix": "Adiciona o prefixo da chave usada para a ordenação da categoria (parte legível da chave de ordenação).",
+       "apihelp-query+categorymembers-paramvalue-prop-type": "Adiciona o tipo com que a página foi categorizada (<samp>page</samp>, <samp>subcat</samp> ou <samp>file</samp>).",
+       "apihelp-query+categorymembers-paramvalue-prop-timestamp": "Adiciona a data e hora de inclusão da página.",
+       "apihelp-query+categorymembers-param-namespace": "Incluir só as páginas destes espaços nominais. Note que pode usar <kbd>$1type=subcat</kbd> ou <kbd>$1type=file</kbd> em vez de <kbd>$1namespace=14</kbd> ou <kbd>6</kbd>.",
+       "apihelp-query+categorymembers-param-type": "O tipo de membros de categoria que devem ser incluídos. Ignorado se <kbd>$1sort=timestamp</kbd> estiver definido.",
+       "apihelp-query+categorymembers-param-limit": "O número máximo de páginas a serem devolvidas.",
+       "apihelp-query+categorymembers-param-sort": "Propriedade pela qual fazer a ordenação.",
+       "apihelp-query+categorymembers-param-dir": "A direção da ordenação.",
+       "apihelp-query+categorymembers-param-start": "A data e hora da página a partir da qual será começada a listagem. Só pode ser usado em conjunto com <kbd>$1sort=timestamp</kbd>.",
+       "apihelp-query+categorymembers-param-end": "A data e hora da página na qual será terminada a listagem. Só pode ser usado em conjunto com <kbd>$1sort=timestamp</kbd>.",
+       "apihelp-query+categorymembers-param-starthexsortkey": "A chave de ordenação a partir da qual a listagem será começada, como devolvida por <kbd>$1prop=sortkey</kbd>. Só pode ser usado com <kbd>$1sort=sortkey</kbd>.",
+       "apihelp-query+categorymembers-param-endhexsortkey": "A chave de ordenação na qual a listagem será terminada, como devolvida por <kbd>$1prop=sortkey</kbd>. só pode ser usado com <kbd>$1sort=sortkey</kbd>.",
+       "apihelp-query+categorymembers-param-startsortkeyprefix": "O prefixo da chave de ordenação a partir do qual a listagem será começada. Só pode ser usado com <kbd>$1sort=sortkey</kbd>. Tem precedência sobre <var>$1starthexsortkey</var>.",
+       "apihelp-query+categorymembers-param-endsortkeyprefix": "O prefixo da chave de ordenação <strong>antes</strong> do qual a listagem será terminada (não <strong>no</strong> qual; se este valor ocorrer não será incluído!). Só pode ser usado com <kbd>$1sort=sortkey</kbd>. Tem precedência sobre <var>$1starthexsortkey</var>.",
+       "apihelp-query+categorymembers-param-startsortkey": "Em vez dele, usar $1starthexsortkey.",
+       "apihelp-query+categorymembers-param-endsortkey": "Em vez dele, usar $1endhexsortkey.",
+       "apihelp-query+categorymembers-example-simple": "Obter as primeiras 10 páginas na categoria <kbd>Category:Physics</kbd>.",
+       "apihelp-query+categorymembers-example-generator": "Obter informações sobre as primeiras 10 páginas na categoria <kbd>Category:Physics</kbd>.",
+       "apihelp-query+contributors-description": "Obter a lista do contribuidores autenticados e a contagem dos contribuidores anónimos de uma página.",
+       "apihelp-query+contributors-param-group": "Incluir só os utilizadores nos grupos indicados. Não inclui os grupos implícitos ou de promoção automática como *, utilizador, ou autoconfirmado.",
+       "apihelp-query+contributors-param-excludegroup": "Excluir os utilizadores nos grupos indicados. Não inclui os grupos implícitos ou de promoção automática como *, utilizador, ou autoconfirmado.",
+       "apihelp-query+contributors-param-rights": "Incluir só os utilizadores com as permissões indicadas. Não inclui as permissões atribuídas por grupos implícitos ou de promoção automática como *, utilizador, ou autoconfirmado.",
+       "apihelp-query+contributors-param-excluderights": "Excluir os utilizadores com as permissões indicadas. Não inclui as permissões atribuídas por grupos implícitos ou de promoção automática como *, utilizador, ou autoconfirmado.",
+       "apihelp-query+contributors-param-limit": "O número de contribuidores a serem devolvidos.",
+       "apihelp-query+contributors-example-simple": "Mostrar os contribuidores da página <kbd>Main Page</kbd>.",
+       "apihelp-query+deletedrevisions-description": "Obter informações sobre as revisões eliminadas.\n\nPode ser usado de várias maneiras:\n# Obter as revisões eliminadas para um conjunto de páginas, definindo títulos ou identificadores de página. Ordenados por título e data e hora.\n# Obter dados sobre um conjunto de revisões eliminadas definindo os respetivos ids: com identificadores de revisão. Ordenados pelo identificador de revisão.",
+       "apihelp-query+deletedrevisions-param-start": "A data e hora da revisão a partir da qual será começada a enumeração. Ignorado ao processar uma lista de identificadores de revisão.",
+       "apihelp-query+deletedrevisions-param-end": "A data e hora da revisão na qual será terminada a enumeração. Ignorado ao processar uma lista de identificadores de revisão.",
+       "apihelp-query+deletedrevisions-param-tag": "Listar só as revisões marcadas com esta etiqueta.",
+       "apihelp-query+deletedrevisions-param-user": "Listar só as revisões deste utilizador.",
+       "apihelp-query+deletedrevisions-param-excludeuser": "Não listar as revisões deste utilizador.",
+       "apihelp-query+deletedrevisions-example-titles": "Listar as revisões eliminadas das páginas <kbd>Main Page</kbd> e <kbd>Talk:Main Page</kbd>, com o conteúdo.",
+       "apihelp-query+deletedrevisions-example-revids": "Listar a informação da revisão eliminada <kbd>123456</kbd>.",
+       "apihelp-query+deletedrevs-description": "Listar as revisões eliminadas.\n\nOpera em três modos:\n# Listar as revisões eliminadas dos títulos indicados, ordenadas por data e hora.\n# Listar as contribuições eliminadas do utilizador indicado, ordenadas por data e hora (sem especificar títulos).\n# Listar todas as revisões eliminadas no espaço nominal indicado, ordenadas por título e por data e hora (sem especificar títulos, sem definir $1user).\n\nAlguns parâmetros só se aplicam a alguns modos e são ignorados noutros.",
        "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|Modo|Modos}}: $2",
+       "apihelp-query+deletedrevs-param-start": "A data e hora da revisão a partir da qual será começada a enumeração.",
+       "apihelp-query+deletedrevs-param-end": "A data e hora da revisão na qual será terminada a enumeração.",
+       "apihelp-query+deletedrevs-param-from": "Começar a listagem neste título.",
+       "apihelp-query+deletedrevs-param-to": "Terminar a listagem neste título.",
+       "apihelp-query+deletedrevs-param-prefix": "Procurar todos os títulos de página que começam por este valor.",
+       "apihelp-query+deletedrevs-param-unique": "Listar só uma revisão para cada página.",
+       "apihelp-query+deletedrevs-param-tag": "Listar só as revisões marcadas com esta etiqueta.",
+       "apihelp-query+deletedrevs-param-user": "Listar só as revisões deste utilizador.",
        "apihelp-query+deletedrevs-param-excludeuser": "Não listar edições deste utilizador.",
-       "apihelp-query+deletedrevs-param-namespace": "Listar apenas as páginas neste domínio.",
-       "apihelp-query+extlinks-example-simple": "Obtenha uma lista de ligações externas na <kbd>Main Page</kbd>.",
-       "apihelp-query+filearchive-example-simple": "Mostrar lista de todos os ficheiros eliminados",
-       "apihelp-query+info-description": "Obter informação básica da página.",
-       "apihelp-query+recentchanges-example-simple": "Lista de mudanças recentes",
-       "apihelp-query+search-param-enablerewrites": "Habilitar rescrever a pesquisa interna. Alguns motores de busca podem rescrever a consulta para outra que acha dará melhores resultados, como a corrigir erros de ortografia.",
+       "apihelp-query+deletedrevs-param-namespace": "Listar só as páginas neste domínio.",
+       "apihelp-query+deletedrevs-param-limit": "O número máximo de revisões a serem listadas.",
+       "apihelp-query+deletedrevs-param-prop": "As propriedades a serem obtidas:\n;revid:Adiciona o identificador da revisão eliminada.\n;parentid:Adiciona o identificador da revisão anterior da página.\n;user:Adiciona o utilizador que fez a revisão.\n;userid:Adiciona o identificador do utilizador que fez a revisão.\n;comment:Adiciona o comentário da revisão.\n;parsedcomment:Adiciona o comentário da revisão após passagem pelo analisador sintático.\n;minor:Etiqueta a revisão como uma revisão menor.\n;len:Adiciona o comprimento (em bytes) da revisão.\n;sha1:Adiciona o SHA-1 da revisão (na base 16).\n;content:Adiciona o conteúdo da revisão.\n;token:<span class=\"apihelp-deprecated\">Obsoleto.</span> Fornece a chave da edição.\n;tags:Etiquetas da revisão.",
+       "apihelp-query+deletedrevs-example-mode1": "Listar só as últimas revisões eliminadas das páginas <kbd>Main Page</kbd> e <kbd>Talk:Main Page</kbd>, com o conteúdo (modo 1).",
+       "apihelp-query+deletedrevs-example-mode2": "Listar as últimas 50 contribuições eliminadas do utilizador <kbd>Bob</kbd> (modo 2).",
+       "apihelp-query+deletedrevs-example-mode3-main": "Listar as primeiras 50 revisões eliminadas no espaço nominal principal (modo 3).",
+       "apihelp-query+deletedrevs-example-mode3-talk": "Listar as primeiras 50 páginas eliminadas no espaço nominal {{ns:talk}} (modo 3).",
+       "apihelp-query+disabled-description": "Este módulo de consulta foi desativado.",
+       "apihelp-query+duplicatefiles-description": "Listar todos os ficheiros que são duplicados dos ficheiros indicados com base no seu resumo criptográfico.",
+       "apihelp-query+duplicatefiles-param-limit": "O número de ficheiros duplicados a serem devolvidos.",
+       "apihelp-query+duplicatefiles-param-dir": "A direção de listagem.",
+       "apihelp-query+duplicatefiles-param-localonly": "Procurar ficheiros só no repositório local.",
+       "apihelp-query+duplicatefiles-example-simple": "Procurar os ficheiros duplicados de [[:File:Albert Einstein Head.jpg]].",
+       "apihelp-query+duplicatefiles-example-generated": "Procurar duplicados de todos os ficheiros.",
+       "apihelp-query+embeddedin-description": "Encontrar todas as páginas que incorporam (transcluem) o título indicado.",
+       "apihelp-query+embeddedin-param-title": "O título a procurar. Não pode ser usado em conjunto com $1pageid.",
+       "apihelp-query+embeddedin-param-pageid": "O identificador da página a procurar. Não pode ser usado em conjunto com $1title.",
+       "apihelp-query+embeddedin-param-namespace": "O espaço nominal a ser enumerado.",
+       "apihelp-query+embeddedin-param-dir": "A direção de listagem.",
+       "apihelp-query+embeddedin-param-filterredir": "Como filtrar os redirecionamentos.",
+       "apihelp-query+embeddedin-param-limit": "O número total de páginas a serem devolvidas.",
+       "apihelp-query+embeddedin-example-simple": "Mostrar as páginas que transcluem <kbd>Template:Stub</kbd>.",
+       "apihelp-query+embeddedin-example-generator": "Obter informação sobre as páginas que transcluem <kbd>Template:Stub</kbd>.",
+       "apihelp-query+extlinks-description": "Devolve todos os URL externos (que não sejam interwikis) das páginas especificadas.",
+       "apihelp-query+extlinks-param-limit": "O número de ''links'' a serem devolvidos.",
+       "apihelp-query+extlinks-param-protocol": "Protocolo do URL. Se vazio e <var>$1query</var> está definido, o protocolo é <kbd>http</kbd>. Deixe isto e  <var>$1query</var> vazios para listar todos os ''links'' externos.",
+       "apihelp-query+extlinks-param-query": "Texto de pesquisa sem protocolo. Útil para verificar se uma determinada página contém um determinado URL externo.",
+       "apihelp-query+extlinks-param-expandurl": "Expandir os URL relativos a protocolo com o protocolo canónico.",
+       "apihelp-query+extlinks-example-simple": "Obter uma lista das ligações externas na <kbd>Main Page</kbd>.",
+       "apihelp-query+exturlusage-description": "Enumerar as páginas que contêm um determinado URL.",
+       "apihelp-query+exturlusage-param-prop": "As informações que devem ser incluídas:",
+       "apihelp-query+exturlusage-paramvalue-prop-ids": "Adiciona o identificador da página.",
+       "apihelp-query+exturlusage-paramvalue-prop-title": "Adiciona o título e o identificador do espaço nominal da página.",
+       "apihelp-query+exturlusage-paramvalue-prop-url": "Adiciona o URL usado na página.",
+       "apihelp-query+exturlusage-param-protocol": "Protocolo do URL. Se vazio e <var>$1query</var> está definido, o protocolo é <kbd>http</kbd>. Deixe isto e  <var>$1query</var> vazios para listar todos os ''links'' externos.",
+       "apihelp-query+exturlusage-param-query": "Texto da pesquisa sem um protocolo. Ver [[Special:LinkSearch]]. Deixar vazio para listar todos os ''links'' externos.",
+       "apihelp-query+exturlusage-param-namespace": "Os espaços nominais a serem enumerados.",
+       "apihelp-query+exturlusage-param-limit": "O número de páginas a serem devolvidas.",
+       "apihelp-query+exturlusage-param-expandurl": "Expandir os URL relativos a protocolo com o protocolo canónico.",
+       "apihelp-query+exturlusage-example-simple": "Mostrar as páginas com ligações para <kbd>http://www.mediawiki.org</kbd>.",
+       "apihelp-query+filearchive-description": "Enumerar todos os ficheiros eliminados sequencialmente.",
+       "apihelp-query+filearchive-param-from": "O título da imagem a partir do qual será começada a enumeração.",
+       "apihelp-query+filearchive-param-to": "O título da imagem no qual será terminada a enumeração.",
+       "apihelp-query+filearchive-param-prefix": "Procurar todos os títulos de imagem que começam por este valor.",
+       "apihelp-query+filearchive-param-limit": "O número total de imagens a devolver.",
+       "apihelp-query+filearchive-param-dir": "A direção de listagem.",
+       "apihelp-query+filearchive-param-sha1": "O resumo criptográfico SHA-1 da imagem. Tem precedência sobre $1sha1base36.",
+       "apihelp-query+filearchive-param-sha1base36": "O resumo criptográfico da imagem na base 36 (usado no MediaWiki).",
+       "apihelp-query+filearchive-param-prop": "As informações da imagem que devem ser obtidas:",
+       "apihelp-query+filearchive-paramvalue-prop-sha1": "Adiciona o resumo criptográfico SHA-1 da imagem.",
+       "apihelp-query+filearchive-paramvalue-prop-timestamp": "Adiciona a data e hora da versão carregada.",
+       "apihelp-query+filearchive-paramvalue-prop-user": "Adiciona o utilizador que carregou a versão da imagem.",
+       "apihelp-query+filearchive-paramvalue-prop-size": "Adiciona o tamanho da imagem em ''bytes'' e a altura, largura e contagem de páginas (se aplicável).",
+       "apihelp-query+filearchive-paramvalue-prop-dimensions": "Nome alternativo para ''size''.",
+       "apihelp-query+filearchive-paramvalue-prop-description": "Adiciona a descrição da versão da imagem.",
+       "apihelp-query+filearchive-paramvalue-prop-parseddescription": "Fazer a análise sintática da descrição da versão.",
+       "apihelp-query+filearchive-paramvalue-prop-mime": "Adiciona o tipo MIME da imagem.",
+       "apihelp-query+filearchive-paramvalue-prop-mediatype": "Adiciona o tipo de multimédia da imagem.",
+       "apihelp-query+filearchive-paramvalue-prop-metadata": "Lista os metadados Exif para a versão da imagem.",
+       "apihelp-query+filearchive-paramvalue-prop-bitdepth": "Adiciona a profundidade em ''bits'' da versão.",
+       "apihelp-query+filearchive-paramvalue-prop-archivename": "Adiciona o nome de ficheiro da versão arquivada das versões anteriores à última.",
+       "apihelp-query+filearchive-example-simple": "Mostrar uma lista de todos os ficheiros eliminados.",
+       "apihelp-query+filerepoinfo-description": "Devolver meta informação sobre os repositórios de imagens configurados na wiki.",
+       "apihelp-query+filerepoinfo-param-prop": "As propriedades do repositório que devem ser obtidas (em algumas wikis poderão haver mais disponíveis):\n;apiurl:URL para a API do repositório - útil para obter informação de imagens do servidor.\n;name:A chave para o repositório - usada, por exemplo, em <var>[[mw:Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> e nos valores de retorno de [[Special:ApiHelp/query+imageinfo|imageinfo]].\n;displayname:O nome legível da wiki repositório.\n;rooturl:URL de raiz para endereços de imagens.\n;local:Se o repositório é o local ou não.",
+       "apihelp-query+filerepoinfo-example-simple": "Obter informações sobre os repositórios de ficheiros.",
+       "apihelp-query+fileusage-description": "Encontrar todas as páginas que usam os ficheiros indicados.",
+       "apihelp-query+fileusage-param-prop": "As propriedades a serem obtidas:",
+       "apihelp-query+fileusage-paramvalue-prop-pageid": "O identificador de cada página.",
+       "apihelp-query+fileusage-paramvalue-prop-title": "O título de cada página.",
+       "apihelp-query+fileusage-paramvalue-prop-redirect": "Indicar se a página é um redirecionamento.",
+       "apihelp-query+fileusage-param-namespace": "Incluir só as páginas destes espaços nominais.",
+       "apihelp-query+fileusage-param-limit": "O número de elementos a serem devolvidos.",
+       "apihelp-query+fileusage-param-show": "Mostrar só as páginas que correspondem a estes critérios:\n;redirect:Mostrar só os redirecionamentos.\n;!redirect:Mostrar só os não redirecionamentos.",
+       "apihelp-query+fileusage-example-simple": "Obter uma lista das páginas que usam [[:File:Example.jpg]].",
+       "apihelp-query+fileusage-example-generator": "Obter informação sobre as páginas que usam [[:File:Example.jpg]].",
+       "apihelp-query+imageinfo-description": "Devolve informação do ficheiro e o historial de carregamentos.",
+       "apihelp-query+imageinfo-param-prop": "As informações do ficheiro que devem ser obtidas:",
+       "apihelp-query+imageinfo-paramvalue-prop-timestamp": "Adiciona a data e hora da versão carregada.",
+       "apihelp-query+imageinfo-paramvalue-prop-user": "Adiciona o utilizador que carregou cada versão de ficheiro.",
+       "apihelp-query+imageinfo-paramvalue-prop-userid": "Adiciona o identificador do utilizador que carregou cada versão de ficheiro.",
+       "apihelp-query+imageinfo-paramvalue-prop-comment": "O comentário da versão.",
+       "apihelp-query+imageinfo-paramvalue-prop-parsedcomment": "Fazer a análise sintática do comentário da versão.",
+       "apihelp-query+imageinfo-paramvalue-prop-canonicaltitle": "Adiciona o título canónico do ficheiro.",
+       "apihelp-query+imageinfo-paramvalue-prop-url": "Devolve URL para o ficheiro e página de descrição.",
+       "apihelp-query+imageinfo-paramvalue-prop-size": "Adiciona o tamanho do ficheiro em ''bytes'' e a altura, largura e contagem de páginas (se aplicável).",
+       "apihelp-query+imageinfo-paramvalue-prop-dimensions": "Nome alternativo para ''size''.",
+       "apihelp-query+imageinfo-paramvalue-prop-sha1": "Adiciona o resumo criptográfico SHA-1 do ficheiro.",
+       "apihelp-query+imageinfo-paramvalue-prop-mime": "Adiciona o tipo MIME do ficheiro.",
+       "apihelp-query+imageinfo-paramvalue-prop-thumbmime": "Adiciona o tipo MIME da miniatura (requer URL e o parâmetro $1urlwidth).",
+       "apihelp-query+imageinfo-paramvalue-prop-mediatype": "Adiciona o tipo de multimédia do ficheiro.",
+       "apihelp-query+imageinfo-paramvalue-prop-metadata": "Lista os metadados Exif para a versão do ficheiro.",
+       "apihelp-query+imageinfo-paramvalue-prop-commonmetadata": "Lista os metadados genéricos do formato de ficheiro para a versão do ficheiro.",
+       "apihelp-query+imageinfo-paramvalue-prop-extmetadata": "Lista os metadados formatados, combinados de várias fontes. Os resultados estão no formato HTML.",
+       "apihelp-query+imageinfo-paramvalue-prop-archivename": "Adiciona o nome de ficheiro da versão arquivada das versões anteriores à última.",
+       "apihelp-query+imageinfo-paramvalue-prop-bitdepth": "Adiciona a profundidade em ''bits'' da versão.",
+       "apihelp-query+imageinfo-paramvalue-prop-uploadwarning": "Usado pela página Special:Upload para obter informação sobre um ficheiro existente. Não se destina a ser usado fora do núcleo central do MediaWiki.",
+       "apihelp-query+imageinfo-param-limit": "O número de revisões a serem devolvidas por ficheiro.",
+       "apihelp-query+imageinfo-param-start": "Data e hora a partir da qual será começada a listagem.",
+       "apihelp-query+imageinfo-param-end": "Data e hora na qual será terminada a listagem.",
+       "apihelp-query+imageinfo-param-urlwidth": "Se $2prop=url está definido, será devolvido um URL para uma imagem redimensionada com este comprimento.\nPor razões de desempenho, se esta opção for usada não serão devolvidas mais de $1 imagens redimensionadas.",
+       "apihelp-query+imageinfo-param-urlheight": "Semelhante a $1urlwidth.",
+       "apihelp-query+imageinfo-param-metadataversion": "Versão de metadados a ser usada. Se for especificado o valor <kbd>latest</kbd>, usar a versão mais recente. Por omissão tem o valor <kbd>1</kbd> para compatibilidade com versões anteriores.",
+       "apihelp-query+imageinfo-param-extmetadatalanguage": "Em que língua obter extmetadata. Isto afeta tanto a tradução que será obtida, caso existam várias, como a formatação de números e vários outros valores.",
+       "apihelp-query+imageinfo-param-extmetadatamultilang": "Se estiverem disponíveis traduções para a propriedade extmetadata, obtê-las todas.",
+       "apihelp-query+imageinfo-param-extmetadatafilter": "Se for especificado e não estiver vazio, só serão devolvidas estas chaves para $1prop=extmetadata.",
+       "apihelp-query+imageinfo-param-urlparam": "Um parâmetro de texto específico do objeto. Por exemplo, ficheiros PDF podem usar <kbd>page15-100px</kbd>. <var>$1urlwidth</var> tem de ser usado e ser consistente com <var>$1urlparam</var>.",
+       "apihelp-query+imageinfo-param-localonly": "Procurar ficheiros só no repositório local.",
+       "apihelp-query+imageinfo-example-simple": "Obter informação sobre a versão atual do ficheiro [[:File:Albert Einstein Head.jpg]].",
+       "apihelp-query+imageinfo-example-dated": "Obter informação sobre as versões de [[:File:Test.jpg]] a partir de 2008.",
+       "apihelp-query+images-description": "Devolve todos os ficheiros contidos nas páginas indicadas.",
+       "apihelp-query+images-param-limit": "O número de ficheiros a serem devolvidos.",
+       "apihelp-query+images-param-images": "Listar só estes ficheiros. Útil para verificar se uma determinada página tem um determinado ficheiro.",
+       "apihelp-query+images-param-dir": "A direção de listagem.",
+       "apihelp-query+images-example-simple": "Obter uma lista dos ficheiros usados na página [[Main Page]].",
+       "apihelp-query+images-example-generator": "Obter informação sobre todos os ficheiros usados na página [[Main Page]].",
+       "apihelp-query+imageusage-description": "Encontrar todas as páginas que utilizam o título da imagem indicada.",
+       "apihelp-query+imageusage-param-title": "O título a procurar. Não pode ser usado em conjunto com $1pageid.",
+       "apihelp-query+imageusage-param-pageid": "O identificador da página a procurar. Não pode ser usado em conjunto com $1title.",
+       "apihelp-query+imageusage-param-namespace": "O espaço nominal a ser enumerado.",
+       "apihelp-query+imageusage-param-dir": "A direção de listagem.",
+       "apihelp-query+imageusage-param-filterredir": "Como filtrar redirecionamentos. Se definido como <kbd>nonredirects</kbd> quando <var>$1redirect</var> está ativado, isto só é aplicado ao segundo nível.",
+       "apihelp-query+imageusage-param-limit": "O número total de páginas a serem devolvidas. Se <var>$1redirect</var> estiver ativado, o nível aplica-se a cada nível em separado (o que significa que até 2 * <var>$1limit</var> resultados podem ser devolvidos).",
+       "apihelp-query+imageusage-param-redirect": "Se a página que contém a ligação é um redirecionamento, procurar também todas as páginas que contêm ligações para esse redirecionamento. O limite máximo é reduzido para metade.",
+       "apihelp-query+imageusage-example-simple": "Mostrar as páginas que usam [[:File:Albert Einstein Head.jpg]].",
+       "apihelp-query+imageusage-example-generator": "Obter informações sobre as páginas que usam o ficheiro [[:File:Albert Einstein Head.jpg]].",
+       "apihelp-query+info-description": "Obter a informação básica da página.",
+       "apihelp-query+info-param-prop": "As propriedades adicionais que devem ser obtidas:",
+       "apihelp-query+info-paramvalue-prop-protection": "Listar o nível de proteção de cada página.",
+       "apihelp-query+info-paramvalue-prop-talkid": "O identificador da página de discussão de cada página que não seja de discussão.",
+       "apihelp-query+info-paramvalue-prop-watched": "Listar o estado de vigilância de cada página.",
+       "apihelp-query+info-paramvalue-prop-watchers": "O número de vigilantes, se for permitido.",
+       "apihelp-query+info-paramvalue-prop-visitingwatchers": "O número de vigilantes de cada página que visitaram edições recentes dessa página, se permitido.",
+       "apihelp-query+info-paramvalue-prop-notificationtimestamp": "A data e hora das notificações de alterações de cada página vigiada.",
+       "apihelp-query+info-paramvalue-prop-subjectid": "O identificador da página progenitora de cada página de discussão.",
+       "apihelp-query+info-paramvalue-prop-url": "Fornece um URL completo, um URL de edição e o URL canónico, para cada página.",
+       "apihelp-query+info-paramvalue-prop-readable": "Indica se o utilizador pode ler esta página.",
+       "apihelp-query+info-paramvalue-prop-preload": "Fornece o texto devolvido por EditFormPreloadText.",
+       "apihelp-query+info-paramvalue-prop-displaytitle": "Fornece a forma como o título da página é apresentado.",
+       "apihelp-query+info-param-testactions": "Testar se o utilizador pode realizar certas operações na página.",
+       "apihelp-query+info-param-token": "Em substituição, usar [[Special:ApiHelp/query+tokens|action=query&meta=tokens]].",
+       "apihelp-query+info-example-simple": "Obter informações sobre a página <kbd>Main Page</kbd>.",
+       "apihelp-query+info-example-protection": "Obter informação geral e de proteção sobre a página <kbd>Main Page</kbd>.",
+       "apihelp-query+iwbacklinks-description": "Encontrar todas as páginas que contêm o ''link'' interwikis indicado.\n\nPode ser usado para encontrar todos os ''links'' com um determinado prefixo, ou todos os ''links'' para um título (com um prefixo indicado). Não usar nenhum dos dois parâmetros significa efetivamente ''todos os ''links'' interwikis''.",
+       "apihelp-query+iwbacklinks-param-prefix": "O prefixo interwikis.",
+       "apihelp-query+iwbacklinks-param-title": "O ''link'' interwikis a ser procurado. Tem de ser usado em conjunto com <var>$1blprefix</var>.",
+       "apihelp-query+iwbacklinks-param-limit": "O número total de páginas a serem devolvidas.",
+       "apihelp-query+iwbacklinks-param-prop": "As propriedades a serem obtidas:",
+       "apihelp-query+iwbacklinks-paramvalue-prop-iwprefix": "Adiciona o prefixo do ''link'' interwikis.",
+       "apihelp-query+iwbacklinks-paramvalue-prop-iwtitle": "Adiciona o título do ''link'' interwikis.",
+       "apihelp-query+iwbacklinks-param-dir": "A direção de listagem.",
+       "apihelp-query+iwbacklinks-example-simple": "Obter as páginas que contêm ligações para [[wikibooks:Test]].",
+       "apihelp-query+iwbacklinks-example-generator": "Obter informação sobre as páginas que contêm ligações para [[wikibooks:Test]].",
+       "apihelp-query+iwlinks-description": "Devolve todos os ''links'' interwikis das páginas indicadas.",
+       "apihelp-query+iwlinks-param-url": "Indica se deve ser obtido o URL completo (não pode ser usado com $1prop).",
+       "apihelp-query+iwlinks-param-prop": "As propriedades adicionais que devem ser obtidas para cada ''link'' interlínguas:",
+       "apihelp-query+iwlinks-paramvalue-prop-url": "Adiciona o URL completo.",
+       "apihelp-query+iwlinks-param-limit": "O número de ''links'' interwikis a serem devolvidos.",
+       "apihelp-query+iwlinks-param-prefix": "Devolver só os ''links'' interwikis com este prefixo.",
+       "apihelp-query+iwlinks-param-title": "Link interwikis a ser procurado. Tem de ser usado em conjunto com <var>$1prefix</var>.",
+       "apihelp-query+iwlinks-param-dir": "A direção de listagem.",
+       "apihelp-query+iwlinks-example-simple": "Obter os ''links'' interwikis da página <kbd>Main Page</kbd>.",
+       "apihelp-query+langbacklinks-description": "Encontrar todas as páginas que contêm ligações para o ''link'' interlínguas indicado.\n\nPode ser usado para encontrar todos os ''links'' para um determinado código de língua, ou todos os ''links'' para um determinado título (de uma língua). Se nenhum for usado, isso efetivamente significa \"todos os ''links'' interlínguas\".\n\nNote que os ''links'' interlínguas adicionados por extensões podem não ser considerados.",
+       "apihelp-query+langbacklinks-param-lang": "A língua do ''link'' interlínguas.",
+       "apihelp-query+langbacklinks-param-title": "Link interlínguas a ser procurado. Tem de ser usado com $1lang.",
+       "apihelp-query+langbacklinks-param-limit": "O número total de páginas a serem devolvidas.",
+       "apihelp-query+langbacklinks-param-prop": "As propriedades a serem obtidas:",
+       "apihelp-query+langbacklinks-paramvalue-prop-lllang": "Adiciona o código de língua da ligação interlínguas.",
+       "apihelp-query+langbacklinks-paramvalue-prop-lltitle": "Adiciona o título do ''link'' interlínguas.",
+       "apihelp-query+langbacklinks-param-dir": "A direção de listagem.",
+       "apihelp-query+langbacklinks-example-simple": "Obter as páginas que contêm ligações para [[:fr:Test]].",
+       "apihelp-query+langbacklinks-example-generator": "Obter informações sobre as páginas que contêm ligações para [[:fr:Test]].",
+       "apihelp-query+langlinks-description": "Devolve todos os ''links'' interlínguas das páginas indicadas.",
+       "apihelp-query+langlinks-param-limit": "O número de ''links'' interlínguas a serem devolvidos.",
+       "apihelp-query+langlinks-param-url": "Indica se deve ser obtido o URL completo (não pode ser usado com $1prop).",
+       "apihelp-query+langlinks-param-prop": "As propriedades adicionais que devem ser obtidas para cada ''link'' interlínguas:",
+       "apihelp-query+langlinks-paramvalue-prop-url": "Adiciona o URL completo.",
+       "apihelp-query+langlinks-paramvalue-prop-langname": "Adiciona o nome da língua localizado (melhor esforço). Usar <var>$1inlanguagecode</var> para controlar a língua.",
+       "apihelp-query+langlinks-paramvalue-prop-autonym": "Adiciona o nome nativo da língua.",
+       "apihelp-query+langlinks-param-lang": "Devolver só os ''links'' interlínguas com este código de língua.",
+       "apihelp-query+langlinks-param-title": "''Link'' a ser procurado. Tem de ser usado com <var>$1lang</var>.",
+       "apihelp-query+langlinks-param-dir": "A direção de listagem.",
+       "apihelp-query+langlinks-param-inlanguagecode": "O código de língua para os nomes de língua localizados.",
+       "apihelp-query+langlinks-example-simple": "Obter os ''links'' interlínguas da página <kbd>Main Page</kbd>.",
+       "apihelp-query+links-description": "Devolve todos os ''links'' das páginas indicadas.",
+       "apihelp-query+links-param-namespace": "Mostrar apenas os ''links'' destes espaços nominais.",
+       "apihelp-query+links-param-limit": "O número de ''links'' a serem devolvidos.",
+       "apihelp-query+links-param-titles": "Listar só as ligações para estes títulos. Útil para verificar se uma determinada página contém ligações para um determinado título.",
+       "apihelp-query+links-param-dir": "A direção de listagem.",
+       "apihelp-query+links-example-simple": "Obter os ''links'' da página <kbd>Main Page</kbd>.",
+       "apihelp-query+links-example-generator": "Obter informação sobre as páginas ligadas na página <kbd>Main Page</kbd>.",
+       "apihelp-query+links-example-namespaces": "Obter os ''links'' da página <kbd>Main Page</kbd> nos espaços nominais {{ns:user}} e {{ns:template}}.",
+       "apihelp-query+linkshere-description": "Encontrar todas as páginas que contêm ''links'' para as páginas indicadas.",
+       "apihelp-query+linkshere-param-prop": "As propriedades a serem obtidas:",
+       "apihelp-query+linkshere-paramvalue-prop-pageid": "O identificador de cada página.",
+       "apihelp-query+linkshere-paramvalue-prop-title": "O título de cada página.",
+       "apihelp-query+linkshere-paramvalue-prop-redirect": "Indicar se a página é um redirecionamento.",
+       "apihelp-query+linkshere-param-namespace": "Incluir só as páginas nestes espaços nominais.",
+       "apihelp-query+linkshere-param-limit": "O número de páginas a serem devolvidas.",
+       "apihelp-query+linkshere-param-show": "Mostrar só as páginas que correspondem a estes critérios:\n;redirect:Mostrar só os redirecionamentos.\n;!redirect:Mostrar só os não redirecionamentos.",
+       "apihelp-query+linkshere-example-simple": "Obter uma lista das páginas com ligações para a página [[Main Page]].",
+       "apihelp-query+linkshere-example-generator": "Obter informação sobre as páginas com ligações para a página [[Main Page]].",
+       "apihelp-query+logevents-description": "Obter eventos dos registos.",
+       "apihelp-query+logevents-param-prop": "As propriedades a serem obtidas:",
+       "apihelp-query+logevents-paramvalue-prop-ids": "Adiciona o identificador do evento do registo.",
+       "apihelp-query+logevents-paramvalue-prop-title": "Adiciona o título da página do evento do registo.",
+       "apihelp-query+logevents-paramvalue-prop-type": "Adiciona o tipo do evento do registo.",
+       "apihelp-query+logevents-paramvalue-prop-user": "Adiciona o utilizador responsável pelo evento do registo.",
+       "apihelp-query+logevents-paramvalue-prop-userid": "Adiciona o identificador do utilizador responsável pelo evento do registo.",
+       "apihelp-query+logevents-paramvalue-prop-timestamp": "Adiciona a data e hora do evento do registo.",
+       "apihelp-query+logevents-paramvalue-prop-comment": "Adiciona o comentário do evento do registo.",
+       "apihelp-query+logevents-paramvalue-prop-parsedcomment": "Adiciona o comentário do evento do registo, após análise sintática.",
+       "apihelp-query+logevents-paramvalue-prop-details": "Lista detalhes adicionais sobre o evento do registo.",
+       "apihelp-query+logevents-paramvalue-prop-tags": "Lista as etiquetas do evento do registo.",
+       "apihelp-query+logevents-param-type": "Filtrar as entradas do registo para produzir só as deste tipo.",
+       "apihelp-query+logevents-param-action": "Filtrar as entradas do registo para produzir só as desta operação. Tem precedência sobre <var>$1type</var>. Na lista dos valores possíveis, os valores com o carácter de substituição asterisco <kbd>action/*</kbd> podem conter outros valores após a barra (/).",
+       "apihelp-query+logevents-param-start": "A data e hora a partir da qual será começada a enumeração.",
+       "apihelp-query+logevents-param-end": "A data e hora na qual será terminada a enumeração.",
+       "apihelp-query+logevents-param-user": "Filtrar as entradas para produzir só as criadas pelo utilizador indicado.",
+       "apihelp-query+logevents-param-title": "Filtrar as entradas para produzir só as relacionadas com uma página.",
+       "apihelp-query+logevents-param-namespace": "Filtrar as entradas para produzir só as que estão no espaço nominal indicado.",
+       "apihelp-query+logevents-param-prefix": "Filtrar as entradas para produzir só as que começam por este prefixo.",
+       "apihelp-query+logevents-param-tag": "Listar só as entradas de eventos marcadas com esta etiqueta.",
+       "apihelp-query+logevents-param-limit": "O número total de entradas de eventos a serem devolvidas.",
+       "apihelp-query+logevents-example-simple": "Listar os eventos recentes do registo.",
+       "apihelp-query+pagepropnames-description": "Listar todos os nomes de propriedades de páginas em uso nesta wiki.",
+       "apihelp-query+pagepropnames-param-limit": "O número máximo de nomes a serem devolvidos.",
+       "apihelp-query+pagepropnames-example-simple": "Obter os primeiros 10 nomes de propriedades.",
+       "apihelp-query+pageprops-description": "Obter várias propriedades de página definidas no conteúdo da página.",
+       "apihelp-query+pageprops-param-prop": "Listar só estas propriedades de página (<kbd>[[Special:ApiHelp/query+pagepropnames|action=query&list=pagepropnames]]</kbd> devolve os nomes das propriedades de página em uso). Útil para verificar se as páginas usam uma determinada propriedade de página.",
+       "apihelp-query+pageprops-example-simple": "Obter as propriedades das páginas <kbd>Main Page</kbd> e <kbd>MediaWiki</kbd>.",
+       "apihelp-query+pageswithprop-description": "Listar todas as páginas que usam uma determinada propriedade.",
+       "apihelp-query+pageswithprop-param-propname": "A propriedade de página a partir da qual as páginas serão enumeradas (<kbd>[[Special:ApiHelp/query+pagepropnames|action=query&list=pagepropnames]]</kbd> devolve os nomes das propriedades de página que estão a ser usadas).",
+       "apihelp-query+pageswithprop-param-prop": "As informações que devem ser incluídas:",
+       "apihelp-query+pageswithprop-paramvalue-prop-ids": "Adiciona o identificador da página.",
+       "apihelp-query+pageswithprop-paramvalue-prop-title": "Adiciona o título e o identificador do espaço nominal da página.",
+       "apihelp-query+pageswithprop-paramvalue-prop-value": "Adiciona o valor da propriedade da página.",
+       "apihelp-query+pageswithprop-param-limit": "O número máximo de páginas a serem devolvidas.",
+       "apihelp-query+pageswithprop-param-dir": "A direção da ordenação.",
+       "apihelp-query+pageswithprop-example-simple": "Listar as primeiras 10 páginas que usam a propriedade <code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>.",
+       "apihelp-query+pageswithprop-example-generator": "Obter informação adicional sobre as primeiras 10 páginas que usam <code>_&#95;NOTOC_&#95;</code>.",
+       "apihelp-query+prefixsearch-description": "Realizar uma procura de prefixo nos títulos de página.\n\nApesar da semelhança de nomes, este módulo não pretende ser equivalente a [[Special:PrefixIndex]]; para este, consulte <kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd> com o parâmetro <kbd>apprefix</kbd>. O propósito deste módulo é semelhante a <kbd>[[Special:ApiHelp/opensearch|action=opensearch]]</kbd>: receber dados introduzidos pelo utilizador e devolver os títulos com melhor correspondência. Dependendo do motor de busca do servidor, isto pode incluir correções de erros ortográficos, evitar redirecionamentos, e outras heurísticas.",
+       "apihelp-query+prefixsearch-param-search": "O texto a ser pesquisado.",
+       "apihelp-query+prefixsearch-param-namespace": "Os espaços nominais onde realizar a pesquisa.",
+       "apihelp-query+prefixsearch-param-limit": "O número máximo de resultados a serem devolvidos.",
+       "apihelp-query+prefixsearch-param-offset": "O número de resultados a serem omitidos.",
+       "apihelp-query+prefixsearch-example-simple": "Procurar os títulos de página que começam por <kbd>meaning</kbd>.",
+       "apihelp-query+prefixsearch-param-profile": "O perfil de pesquisa a ser utilizado.",
+       "apihelp-query+protectedtitles-description": "Listar todos os títulos cuja criação está impedida.",
+       "apihelp-query+protectedtitles-param-namespace": "Listar só os títulos nestes espaços nominais.",
+       "apihelp-query+protectedtitles-param-level": "Listar só os títulos com estes níveis de proteção.",
+       "apihelp-query+protectedtitles-param-limit": "O número total de páginas a serem devolvidas.",
+       "apihelp-query+protectedtitles-param-start": "Começar a listagem pelo título que tem esta data e hora de proteção.",
+       "apihelp-query+protectedtitles-param-end": "Terminar a listagem no título que tem esta data e hora de proteção.",
+       "apihelp-query+protectedtitles-param-prop": "As propriedades a serem obtidas:",
+       "apihelp-query+protectedtitles-paramvalue-prop-timestamp": "Adiciona a data e hora a que a proteção foi adicionada.",
+       "apihelp-query+protectedtitles-paramvalue-prop-user": "Adiciona o utilizador que fez a proteção.",
+       "apihelp-query+protectedtitles-paramvalue-prop-userid": "Adiciona o identificador do utilizador que fez a proteção.",
+       "apihelp-query+protectedtitles-paramvalue-prop-comment": "Adiciona o comentário da proteção.",
+       "apihelp-query+protectedtitles-paramvalue-prop-parsedcomment": "Adiciona o comentário da proteção após a análise sintática.",
+       "apihelp-query+protectedtitles-paramvalue-prop-expiry": "Adiciona a data e hora a que a proteção será removida.",
+       "apihelp-query+protectedtitles-paramvalue-prop-level": "Adiciona o nível de proteção.",
+       "apihelp-query+protectedtitles-example-simple": "Lista os títulos protegidos.",
+       "apihelp-query+protectedtitles-example-generator": "Encontrar as ligações para os títulos protegidos que pertencem ao espaço nominal principal.",
+       "apihelp-query+querypage-description": "Obter uma lista fornecida por uma página especial baseada em consultas (''QueryPage'').",
+       "apihelp-query+querypage-param-page": "O nome da página especial. Note que este é sensível a maiúsculas e minúsculas.",
+       "apihelp-query+querypage-param-limit": "O número de resultados a serem devolvidos.",
+       "apihelp-query+querypage-example-ancientpages": "Devolver os resultados da página [[Special:Ancientpages]].",
+       "apihelp-query+random-description": "Obter um conjunto de páginas aleatórias.\n\nAs páginas são listadas em sequência fixa, só o ponto de início da listagem é aleatório. Isto significa, por exemplo, que se a primeira página aleatória na lista é <samp>Main Page</samp>, a página <samp>List of fictional monkeys</samp> será <em>sempre</em> a segunda, a página <samp>List of people on stamps of Vanuatu</samp> a terceira, etc.",
+       "apihelp-query+random-param-namespace": "Devolver só as páginas que estão nestes espaços nominais.",
+       "apihelp-query+random-param-limit": "Limitar o número de páginas aleatórias que serão devolvidas.",
+       "apihelp-query+random-param-redirect": "Em vez dele, usar <kbd>$1filterredir=redirects</kbd>.",
+       "apihelp-query+random-param-filterredir": "Como filtrar redirecionamentos.",
+       "apihelp-query+random-example-simple": "Devolver duas páginas aleatórias do espaço nominal principal.",
+       "apihelp-query+random-example-generator": "Devolver informação de página sobre duas páginas aleatórias do espaço nominal principal.",
+       "apihelp-query+recentchanges-description": "Enumerar as mudanças recentes.",
+       "apihelp-query+recentchanges-param-start": "A data e hora a partir da qual será começada a enumeração.",
+       "apihelp-query+recentchanges-param-end": "A data e hora na qual será terminada a enumeração.",
+       "apihelp-query+recentchanges-param-namespace": "Filtrar as mudanças para produzir só as destes espaços nominais.",
+       "apihelp-query+recentchanges-param-user": "Listar só as mudanças feitas por este utilizador.",
+       "apihelp-query+recentchanges-param-excludeuser": "Não listar as mudanças feitas por este utilizador.",
+       "apihelp-query+recentchanges-param-tag": "Listar só as mudanças marcadas com esta etiqueta.",
+       "apihelp-query+recentchanges-param-prop": "Incluir informações adicionais:",
+       "apihelp-query+recentchanges-paramvalue-prop-user": "Adiciona o utilizador responsável pela edição e marca se o utilizador é um endereço IP.",
+       "apihelp-query+recentchanges-paramvalue-prop-userid": "Adiciona o identificador do utilizador responsável pela edição.",
+       "apihelp-query+recentchanges-paramvalue-prop-comment": "Adiciona o comentário da edição.",
+       "apihelp-query+recentchanges-paramvalue-prop-parsedcomment": "Adiciona o comentário da edição, após análise sintática.",
+       "apihelp-query+recentchanges-paramvalue-prop-flags": "Adiciona as etiquetas da edição.",
+       "apihelp-query+recentchanges-paramvalue-prop-timestamp": "Adiciona a data e hora da edição.",
+       "apihelp-query+recentchanges-paramvalue-prop-title": "Adiciona o título de página da edição.",
+       "apihelp-query+recentchanges-paramvalue-prop-ids": "Adiciona o identificadores da página, das mudanças recentes, e das revisões nova e antiga.",
+       "apihelp-query+recentchanges-paramvalue-prop-sizes": "Adiciona os tamanhos antigo e novo da página em ''bytes''.",
+       "apihelp-query+recentchanges-paramvalue-prop-redirect": "Etiqueta a página se esta for um redirecionamento.",
+       "apihelp-query+recentchanges-paramvalue-prop-patrolled": "Etiqueta as edições que podem ser patrulhadas, marcando-as como patrulhadas ou não patrulhadas.",
+       "apihelp-query+recentchanges-paramvalue-prop-loginfo": "Adiciona informação de registo (identificador do registo, tipo de entrada, etc.) às entradas do registo.",
+       "apihelp-query+recentchanges-paramvalue-prop-tags": "Lista as etiquetas da entrada.",
+       "apihelp-query+recentchanges-paramvalue-prop-sha1": "Adiciona a soma de controlo do conteúdo para as entradas associadas com uma revisão.",
+       "apihelp-query+recentchanges-param-token": "Em substituição, usar <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
+       "apihelp-query+recentchanges-param-show": "Mostrar só as entradas que correspondem a estes critérios. Por exemplo, para ver só as edições menores feitas por utilizadores autenticados, defina $1show=minor|!anon.",
+       "apihelp-query+recentchanges-param-limit": "O número total de mudanças a serem devolvidas.",
+       "apihelp-query+recentchanges-param-type": "Os tipos de mudanças a serem mostradas.",
+       "apihelp-query+recentchanges-param-toponly": "Listar só as alterações que são a revisão mais recente.",
+       "apihelp-query+recentchanges-param-generaterevisions": "Ao ser usado como gerador, gerar identificadores de revisões em vez de títulos. As entradas das mudanças recentes que não tenham identificadores de revisão associados (por exemplo, a maioria das entradas do registo) não geram nada.",
+       "apihelp-query+recentchanges-example-simple": "Listar as mudanças recentes.",
+       "apihelp-query+recentchanges-example-generator": "Obter informação de página acerca das mudanças recentes não patrulhadas.",
+       "apihelp-query+redirects-description": "Devolve todos os redirecionamentos para as páginas indicadas.",
+       "apihelp-query+redirects-param-prop": "As propriedades a serem obtidas:",
+       "apihelp-query+redirects-paramvalue-prop-pageid": "O identificador de página de cada redirecionamento.",
+       "apihelp-query+redirects-paramvalue-prop-title": "O título de cada redirecionamento.",
+       "apihelp-query+redirects-paramvalue-prop-fragment": "O fragmento de cada redirecionamento, se existir.",
+       "apihelp-query+redirects-param-namespace": "Incluir só as páginas destes espaços nominais.",
+       "apihelp-query+redirects-param-limit": "O número de redirecionamentos a serem devolvidos.",
+       "apihelp-query+redirects-param-show": "Mostrar só as páginas que correspondem a estes critérios:\n;fragment:Mostrar só os redirecionamentos com um fragmento.\n;!fragment:Mostrar só os redirecionamentos sem um fragmento.",
+       "apihelp-query+redirects-example-simple": "Obter uma lista dos redirecionamentos para a página [[Main Page]].",
+       "apihelp-query+redirects-example-generator": "Obter informação sobre todos os redirecionamentos para a página [[Main Page]].",
+       "apihelp-query+revisions-description": "Obter informação da revisão.\n\nPode ser usado de várias maneiras:\n# Obter dados sobre um conjunto de páginas (última revisão), definindo títulos ou identificadores de páginas.\n# Obter as revisões de uma página indicada, usando títulos ou identificadores de páginas, com start, end ou limit.\n# Obter dados sobre um conjunto de revisões definindo os respetivos identificadores de revisões.",
+       "apihelp-query+revisions-paraminfo-singlepageonly": "Só pode ser usado com uma única página (modo #2)",
+       "apihelp-query+revisions-param-startid": "O identificador de revisão a partir do qual será começada a enumeração.",
+       "apihelp-query+revisions-param-endid": "Terminar a enumeração de revisões neste identificador de revisão.",
+       "apihelp-query+revisions-param-start": "A data e hora da revisão a partir da qual será começada a enumeração.",
+       "apihelp-query+revisions-param-end": "A data e hora da revisão na qual será terminada a enumeração.",
+       "apihelp-query+revisions-param-user": "Incluir só as revisões deste utilizador.",
+       "apihelp-query+revisions-param-excludeuser": "Excluir as revisões deste utilizador.",
+       "apihelp-query+revisions-param-tag": "Listar só as revisões marcadas com esta etiqueta.",
+       "apihelp-query+revisions-param-token": "Que chaves obter para cada revisão.",
+       "apihelp-query+revisions-example-content": "Obter dados com o conteúdo da última revisão dos títulos <kbd>API</kbd> e <kbd>Main Page</kbd>.",
+       "apihelp-query+revisions-example-last5": "Obter as últimas 5 revisões da página <kbd>Main Page</kbd>.",
+       "apihelp-query+revisions-example-first5": "Obter as primeiras 5 revisões da página <kbd>Main Page</kbd>.",
+       "apihelp-query+revisions-example-first5-after": "Obter as primeiras 5 revisões da página <kbd>Main Page</kbd> feitas após 2006-05-01.",
+       "apihelp-query+revisions-example-first5-not-localhost": "Obter as primeiras 5 revisões da página <kbd>Main Page</kbd> que não foram feitas pelo utilizador anónimo <kbd>127.0.0.1</kbd>.",
+       "apihelp-query+revisions-example-first5-user": "Obter as primeiras 5 revisões da página <kbd>Main Page</kbd> feitas pelo utilizador <kbd>MediaWiki default</kbd>.",
+       "apihelp-query+revisions+base-param-prop": "As propriedades a serem obtidas para cada revisão:",
+       "apihelp-query+revisions+base-paramvalue-prop-ids": "O identificador da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-flags": "As etiquetas da revisão (menor).",
+       "apihelp-query+revisions+base-paramvalue-prop-timestamp": "A data e hora da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-user": "O utilizador que fez a revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-userid": "O identificador de utilizador do criador da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-size": "O tamanho (em bytes) da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-sha1": "O resumo criptográfico SHA-1 (na base 16) da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "O identificador do modelo de conteúdo da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-comment": "O comentário do utilizador para a revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-parsedcomment": "O comentário do utilizador para a revisão, após a análise sintática.",
+       "apihelp-query+revisions+base-paramvalue-prop-content": "O texto da revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-tags": "As etiquetas para a revisão.",
+       "apihelp-query+revisions+base-paramvalue-prop-parsetree": "A árvore de análise XML do conteúdo da revisão (requer o modelo de conteúdo <code>$1</code>).",
+       "apihelp-query+revisions+base-param-limit": "Limitar o número de revisões que serão devolvidas.",
+       "apihelp-query+revisions+base-param-expandtemplates": "Expandir predefinições no conteúdo da revisão (requer $1prop=content).",
+       "apihelp-query+revisions+base-param-generatexml": "Gerar a árvore de análise sintática em XML do conteúdo da revisão (requer $1prop=content; substituído por <kbd>$1prop=parsetree</kbd>).",
+       "apihelp-query+revisions+base-param-parse": "Fazer a análise sintática do conteúdo da revisão (requer $1prop=content). Por motivos de desempenho, se esta opção for usada $1limit é forçado a ser 1.",
+       "apihelp-query+revisions+base-param-section": "Obter apenas o conteúdo da secção que tem este número.",
+       "apihelp-query+revisions+base-param-diffto": "O identificador da revisão contra a qual será tirada uma lista de diferenças de cada revisão. Usar <kbd>prev</kbd> (anterior), <kbd>next</kbd> (seguinte) e <kbd>cur</kbd> (atual).",
+       "apihelp-query+revisions+base-param-difftotext": "O texto contra o qual será tirada uma lista de diferenças de cada revisão. Só produz as diferenças para um número limitado de revisões. Tem precedência sobre <var>$1diffto</var>. Se <var>$1section</var> estiver definido, só o conteúdo dessa secção será comparado contra o texto.",
+       "apihelp-query+revisions+base-param-difftotextpst": "Fazer uma transformação de pré-gravação ao texto antes de calcular as diferenças. Só é válido quando usado com <var>$1difftotext</var>.",
+       "apihelp-query+revisions+base-param-contentformat": "O formato de seriação usado para <var>$1difftotext</var> e esperado para o conteúdo produzido.",
+       "apihelp-query+search-description": "Efetuar uma pesquisa do texto integral.",
+       "apihelp-query+search-param-search": "Procurar os títulos de página ou o conteúdo que corresponda a este valor. Pode usar o texto da pesquisa para invocar funcionalidades de pesquisa especiais, dependendo dos meios de pesquisa do servidor da wiki.",
+       "apihelp-query+search-param-namespace": "Pesquisar só nestes espaços nominais.",
+       "apihelp-query+search-param-what": "O tipo de pesquisa a executar.",
+       "apihelp-query+search-param-info": "Quais os metadados a serem devolvidos.",
+       "apihelp-query+search-param-prop": "As propriedades a serem devolvidas:",
+       "apihelp-query+search-param-qiprofile": "O perfil independente das pesquisas a ser usado (afeta o algoritmo de classificação).",
+       "apihelp-query+search-paramvalue-prop-size": "Adiciona o tamanho da página em ''bytes''.",
+       "apihelp-query+search-paramvalue-prop-wordcount": "Adiciona o número de palavras da página.",
+       "apihelp-query+search-paramvalue-prop-timestamp": "Adiciona a data e hora a que a página foi editada pela última vez.",
+       "apihelp-query+search-paramvalue-prop-snippet": "Adiciona um fragmento de código com a página, após análise sintática.",
+       "apihelp-query+search-paramvalue-prop-titlesnippet": "Adiciona um fragmento de código com o título da página, após análise sintática.",
+       "apihelp-query+search-paramvalue-prop-redirectsnippet": "Adiciona um fragmento de código com o título redirecionado, após análise sintática.",
+       "apihelp-query+search-paramvalue-prop-redirecttitle": "Adiciona o título do redirecionamento correspondente.",
+       "apihelp-query+search-paramvalue-prop-sectionsnippet": "Adiciona um fragmento de código com o título da secção correspondente, após análise sintática.",
+       "apihelp-query+search-paramvalue-prop-sectiontitle": "Adiciona o título da secção correspondente.",
+       "apihelp-query+search-paramvalue-prop-categorysnippet": "Adiciona um fragmento de código com a categoria correspondente, após análise sintática.",
+       "apihelp-query+search-paramvalue-prop-isfilematch": "Adiciona um valor booleano que indica se a pesquisa encontrou correspondência no conteúdo de ficheiros.",
+       "apihelp-query+search-paramvalue-prop-score": "<span class=\"apihelp-deprecated\">Obsoleto e ignorado.</span>",
+       "apihelp-query+search-paramvalue-prop-hasrelated": "<span class=\"apihelp-deprecated\">Obsoleto e ignorado.</span>",
+       "apihelp-query+search-param-limit": "O número total de páginas a serem devolvidas.",
+       "apihelp-query+search-param-interwiki": "Incluir resultados interwikis na pesquisa, se disponíveis.",
+       "apihelp-query+search-param-backend": "O servidor de pesquisas a ser usado, se diferente do servidor padrão.",
+       "apihelp-query+search-param-enablerewrites": "Ativar a reescrita da pesquisa interna. Alguns motores de pesquisa podem reescrever a pesquisa, substituindo-a por outra que consideram que dará melhores resultados, como acontece na correção de erros de ortografia.",
+       "apihelp-query+search-example-simple": "Pesquisar <kbd>meaning</kbd>.",
+       "apihelp-query+search-example-text": "Pesquisar <kbd>meaning</kbd> nos textos.",
+       "apihelp-query+search-example-generator": "Obter informação sobre as páginas devolvidas por uma pesquisa do termo <kbd>meaning</kbd>.",
+       "apihelp-query+siteinfo-description": "Devolver informação geral sobre o ''site''.",
+       "apihelp-query+siteinfo-param-prop": "A informação a ser obtida:",
+       "apihelp-query+siteinfo-paramvalue-prop-general": "Informação global do sistema.",
+       "apihelp-query+siteinfo-paramvalue-prop-namespaces": "Uma lista dos espaços nominais registados e dos seus nomes canónicos.",
+       "apihelp-query+siteinfo-paramvalue-prop-namespacealiases": "Uma lista dos nomes alternativos dos espaços nominais registados.",
+       "apihelp-query+siteinfo-paramvalue-prop-specialpagealiases": "Uma lista dos nomes alternativos das páginas especiais.",
+       "apihelp-query+siteinfo-paramvalue-prop-magicwords": "Uma lista das palavras mágicas e dos seus nomes alternativos.",
+       "apihelp-query+siteinfo-paramvalue-prop-statistics": "Devolve as estatísticas do ''site''.",
+       "apihelp-query+siteinfo-paramvalue-prop-interwikimap": "Devolve o mapa de interwikis (opcionalmente filtrado, opcionalmente localizado usando <var>$1inlanguagecode</var>).",
+       "apihelp-query+siteinfo-paramvalue-prop-dbrepllag": "Devolve o servidor da base de dados com o maior atraso de replicação.",
+       "apihelp-query+siteinfo-paramvalue-prop-usergroups": "Devolve os grupos de utilizadores e as permissões associadas.",
+       "apihelp-query+siteinfo-paramvalue-prop-libraries": "Devolve as bibliotecas instaladas na wiki.",
+       "apihelp-query+siteinfo-paramvalue-prop-extensions": "Devolve as extensões instaladas na wiki.",
+       "apihelp-query+siteinfo-paramvalue-prop-fileextensions": "Devolve uma lista das extensões (tipos) dos ficheiros que podem ser carregados.",
+       "apihelp-query+siteinfo-paramvalue-prop-rightsinfo": "Devolve informação sobre os direitos (a licença) da wiki, se disponível.",
+       "apihelp-query+siteinfo-paramvalue-prop-restrictions": "Devolve informação sobre os tipos de restrição (proteção) disponíveis.",
+       "apihelp-query+siteinfo-paramvalue-prop-languages": "Devolve uma lista das línguas que o MediaWiki suporta (opcionalmente localizada, usando <var>$1inlanguagecode</var>).",
+       "apihelp-query+siteinfo-paramvalue-prop-skins": "Devolve uma lista de todos os temas ativados (opcionalmente localizada, usando <var>$1inlanguagecode</var>, ou então na língua do conteúdo).",
+       "apihelp-query+siteinfo-paramvalue-prop-extensiontags": "Devolve uma lista dos elementos de extensões do analisador sintático.",
+       "apihelp-query+siteinfo-paramvalue-prop-functionhooks": "Devolve uma lista dos ''hooks'' de funções do analisador sintático.",
+       "apihelp-query+siteinfo-paramvalue-prop-showhooks": "Devolve uma lista de todos os ''hooks'' subscritos (conteúdo de <var>[[mw:Manual:$wgHooks|$wgHooks]]</var>).",
+       "apihelp-query+siteinfo-paramvalue-prop-variables": "Devolve uma lista de identificadores de variáveis.",
+       "apihelp-query+siteinfo-paramvalue-prop-protocols": "Devolve uma lista dos protocolos permitidos nos ''links'' externos.",
+       "apihelp-query+siteinfo-paramvalue-prop-defaultoptions": "Devolve os valores padrão para as preferências dos utilizadores.",
+       "apihelp-query+siteinfo-paramvalue-prop-uploaddialog": "Devolve a configuração do diálogo de carregamento.",
+       "apihelp-query+siteinfo-param-filteriw": "Devolver só as entradas locais, ou só as não locais, do mapa de interwikis.",
+       "apihelp-query+siteinfo-param-showalldb": "Listar todos os servidores da base de dados, não só aquele que tem maior atraso.",
+       "apihelp-query+siteinfo-param-numberingroup": "Lista o número de utilizadores nos grupos de utilizadores.",
+       "apihelp-query+siteinfo-param-inlanguagecode": "O código de língua dos nomes localizados (o melhor possível) das línguas e dos temas.",
+       "apihelp-query+siteinfo-example-simple": "Obter as informações do ''site''.",
+       "apihelp-query+siteinfo-example-interwiki": "Obter uma lista dos prefixos interwikis locais.",
+       "apihelp-query+siteinfo-example-replag": "Verificar o atraso de replicação atual.",
+       "apihelp-query+stashimageinfo-description": "Devolve informações dos ficheiros escondidos.",
+       "apihelp-query+stashimageinfo-param-filekey": "Chave que identifica um carregamento anterior que foi escondido temporariamente.",
+       "apihelp-query+stashimageinfo-param-sessionkey": "Nome alternativo de $1filekey, para compatibilidade com versões anteriores.",
+       "apihelp-query+stashimageinfo-example-simple": "Devolve informação sobre um ficheiro escondido.",
+       "apihelp-query+stashimageinfo-example-params": "Devolve as miniaturas de dois ficheiros escondidos.",
+       "apihelp-query+tags-description": "Listar as etiquetas de modificação.",
+       "apihelp-query+tags-param-limit": "O número máximo de etiquetas a serem listadas.",
+       "apihelp-query+tags-param-prop": "As propriedades a serem obtidas:",
+       "apihelp-query+tags-paramvalue-prop-name": "Adiciona o nome da etiqueta.",
+       "apihelp-query+tags-paramvalue-prop-displayname": "Adiciona a mensagem de sistema para a etiqueta.",
+       "apihelp-query+tags-paramvalue-prop-description": "Adiciona a descrição da etiqueta.",
+       "apihelp-query+tags-paramvalue-prop-hitcount": "Adiciona o número de revisões e de entradas no registo que têm esta etiqueta.",
+       "apihelp-query+tags-paramvalue-prop-defined": "Indicar se a etiqueta está definida.",
+       "apihelp-query+tags-paramvalue-prop-source": "Obter as fontes da etiqueta, que podem incluir <samp>extension</samp> para etiquetas definidas por extensões e <samp>manual</samp> para etiquetas que podem ser manualmente aplicadas pelos utilizadores.",
+       "apihelp-query+tags-paramvalue-prop-active": "Indica se a etiqueta ainda está a ser aplicada.",
+       "apihelp-query+tags-example-simple": "Listar as etiquetas disponíveis.",
+       "apihelp-query+templates-description": "Devolve todas as páginas que são transcluídas nas páginas indicadas.",
+       "apihelp-query+templates-param-namespace": "Mostrar só as predefinições nestes espaços nominais.",
+       "apihelp-query+templates-param-limit": "O número de predefinições a serem devolvidas.",
+       "apihelp-query+templates-param-templates": "Listar só estas predefinições. Útil para verificar se uma determinada página contém uma determinada predefinição.",
+       "apihelp-query+templates-param-dir": "A direção de listagem.",
+       "apihelp-query+templates-example-simple": "Obter as predefinições usadas na página <kbd>Main Page</kbd>.",
+       "apihelp-query+templates-example-generator": "Obter informação sobre as páginas das predefinições usadas na página <kbd>Main Page</kbd>.",
+       "apihelp-query+templates-example-namespaces": "Obter as páginas dos espaços nominais {{ns:user}} e {{ns:template}} que são transcluídas na página <kbd>Main Page</kbd>.",
+       "apihelp-query+tokens-description": "Obtém chaves para operações de modificação de dados.",
+       "apihelp-query+tokens-param-type": "Tipos de chave a pedir.",
+       "apihelp-query+tokens-example-simple": "Obter uma chave csfr (padrão).",
+       "apihelp-query+tokens-example-types": "Obter uma chave de vigilância e uma chave de patrulha.",
+       "apihelp-query+transcludedin-description": "Obter todas as páginas que transcluem as páginas indicadas.",
+       "apihelp-query+transcludedin-param-prop": "As propriedades a serem obtidas:",
+       "apihelp-query+transcludedin-paramvalue-prop-pageid": "O identificador de cada página.",
+       "apihelp-query+transcludedin-paramvalue-prop-title": "O título de cada página.",
+       "apihelp-query+transcludedin-paramvalue-prop-redirect": "Indicar se a página é um redirecionamento.",
+       "apihelp-query+transcludedin-param-namespace": "Incluir só as páginas nestes espaços nominais.",
+       "apihelp-query+transcludedin-param-limit": "O número de entradas a serem devolvidas.",
+       "apihelp-query+transcludedin-param-show": "Mostrar só as entradas que correspondem a estes critérios:\n;redirect:Mostrar só os redirecionamentos.\n;!redirect:Mostrar só as que não são redirecionamentos.",
+       "apihelp-query+transcludedin-example-simple": "Obter uma lista das páginas que transcluem <kbd>Main Page</kbd>.",
+       "apihelp-query+transcludedin-example-generator": "Obter informação sobre as páginas que transcluem <kbd>Main Page</kbd>.",
+       "apihelp-query+usercontribs-description": "Obter todas as edições de um utilizador.",
+       "apihelp-query+usercontribs-param-limit": "O número máximo de contribuições a serem devolvidas.",
+       "apihelp-query+usercontribs-param-start": "A data e hora da contribuição pela qual será começada a devolução de resultados.",
+       "apihelp-query+usercontribs-param-end": "A data e hora da contribuição na qual será terminada a devolução de resultados.",
+       "apihelp-query+usercontribs-param-user": "Os utilizadores cujas contribuições serão obtidas.",
+       "apihelp-query+usercontribs-param-userprefix": "Obter as contribuições de todos os utilizadores cujos nomes começam por este valor. Tem precedência sobre $1user.",
+       "apihelp-query+usercontribs-param-namespace": "Listar só as contribuições nestes espaços nominais.",
+       "apihelp-query+usercontribs-param-prop": "Incluir informações adicionais:",
+       "apihelp-query+usercontribs-paramvalue-prop-ids": "Adiciona os identificadores da página e da revisão.",
+       "apihelp-query+usercontribs-paramvalue-prop-title": "Adiciona o título e o identificador do espaço nominal da página.",
+       "apihelp-query+usercontribs-paramvalue-prop-timestamp": "Adiciona a data e hora da edição.",
+       "apihelp-query+usercontribs-paramvalue-prop-comment": "Adiciona o comentário da edição.",
+       "apihelp-query+usercontribs-paramvalue-prop-parsedcomment": "Adiciona o comentário da edição, após análise sintática.",
+       "apihelp-query+usercontribs-paramvalue-prop-size": "Adiciona o novo tamanho da edição.",
+       "apihelp-query+usercontribs-paramvalue-prop-sizediff": "Adiciona a diferença de tamanho entre a edição e a sua progenitora.",
+       "apihelp-query+usercontribs-paramvalue-prop-flags": "Adiciona as etiquetas da edição.",
+       "apihelp-query+usercontribs-paramvalue-prop-patrolled": "Etiqueta as edições patrulhadas.",
+       "apihelp-query+usercontribs-paramvalue-prop-tags": "Lista as etiquetas da edição.",
+       "apihelp-query+usercontribs-param-show": "Mostrar só as contribuições que correspondem a estes critérios; por exemplo, só as edições não menores: <kbd>$2show=!minor</kbd>.\n\nSe um dos valores <kbd>$2show=patrolled</kbd> ou <kbd>$2show=!patrolled</kbd> estiver definido, as revisões feitas há mais de <var>[[mw:Manual:$wgRCMaxAge|$wgRCMaxAge]]</var> ($1 {{PLURAL:$1|segundo|segundos}}) não serão mostradas.",
+       "apihelp-query+usercontribs-param-tag": "Listar só as revisões marcadas com esta etiqueta.",
+       "apihelp-query+usercontribs-param-toponly": "Listar só as alterações que são a revisão mais recente.",
+       "apihelp-query+usercontribs-example-user": "Mostrar as contribuições do utilizador <kbd>Example</kbd>.",
+       "apihelp-query+usercontribs-example-ipprefix": "Mostrar as contribuições de todos os endereços IP com o prefixo <kbd>192.0.2.</kbd>.",
+       "apihelp-query+userinfo-description": "Obter informações sobre o utilizador atual.",
+       "apihelp-query+userinfo-param-prop": "As informações que devem ser incluídas:",
+       "apihelp-query+userinfo-paramvalue-prop-blockinfo": "Etiquetas que indicam se o utilizador atual está bloqueado, por quem, e qual o motivo.",
+       "apihelp-query+userinfo-paramvalue-prop-hasmsg": "Adiciona uma etiqueta <samp>messages</samp> se o utilizador atual tem mensagens pendentes.",
+       "apihelp-query+userinfo-paramvalue-prop-groups": "Lista todos os grupos aos quais o utilizador atual pertence.",
+       "apihelp-query+userinfo-paramvalue-prop-implicitgroups": "Lista todos os grupos aos quais o utilizador atual pertence automaticamente.",
+       "apihelp-query+userinfo-paramvalue-prop-rights": "Lista todas as permissões que o utilizador atual tem.",
+       "apihelp-query+userinfo-paramvalue-prop-changeablegroups": "Lista os grupos aos quais o utilizador atual pode ser adicionado ou de onde pode ser removido.",
+       "apihelp-query+userinfo-paramvalue-prop-options": "Lista todas as preferências que o utilizador atual definiu.",
+       "apihelp-query+userinfo-paramvalue-prop-preferencestoken": "<span class=\"apihelp-deprecated\">Obsoleto.</span> Obter uma chave para alterar as preferências do utilizador atual.",
+       "apihelp-query+userinfo-paramvalue-prop-editcount": "Adiciona a contagem de edições do utilizador atual.",
+       "apihelp-query+userinfo-paramvalue-prop-ratelimits": "Lista todas as frequências limite do utilizador atual.",
+       "apihelp-query+userinfo-paramvalue-prop-realname": "Adiciona o nome real do utilizador.",
+       "apihelp-query+userinfo-paramvalue-prop-email": "Adicionar o correio eletrónico do utilizador e a data de autenticação do correio eletrónico.",
+       "apihelp-query+userinfo-paramvalue-prop-acceptlang": "Faz eco do cabeçalho <code>Accept-Language</code> enviado pelo cliente num formato estruturado.",
+       "apihelp-query+userinfo-paramvalue-prop-registrationdate": "Adiciona a data de registo do utilizador.",
+       "apihelp-query+userinfo-paramvalue-prop-unreadcount": "Adiciona a contagem de páginas não lidas da lista de páginas vigiadas do utilizador (máximo $1; devolve <samp>$2</samp> se forem mais).",
+       "apihelp-query+userinfo-paramvalue-prop-centralids": "Adiciona os identificadores centrais e o estado de ligação central (''attachment'') do utilizador.",
+       "apihelp-query+userinfo-param-attachedwiki": "Com <kbd>$1prop=centralids</kbd>, indicar se o utilizador tem ligação com a wiki designada por este identificador.",
+       "apihelp-query+userinfo-example-simple": "Obter informações sobre o utilizador atual.",
+       "apihelp-query+userinfo-example-data": "Obter informações adicionais sobre o utilizador atual.",
+       "apihelp-query+users-description": "Obter informações sobre uma lista de utilizadores.",
+       "apihelp-query+users-param-prop": "As informações que devem ser incluídas:",
+       "apihelp-query+users-paramvalue-prop-blockinfo": "Etiquetas que indicam se o utilizador está bloqueado, por quem, e qual o motivo.",
+       "apihelp-query+users-paramvalue-prop-groups": "Lista todos os grupos aos quais cada utilizador pertence.",
+       "apihelp-query+users-paramvalue-prop-implicitgroups": "Lista todos os grupos aos quais um utilizador pertence automaticamente.",
+       "apihelp-query+users-paramvalue-prop-rights": "Lista todas as permissões que cada utilizador tem.",
+       "apihelp-query+users-paramvalue-prop-editcount": "Adiciona a contagem de edições do utilizador.",
+       "apihelp-query+users-paramvalue-prop-registration": "Adiciona a data e hora de registo do utilizador.",
+       "apihelp-query+users-paramvalue-prop-emailable": "Etiqueta que indica se o utilizador pode e quer receber correio eletrónico através de [[Special:Emailuser]].",
+       "apihelp-query+users-paramvalue-prop-gender": "Etiqueta que indica o género do utilizador. Devolve \"male\" (masculino), \"female\" (feminino) ou \"unknown\" (desconhecido).",
+       "apihelp-query+users-paramvalue-prop-centralids": "Adiciona os identificadores centrais e o estado de ligação central (''attachment'') do utilizador.",
+       "apihelp-query+users-paramvalue-prop-cancreate": "Indica se pode ser criada uma conta para os nomes de utilizador não registados, mas válidos.",
+       "apihelp-query+users-param-attachedwiki": "Com <kbd>$1prop=centralids</kbd>, indicar se o utilizador tem ligação com a wiki designada por este identificador.",
+       "apihelp-query+users-param-users": "Uma lista de utilizadores dos quais serão obtidas informações.",
+       "apihelp-query+users-param-token": "Em substituição, usar <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
+       "apihelp-query+users-example-simple": "Devolver informações sobre o utilizador <kbd>Example</kbd>.",
+       "apihelp-query+watchlist-description": "Obter mudanças recentes das páginas vigiadas do utilizador atual.",
+       "apihelp-query+watchlist-param-allrev": "Incluir múltiplas revisões da mesma página dentro do intervalo de tempo indicado.",
+       "apihelp-query+watchlist-param-start": "A data e hora da mudança recente a partir da qual será começada a enumeração.",
+       "apihelp-query+watchlist-param-end": "A data e hora da mudança recente na qual será terminada a enumeração.",
+       "apihelp-query+watchlist-param-namespace": "Filtrar as mudanças para produzir só as dos espaços nominais indicados.",
+       "apihelp-query+watchlist-param-user": "Listar só as mudanças deste utilizador.",
+       "apihelp-query+watchlist-param-excludeuser": "Não listar as mudanças deste utilizador.",
+       "apihelp-query+watchlist-param-limit": "O número total de resultados a serem devolvidos por pedido.",
+       "apihelp-query+watchlist-param-prop": "As propriedades adicionais que devem ser obtidas:",
+       "apihelp-query+watchlist-paramvalue-prop-ids": "Adiciona identificadores de revisões e de páginas.",
+       "apihelp-query+watchlist-paramvalue-prop-title": "Adiciona o título da página.",
+       "apihelp-query+watchlist-paramvalue-prop-flags": "Adiciona etiquetas para a edição.",
+       "apihelp-query+watchlist-paramvalue-prop-user": "Adiciona o utilizador que fez a edição.",
+       "apihelp-query+watchlist-paramvalue-prop-userid": "Adiciona o identificador do utilizador que realizou a edição.",
+       "apihelp-query+watchlist-paramvalue-prop-comment": "Adiciona o comentário da edição.",
+       "apihelp-query+watchlist-paramvalue-prop-parsedcomment": "Adiciona o comentário da edição, após análise sintática.",
+       "apihelp-query+watchlist-paramvalue-prop-timestamp": "Adiciona a data e hora da edição.",
+       "apihelp-query+watchlist-paramvalue-prop-patrol": "Etiqueta que indica as edições que são patrulhadas.",
+       "apihelp-query+watchlist-paramvalue-prop-sizes": "Adiciona os tamanhos novo e antigo da página.",
+       "apihelp-query+watchlist-paramvalue-prop-notificationtimestamp": "Adiciona a data e hora da última vez em que o utilizador foi notificado da edição.",
+       "apihelp-query+watchlist-paramvalue-prop-loginfo": "Adiciona informação do registo quando apropriado.",
+       "apihelp-query+watchlist-param-show": "Mostrar só as entradas que correspondem a estes critérios. Por exemplo, para ver só as edições menores feitas por utilizadores autenticados, definir $1show=minor|!anon.",
+       "apihelp-query+watchlist-param-type": "Os tipos de alterações a serem mostradas:",
+       "apihelp-query+watchlist-paramvalue-type-edit": "Edições normais.",
+       "apihelp-query+watchlist-paramvalue-type-external": "Mudanças externas.",
+       "apihelp-query+watchlist-paramvalue-type-new": "Criações de páginas.",
+       "apihelp-query+watchlist-paramvalue-type-log": "Entradas do registo.",
+       "apihelp-query+watchlist-paramvalue-type-categorize": "Alterações de pertença a categorias.",
+       "apihelp-query+watchlist-param-owner": "Usado com $1token para aceder à lista de páginas vigiadas de outro utilizador.",
+       "apihelp-query+watchlist-param-token": "Uma chave de segurança (disponível nas [[Special:Preferences#mw-prefsection-watchlist|preferências]] do utilizador) para permitir acesso à lista de páginas vigiadas de outro utilizador.",
+       "apihelp-query+watchlist-example-simple": "Listar a revisão mais recente das páginas com mudanças recentes na lista de páginas vigiadas do utilizador atual.",
+       "apihelp-query+watchlist-example-props": "Obter informação adicional sobre a revisão mais recente das páginas vigiadas do utilizador atual que tenham sido alteradas.",
+       "apihelp-query+watchlist-example-allrev": "Obter informações sobre todas as mudanças recentes às páginas vigiadas do utilizador atual.",
+       "apihelp-query+watchlist-example-generator": "Obter informações das páginas na lista de páginas vigiadas do utilizador atual que tenham sido recentemente alteradas.",
+       "apihelp-query+watchlist-example-generator-rev": "Obter informações de revisão para as mudanças recentes às páginas vigiadas do utilizador atual.",
+       "apihelp-query+watchlist-example-wlowner": "Listar a revisão mais recente das páginas na lista de páginas vigiadas do utilizador <kbd>Example</kbd> que tenham sido recentemente alteradas.",
+       "apihelp-query+watchlistraw-description": "Obter todas as páginas na lista de páginas vigiadas do utilizador atual.",
+       "apihelp-query+watchlistraw-param-namespace": "Listar só as páginas nos espaços nominais indicados.",
+       "apihelp-query+watchlistraw-param-limit": "O número total de resultados a serem devolvidos por pedido.",
+       "apihelp-query+watchlistraw-param-prop": "As propriedades adicionais que devem ser obtidas:",
+       "apihelp-query+watchlistraw-paramvalue-prop-changed": "Adiciona a data e hora da última vez em que o utilizador foi notificado da edição.",
+       "apihelp-query+watchlistraw-param-show": "Listar só os elementos que preenchem estes critérios.",
+       "apihelp-query+watchlistraw-param-owner": "Usado em conjunto com o parâmetro $1token para aceder à lista de páginas vigiadas de outro utilizador.",
+       "apihelp-query+watchlistraw-param-token": "Uma chave de segurança (disponível nas [[Special:Preferences#mw-prefsection-watchlist|preferências]] do utilizador) para permitir acesso à lista de páginas vigiadas de outro utilizador.",
+       "apihelp-query+watchlistraw-param-dir": "A direção de listagem.",
+       "apihelp-query+watchlistraw-param-fromtitle": "O título (com o prefixo do espaço nominal) a partir do qual será começada a enumeração.",
+       "apihelp-query+watchlistraw-param-totitle": "O título (com o prefixo do espaço nominal) no qual será terminada a enumeração.",
+       "apihelp-query+watchlistraw-example-simple": "Listar as páginas na lista de páginas vigiadas do utilizador atual.",
+       "apihelp-query+watchlistraw-example-generator": "Obter informações das páginas na lista de páginas vigiadas do utilizador atual.",
+       "apihelp-removeauthenticationdata-description": "Remover os dados de autenticação do utilizador atual.",
+       "apihelp-removeauthenticationdata-example-simple": "Tentar remover os dados do utilizador atual para o pedido de autenticação <kbd>FooAuthenticationRequest</kbd>.",
+       "apihelp-resetpassword-description": "Enviar a um utilizador uma mensagem eletrónica de reinício da palavra-passe.",
+       "apihelp-resetpassword-description-noroutes": "Não estão disponíveis rotas de reinício da palavra-passe.\n\nPara usar este módulo, ative uma rota em <var>[[mw:Manual:$wgPasswordResetRoutes|$wgPasswordResetRoutes]]</var>.",
+       "apihelp-resetpassword-param-user": "O utilizar cuja palavra-passe será reiniciada.",
+       "apihelp-resetpassword-param-email": "O correio eletrónico do utilizador cuja palavra-passe será reiniciada.",
+       "apihelp-resetpassword-param-capture": "Devolver as palavras-passe temporárias que foram enviadas. Requer a permissão <code>passwordreset</code>.",
+       "apihelp-resetpassword-example-user": "Enviar uma mensagem eletrónica para reinício da palavra-passe ao utilizador <kbd>Example</kbd>.",
+       "apihelp-resetpassword-example-email": "Enviar uma mensagem eletrónica para reinício da palavra-passe a todos os utilizadores com o correio eletrónico <kbd>user@example.com</kbd>.",
+       "apihelp-revisiondelete-description": "Eliminar e restaurar revisões.",
+       "apihelp-revisiondelete-param-type": "O tipo de eliminação de revisão que está a ser feito.",
+       "apihelp-revisiondelete-param-target": "O título de página para a eliminação da revisão, se for necessário para o tipo de eliminação.",
+       "apihelp-revisiondelete-param-ids": "Os identificadores das revisões a serem eliminadas.",
+       "apihelp-revisiondelete-param-hide": "O que deve ser ocultado para cada revisão.",
+       "apihelp-revisiondelete-param-show": "O que deve ser mostrado para cada revisão.",
+       "apihelp-revisiondelete-param-suppress": "Indica se devem ser suprimidos os dados aos administradores como a todos os restantes utilizadores.",
+       "apihelp-revisiondelete-param-reason": "O motivo da eliminação ou restauro.",
+       "apihelp-revisiondelete-example-revision": "Ocultar o conteúdo da revisão <kbd>12345</kbd> na página <kbd>Main Page</kbd>.",
+       "apihelp-revisiondelete-example-log": "Ocultar todos os dados na entrada <kbd>67890</kbd> do registo com o motivo <kbd>BLP violation</kbd>.",
+       "apihelp-rollback-description": "Desfazer a última edição da página.\n\nSe o último utilizador a editar a página realizou várias edições em sequência, estas serão todas desfeitas.",
+       "apihelp-rollback-param-title": "O título da página a reverter. Não pode ser usado em conjunto com <var>$1pageid</var>.",
+       "apihelp-rollback-param-pageid": "O identificador da página a reverter. Não pode ser usado em conjunto com <var>$1title</var>.",
+       "apihelp-rollback-param-tags": "As etiquetas a aplicar à reversão.",
+       "apihelp-rollback-param-user": "O nome do utilizador cujas edições vão ser revertidas.",
+       "apihelp-rollback-param-summary": "Resumo personalizado da edição. Se estiver vazio, será utilizado o resumo por omissão.",
+       "apihelp-rollback-param-markbot": "Marcar as edições revertidas e a reversão como edições de robôs.",
+       "apihelp-rollback-param-watchlist": "Adicionar ou remover incondicionalmente a página da lista de páginas vigiadas do utilizador atual, usar as preferências ou não alterar o estado de vigilância.",
+       "apihelp-rollback-example-simple": "Reverter as últimas edições da página <kbd>Main Page</kbd> pelo utilizador <kbd>Example</kbd>.",
+       "apihelp-rollback-example-summary": "Reverter as últimas edições da página <kbd>Main Page</kbd> pelo utilizador IP <kbd>192.0.2.5</kbd> com o resumo <kbd>Reverting vandalism</kbd>, e marcar essas edições e a reversão como edições de robôs.",
+       "apihelp-rsd-description": "Exportar um esquema (''schema'') RSD (Really Simple Discovery).",
+       "apihelp-rsd-example-simple": "Exportar o esquema RSD.",
+       "apihelp-setnotificationtimestamp-description": "Atualizar a data e hora de notificação de alterações às páginas vigiadas.\n\nIsto afeta o realce das páginas alteradas, na lista de páginas vigiadas e no histórico, e o envio de mensagens de correio quando a preferência \"{{int:tog-enotifwatchlistpages}}\" está ativada.",
+       "apihelp-setnotificationtimestamp-param-entirewatchlist": "Trabalhar em todas as páginas vigiadas.",
+       "apihelp-setnotificationtimestamp-param-timestamp": "A data e hora a definir como data e hora da notificação.",
+       "apihelp-setnotificationtimestamp-param-torevid": "A revisão para a qual definir a data e hora de notificação (só uma página).",
+       "apihelp-setnotificationtimestamp-param-newerthanrevid": "A revisão da qual definir que a data e hora de notificação é mais recente (só uma página).",
+       "apihelp-setnotificationtimestamp-example-all": "Reiniciar o estado de notificação de todas as páginas vigiadas.",
+       "apihelp-setnotificationtimestamp-example-page": "Reiniciar o estado de notificação da página <kbd>Main page</kbd>.",
+       "apihelp-setnotificationtimestamp-example-pagetimestamp": "Definir a data e hora de notificação para a página <kbd>Main page</kbd> de forma a que todas as edições desde 1 de janeiro de 2012 passem a ser consideradas não vistas",
+       "apihelp-setnotificationtimestamp-example-allpages": "Reiniciar o estado de notificação das páginas no espaço nominal <kbd>{{ns:user}}</kbd>.",
+       "apihelp-stashedit-description": "Preparar uma edição na ''cache'' partilhada.\n\nIsto destina-se a ser usado via AJAX a partir do formulário de edição, para melhorar o desempenho da gravação da página.",
+       "apihelp-stashedit-param-title": "Título da página que está a ser editada.",
+       "apihelp-stashedit-param-section": "Número da secção. <kbd>0</kbd> para a secção do topo, <kbd>new</kbd> para uma secção nova.",
+       "apihelp-stashedit-param-sectiontitle": "O título para uma secção nova.",
+       "apihelp-stashedit-param-text": "O conteúdo da página.",
+       "apihelp-stashedit-param-stashedtexthash": "O resumo criptográfico do conteúdo da página, resultante de uma colocação anterior na área de ficheiros escondidos, a ser usado em vez de outro.",
+       "apihelp-stashedit-param-contentmodel": "O modelo de conteúdo do novo conteúdo.",
+       "apihelp-stashedit-param-contentformat": "O formato de seriação do conteúdo usado para o texto de entrada.",
+       "apihelp-stashedit-param-baserevid": "O identificador de revisão da revisão de base.",
+       "apihelp-stashedit-param-summary": "O resumo da mudança.",
+       "apihelp-tag-description": "Adicionar ou remover as etiquetas de modificação aplicadas a revisões individuais ou a entradas do registo.",
+       "apihelp-tag-param-rcid": "Um ou mais identificadores de mudanças recentes às quais adicionar ou remover a etiqueta.",
+       "apihelp-tag-param-revid": "Um ou mais identificadores de revisões às quais adicionar ou remover a etiqueta.",
+       "apihelp-tag-param-logid": "Um ou mais identificadores de entradas do registo às quais adicionar ou remover a etiqueta.",
+       "apihelp-tag-param-add": "As etiquetas a serem adicionadas. Só podem ser adicionadas as etiquetas definidas manualmente.",
+       "apihelp-tag-param-remove": "As etiquetas a serem removidas. Só podem ser removidas as etiquetas definidas manualmente ou completamente indefinidas.",
+       "apihelp-tag-param-reason": "O motivo da alteração.",
+       "apihelp-tag-example-rev": "Adicionar a etiqueta <kbd>vandalism</kbd> à revisão com o identificador 123, sem especificar um motivo.",
+       "apihelp-tag-example-log": "Remover a etiqueta <kbd>spam</kbd> da entrada do registo com o identificador 123, com o motivo <kbd>Wrongly applied</kbd>.",
+       "apihelp-tokens-description": "Obter chaves para operações de modificação de dados.\n\nEste módulo é obsoleto e foi substituído por [[Special:ApiHelp/query+tokens|action=query&meta=tokens]].",
+       "apihelp-tokens-param-type": "Tipos de chave a pedir.",
+       "apihelp-tokens-example-edit": "Obter uma chave de edição (padrão).",
+       "apihelp-tokens-example-emailmove": "Obter uma chave de correio eletrónico e uma chave de movimentação.",
        "apihelp-unblock-description": "Desbloquear um utilizador.",
+       "apihelp-unblock-param-id": "Identificador do bloqueio a desfazer (obtido com <kbd>list=blocks</kbd>). Não pode ser usado em conjunto com <var>$1user</var>.",
+       "apihelp-unblock-param-user": "Nome de utilizador, endereço IP ou gama de endereços IP a desbloquear. Não pode ser usado em conjunto com <var>$1id</var>.",
        "apihelp-unblock-param-reason": "Motivo para o desbloqueio.",
+       "apihelp-unblock-param-tags": "As etiquetas de modificação a aplicar à entrada no registo de bloqueios.",
+       "apihelp-unblock-example-id": "Desfazer o bloqueio com o identificador #<kbd>105</kbd>.",
+       "apihelp-unblock-example-user": "Desbloquear o utilizador <kbd>Bob</kbd> com o motivo <kbd>Sorry Bob</kbd>.",
+       "apihelp-undelete-description": "Restaurar revisões de uma página eliminada.\n\nPode obter-se uma lista de revisões eliminadas (incluindo as datas e horas de eliminação) com [[Special:ApiHelp/query+deletedrevs|list=deletedrevs]] e uma lista de identificadores de ficheiros eliminados com [[Special:ApiHelp/query+filearchive|list=filearchive]].",
        "apihelp-undelete-param-title": "Título da página a restaurar.",
-       "apihelp-upload-param-watch": "Vigiar página.",
+       "apihelp-undelete-param-reason": "Motivo para restaurar a página.",
+       "apihelp-undelete-param-tags": "Etiquetas de modificação a aplicar à entrada no registo de eliminações.",
+       "apihelp-undelete-param-timestamps": "As datas e horas das revisões a serem restauradas. Se ambos os parâmetros <var>$1timestamps</var> e <var>$1fileids</var> estiverem vazios, serão restauradas todas as revisões.",
+       "apihelp-undelete-param-fileids": "Os identificadores das revisões a serem restauradas. Se ambos os parâmetros <var>$1timestamps</var> e <var>$1fileids</var> estiverem vazios, serão restauradas todas as revisões.",
+       "apihelp-undelete-param-watchlist": "Adicionar ou remover incondicionalmente a página da lista de páginas vigiadas do utilizador atual, usar as preferências ou não alterar o estado de vigilância.",
+       "apihelp-undelete-example-page": "Restaurar a página <kbd>Main Page</kbd>.",
+       "apihelp-undelete-example-revisions": "Restaurar duas revisões da página <kbd>Main Page</kbd>.",
+       "apihelp-unlinkaccount-description": "Remover do utilizador atual uma conta ligada de uma wiki terceira.",
+       "apihelp-unlinkaccount-example-simple": "Tentar remover a ligação do utilizador atual ao fornecedor associado com <kbd>FooAuthenticationRequest</kbd>.",
+       "apihelp-upload-description": "Atualizar um ficheiro, ou obter o estado de carregamentos pendentes.\n\nEstão disponíveis vários métodos:\n* Carregar diretamente o conteúdo do ficheiro, usando o parâmetro <var>$1file</var>.\n* Carregar o ficheiro por segmentos, usando os parâmetros <var>$1filesize</var>, <var>$1chunk</var> e <var>$1offset</var>.\n* Instruir o servidor do MediaWiki para obter o ficheiro a partir de um URL, usando o parâmetro <var>$1url</var>.\n* Terminar um carregamento anterior que falhou devido a avisos, usando o parâmetro <var>$1filekey</var>.\nNote que o POST do HTTP tem de ser feito como um carregamento de ficheiro (isto é, usando <code>multipart/form-data</code>) ao enviar o <var>$1file</var>.",
+       "apihelp-upload-param-filename": "O nome de destino do ficheiro.",
+       "apihelp-upload-param-comment": "O comentário do carregamento. Também é usado como texto da página inicial para ficheiros novos se <var>$1text</var> não for especificado.",
+       "apihelp-upload-param-tags": "Etiquetas de modificação a aplicar à entrada do carregamento no registo e à revisão da página de ficheiro.",
+       "apihelp-upload-param-text": "Texto inicial da página para ficheiros novos.",
+       "apihelp-upload-param-watch": "Vigiar a página.",
+       "apihelp-upload-param-watchlist": "Adicionar ou remover incondicionalmente a página da lista de páginas vigiadas do utilizador atual, usar as preferências ou não alterar o estado de vigilância.",
        "apihelp-upload-param-ignorewarnings": "Ignorar todos os avisos.",
-       "apihelp-userrights-param-user": "Nome de utilizador(a).",
-       "apihelp-userrights-param-userid": "ID de utilizador.",
+       "apihelp-upload-param-file": "O conteúdo do ficheiro.",
+       "apihelp-upload-param-url": "O URL de onde obter o ficheiro.",
+       "apihelp-upload-param-filekey": "Chave que identifica um carregamento prévio que está temporariamente na área de ficheiros escondidos.",
+       "apihelp-upload-param-sessionkey": "O mesmo que $1filekey, mantido para compatibilidade com versões anteriores.",
+       "apihelp-upload-param-stash": "Se definido, o servidor irá colocar temporariamente o ficheiro na área de ficheiros escondidos em vez de o adicionar ao repositório.",
+       "apihelp-upload-param-filesize": "O tamanho do carregamento completo.",
+       "apihelp-upload-param-offset": "Posição do segmento em ''bytes''.",
+       "apihelp-upload-param-chunk": "O conteúdo do segmento.",
+       "apihelp-upload-param-async": "Tornar assíncronas as operações sobre ficheiros possivelmente grandes, quando possível.",
+       "apihelp-upload-param-checkstatus": "Obter só o estado de carregamento para a chave de ficheiro indicada.",
+       "apihelp-upload-example-url": "Carregar de um URL.",
+       "apihelp-upload-example-filekey": "Prosseguir um carregamento que falhou devido a avisos.",
+       "apihelp-userrights-description": "Alterar os membros de um grupo de utilizadores.",
+       "apihelp-userrights-param-user": "O nome de utilizador.",
+       "apihelp-userrights-param-userid": "O identificador de utilizador.",
        "apihelp-userrights-param-add": "Adicionar o utilizador a estes grupos.",
-       "apihelp-userrights-param-remove": "Remover este utilizador destes grupos.",
-       "apihelp-watch-example-unwatch": "Deixar de vigiar a página <kbd>Página Principal</kbd>.",
-       "apihelp-json-description": "Dados de saída em formato JSON.",
-       "api-help-title": "Ajuda API da MediaWiki",
-       "api-help-lead": "Esta é uma página de documentação API do MediaWiki gerada automaticamente.\n\nDocumentação e exemplos: https://www.mediawiki.org/wiki/API",
+       "apihelp-userrights-param-remove": "Remover o utilizador destes grupos.",
+       "apihelp-userrights-param-reason": "O motivo da alteração.",
+       "apihelp-userrights-example-user": "Adicionar o utilizador <kbd>FooBot</kbd> ao grupo <kbd>bot</kbd> e removê-lo dos grupos <kbd>sysop</kbd> e <kbd>bureaucrat</kbd>.",
+       "apihelp-userrights-example-userid": "Adicionar o utilizador com o identificador <kbd>123</kbd> ao grupo <kbd>bot</kbd> e removê-lo dos grupos <kbd>sysop</kbd> e <kbd>bureaucrat</kbd>.",
+       "apihelp-watch-description": "Adicionar ou remover páginas da lista de páginas vigiadas do utilizador atual.",
+       "apihelp-watch-param-title": "A página a vigiar ou deixar de ser vigiada. Em vez disto, usar <var>$1titles</var>.",
+       "apihelp-watch-param-unwatch": "Se definido, a página deixará de ser vigiada, em vez de o ser.",
+       "apihelp-watch-example-watch": "Vigiar a página <kbd>Main Page</kbd>.",
+       "apihelp-watch-example-unwatch": "Deixar de vigiar a página <kbd>Main Page</kbd>.",
+       "apihelp-watch-example-generator": "Vigiar as primeiras páginas do espaço nominal principal.",
+       "apihelp-format-example-generic": "Devolver o resultado da consulta no formato $1.",
+       "apihelp-format-param-wrappedhtml": "Devolver o HTML com realce sintático e os módulos ResourceLoader associados, na forma de um objeto JSON.",
+       "apihelp-json-description": "Produzir os dados de saída no formato JSON.",
+       "apihelp-json-param-callback": "Se especificado, envolve o resultado de saída na forma de uma chamada para uma função. Por segurança, todos os dados específicos do utilizador estarão restringidos.",
+       "apihelp-json-param-utf8": "Se especificado, codifica a maioria dos caracteres não ASCII (mas não todos) em UTF-8, em vez de substitui-los por sequências de escape hexadecimais. É o comportamento padrão quando <var>formatversion</var> não tem o valor <kbd>1</kbd>.",
+       "apihelp-json-param-ascii": "Se especificado, codifica todos caracteres não ASCII usando sequências de escape hexadecimais. É o comportamento padrão quando <var>formatversion</var> tem o valor <kbd>1</kbd>.",
+       "apihelp-json-param-formatversion": "Formatação do resultado de saída:\n;1:Formato compatível com versões anteriores (booleanos ao estilo XML, <samp>*</samp> chaves para nodos de conteúdo, etc.).\n;2:Formato moderno experimental. As especificações podem mudar!\n;latest:Usar o formato mais recente (atualmente <kbd>2</kbd>), mas pode ser alterado sem aviso prévio.",
+       "apihelp-jsonfm-description": "Produzir os dados de saída em formato JSON (realce sintático em HTML).",
+       "apihelp-none-description": "Não produzir nada.",
+       "apihelp-php-description": "Produzir os dados de saída em formato PHP seriado.",
+       "apihelp-php-param-formatversion": "Formatação do resultado de saída:\n;1:Formato compatível com versões anteriores (booleanos ao estilo XML, <samp>*</samp> chaves para nodos de conteúdo, etc.).\n;2:Formato moderno experimental. As especificações podem mudar!\n;latest:Usar o formato mais recente (atualmente <kbd>2</kbd>), mas pode ser alterado sem aviso prévio.",
+       "apihelp-phpfm-description": "Produzir os dados de saída em formato PHP seriado (realce sintático em HTML).",
+       "apihelp-rawfm-description": "Produzir os dados de saída, incluindo elementos para despiste de erros, em formato JSON (realce sintático em HTML).",
+       "apihelp-xml-description": "Produzir os dados de saída em formato XML.",
+       "apihelp-xml-param-xslt": "Se especificado, adiciona a página nomeada como uma folha de estilo XSL. O valor tem de ser um título no espaço nominal {{ns:mediawiki}} e acabar em <code>.xsl</code>.",
+       "apihelp-xml-param-includexmlnamespace": "Se especificado, adiciona um espaço nominal XML.",
+       "apihelp-xmlfm-description": "Produzir os dados de saída em formato XML (realce sintático em HTML).",
+       "api-format-title": "Resultado da API do MediaWiki.",
+       "api-format-prettyprint-header": "Esta é a representação em HTML do formato $1. O HTML é bom para o despiste de erros, mas inadequado para uso na aplicação.\n\nEspecifique o parâmetro <var>format</var> para alterar o formato de saída. Para ver a representação que não é em HTML do formato $1, defina <kbd>format=$2</kbd>.\n\nConsulte a [[mw:API|documentação completa]], ou a [[Special:ApiHelp/main|ajuda da API]] para mais informação.",
+       "api-format-prettyprint-header-only-html": "Esta é uma representação em HTML para ser usada no despiste de erros, mas inadequada para uso na aplicação.\n\nConsulte a [[mw:API|documentação completa]], ou a [[Special:ApiHelp/main|ajuda da API]] para mais informação.",
+       "api-format-prettyprint-status": "Esta resposta seria devolvida com o estado de HTTP: $1 $2.",
+       "api-pageset-param-titles": "Uma lista dos títulos a serem trabalhados.",
+       "api-pageset-param-pageids": "Uma lista dos identificadores de página a serem trabalhados.",
+       "api-pageset-param-revids": "Uma lista dos identificadores de revisões a serem trabalhados.",
+       "api-pageset-param-generator": "Obter a lista de páginas nas quais trabalhar, executando o módulo de consulta especificado.\n\n<strong>Nota:</strong> Os nomes dos parâmetros de geradores têm de ser prefixados com um \"g\", veja os exemplos.",
+       "api-pageset-param-redirects-generator": "Resolver automaticamente os redirecionamentos listados nos parâmetros  <var>$1titles</var>, <var>$1pageids</var> e <var>$1revids</var>, e nas páginas devolvidas por <var>$1generator</var>.",
+       "api-pageset-param-redirects-nogenerator": "Resolver automaticamente os redirecionamentos listados nos parâmetros <var>$1titles</var>, <var>$1pageids</var> e <var>$1revids</var>.",
+       "api-pageset-param-converttitles": "Converter os títulos noutras variantes de língua, se necessário. Só funciona se a língua de conteúdo da wiki suporta a conversão entre variantes. As línguas que suportam conversão entre variantes incluem $1.",
+       "api-help-title": "Ajuda da API do MediaWiki",
+       "api-help-lead": "Esta é uma página de documentação da API do MediaWiki gerada automaticamente.\n\nDocumentação e exemplos: https://www.mediawiki.org/wiki/API",
        "api-help-main-header": "Módulo principal",
-       "api-help-flag-deprecated": "Este módulo está obsoleto.",
+       "api-help-flag-deprecated": "Este módulo é obsoleto.",
+       "api-help-flag-internal": "<strong>Este módulo é interno ou instável.</strong> O seu funcionamento pode ser alterado sem aviso prévio.",
        "api-help-flag-readrights": "Este módulo requer direitos de leitura.",
-       "api-help-flag-writerights": "Este módulo requer direitos de leitura.",
-       "api-help-flag-mustbeposted": "Este módulo aceita somente solicitações POST.",
+       "api-help-flag-writerights": "Este módulo requer direitos de escrita.",
+       "api-help-flag-mustbeposted": "Este módulo só aceita pedidos POST.",
+       "api-help-flag-generator": "Este módulo pode ser usado como gerador.",
        "api-help-source": "Fonte: $1",
+       "api-help-source-unknown": "Fonte: <span class=\"apihelp-unknown\">desconhecida</span>",
        "api-help-license": "Licença: [[$1|$2]]",
        "api-help-license-noname": "Licença: [[$1|Ver ligação]]",
        "api-help-license-unknown": "Licença: <span class=\"apihelp-unknown\">desconhecida</span>",
        "api-help-param-deprecated": "Obsoleto.",
        "api-help-param-required": "Este parâmetro é obrigatório.",
        "api-help-datatypes-header": "Tipo de dados",
-       "api-help-datatypes": "Alguns tipos de parâmetro na API necessitam de mais explicações:\n;boolean\n:Os parâmetros booleanos funcionam como as caixas de seleção HTML: se o parâmetro for especificado, independentemente do valor, é considerado verdadeiro. Para um valor falso, omitir o parâmetro completo.\n;timestamp\n:Timestamps podem ser especificados em vários formatos. Formato de data e hora ISO 8601 é recomendado. Todos os horários estão em UTC, qualquer inclusão de fuso horário é ignorado.\n:* Data e hora ISO 8601, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (pontuação e <kbd>Z</kbd> são opcionais)\n:* Data e hora ISO 8601 com segundos fracionários (ignorado), <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (traços, dois pontos e <kbd>Z</kbd> são opcionais)\n:* Formato do MediaWiki, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Formato numérico genérico, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (fuso horário opcional do <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, or <kbd>-<var>##</var></kbd> são ignorados)\n:* Formato EXIF, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*Formato RFC 2822 (o fuso horário pode ser omitido), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato RFC 850 (o fuso horário pode ser omitido), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato C ctime, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Segundos desde 1970-01-01T00:00:00Z como um inteiro de 1 a 13 dígitos (excluindo <kbd>0</kbd>)\n:* A string <kbd>now</kbd>",
+       "api-help-datatypes": "O formato de entrada para o MediaWiki deve ser UTF-8, normalizado de acordo com a norma NFC. O MediaWiki pode converter outros tipos de entrada, mas esta conversão pode originar a falha de algumas operações (tais como as [[Special:ApiHelp/edit|edições]] com verificações MD5).\n\nAlguns tipos de parâmetros nos pedidos à API necessitam de mais explicações:\n;boolean\n:Os parâmetros booleanos funcionam como as caixas de seleção HTML: se o parâmetro for especificado, independentemente do seu valor, é considerado verdadeiro. Para um valor falso, omitir o parâmetro completo.\n;timestamp\n:As datas e horas podem ser especificadas em vários formatos. É recomendado o formato ISO 8601. Todas as horas estão em UTC, qualquer inclusão do fuso horário é ignorada.\n:* Data e hora ISO 8601, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (pontuação e <kbd>Z</kbd> são opcionais)\n:* Data e hora ISO 8601 com segundos fracionários (estes são ignorados), <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (traços, dois pontos e <kbd>Z</kbd> são opcionais)\n:* Formato do MediaWiki, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Formato numérico genérico, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (fuso horário opcional <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, ou <kbd>-<var>##</var></kbd> são ignorados)\n:* Formato EXIF, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*Formato RFC 2822 (o fuso horário pode ser omitido), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato RFC 850 (o fuso horário pode ser omitido), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* Formato C ctime, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Segundos desde 1970-01-01T00:00:00Z como um inteiro de 1 a 13 algarismos (excluindo <kbd>0</kbd>)\n:* O texto <kbd>now</kbd>\n;separador alternativo de valores múltiplos\n:Os parâmetros que aceitam vários valores são normalmente fornecidos com os valores separados por uma barra vertical (''pipe''), por exemplo <kbd>parâmetro=valor1|valor2</kbd> ou <kbd>parâmetro=valor1%7Cvalor2</kbd>. Se um valor contém a barra vertical, use como separador o U+001F (Separador de Unidades) ''e'' prefixe o valor com U+001F, isto é, <kbd>parâmetro=%1Fvalor1%1Fvalor2</kbd>.",
        "api-help-param-type-limit": "Tipo: inteiro ou <kbd>max</kbd>",
-       "api-help-param-type-boolean": "Tipo: boolean ([[Special:ApiHelp/main#main/datatypes|detalhes]])",
+       "api-help-param-type-integer": "Tipo: {{PLURAL:$1|1=inteiro|2=lista de números inteiros}}",
+       "api-help-param-type-boolean": "Tipo: booleano ([[Special:ApiHelp/main#main/datatypes|detalhes]])",
+       "api-help-param-type-timestamp": "Tipo: {{PLURAL:$1|1=data e hora|2=lista de datas e horas}} ([[Special:ApiHelp/main#main/datatypes|formatos permitidos]])",
        "api-help-param-type-user": "Tipo: {{PLURAL:$1|1=nome de utilizador|2=lista de nomes de utilizadores}}",
-       "api-help-param-list": "{{PLURAL:$1|1=Um dos seguintes valores|2=Valores (separar com <kbd>{{!}}</kbd>)}}: $2",
-       "api-help-param-multi-separate": "Separe os valores com <kbd>|</kbd>.",
+       "api-help-param-list": "{{PLURAL:$1|1=Um dos seguintes valores|2=Valores (separados com <kbd>{{!}}</kbd> ou [[Special:ApiHelp/main#main/datatypes|alternativas]])}}: $2",
+       "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Tem de estar vazio|Pode estar vazio, ou ser $2}}",
+       "api-help-param-limit": "Não são permitidos mais do que: $1",
+       "api-help-param-limit2": "Não são permitidos mais do que $1 ($2 para robôs).",
+       "api-help-param-integer-min": "{{PLURAL:$1|1=O valor não pode ser inferior a|2=Os valores não podem ser inferiores a}} $2.",
+       "api-help-param-integer-max": "{{PLURAL:$1|1=O valor não pode ser superior a|2=Os valores não podem ser superiores a}} $3.",
+       "api-help-param-integer-minmax": "{{PLURAL:$1|1=O valor tem de estar compreendido|2=Os valores têm de estar compreendidos}} entre $2 e $3.",
+       "api-help-param-upload": "Tem ser enviado (''posted'') como um carregamento de ficheiro usando multipart/form-data.",
+       "api-help-param-multi-separate": "Separar os valores com <kbd>|</kbd> ou [[Special:ApiHelp/main#main/datatypes|alternativas]].",
        "api-help-param-multi-max": "O número máximo de valores é {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} para robôs).",
-       "api-help-param-default": "Padrão: $1",
+       "api-help-param-default": "Valor por omissão: $1",
        "api-help-param-default-empty": "Padrão: <span class=\"apihelp-empty\">(vazio)</span>",
+       "api-help-param-token": "Uma chave \"$1\" obtida de [[Special:ApiHelp/query+tokens|action=query&meta=tokens]]",
+       "api-help-param-token-webui": "Para efeitos de compatibilidade, a chave usada na interface ''web'' também é aceite.",
+       "api-help-param-disabled-in-miser-mode": "Desativado devido ao [[mw:Manual:$wgMiserMode|modo avarento]] (''miser mode'').",
+       "api-help-param-limited-in-miser-mode": "<strong>Nota:</strong> devido ao [[mw:Manual:$wgMiserMode|modo avarento]] (''miser mode''), usar isto pode resultar na devolução de menos de <var>$1limit</var> resultados antes de continuar; em casos extremos pode não ser devolvido qualquer resultado.",
+       "api-help-param-direction": "A direção da enumeração:\n;newer:Listar o mais antigo primeiro. Nota: $1start tem de estar antes de $1end.\n;older:Listar o mais recente primeiro (padrão). Nota: $1start tem de estar depois de $1end.",
+       "api-help-param-continue": "Quando houver mais resultados disponíveis, usar isto para continuar",
        "api-help-param-no-description": "<span class=\"apihelp-empty\">(sem descrição)</span>",
        "api-help-examples": "{{PLURAL:$1|Exemplo|Exemplos}}:",
-       "api-help-permissions": "{{PLURAL:$1|Permissão|Permissiões}}:",
+       "api-help-permissions": "{{PLURAL:$1|Permissão|Permissões}}:",
        "api-help-permissions-granted-to": "{{PLURAL:$1|Concedida a|Concedidas a}}: $2",
+       "api-help-right-apihighlimits": "Usar limites mais altos em consultas da API (consultas lentas: $1; consultas rápidas: $2). Os limites para consultas lentas também se aplicam a parâmetros com vários valores.",
        "api-help-open-in-apisandbox": "<small>[abrir na página de testes]</small>",
+       "api-help-authmanager-general-usage": "O procedimento geral para usar este módulo é:\n# Obtenha os campos disponíveis usando <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> com <kbd>amirequestsfor=$4</kbd> e uma chave <kbd>$5</kbd> obtida de <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.\n# Apresente os campos ao utilizador e obtenha os dados fornecidos por este.\n# Publique-os para este módulo, fornecendo <var>$1returnurl</var> e quaisquer campos relevantes.\n# Verifique o valor de <samp>status</samp> na resposta.\n#* Se recebeu <samp>PASS</samp> ou <samp>FAIL</samp>, terminou. A operação terá tido sucesso ou falhado.\n#* Se recebeu <samp>UI</samp>, apresente os novos campos ao utilizador e obtenha os dados fornecidos por este. Depois publique-os para este módulo com <var>$1continue</var> e os campos relevantes preenchidos, e repita o passo 4.\n#* Se recebeu <samp>REDIRECT</samp>, encaminhe o utilizador para <samp>redirecttarget</samp> e aguarde o retorno para o URL <var>$1returnurl</var>. Depois publique para este módulo com <var>$1continue</var> quaisquer campos que tenham sido passados ao URL de retorno, e repita o passo 4.\n#* Se recebeu <samp>RESTART</samp>, isto significa que a autenticação funcionou mas não temos uma conta de utilizador associada. Pode dar-lhe o tratamento de <samp>UI</samp> ou <samp>FAIL</samp>.",
+       "api-help-authmanagerhelper-requests": "Usar só estes pedidos de autenticação, com o <samp>id</samp> devolvido por <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> com <kbd>amirequestsfor=$1</kbd> ou por uma resposta anterior deste módulo.",
+       "api-help-authmanagerhelper-request": "Usar este pedido de autenticação, com o <samp>id</samp> devolvido por <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> com <kbd>amirequestsfor=$1</kbd>.",
+       "api-help-authmanagerhelper-messageformat": "Formato a usar nas mensagens de saída.",
+       "api-help-authmanagerhelper-mergerequestfields": "Combinar a informação de todos os pedidos de autenticação numa única matriz.",
+       "api-help-authmanagerhelper-preservestate": "Preservar o estado de uma tentativa de autenticação anterior falhada, se possível.",
+       "api-help-authmanagerhelper-returnurl": "O URL de retorno para processos de autenticação por terceiros tem de ser absoluto. É obrigatório fornecer este URL ou <var>$1continue</var>.\n\nTipicamente, após receber uma resposta <samp>REDIRECT</samp>, abrirá um ''browser'' ou uma ''web view'' para o URL <samp>redirecttarget</samp> especificado, para dar lugar ao processo de autenticação por terceiros. Quando esse processo terminar, a terceira entidade encaminhará o ''browser'' ou a ''web view'' para este URL. Deve extrair do URL quaisquer parâmetros de consulta ou de POST, e passá-los como um pedido <var>$1continue</var> a este módulo da API.",
+       "api-help-authmanagerhelper-continue": "Este pedido é uma continuação após uma resposta anterior com o valor <samp>UI</samp> ou <samp>REDIRECT</samp>. É obrigatório fornecer este parâmetro ou o parâmetro <var>$1returnurl</var>.",
+       "api-help-authmanagerhelper-additional-params": "Este módulo aceita parâmetros adicionais, dependendo dos pedidos de autenticação disponíveis. Use <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> com <kbd>amirequestsfor=$1</kbd> (ou uma resposta anterior deste módulo, se aplicável) para determinar os pedidos disponíveis e os campos que estes utilizam.",
        "api-credits-header": "Créditos",
-       "api-credits": "Programadores API:\n* Roan Kattouw (programador principal Set 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (criador, programador-líder Set 2006–Set 2007)\n* Brad Jorsch (programador-líder 2013–presente)\n\nPor favor, envie os seus comentários, sugestões e perguntas para mediawiki-api@lists.wikimedia.org ou reporte um erro técnico em https://phabricator.wikimedia.org/."
+       "api-credits": "Programadores da API:\n* Yuri Astrakhan (criador, programador principal, set 2006–set 2007)\n* Roan Kattouw (programador principal, set 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Brad Jorsch (programador principal, 2013–presente)\n\nPode enviar os seus comentários, sugestões e perguntas para o endereço mediawiki-api@lists.wikimedia.org, ou reportar quaisquer defeitos que encontre em https://phabricator.wikimedia.org/."
 }
index caa89b5..f7c750e 100644 (file)
@@ -12,7 +12,8 @@
                        "Amire80",
                        "Siebrand",
                        "Purodha",
-                       "Tacsipacsi"
+                       "Tacsipacsi",
+                       "D41D8CD98F"
                ]
        },
        "apihelp-main-description": "{{doc-apihelp-description|main}}",
@@ -22,6 +23,7 @@
        "apihelp-main-param-smaxage": "{{doc-apihelp-param|main|smaxage}}",
        "apihelp-main-param-maxage": "{{doc-apihelp-param|main|maxage}}",
        "apihelp-main-param-assert": "{{doc-apihelp-param|main|assert}}",
+       "apihelp-main-param-assertuser": "{{doc-apihelp-param|main|assertuser}}",
        "apihelp-main-param-requestid": "{{doc-apihelp-param|main|requestid}}",
        "apihelp-main-param-servedby": "{{doc-apihelp-param|main|servedby}}",
        "apihelp-main-param-curtimestamp": "{{doc-apihelp-param|main|curtimestamp}}",
        "api-format-title": "{{technical}}\nPage title when API output is pretty-printed in HTML.",
        "api-format-prettyprint-header": "{{technical}} Displayed as a header when API output is pretty-printed in HTML.\n\nParameters:\n* $1 - Format name\n* $2 - Non-pretty-printing module name",
        "api-format-prettyprint-header-only-html": "{{technical}} Displayed as a header when API output is pretty-printed in HTML, but there is no non-html module.\n\nParameters:\n* $1 - Format name",
+       "api-format-prettyprint-status": "{{technical}} Displayed as a header when API pretty-printed output is used for a response that uses an unusual HTTP status code.\n\nParameters:\n* $1 - HTTP status code (integer)\n* $2 - Standard English text for the status code.",
        "api-pageset-param-titles": "{{doc-apihelp-param|pageset|titles|description=the \"titles\" parameter in pageset-using modules}}",
        "api-pageset-param-pageids": "{{doc-apihelp-param|pageset|pageids|description=the \"pageids\" parameter in pageset-using modules}}",
        "api-pageset-param-revids": "{{doc-apihelp-param|pageset|revids|description=the \"revids\" parameter in pageset-using modules}}",
        "api-help-param-deprecated": "Displayed in the API help for any deprecated parameter\n{{Identical|Deprecated}}",
        "api-help-param-required": "Displayed in the API help for any required parameter",
        "api-help-datatypes-header": "Header for the data type section in the API help output",
-       "api-help-datatypes": "{{technical}} {{doc-important|Do not translate or reformat dates inside &lt;kbd%gt; tags}} Documentation of certain API data types\nSee also:\n* [[Special:PrefixIndex/MediaWiki:api-help-param-type]]",
+       "api-help-datatypes": "{{technical}} {{doc-important|Do not translate or reformat dates inside &lt;kbd&gt; tags}} Documentation of certain API data types\nSee also:\n* [[Special:PrefixIndex/MediaWiki:api-help-param-type]]",
        "api-help-param-type-limit": "{{technical}} {{doc-important|Do not translate text inside &lt;kbd&gt; tags}} Used to indicate that a parameter is a \"limit\" type. Parameters:\n* $1 - Always 1.\nSee also:\n* {{msg-mw|api-help-datatypes}}\n* [[Special:PrefixIndex/MediaWiki:api-help-param-type]]",
        "api-help-param-type-integer": "{{technical}} Used to indicate that a parameter is an integer or list of integers. Parameters:\n* $1 - 1 if the parameter takes one value, 2 if the parameter takes a list of values.\nSee also:\n* {{msg-mw|api-help-datatypes}}\n* [[Special:PrefixIndex/MediaWiki:api-help-param-type]]",
        "api-help-param-type-boolean": "{{technical}} {{doc-important|Do not translate <code>Special:ApiHelp</code> in this message.}} Used to indicate that a parameter is a boolean. Parameters:\n* $1 - Always 1.\nSee also:\n* {{msg-mw|api-help-datatypes}}\n* [[Special:PrefixIndex/MediaWiki:api-help-param-type]]",
index aa0d99a..2879020 100644 (file)
                        "Лилиә",
                        "Айсар",
                        "Гизатуллина",
-                       "MaxSem"
+                       "MaxSem",
+                       "Irus",
+                       "MaxBioHazard",
+                       "Kareyac"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Документация]]\n* [[mw:API: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]].",
        "apihelp-main-param-action": "Действие, которое следует выполнить.",
        "apihelp-main-param-format": "Формат вывода.",
+       "apihelp-main-param-maxlag": "Максимальное отставание может быть использован, когда Медиавики устанавливается на реплицируемой базы данных кластера. Чтобы спасти действий, способных причинить больше отставать репликации сайта, этот параметр может заставлять клиента ждать до задержки репликации меньше указанного значения. В случае чрезмерной задержки, код ошибки <samp>maxlag</samp> возвращается с сообщением <samp>ждет $ведущий: $отставать секунд отстала</samp>.<br />См. [[mw:Manual:Maxlag_parameter|Maxlag параметр]] для получения дополнительной информации.",
        "apihelp-main-param-smaxage": "Устанавливает значение HTTP-заголовка Cache-Control <code>s-maxage</code> в заданное число секунд. Ошибки никогда не кэшируются.",
        "apihelp-main-param-maxage": "Устанавливает значение HTTP-заголовка Cache-Control <code>s-maxage</code> в заданное число секунд. Ошибки никогда не кэшируются.",
        "apihelp-main-param-assert": "Удостовериться, что пользователь авторизован, если задано <kbd>user</kbd>, или что имеет права бота, если задано <kbd>bot</kbd>.",
+       "apihelp-main-param-assertuser": "Убедитесь, что текущий пользователь является именем пользователя.",
        "apihelp-main-param-requestid": "Любое заданное здесь значение будет включено в ответ. Может быть использовано для различения запросов.",
        "apihelp-main-param-servedby": "Включить в результаты имя хоста, обработавшего запрос.",
        "apihelp-main-param-curtimestamp": "Включить в результаты временную метку.",
        "apihelp-main-param-origin": "При обращении к API, используя кросс-доменный AJAX-запрос (CORS), задайте параметру значение исходного домена. Он должен быть включён в любой предварительный запрос и таким образом должен быть частью URI-запроса (не тела POST).\n\nДля аутентифицированных запросов он должен точно соответствовать одному из источников в заголовке <code>Origin</code>, так что он должен быть задан наподобие <kbd>https://ru.wikipedia.org</kbd> или <kbd>https://meta.wikimedia.org</kbd>. Если параметр не соответствует заголовку <code>Origin</code>, будет возвращён ответ с кодом ошибки 403. Если параметр соответствует заголовку <code>Origin</code>, и источник находится в белом списке, будут установлены заголовки <code>Access-Control-Allow-Origin</code> и <code>Access-Control-Allow-Credentials</code>.\n\nДля неаутентифицированных запросов укажите значение <kbd>*</kbd>. Это приведёт к установке заголовка <code>Access-Control-Allow-Origin</code> заголовка должен быть установлен, но <code>Access-Control-Allow-Credentials</code> примет значение <code>false</code> и все пользовательские данные будут ограничены.",
+       "apihelp-main-param-uselang": "Язык, используемый для перевода Сообщений. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> с <kbd>siprop=языки</kbd> возвращает список кодов языков, или указать <kbd>пользователей</kbd> , чтобы использовать текущий язык пользователя предпочтения, или указать <kbd>контента</kbd> для использования этой Вики содержание язык.",
        "apihelp-block-description": "Блокировка участника.",
        "apihelp-block-param-user": "Имя участника, IP-адрес или диапазон IP-адресов, которые вы хотите заблокировать.",
+       "apihelp-block-param-expiry": "Время истечения срока действия. Могут быть относительными (например, <kbd>5 месяцев</kbd> или <kbd>2 недели</kbd>) или абсолютными (например, <kbd>2014-09-18T12:34:56Z</kbd>). Если задано <kbd>бессрочно</kbd>, <kbd>бессрочно</kbd>, или <kbd>не</kbd>, блок никогда не истекает.",
        "apihelp-block-param-reason": "Причина блокировки.",
        "apihelp-block-param-anononly": "Блокировать только анонимных пользователей (т. е. запретить анонимные правки для этого IP-адреса).",
        "apihelp-block-param-nocreate": "Запретить создание учётных записей.",
        "apihelp-block-param-allowusertalk": "Позволяет участникам редактировать их собственные страницы обсуждения (зависит от <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
        "apihelp-block-param-reblock": "Если участник уже заблокирован, перезаписать существующую блокировку.",
        "apihelp-block-param-watchuser": "Следить за страницей пользователя или IP-участника и страницей обсуждения.",
+       "apihelp-block-example-ip-simple": "Заблокировать IP-адрес <kbd>192.0.2.5</kbd> в течение трех дней с причиной <kbd>первого удара</kbd>.",
+       "apihelp-block-example-user-complex": "Заблокировать пользователя <kbd>Вандал</kbd> на бессрочно срок по причине <kbd>вандализма</kbd>, и предотвратить появление новых счет создания и отправки электронной почты.",
+       "apihelp-changeauthenticationdata-description": "Изменить данные проверки подлинности для текущего пользователя.",
+       "apihelp-changeauthenticationdata-example-password": "Попытка изменить текущий пароль пользователя в <kbd>ExamplePassword</kbd>.",
+       "apihelp-checktoken-description": "Проверить валидность токена от <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=token]]</kbd>.",
        "apihelp-checktoken-param-type": "Тип маркера проходит тестирование.",
        "apihelp-checktoken-param-token": "токен для проверки",
        "apihelp-checktoken-param-maxtokenage": "Максимально допустимый возраст токена (в секундах).",
        "apihelp-checktoken-example-simple": "Проверить годность <kbd>csrf</kbd>-токена.",
        "apihelp-clearhasmsg-description": "Очищает флаг <code>hasmsg</code> для текущего участника.",
        "apihelp-clearhasmsg-example-1": "Очистить флаг <code>hasmsg</code> для текущего участника.",
+       "apihelp-clientlogin-description": "Войдите в вики с помощью интерактивного потока.",
+       "apihelp-clientlogin-example-login": "Начать процесс регистрации в вики в качестве пользователя <kbd>пример</kbd> с паролем <kbd>ExamplePassword</kbd>.",
+       "apihelp-clientlogin-example-login2": "Продолжить ведение журнала в после <samp>интерфейс</samp> ответ для двухфакторной аутентификации, поставляя <var>OATHToken</var> из <kbd>987654</kbd>.",
+       "apihelp-compare-description": "Сделать разницу между 2 страницами.\n\nНомер редакции, Заголовок страницы, или страницы с ID для обоих \"из\" и \"в\" должны быть переданы.",
        "apihelp-compare-param-fromtitle": "Первый заголовок для сравнения.",
        "apihelp-compare-param-fromid": "Первый идентификатор страницы для сравнения.",
        "apihelp-compare-param-fromrev": "Первая редакция для сравнения.",
@@ -55,6 +71,8 @@
        "apihelp-compare-param-torev": "Вторая версия для сравнения",
        "apihelp-compare-example-1": "Создание различий между версиями 1 и 2.",
        "apihelp-createaccount-description": "Создайте новую учетную запись Пользователя.",
+       "apihelp-createaccount-param-preservestate": "Если <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> возвращается True для <samp>hasprimarypreservedstate</samp>, просит отмечен как <samp>основной-обязательно</samp> должен быть опущен. Если он возвращает непустое значение для <samp>preservedusername</samp>, что имя пользователя должно быть использовано для <var>пользователя</var> параметр.",
+       "apihelp-createaccount-example-create": "Запустить процесс создания пользователя <kbd>пример</kbd> с паролем <kbd>ExamplePassword</kbd>.",
        "apihelp-createaccount-param-name": "Имя участника.",
        "apihelp-createaccount-param-password": "Пароль (ignored if <var>$1mailpassword</var> is set).",
        "apihelp-createaccount-param-domain": "Домен для внешней аутентификации (дополнительно).",
        "apihelp-createaccount-param-language": "Установить код языка по умолчанию для пользователя (необязательный, по умолчанию используется язык содержимого).",
        "apihelp-createaccount-example-pass": "Создать пользователя <kbd>testuser</kbd> с паролем <kbd>test123</kbd>.",
        "apihelp-createaccount-example-mail": "Создать пользователя <kbd>testmailuser</kbd> и адрес электронной почты, сгенерировать случайный пароль.",
+       "apihelp-cspreport-description": "Используемые браузеры сообщать о нарушениях политики безопасности. Этот модуль никогда не должно использоваться, за исключением, когда автоматически используется совместимый КРИПТОПРОВАЙДЕР веб-браузер.",
+       "apihelp-cspreport-param-reportonly": "Отметить как доклад по мониторингу политики, а не принудительная политика",
+       "apihelp-cspreport-param-source": "Что генерируется Заголовок СКП, которые вызвали этот доклад",
        "apihelp-delete-description": "Удалить страницу.",
        "apihelp-delete-param-title": "Заголовок страницы удалить. Совместное использование с <var>$1страницы</var> невозможно.",
+       "apihelp-delete-param-pageid": "Идентификатор страницы для удаления. Нельзя использовать вместе с <var>$1титул</var>.",
+       "apihelp-delete-param-reason": "Причиной для удаления. Если не задано, автоматически сгенерированный причина будет использоваться.",
+       "apihelp-delete-param-tags": "Изменить теги для подачи заявки на запись в журнале удаления.",
        "apihelp-delete-param-watch": "Добавить страницу к текущему списку наблюдения пользователя.",
+       "apihelp-delete-param-watchlist": "Безоговорочно добавить или удалить страницы из списка наблюдения текущего пользователя, используйте предпочтения или не менять часы.",
        "apihelp-delete-param-unwatch": "Удалить страницу из списка наблюдения текущего пользователя.",
        "apihelp-delete-example-simple": "удалить <kbd>Main Page</kbd>.",
        "apihelp-delete-example-reason": "Удалить <kbd>Main Page</kbd> причина <kbd>Preparing for move</kbd>.",
        "apihelp-edit-description": "Создать и отредактировать страницы.",
        "apihelp-edit-param-sectiontitle": "Заголовок для нового раздела.",
        "apihelp-edit-param-text": "Содержание страницы.",
+       "apihelp-edit-param-tags": "Изменить теги для подачи заявки на пересмотр.",
        "apihelp-edit-param-minor": "Незначительное изменение (малая правка).",
        "apihelp-edit-param-notminor": "Значительное изменение (обычная, не «малая», правка).",
        "apihelp-edit-param-bot": "Пометить правку как сделанную ботом.",
+       "apihelp-edit-param-recreate": "Возвращает сообщение об ошибке не, если страница тем временем был удален.",
        "apihelp-edit-param-createonly": "Не редактировать страницу, если она уже существует.",
        "apihelp-edit-param-nocreate": "Выбрасывать ошибку, если страницы не существует.",
        "apihelp-edit-param-watch": "Добавить страницу к текущему списку наблюдения пользователя.",
        "apihelp-edit-param-unwatch": "Удалить страницу из списка наблюдения текущего пользователя.",
+       "apihelp-edit-param-watchlist": "Безоговорочно добавить или удалить страницы из списка наблюдения текущего пользователя, используйте предпочтения или не менять часы.",
+       "apihelp-edit-param-md5": "MD5-хеша $1текстовый параметр, или $1prependtext и $1appendtext параметры объединяются. Если установлен, то изменение не будет сделано, если хэш является правильным.",
+       "apihelp-edit-param-prependtext": "Добавьте этот текст в начале страницы. Переопределяет $1текст.",
+       "apihelp-edit-param-appendtext": "Добавьте этот текст внизу страницы. Переопределяет $1текст.\n\nИспользуйте вместо этого параметра $1раздел = new, чтобы добавить новый раздел.",
+       "apihelp-edit-param-undo": "Отменить это изменение. Переопределяет $1текст, $1prependtext и $1appendtext.",
+       "apihelp-edit-param-undoafter": "Отменить все изменения от $1, чтобы отменить это. Если не набор, просто отменить одну ревизию.",
        "apihelp-edit-param-redirect": "Автоматически разрешать редиректы.",
        "apihelp-edit-param-contentformat": "Формат сериализации содержимого, используемый для ввода текста.",
+       "apihelp-edit-param-contentmodel": "Контентная модель нового содержимого.",
+       "apihelp-edit-param-token": "Маркер всегда должен быть послан в качестве последнего параметра, или, по крайней мере, после $1текстовый параметр.",
        "apihelp-edit-example-edit": "Редактировать страницу",
        "apihelp-edit-example-prepend": "Добавить магическое слово <kbd>_&#95;NOTOC_&#95;</kbd> в начало страницы.",
        "apihelp-edit-example-undo": "Отменить изменения с 13579 по 13585 с добавлением автоматического описания правки.",
        "apihelp-emailuser-param-text": "Содержание письма",
        "apihelp-emailuser-param-ccme": "Отправить копию этого сообщения мне.",
        "apihelp-emailuser-example-email": "Отправить письмо пользователю <kbd>WikiSysop</kbd> с текстом <kbd>Content</kbd>.",
-       "apihelp-expandtemplates-description": "Разворачивает все шаблоны в wikitext.",
+       "apihelp-expandtemplates-description": "Разворачивает все шаблоны в викитекст.",
        "apihelp-expandtemplates-param-title": "Заголовок страницы.",
        "apihelp-expandtemplates-param-text": "Викитекст для конвертирования",
+       "apihelp-expandtemplates-param-revid": "Номер версии, для <nowiki>{{REVISIONID}}</nowiki> и аналогичных переменных.",
+       "apihelp-expandtemplates-param-prop": "Какие фрагменты информации получить.\n\nОбратите внимание, что если ни одно из значений не выбрано, результат будет содержать викитекст, но вывод будет в устаревшем формате.",
        "apihelp-expandtemplates-paramvalue-prop-wikitext": "Расширенный викитекст",
+       "apihelp-expandtemplates-paramvalue-prop-categories": "Любой категории присутствуют во входных данных, которые не представлены в тексте вывод.",
+       "apihelp-expandtemplates-paramvalue-prop-properties": "Страница свойств определяются расширенные волшебные слова в тексте.",
+       "apihelp-expandtemplates-paramvalue-prop-volatile": "Есть ли выход летучих и не должны использоваться повторно в другом месте на странице.",
+       "apihelp-expandtemplates-paramvalue-prop-ttl": "Максимальное время, по прошествии которого кэш результата должен быть признан недействительным.",
+       "apihelp-expandtemplates-paramvalue-prop-jsconfigvars": "Дает переменные конфигурации JavaScript конкретной странице.",
+       "apihelp-expandtemplates-paramvalue-prop-encodedjsconfigvars": "Дает переменные конфигурации JavaScript, определенных на страницу в виде строки JSON.",
        "apihelp-expandtemplates-paramvalue-prop-parsetree": "Дерево разбора XML входных данных.",
+       "apihelp-expandtemplates-param-includecomments": "Нужно ли включать комментарии HTML на выходе.",
+       "apihelp-expandtemplates-param-generatexml": "Создать XML-дерево разбора (заменить $1prop=parsetree).",
+       "apihelp-feedcontributions-description": "Возвращает список правок участника.",
        "apihelp-feedcontributions-param-feedformat": "Биреү форматы",
+       "apihelp-feedcontributions-param-user": "Что пользователи, чтобы получить взносы.",
+       "apihelp-feedcontributions-param-namespace": "По какому пространству имён фильтровать вклад.",
        "apihelp-feedcontributions-param-year": "От года (и ранее).",
        "apihelp-feedcontributions-param-month": "От месяца (и ранее).",
+       "apihelp-feedcontributions-param-tagfilter": "Взносы фильтра, которые имеют эти теги.",
        "apihelp-feedcontributions-param-deletedonly": "Показать только удалённые правки.",
        "apihelp-feedcontributions-param-toponly": "Показать только правки, являющиеся последними версиями.",
        "apihelp-feedcontributions-param-newonly": "Показывать только правки, являющиеся созданием страниц.",
        "apihelp-filerevert-description": "Файлды иҫке версияға ҡайтарырға.",
        "apihelp-filerevert-param-filename": "Целевое имя файла без префикса File:.",
        "apihelp-filerevert-param-comment": "Загрузить комментарий.",
+       "apihelp-filerevert-example-revert": "Откат <kbd>Wiki.png</kbd> к версии от <kbd>2011-03-05T15:27:40Z</kbd>.",
        "apihelp-help-param-helpformat": "Белешмә яҙыу форматы.",
        "apihelp-help-example-main": "Помощь по главному модулю.",
        "apihelp-help-example-recursive": "Вся справка в одном разделе.",
        "apihelp-options-example-reset": "Сбросить все настройки.",
        "apihelp-paraminfo-description": "Получить информацию о модулях API.",
        "apihelp-paraminfo-param-helpformat": "Формат строк справки.",
+       "apihelp-parse-param-prop": "Какие части информации получить:",
+       "apihelp-parse-paramvalue-prop-text": "Дает разобранного текста в тексте.",
+       "apihelp-parse-paramvalue-prop-langlinks": "Возвращает язык ссылки в анализируемой wikitext.",
+       "apihelp-parse-paramvalue-prop-categorieshtml": "Возвращает HTML-версию категорий.",
        "apihelp-parse-param-disablepp": "Урынына <var>$1disablelimitreport</var> ҡулланырға.",
        "apihelp-parse-param-preview": "Алдан ҡарау режимында синтаксик анализ",
        "apihelp-parse-param-disabletoc": "Не включать в вывод таблицу содержания.",
        "apihelp-protect-example-unprotect2": "Бер ниндәй сикләүҙәр ҡуймай биттән һаҡлауҙы алырға.",
        "apihelp-purge-param-forcelinkupdate": "Обновление связей таблиц.",
        "apihelp-purge-param-forcerecursivelinkupdate": "Һылтанманы һәм таблицаны яңыртығыҙ һәм был битте шаблон итеп ҡулланған башҡа биттәр өсөн һылтанмаларҙы ла яңыртығыҙ.",
+       "apihelp-purge-example-generator": "Продувка первые 10 страниц в основном пространстве имен.",
        "apihelp-query-param-list": "Какие списки использовать",
        "apihelp-query-param-meta": "Какие метаданные использовать",
        "apihelp-query+allcategories-description": "Перечислить все категории.",
        "apihelp-query+allmessages-description": "Был сайттан хәбәр ҡайтарыу.",
        "apihelp-query+allmessages-param-prop": "Ниндәй үҙенсәлектәрҙе ҡайтарырға.",
        "apihelp-query+allmessages-param-args": "Аргументтар Хәбәрҙәрҙә биреләсәк.",
+       "apihelp-query+allmessages-param-lang": "Вернуть сообщения на этом языке.",
        "apihelp-query+blocks-example-simple": "Список блоков.",
        "apihelp-query+categories-param-limit": "Сколько категорий на возврат.",
        "apihelp-query+categorymembers-param-sort": "Свойство для сортировки.",
index 35389b0..e409591 100644 (file)
@@ -89,7 +89,7 @@
        "apihelp-edit-param-tags": "Ändra taggar till att gälla för revideringen.",
        "apihelp-edit-param-minor": "Mindre redigering.",
        "apihelp-edit-param-notminor": "Icke-mindre redigering.",
-       "apihelp-edit-param-bot": "Markera denna redigering som robotredigering.",
+       "apihelp-edit-param-bot": "Markera denna redigering som en robotredigering.",
        "apihelp-edit-param-basetimestamp": "Tidsstämpel för grundversionen, används för att upptäcka redigeringskonflikter. Kan erhållas genom [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
        "apihelp-edit-param-starttimestamp": "Tidsstämpel för när redigeringsprocessen började, används för att upptäcka redigeringskonflikter. Ett lämpligt värde kan erhållas via  <var>[[Special:ApiHelp/main|curtimestamp]]</var> när redigeringsprocessen startas (t.ex. när sidans innehåll laddas för redigering).",
        "apihelp-edit-param-recreate": "Ignorera felmeddelande om sidan har blivit raderad under tiden.",
        "apihelp-emailuser-param-text": "E-postmeddelandets innehåll.",
        "apihelp-emailuser-param-ccme": "Skicka en kopia av detta e-postmeddelande till mig.",
        "apihelp-emailuser-example-email": "Skicka ett e-postmeddelande till användaren <kbd>WikiSysop</kbd> med texten <kbd>Content</kbd>.",
-       "apihelp-expandtemplates-description": "Expanderar alla mallar i wikitext.",
+       "apihelp-expandtemplates-description": "Expanderar alla mallar inom wikitext.",
        "apihelp-expandtemplates-param-title": "Sidans rubrik.",
        "apihelp-expandtemplates-param-text": "Wikitext att konvertera.",
        "apihelp-expandtemplates-param-revid": "Revision ID, för <nowiki>{{REVISIONID}}</nowiki> och liknande variabler.",
index 1a079df..a02d1f9 100644 (file)
@@ -21,6 +21,7 @@
        "apihelp-main-param-smaxage": "Встановити <code>s-maxage</code> HTTP кеш-контроль заголовок на стільки секунд. Помилки ніколи не кешуються.",
        "apihelp-main-param-maxage": "Встановити <code>max-age</code> HTTP кеш-контроль заголовок на стільки секунд. Помилки ніколи не кешуються.",
        "apihelp-main-param-assert": "Перевірити, що користувач увійшов у систему, якщо задано <kbd>user</kbd>, або має права бота, якщо задано <kbd>bot</kbd>.",
+       "apihelp-main-param-assertuser": "Перевірити, чи поточний користувач є найменованим користувачем.",
        "apihelp-main-param-requestid": "Будь-яке значення, вказане тут, буде включене у відповідь. Може використовуватися, щоб відрізняти запити.",
        "apihelp-main-param-servedby": "Включити в результати ім'я хоста, який обробив запит.",
        "apihelp-main-param-curtimestamp": "Включити в результат поточну мітку часу.",
        "apihelp-edit-param-tags": "Змінити теги для версії.",
        "apihelp-edit-param-minor": "Незначне редагування.",
        "apihelp-edit-param-notminor": "Не «незначне» редагування.",
-       "apihelp-edit-param-bot": "Ð\9fомÑ\96Ñ\82ити редагування як зроблене ботом.",
+       "apihelp-edit-param-bot": "Ð\9fознаÑ\87ити редагування як зроблене ботом.",
        "apihelp-edit-param-basetimestamp": "Мітка часу для основної версії, використовується для виявлення конфлікту редагувань. Може бути отримана через [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
        "apihelp-edit-param-starttimestamp": "Мітка часу, з якого почався процес редагування, використовується для виявлення конфліктів редагувань. Відповідне значення можна отримати з допомогою <var>[[Special:ApiHelp/main|curtimestamp]]</var> на початку процесу редагування (напр., коли завантажується вміст сторінки для редагування).",
        "apihelp-edit-param-recreate": "Відкинути будь-які помилки щодо цієї сторінки, вилучені нещодавно.",
        "apihelp-emailuser-param-text": "Тіло листа.",
        "apihelp-emailuser-param-ccme": "Надіслати копію цього повідомлення мені.",
        "apihelp-emailuser-example-email": "Відправити листа користувачу <kbd>WikiSysop</kbd> з текстом <kbd>Content</kbd>.",
-       "apihelp-expandtemplates-description": "Розгортає усі шаблони у вікітекст.",
+       "apihelp-expandtemplates-description": "Розгортає усі шаблони в межах вікірозмітки.",
        "apihelp-expandtemplates-param-title": "Заголовок сторінки.",
        "apihelp-expandtemplates-param-text": "Вікітекст для перетворення.",
        "apihelp-expandtemplates-param-revid": "ID версії, для <nowiki>{{REVISIONID}}</nowiki> і подібних змінних.",
        "apihelp-options-description": "Змінити налаштування поточного користувача.\n\nМожна встановити лише опції, які зареєстровані у ядрі або в одному з інстальованих розширень, або опції з префіксом ключів <code>userjs-</code> (призначені для використання користувацькими скриптами).",
        "apihelp-options-param-reset": "Встановлює налаштування сайту за замовчуванням.",
        "apihelp-options-param-resetkinds": "Список типів опцій для перевстановлення, коли вказана опція <var>$1reset</var>.",
-       "apihelp-options-param-change": "СпиÑ\81ок Ð·Ð¼Ñ\96н, Ð²Ñ\96дÑ\84оÑ\80маÑ\82ованиÑ\85 Ñ\8fк Ð½Ð°Ð·Ð²Ð°=знаÑ\87еннÑ\8f (напÑ\80., skin=vector). Ð\97наÑ\87еннÑ\8f Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð¼Ñ\96Ñ\81Ñ\82иÑ\82и Ð²ÐµÑ\80Ñ\82икалÑ\8cниÑ\85 Ñ\80иÑ\81ок. Ð¯ÐºÑ\89о Ð·Ð½Ð°Ñ\87еннÑ\8f Ð½Ðµ Ð²ÐºÐ°Ð·Ð°Ð½Ðµ (навÑ\96Ñ\82Ñ\8c Ð½ÐµÐ¼Ð°Ñ\94 Ð·Ð½Ð°ÐºÐ° Ñ\80Ñ\96вноÑ\81Ñ\82Ñ\96) , Ð½Ð°Ð¿Ñ\80., optionname|otheroption|â\80¦, Ð¾Ð¿Ñ\86Ñ\96Ñ\8e Ð±Ñ\83де Ð¿ÐµÑ\80евÑ\81Ñ\82ановлено Ð´Ð¾ Ñ\97Ñ\97 Ð·Ð½Ð°Ñ\87еннÑ\8f Ð·Ð° Ð·Ð°Ð¼Ð¾Ð²Ñ\87Ñ\83ваннÑ\8fм.",
+       "apihelp-options-param-change": "СпиÑ\81ок Ð·Ð¼Ñ\96н, Ð²Ñ\96дÑ\84оÑ\80маÑ\82ованиÑ\85 Ñ\8fк Ð½Ð°Ð·Ð²Ð°=знаÑ\87еннÑ\8f (напÑ\80., skin=vector). Ð¯ÐºÑ\89о Ð·Ð½Ð°Ñ\87еннÑ\8f Ð½Ðµ Ð²ÐºÐ°Ð·Ð°Ð½Ðµ (навÑ\96Ñ\82Ñ\8c Ð½ÐµÐ¼Ð°Ñ\94 Ð·Ð½Ð°ÐºÐ° Ñ\80Ñ\96вноÑ\81Ñ\82Ñ\96) , Ð½Ð°Ð¿Ñ\80., optionname|otheroption|â\80¦, Ð¾Ð¿Ñ\86Ñ\96Ñ\8e Ð±Ñ\83де Ð¿ÐµÑ\80евÑ\81Ñ\82ановлено Ð´Ð¾ Ñ\97Ñ\97 Ð·Ð½Ð°Ñ\87еннÑ\8f Ð·Ð° Ð·Ð°Ð¼Ð¾Ð²Ñ\87Ñ\83ваннÑ\8fм. Ð¯ÐºÑ\89о Ð±Ñ\83дÑ\8c\8fке Ð·Ñ\96 Ð·Ð½Ð°Ñ\87енÑ\8c Ð¼Ñ\96Ñ\81Ñ\82иÑ\82Ñ\8c Ñ\81имвол Ð²ÐµÑ\80Ñ\82икалÑ\8cноÑ\97 Ñ\80иÑ\81ки (<kbd>|</kbd>), Ð²Ð¸ÐºÐ¾Ñ\80иÑ\81Ñ\82айÑ\82е [[Special:ApiHelp/main#main/datatypes|алÑ\8cÑ\82еÑ\80наÑ\82ивний Ñ\80оздÑ\96лÑ\8eваÑ\87 Ð·Ð½Ð°Ñ\87енÑ\8c]] Ð´Ð»Ñ\8f ÐºÐ¾Ñ\80екÑ\82ного Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ\8f Ð¾Ð¿ÐµÑ\80аÑ\86Ñ\96Ñ\97.",
        "apihelp-options-param-optionname": "Назва опції, якій має бути присвоєне значення <var>$1optionvalue</var>.",
-       "apihelp-options-param-optionvalue": "Значення опції, вказане в <var>$1optionname</var>, може містити вертикальні риски.",
+       "apihelp-options-param-optionvalue": "Значення опції, вказане в <var>$1optionname</var>.",
        "apihelp-options-example-reset": "Скинути всі налаштування.",
        "apihelp-options-example-change": "Змінити налаштування <kbd>skin</kbd> та <kbd>hideminor</kbd>.",
        "apihelp-options-example-complex": "Скинути всі налаштування, потім встановити <kbd>skin</kbd> та <kbd>nickname</kbd>.",
        "api-format-title": "Результат запиту до API MediaWiki",
        "api-format-prettyprint-header": "Це HTML-представлення формату $1. HTML є гарним для налагодження, однак не придатний для прикладного використання.\n\nУкажіть значення для параметра <var>format</var>, для того щоб змінити формат. Для перегляду не-HTML-представлення формату, $1, вкажіть <kbd>format=$2</kbd>.\n\nДив. [[mw:API|повну документацію]], або [[Special:ApiHelp/main|довідку з API]] для детальнішої інформації.",
        "api-format-prettyprint-header-only-html": "Це HTML-представлення призначене для налагодження, однак не придатне для прикладного використання.\n\nДив. [[mw:API|повну документацію]], або [[Special:ApiHelp/main|довідку з API]] для детальнішої інформації.",
+       "api-format-prettyprint-status": "Відповідь повернеться із HTTP-статусом $1 $2.",
        "api-pageset-param-titles": "Список назв над якими працювати.",
        "api-pageset-param-pageids": "Список ідентифікаторів сторінок над якими працювати.",
        "api-pageset-param-revids": "Список ідентифікаторів версій над якими працювати.",
index 573748d..27fac5d 100644 (file)
@@ -21,7 +21,8 @@
                        "PhiLiP",
                        "Arthur2e5",
                        "損齋",
-                       "Myy730"
+                       "Myy730",
+                       "D41D8CD98F"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|文档]]\n* [[mw:API: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 header将会返回一个包含\"MediaWiki-API-Error\"的值,随后header的值与error code将会送回并设置为相同的值。详细信息请参阅[[mw:API:Errors_and_warnings|API: 错误与警告]]。\n\n<strong>测试中:</strong>测试API请求的易用性,请参见[[Special:ApiSandbox]]。",
@@ -31,7 +32,8 @@
        "apihelp-main-param-smaxage": "设置<code>s-maxage</code> HTTP缓存控制头至这些秒。错误不会缓存。",
        "apihelp-main-param-maxage": "设置<code>max-age</code> HTTP缓存控制头至这些秒。错误不会缓存。",
        "apihelp-main-param-assert": "如果设置为<kbd>user</kbd>就验证用户是否登录,或如果设置为<kbd>bot</kbd>就验证是否有机器人用户权限。",
-       "apihelp-main-param-requestid": "任何在此提供的值将包含在响应中。可能可以用以区别请求。",
+       "apihelp-main-param-assertuser": "验证当前用户是命名用户。",
+       "apihelp-main-param-requestid": "任何在此提供的值将包含在响应中。可以用以区别请求。",
        "apihelp-main-param-servedby": "包含保存结果请求的主机名。",
        "apihelp-main-param-curtimestamp": "在结果中包括当前时间戳。",
        "apihelp-main-param-origin": "当通过跨域名AJAX请求(CORS)访问API时,设置此作为起始域名。这必须包括在任何pre-flight请求中,并因此必须是请求的URI的一部分(而不是POST正文)。\n\n对于已验证的请求,这必须正确匹配<code>Origin</code>标头中的原点之一,因此它已经设置为像<kbd>https://zh.wikipedia.org</kbd>或<kbd>https://meta.wikimedia.org</kbd>的东西。如果此参数不匹配<code>Origin</code>页顶,就返回403错误响应。如果此参数匹配<code>Origin</code>页顶并且起点被白名单,将设置<code>Access-Control-Allow-Origin</code>和<code>Access-Control-Allow-Credentials</code>开头。\n\n对于未验证的请求,会指定值<kbd>*</kbd>。这将导致<code>Access-Control-Allow-Origin</code>标头被设置,但<code>Access-Control-Allow-Credentials</code>将为<code>false</code>,且所有用户特定数据将受限制。",
@@ -62,7 +64,7 @@
        "apihelp-clientlogin-description": "使用交互式流登录wiki。",
        "apihelp-clientlogin-example-login": "开始作为用户<kbd>Example</kbd>和密码<kbd>ExamplePassword</kbd>登录至wiki的过程。",
        "apihelp-clientlogin-example-login2": "在<samp>UI</samp>响应双因素验证后继续登录,补充<var>OATHToken</var> <kbd>987654</kbd>。",
-       "apihelp-compare-description": "获取2个页面之间的差别。\n\n用于“from”和“to”的修订版本号、页面标题或页面 ID 必须获得通过。",
+       "apihelp-compare-description": "获取2个页面之间的差别。\n\n必须传递用于“from”和“to”的修订版本号、页面标题或页面 ID 。",
        "apihelp-compare-param-fromtitle": "要比较的第一个标题。",
        "apihelp-compare-param-fromid": "要比较的第一个页面 ID。",
        "apihelp-compare-param-fromrev": "要比较的第一个修订版本。",
        "apihelp-edit-param-sectiontitle": "新段落的标题。",
        "apihelp-edit-param-text": "页面内容。",
        "apihelp-edit-param-summary": "编辑摘要。当$1section=new且未设置$1sectiontitle时,还包括小节标题。",
-       "apihelp-edit-param-tags": "更改标签以应用修订。",
+       "apihelp-edit-param-tags": "应用到此修订的更改标签。",
        "apihelp-edit-param-minor": "小编辑。",
        "apihelp-edit-param-notminor": "不是小编辑。",
        "apihelp-edit-param-bot": "标记此编辑为机器人编辑。",
-       "apihelp-edit-param-basetimestamp": "基础修订的时间戳,用于检测编辑冲突。也许可以通过[[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]]得到。",
+       "apihelp-edit-param-basetimestamp": "基础修订的时间戳,用于检测编辑冲突。可以通过[[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]]得到。",
        "apihelp-edit-param-starttimestamp": "编辑过程开始的时间戳,用于检测编辑冲突。当开始编辑过程时(例如当加载要编辑的页面时)使用<var>[[Special:ApiHelp/main|curtimestamp]]</var>可能取得一个适当的值。",
        "apihelp-edit-param-recreate": "覆盖有关该页面在此期间已被删除的任何错误。",
        "apihelp-edit-param-createonly": "不要编辑页面,如果已经存在。",
        "apihelp-edit-param-token": "令牌应总是发送为最后参数,或至少在$1text参数之后。",
        "apihelp-edit-example-edit": "编辑一个页面。",
        "apihelp-edit-example-prepend": "页面中预置<kbd>_&#95;NOTOC_&#95;</kbd>。",
-       "apihelp-edit-example-undo": "通过13585撤销修订版本13579并自动填写编辑摘要。",
+       "apihelp-edit-example-undo": "撤销修订版本13579至13585并自动填写编辑摘要。",
        "apihelp-emailuser-description": "电子邮件联系一位用户。",
        "apihelp-emailuser-param-target": "电子邮件的目标用户。",
        "apihelp-emailuser-param-subject": "主题页眉。",
        "apihelp-expandtemplates-param-text": "要转换的wiki文本。",
        "apihelp-expandtemplates-param-revid": "修订版本ID,用于<nowiki>{{REVISIONID}}</nowiki>和类似变体。",
        "apihelp-expandtemplates-param-prop": "要获取的那条信息。\n\n注意如果没有选定值,结果将包含wiki文本,但将以弃用的格式显示。",
-       "apihelp-expandtemplates-paramvalue-prop-wikitext": "扩充的wiki文本。",
+       "apihelp-expandtemplates-paramvalue-prop-wikitext": "展开后的wiki文本。",
        "apihelp-expandtemplates-paramvalue-prop-categories": "任何在输出中提供的,未在wiki文本输出中表现的分类。",
        "apihelp-expandtemplates-paramvalue-prop-properties": "由wiki文本中扩充的魔术字定义的页面属性。",
-       "apihelp-expandtemplates-paramvalue-prop-volatile": "无论输出是否常常变动,均不应被在页面中其他任何位置重用。",
+       "apihelp-expandtemplates-paramvalue-prop-volatile": "输出是否常常变动,是否不应被在页面中其他任何位置重用。",
        "apihelp-expandtemplates-paramvalue-prop-ttl": "结果缓存应无效化后的最长时间。",
-       "apihelp-expandtemplates-paramvalue-prop-modules": "任何解析器函数请求添加至输出的ResourceLoader模块。无论<kbd>jsconfigvars</kbd>还是<kbd>encodedjsconfigvars</kbd>都必须与<kbd>modules</kbd>共同被请求。",
+       "apihelp-expandtemplates-paramvalue-prop-modules": "任何解析器函数请求添加至输出的ResourceLoader模块。<kbd>jsconfigvars</kbd>和<kbd>encodedjsconfigvars</kbd>之一必须与<kbd>modules</kbd>共同被请求。",
        "apihelp-expandtemplates-paramvalue-prop-jsconfigvars": "针对页面提供JavaScript配置变量。",
        "apihelp-expandtemplates-paramvalue-prop-encodedjsconfigvars": "针对页面提供JavaScript配置变量为一个JSON字符串。",
        "apihelp-expandtemplates-paramvalue-prop-parsetree": "输入的XML分析树。",
-       "apihelp-expandtemplates-param-includecomments": "è¾\93å\87ºæ\97¶æ\98¯å\90¦å\8c\85å\90«HTMLæ\91\98è¦\81。",
+       "apihelp-expandtemplates-param-includecomments": "è¾\93å\87ºæ\97¶æ\98¯å\90¦å\8c\85å\90«HTML注é\87\8a。",
        "apihelp-expandtemplates-param-generatexml": "生成XML解析树(取代自$1prop=parsetree)。",
        "apihelp-expandtemplates-example-simple": "展开wiki文本<kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>。",
        "apihelp-feedcontributions-description": "返回用户贡献纲要。",
        "apihelp-options-description": "更改当前用户的偏好设置。\n\n只有注册在核心或者已安装扩展中的选项,或者具有<code>userjs-</code>键值前缀(旨在被用户脚本使用)的选项可被设置。",
        "apihelp-options-param-reset": "将参数设置重置为网站默认值。",
        "apihelp-options-param-resetkinds": "当<var>$1reset</var>选项被设置时,要重置的选项类型列表。",
-       "apihelp-options-param-change": "æ\9b´æ\94¹å\88\97表ï¼\8c以name=valueæ ¼å¼\8få\8c\96ï¼\88ä¾\8bå¦\82skin=vectorï¼\89ã\80\82å\80¼ä¸\8dè\83½å\8c\85å\90«ç®¡é\81\93å­\97符ã\80\82å¦\82æ\9e\9c没æ\8f\90ä¾\9bå\80¼ï¼\88ç\94\9aè\87³æ²¡æ\9c\89ç­\89å\8f·ï¼\89ï¼\8cä¾\8bå¦\82optionname|otheroption|...ï¼\8cé\80\89项å°\86é\87\8d置为é»\98认å\80¼。",
+       "apihelp-options-param-change": "æ\9b´æ\94¹å\88\97表ï¼\8c以name=valueæ ¼å¼\8få\8c\96ï¼\88ä¾\8bå¦\82skin=vectorï¼\89ã\80\82å¦\82æ\9e\9c没æ\8f\90ä¾\9bå\80¼ï¼\88ç\94\9aè\87³æ²¡æ\9c\89ç­\89å\8f·ï¼\89ï¼\8cä¾\8bå¦\82optionname|otheroption|...ï¼\8cé\80\89项å°\86é\87\8d置为é»\98认å\80¼ã\80\82å¦\82æ\9e\9cä»»ä½\95ä¼ é\80\92ç\9a\84å\80¼å\8c\85å\90«ç®¡é\81\93å­\97符ï¼\88<kbd>|</kbd>ï¼\89ï¼\8c请æ\94¹ç\94¨[[Special:ApiHelp/main#main/datatypes|æ\9b¿ä»£å¤\9aå\80¼å\88\86é\9a\94符]]以正确æ\93\8dä½\9c。",
        "apihelp-options-param-optionname": "应设置为由<var>$1optionvalue</var>提供值的选项名称。",
-       "apihelp-options-param-optionvalue": "用于由<var>$1optionname</var>指定的选项的值,可以包含管道字符。",
+       "apihelp-options-param-optionvalue": "用于由<var>$1optionname</var>指定的选项的值。",
        "apihelp-options-example-reset": "重置所有用户设置。",
        "apihelp-options-example-change": "更改<kbd>skin</kbd>和<kbd>hideminor</kbd>设置。",
        "apihelp-options-example-complex": "重置所有设置,然后设置<kbd>skin</kbd>和<kbd>nickname</kbd>。",
        "apihelp-query+logevents-paramvalue-prop-ids": "添加日志活动的ID。",
        "apihelp-query+logevents-paramvalue-prop-title": "为日志事件添加页面标题。",
        "apihelp-query+logevents-paramvalue-prop-type": "添加日志活动的类型。",
-       "apihelp-query+logevents-paramvalue-prop-user": "为日志事件添加用户责任。",
-       "apihelp-query+logevents-paramvalue-prop-userid": "为日志事件添加对此负责的用户ID。",
+       "apihelp-query+logevents-paramvalue-prop-user": "添加对此日志事件负责的用户。",
+       "apihelp-query+logevents-paramvalue-prop-userid": "添加对此日志事件负责的用户的ID。",
        "apihelp-query+logevents-paramvalue-prop-timestamp": "为日志活动添加时间戳。",
        "apihelp-query+logevents-paramvalue-prop-comment": "添加日志活动的摘要。",
        "apihelp-query+logevents-paramvalue-prop-parsedcomment": "添加被解析的日志活动的摘要。",
        "apihelp-query+recentchanges-param-excludeuser": "不要列出此用户的更改。",
        "apihelp-query+recentchanges-param-tag": "只列出带此标签的更改。",
        "apihelp-query+recentchanges-param-prop": "包含的额外信息束:",
-       "apihelp-query+recentchanges-paramvalue-prop-user": "为编辑和标签添加用户责任,如果它们是IP的话。",
+       "apihelp-query+recentchanges-paramvalue-prop-user": "添加造成编辑的用户,并标出它们是否是IP。",
        "apihelp-query+recentchanges-paramvalue-prop-userid": "为编辑添加用户ID责任。",
        "apihelp-query+recentchanges-paramvalue-prop-comment": "为编辑添加摘要。",
        "apihelp-query+recentchanges-paramvalue-prop-parsedcomment": "为编辑添加解析的摘要。",
        "apihelp-query+recentchanges-paramvalue-prop-patrolled": "将可巡查编辑标记为已巡查或未巡查。",
        "apihelp-query+recentchanges-paramvalue-prop-loginfo": "添加日志信息(日志ID、日志类型等)至日志记录。",
        "apihelp-query+recentchanges-paramvalue-prop-tags": "列举条目的标签。",
-       "apihelp-query+recentchanges-paramvalue-prop-sha1": "Adds the content checksum for entries associated with a revision.",
+       "apihelp-query+recentchanges-paramvalue-prop-sha1": "为与某一修订版本有关的记录添加内容校验和。",
        "apihelp-query+recentchanges-param-token": "请改用<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>。",
        "apihelp-query+recentchanges-param-show": "只显示满足这些标准的项目。例如,要只查看由登录用户做出的小编辑,设置$1show=minor|!anon。",
        "apihelp-query+recentchanges-param-limit": "返回总计更新数。",
        "apihelp-query+revisions-example-first5-not-localhost": "获取<kbd>Main Page</kbd>的前5次不是由匿名用户<kbd>127.0.0.1</kbd>做出的修订。",
        "apihelp-query+revisions-example-first5-user": "获取<kbd>Main Page</kbd>的前5次由用户<kbd>MediaWiki default</kbd>做出的修订。",
        "apihelp-query+revisions+base-param-prop": "要为每个修订获取的属性:",
-       "apihelp-query+revisions+base-paramvalue-prop-ids": "修订ID。",
+       "apihelp-query+revisions+base-paramvalue-prop-ids": "修订版本的ID。",
        "apihelp-query+revisions+base-paramvalue-prop-flags": "修订标记(小编辑)。",
        "apihelp-query+revisions+base-paramvalue-prop-timestamp": "修订的时间戳。",
        "apihelp-query+revisions+base-paramvalue-prop-user": "做出修订的用户。",
        "apihelp-query+search-paramvalue-prop-size": "添加页面大小,单位为字节。",
        "apihelp-query+search-paramvalue-prop-wordcount": "添加页面的字数。",
        "apihelp-query+search-paramvalue-prop-timestamp": "添加页面上次编辑时的时间戳。",
-       "apihelp-query+search-paramvalue-prop-snippet": "Adds a parsed snippet of the page.",
-       "apihelp-query+search-paramvalue-prop-titlesnippet": "Adds a parsed snippet of the page title.",
+       "apihelp-query+search-paramvalue-prop-snippet": "添加已解析的页面片段。",
+       "apihelp-query+search-paramvalue-prop-titlesnippet": "添加已解析的页面标题片段。",
        "apihelp-query+search-paramvalue-prop-redirectsnippet": "添加被解析的重定向标题的片段。",
        "apihelp-query+search-paramvalue-prop-redirecttitle": "添加匹配的重定向的标题。",
-       "apihelp-query+search-paramvalue-prop-sectionsnippet": "Adds a parsed snippet of the matching section title.",
-       "apihelp-query+search-paramvalue-prop-sectiontitle": "Adds the title of the matching section.",
-       "apihelp-query+search-paramvalue-prop-categorysnippet": "Adds a parsed snippet of the matching category.",
+       "apihelp-query+search-paramvalue-prop-sectionsnippet": "添加已解析的匹配章节标题片段。",
+       "apihelp-query+search-paramvalue-prop-sectiontitle": "添加匹配章节的标题。",
+       "apihelp-query+search-paramvalue-prop-categorysnippet": "添加已解析的匹配分类片段。",
        "apihelp-query+search-paramvalue-prop-isfilematch": "添加布尔值,表明搜索是否匹配文件内容。",
        "apihelp-query+search-paramvalue-prop-score": "<span class=\"apihelp-deprecated\">已弃用并已忽略。</span>",
        "apihelp-query+search-paramvalue-prop-hasrelated": "<span class=\"apihelp-deprecated\">已弃用并已忽略。</span>",
        "apihelp-query+siteinfo-paramvalue-prop-libraries": "返回wiki上安装的库。",
        "apihelp-query+siteinfo-paramvalue-prop-extensions": "返回wiki上安装的扩展。",
        "apihelp-query+siteinfo-paramvalue-prop-fileextensions": "返回允许上传的文件扩展名(文件类型)列表。",
-       "apihelp-query+siteinfo-paramvalue-prop-rightsinfo": "å¦\82æ\9e\9cå\8f¯ç\94¨ï¼\8cè¿\94å\9b\9ewikiç\9a\84ç\89\88æ\9d\83信息。",
+       "apihelp-query+siteinfo-paramvalue-prop-rightsinfo": "å½\93å\8f¯ç\94¨æ\97¶è¿\94å\9b\9ewikiç\9a\84ç\89\88æ\9d\83ï¼\88许å\8f¯å\8d\8fè®®ï¼\89信息。",
        "apihelp-query+siteinfo-paramvalue-prop-restrictions": "返回可用的编辑限制(保护)类型信息。",
        "apihelp-query+siteinfo-paramvalue-prop-languages": "返回MediaWiki支持的语言列表(可选择使用<var>$1inlanguagecode</var>本地化)。",
        "apihelp-query+siteinfo-paramvalue-prop-skins": "返回所有启用的皮肤列表(可选择使用<var>$1inlanguagecode</var>本地化,否则是内容语言)。",
        "apihelp-query+stashimageinfo-example-params": "返回两个藏匿文件的缩略图。",
        "apihelp-query+tags-description": "列出更改标签。",
        "apihelp-query+tags-param-limit": "列出标签的最大数量。",
-       "apihelp-query+tags-param-prop": "要获取哪个属性:",
+       "apihelp-query+tags-param-prop": "要获取属性:",
        "apihelp-query+tags-paramvalue-prop-name": "添加标签名称。",
        "apihelp-query+tags-paramvalue-prop-displayname": "为标签添加系统消息。",
        "apihelp-query+tags-paramvalue-prop-description": "为标签添加描述。",
        "apihelp-query+userinfo-paramvalue-prop-groups": "列举当前用户隶属的所有群组。",
        "apihelp-query+userinfo-paramvalue-prop-implicitgroups": "列举当前用户的所有自动成为成员的用户组。",
        "apihelp-query+userinfo-paramvalue-prop-rights": "列举当前用户拥有的所有权限。",
-       "apihelp-query+userinfo-paramvalue-prop-changeablegroups": "Lists the groups the current user can add to and remove from.",
-       "apihelp-query+userinfo-paramvalue-prop-options": "Lists all preferences the current user has set.",
+       "apihelp-query+userinfo-paramvalue-prop-changeablegroups": "列举当前用户可以添加并移除的用户组。",
+       "apihelp-query+userinfo-paramvalue-prop-options": "列举当前用户设置的所有参数设置。",
        "apihelp-query+userinfo-paramvalue-prop-preferencestoken": "<span class=\"apihelp-deprecated\">已弃用。</span>获取令牌以更改当前用户的参数设置。",
        "apihelp-query+userinfo-paramvalue-prop-editcount": "添加当前用户的编辑计数。",
-       "apihelp-query+userinfo-paramvalue-prop-ratelimits": "Lists all rate limits applying to the current user.",
+       "apihelp-query+userinfo-paramvalue-prop-ratelimits": "列举所有应用到当前用户的速率限制。",
        "apihelp-query+userinfo-paramvalue-prop-realname": "添加用户的真实姓名。",
-       "apihelp-query+userinfo-paramvalue-prop-email": "Adds the user's email address and email authentication date.",
-       "apihelp-query+userinfo-paramvalue-prop-acceptlang": "Echoes the <code>Accept-Language</code> header sent by the client in a structured format.",
+       "apihelp-query+userinfo-paramvalue-prop-email": "添加用户的电子邮件地址及电子邮件验证日期。",
+       "apihelp-query+userinfo-paramvalue-prop-acceptlang": "重复由客户端以结构化格式发送的<code>Accept-Language</code>标头。",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "添加用户的注册时间。",
-       "apihelp-query+userinfo-paramvalue-prop-unreadcount": "Adds the count of unread pages on the user's watchlist (maximum $1; returns <samp>$2</samp> if more).",
+       "apihelp-query+userinfo-paramvalue-prop-unreadcount": "添加用户监视列表上的未独页面计数(最高$1;如果更多则返回<samp>$2</samp>)。",
        "apihelp-query+userinfo-paramvalue-prop-centralids": "添加中心ID并为用户附加状态。",
        "apihelp-query+userinfo-param-attachedwiki": "与<kbd>$1prop=centralids</kbd>一起使用,表明用户是否附加于此ID定义的wiki。",
        "apihelp-query+userinfo-example-simple": "获取有关当前用户的信息。",
        "apihelp-query+users-param-prop": "要包含的信息束:",
        "apihelp-query+users-paramvalue-prop-blockinfo": "如果用户被封禁就标记,并注明是谁封禁,以何种原因封禁的。",
        "apihelp-query+users-paramvalue-prop-groups": "列举每位用户属于的所有组。",
-       "apihelp-query+users-paramvalue-prop-implicitgroups": "Lists all the groups a user is automatically a member of.",
+       "apihelp-query+users-paramvalue-prop-implicitgroups": "列举用户自动作为成员之一的所有组。",
        "apihelp-query+users-paramvalue-prop-rights": "列举每位用户拥有的所有权限。",
        "apihelp-query+users-paramvalue-prop-editcount": "添加用户的编辑计数。",
        "apihelp-query+users-paramvalue-prop-registration": "添加用户的注册时间戳。",
-       "apihelp-query+users-paramvalue-prop-emailable": "Tags if the user can and wants to receive email through [[Special:Emailuser]].",
+       "apihelp-query+users-paramvalue-prop-emailable": "当用户可以并希望通过[[Special:Emailuser]]接收电子邮件时标记。",
        "apihelp-query+users-paramvalue-prop-gender": "标记用户性别。返回“male”、“female”或“unknown”。",
        "apihelp-query+users-paramvalue-prop-centralids": "添加中心ID并为用户附加状态。",
        "apihelp-query+users-paramvalue-prop-cancreate": "表明是否可以为有效但尚未注册的用户名创建一个账户。",
        "apihelp-json-param-callback": "如果指定,将输出内容包裹在一个指定的函数调用中。出于安全考虑,所有用户相关的数据将被限制。",
        "apihelp-json-param-utf8": "如果指定,使用十六进制转义序列将大多数(但不是全部)非ASCII的字符编码为UTF-8,而不是替换它们。默认当<var>formatversion</var>不是<kbd>1</kbd>时。",
        "apihelp-json-param-ascii": "如果指定,使用十六进制转义序列将所有非ASCII编码。默认当<var>formatversion</var>为<kbd>1</kbd>时。",
-       "apihelp-json-param-formatversion": "输出格式:\n;1:向后兼容格式(XML样式布尔值、用于内容节点的<samp>*</samp>键等)。\n;2:实验现代格式。细节可以更改!\n;latest:使用最新格式(当前为<kbd>2</kbd>),可以在没有警告的情况下更改。",
+       "apihelp-json-param-formatversion": "输出格式:\n;1:向后兼容格式(XML样式布尔值、用于内容节点的<samp>*</samp>键等)。\n;2:实验现代格式。细节可能更改!\n;latest:使用最新格式(当前为<kbd>2</kbd>),格式可能在没有警告的情况下更改。",
        "apihelp-jsonfm-description": "输出数据为JSON格式(HTML优质打印效果)。",
        "apihelp-none-description": "不输出任何东西。",
        "apihelp-php-description": "输出数据为序列化PHP格式。",
-       "apihelp-php-param-formatversion": "输出格式:\n;1:向后兼容格式(XML样式布尔值、用于内容节点的<samp>*</samp>键等)。\n;2:实验现代格式。细节可以更改!\n;latest:使用最新格式(当前为<kbd>2</kbd>),可以在没有警告的情况下更改。",
+       "apihelp-php-param-formatversion": "输出格式:\n;1:向后兼容格式(XML样式布尔值、用于内容节点的<samp>*</samp>键等)。\n;2:实验现代格式。细节可能更改!\n;latest:使用最新格式(当前为<kbd>2</kbd>),格式可能在没有警告的情况下更改。",
        "apihelp-phpfm-description": "输出数据为序列化PHP格式(HTML优质打印效果)。",
        "apihelp-rawfm-description": "输出数据为JSON格式,包含调试元素(HTML优质打印效果)。",
        "apihelp-xml-description": "输出数据为XML格式。",
        "api-format-title": "MediaWiki API 结果",
        "api-format-prettyprint-header": "这是$1格式的HTML表示。HTML对调试很有用,但不适合应用程序使用。\n\n指定<var>format</var>参数以更改输出格式。要查看$1格式的非HTML表示,设置<kbd>format=$2</kbd>。\n\n参见[[mw:API|完整文档]],或[[Special:ApiHelp/main|API 帮助]]以获取更多信息。",
        "api-format-prettyprint-header-only-html": "这是用来调试的HTML表现,不适合实际使用。\n\n参见[[mw:API|完整文档]],或[[Special:ApiHelp/main|API帮助]]以获取更多信息。",
+       "api-format-prettyprint-status": "此响应将会返回HTTP状态$1 $2。",
        "api-pageset-param-titles": "要工作的标题列表。",
        "api-pageset-param-pageids": "要工作的页面ID列表。",
        "api-pageset-param-revids": "要工作的修订ID列表。",
        "api-help-param-deprecated": "已弃用。",
        "api-help-param-required": "这个参数是必须的。",
        "api-help-datatypes-header": "数据类型",
-       "api-help-datatypes": "至MediaWiki的输入应为NFC标准化的UTF-8。MediaWiki可以尝试转换其他输入,但这可能导致一些操作失败(例如[[Special:ApiHelp/edit|edits]]与MD5校验)。\n\n一些在API请求中的参数类型需要更进一步解释:\n;boolean\n:布尔参数就像HTML复选框一样工作:如果指定参数,无论何值都被认为是真。如果要假值,则可完全忽略参数。\n;timestamp\n:时间戳可被指定为很多格式。推荐使用ISO 8601日期和时间标准。所有时间为UTC时间,包含的任何时区会被忽略。\n:* ISO 8601日期和时间,<kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd>(标点和<kbd>Z</kbd>是可选项)\n:* 带小数秒(会被忽略)的ISO 8601日期和时间,<kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd>(破折号、括号和<kbd>Z</kbd>是可选的)\n:* MediaWiki格式,<kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* 一般数字格式,<kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>(<kbd>GMT</kbd>、<kbd>+<var>##</var></kbd>或<kbd>-<var>##</var></kbd>的可选时区会被忽略)\n:* EXIF格式,<kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 2822格式(时区可能会被省略),<kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 850格式(时区可能会被省略),<kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctime格式,<kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* 秒数是从1970-01-01T00:00:00Z开始,作为1到13位数的整数(除了<kbd>0</kbd>)\n:* 字符串<kbd>now</kbd>\n;替代多值分隔符\n:使用多个值的参数通常会与管道符号分隔的值一起提交,例如<kbd>param=value1|value2</kbd>或<kbd>param=value1%7Cvalue2</kbd>。如果值必须包含管道符号,使用U+001F(单位分隔符)作为分隔符,''并''在值前加前缀U+001F,例如<kbd>param=%1Fvalue1%1Fvalue2</kbd>。",
+       "api-help-datatypes": "至MediaWiki的输入应为NFC标准化的UTF-8。MediaWiki可以尝试转换其他输入,但这可能导致一些操作失败(例如带MD5校验[[Special:ApiHelp/edit|编辑]])。\n\n一些在API请求中的参数类型需要更进一步解释:\n;boolean\n:布尔参数就像HTML复选框一样工作:如果指定参数,无论何值都被认为是真。如果要假值,则可完全忽略参数。\n;timestamp\n:时间戳可被指定为很多格式。推荐使用ISO 8601日期和时间标准。所有时间为UTC时间,包含的任何时区会被忽略。\n:* ISO 8601日期和时间,<kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd>(标点和<kbd>Z</kbd>是可选项)\n:* 带小数秒(会被忽略)的ISO 8601日期和时间,<kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd>(破折号、冒号和<kbd>Z</kbd>是可选的)\n:* MediaWiki格式,<kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* 一般数字格式,<kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>(<kbd>GMT</kbd>、<kbd>+<var>##</var></kbd>或<kbd>-<var>##</var></kbd>的可选时区会被忽略)\n:* EXIF格式,<kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 2822格式(时区可省略),<kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 850格式(时区可省略),<kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctime格式,<kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* 从1970-01-01T00:00:00Z开始的秒数,作为1到13位数的整数(除了<kbd>0</kbd>)\n:* 字符串<kbd>now</kbd>\n;替代多值分隔符\n:使用多个值的参数通常会与管道符号分隔的值一起提交,例如<kbd>param=value1|value2</kbd>或<kbd>param=value1%7Cvalue2</kbd>。如果值必须包含管道符号,使用U+001F(单位分隔符)作为分隔符,''并''在值前加前缀U+001F,例如<kbd>param=%1Fvalue1%1Fvalue2</kbd>。",
        "api-help-param-type-limit": "类型:整数或<kbd>max</kbd>",
        "api-help-param-type-integer": "类型:{{PLURAL:$1|1=整数|2=整数列表}}",
        "api-help-param-type-boolean": "类型:布尔值([[Special:ApiHelp/main#main/datatypes|详细信息]])",
        "api-help-param-integer-minmax": "{{PLURAL:$1|值}}必须介于$2和$3之间。",
        "api-help-param-upload": "必须被公布为使用multipart/form-data的一次文件上传。",
        "api-help-param-multi-separate": "通过<kbd>|</kbd>或[[Special:ApiHelp/main#main/datatypes|替代物]]隔开各值。",
-       "api-help-param-multi-max": "值的最高数字是{{PLURAL:$1|$1}}(对于机器人则是{{PLURAL:$2|$2}})。",
+       "api-help-param-multi-max": "值的最大数量是{{PLURAL:$1|$1}}(对于机器人则是{{PLURAL:$2|$2}})。",
        "api-help-param-default": "默认:$1",
        "api-help-param-default-empty": "默认:<span class=\"apihelp-empty\">(空)</span>",
        "api-help-param-token": "从[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]取回的“$1”令牌",
        "api-help-permissions-granted-to": "{{PLURAL:$1|授予}}:$2",
        "api-help-right-apihighlimits": "在API查询中使用更高的上限(慢查询:$1;快查询:$2)。慢查询的限制也适用于多值参数。",
        "api-help-open-in-apisandbox": "<small>[在沙盒中打开]</small>",
-       "api-help-authmanager-general-usage": "使用此模块的一般程序是:\n# 通过<kbd>amirequestsfor=$4</kbd>取得来自<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>的可用字段,和来自<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>的<kbd>$5</kbd>令牌。\n# 向用户显示字段,并获得其提交内容。\n# 发送至此模块,提供<var>$1returnurl</var>及任何相关字段。\n# 在响应中检查<samp>status</samp>。\n#* 如果您收到了<samp>PASS</samp>或<samp>FAIL</samp>,您已经完成。The operation either succeeded or it didn't.\n#* 如果您收到了<samp>UI</samp>,present the new fields to the user and obtain their submission. Then post to this module with <var>$1continue</var> and the relevant fields set, and repeat step 4.\n#* 如果您收到了<samp>REDIRECT</samp>,direct the user to the <samp>redirecttarget</samp> and wait for the return to <var>$1returnurl</var>. Then post to this module with <var>$1continue</var> and any fields passed to the return URL, and repeat step 4.\n#* 如果您收到了<samp>RESTART</samp>,that means the authentication worked but we don't have a linked user account. You might treat this as <samp>UI</samp> or as <samp>FAIL</samp>.",
+       "api-help-authmanager-general-usage": "使用此模块的一般程序是:\n# 通过<kbd>amirequestsfor=$4</kbd>取得来自<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>的可用字段,和来自<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>的<kbd>$5</kbd>令牌。\n# 向用户显示字段,并获得其提交内容。\n# 发送至此模块,提供<var>$1returnurl</var>及任何相关字段。\n# 在响应中检查<samp>status</samp>。\n#* 如果您收到了<samp>PASS</samp>或<samp>FAIL</samp>,您已经完成。操作要么成功,要么不成功。\n#* 如果您收到了<samp>UI</samp>,present the new fields to the user and obtain their submission. Then post to this module with <var>$1continue</var> and the relevant fields set, and repeat step 4.\n#* 如果您收到了<samp>REDIRECT</samp>,direct the user to the <samp>redirecttarget</samp> and wait for the return to <var>$1returnurl</var>. Then post to this module with <var>$1continue</var> and any fields passed to the return URL, and repeat step 4.\n#* 如果您收到了<samp>RESTART</samp>,that means the authentication worked but we don't have a linked user account. You might treat this as <samp>UI</samp> or as <samp>FAIL</samp>.",
+       "api-help-authmanagerhelper-requests": "只使用这些身份验证请求,通过返回自<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>的<samp>id</samp>与<kbd>amirequestsfor=$1</kbd>,或来自此模块之前的响应。",
        "api-help-authmanagerhelper-request": "使用此身份验证请求,通过返回自<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>的<samp>id</samp>与<kbd>amirequestsfor=$1</kbd>。",
        "api-help-authmanagerhelper-messageformat": "返回消息使用的格式。",
        "api-help-authmanagerhelper-mergerequestfields": "合并用于所有身份验证请求的字段信息至一个数组中。",
        "api-help-authmanagerhelper-preservestate": "从之前失败的登录尝试中保持状态,如果可能。",
+       "api-help-authmanagerhelper-returnurl": "为第三方身份验证流返回URL,必须为绝对值。需要此值或<var>$1continue</var>两者之一。\n\nUpon receiving a <samp>REDIRECT</samp> response, you will typically open a browser or web view to the specified <samp>redirecttarget</samp> URL for a third-party authentication flow. When that completes, the third party will send the browser or web view to this URL. You should extract any query or POST parameters from the URL and pass them as a <var>$1continue</var> request to this API module.",
        "api-help-authmanagerhelper-continue": "此请求是在早先的<samp>UI</samp>或<samp>REDIRECT</samp>响应之后的附加请求。必需此值或<var>$1returnurl</var>。",
        "api-help-authmanagerhelper-additional-params": "此模块允许额外参数,取决于可用的身份验证请求。使用<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>与<kbd>amirequestsfor=$1</kbd>(或之前来自此模块的相应,如果可以)以决定可用请求及其使用的字段。",
        "api-credits-header": "制作人员",
diff --git a/includes/api/i18n/zu.json b/includes/api/i18n/zu.json
new file mode 100644 (file)
index 0000000..f9a5eb6
--- /dev/null
@@ -0,0 +1,10 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Irus"
+               ]
+       },
+       "apihelp-block-description": "Vimbela umsebenzisi",
+       "apihelp-block-param-user": "Igama lomsebenzisi, ikheli le-IP, noma ikheli le-IP uhla ukuvimba.",
+       "apihelp-block-param-reblock": "Uma umsebenzisi usevele ivinjiwe, isula block ekhona."
+}
index 51efe56..d88a5b2 100644 (file)
@@ -1678,7 +1678,7 @@ class AuthManager implements LoggerAwareInterface {
 
                // Ignore warnings about master connections/writes...hard to avoid here
                $trxProfiler = \Profiler::instance()->getTransactionProfiler();
-               $trxProfiler->setSilenced( true );
+               $old = $trxProfiler->setSilenced( true );
                try {
                        $status = $user->addToDatabase();
                        if ( !$status->isOK() ) {
@@ -1694,9 +1694,9 @@ class AuthManager implements LoggerAwareInterface {
                                        $status = Status::newGood();
                                        $status->warning( 'userexists' );
                                } else {
-                                       $this->logger->error( __METHOD__ . ': {username} failed with message {message}', [
+                                       $this->logger->error( __METHOD__ . ': {username} failed with message {msg}', [
                                                'username' => $username,
-                                               'message' => $status->getWikiText( null, null, 'en' )
+                                               'msg' => $status->getWikiText( null, null, 'en' )
                                        ] );
                                        $user->setId( 0 );
                                        $user->loadFromId();
@@ -1704,7 +1704,7 @@ class AuthManager implements LoggerAwareInterface {
                                return $status;
                        }
                } catch ( \Exception $ex ) {
-                       $trxProfiler->setSilenced( false );
+                       $trxProfiler->setSilenced( $old );
                        $this->logger->error( __METHOD__ . ': {username} failed with exception {exception}', [
                                'username' => $username,
                                'exception' => $ex,
@@ -1743,7 +1743,7 @@ class AuthManager implements LoggerAwareInterface {
                        $logEntry->insert();
                }
 
-               $trxProfiler->setSilenced( false );
+               $trxProfiler->setSilenced( $old );
 
                if ( $login ) {
                        $this->setSessionDataForUser( $user );
@@ -2382,7 +2382,7 @@ class AuthManager implements LoggerAwareInterface {
                $session->set( 'AuthManager:lastAuthTimestamp', time() );
                $session->persist();
 
-               \ScopedCallback::consume( $delay );
+               \Wikimedia\ScopedCallback::consume( $delay );
 
                \Hooks::run( 'UserLoggedIn', [ $user ] );
        }
index 88df68d..859fd0c 100644 (file)
@@ -104,7 +104,7 @@ class LocalPasswordPrimaryAuthenticationProvider
                // The old hash format was just an md5 hex hash, with no type information
                if ( preg_match( '/^[0-9a-f]{32}$/', $row->user_password ) ) {
                        if ( $this->config->get( 'PasswordSalt' ) ) {
-                               $row->user_password = ":A:{$row->user_id}:{$row->user_password}";
+                               $row->user_password = ":B:{$row->user_id}:{$row->user_password}";
                        } else {
                                $row->user_password = ":A:{$row->user_password}";
                        }
@@ -132,12 +132,12 @@ class LocalPasswordPrimaryAuthenticationProvider
 
                // @codeCoverageIgnoreStart
                if ( $this->getPasswordFactory()->needsUpdate( $pwhash ) ) {
-                       $pwhash = $this->getPasswordFactory()->newFromPlaintext( $req->password );
-                       \DeferredUpdates::addCallableUpdate( function () use ( $pwhash, $oldRow ) {
+                       $newHash = $this->getPasswordFactory()->newFromPlaintext( $req->password );
+                       \DeferredUpdates::addCallableUpdate( function () use ( $newHash, $oldRow ) {
                                $dbw = wfGetDB( DB_MASTER );
                                $dbw->update(
                                        'user',
-                                       [ 'user_password' => $pwhash->toString() ],
+                                       [ 'user_password' => $newHash->toString() ],
                                        [
                                                'user_id' => $oldRow->user_id,
                                                'user_password' => $oldRow->user_password
index 9962fa3..2e6f93c 100644 (file)
@@ -154,6 +154,16 @@ class TemporaryPasswordPrimaryAuthenticationProvider
                        return $this->failResponse( $req );
                }
 
+               // Add an extra log entry since a temporary password is
+               // an unusual way to log in, so its important to keep track
+               // of in case of abuse.
+               $this->logger->info( "{user} successfully logged in using temp password",
+                       [
+                               'user' => $username,
+                               'requestIP' => $this->manager->getRequest()->getIP()
+                       ]
+               );
+
                $this->setPasswordResetFlag( $username, $status );
 
                return AuthenticationResponse::newPass( $username );
index f47c606..000b070 100644 (file)
@@ -135,7 +135,7 @@ class Throttler implements LoggerAwareInterface {
                                $this->cache->incr( $throttleKey );
                        } else { // throttled
                                $this->logRejection( [
-                                       'type' => $this->type,
+                                       'throttle' => $this->type,
                                        'index' => $index,
                                        'ip' => $ipKey,
                                        'username' => $username,
@@ -191,7 +191,7 @@ class Throttler implements LoggerAwareInterface {
        }
 
        protected function logRejection( array $context ) {
-               $logMsg = 'Throttle {type} hit, throttled for {expiry} seconds due to {count} attempts '
+               $logMsg = 'Throttle {throttle} hit, throttled for {expiry} seconds due to {count} attempts '
                        . 'from username {username} and IP {ip}';
 
                // If we are hitting a throttle for >= warningLimit attempts, it is much more likely to be
index 9dfabfd..9e6cf1e 100644 (file)
@@ -139,7 +139,7 @@ class BacklinkCache {
        /**
         * Get the replica DB connection to the database
         * When non existing, will initialize the connection.
-        * @return DatabaseBase
+        * @return Database
         */
        protected function getDB() {
                if ( !isset( $this->db ) ) {
index a85639f..ae8efa9 100644 (file)
@@ -157,6 +157,7 @@ class HTMLFileCache extends FileCacheBase {
         * @return void
         */
        public function loadFromFileCache( IContextSource $context, $mode = self::MODE_NORMAL ) {
+               global $wgContLang;
                $config = MediaWikiServices::getInstance()->getMainConfig();
 
                wfDebug( __METHOD__ . "()\n" );
@@ -169,7 +170,7 @@ class HTMLFileCache extends FileCacheBase {
 
                $context->getOutput()->sendCacheControl();
                header( "Content-Type: {$config->get( 'MimeType' )}; charset=UTF-8" );
-               header( "Content-Language: {$config->get( 'LanguageCode' )}" );
+               header( "Content-Language: {$wgContLang->getHtmlCode()}" );
                if ( $this->useGzip() ) {
                        if ( wfClientAcceptsGzip() ) {
                                header( 'Content-Encoding: gzip' );
index e871855..1bcab41 100644 (file)
@@ -20,6 +20,9 @@
  * @file
  * @ingroup Cache
  */
+use MediaWiki\MediaWikiServices;
+use Wikimedia\ScopedCallback;
+use MediaWiki\Logger\LoggerFactory;
 
 /**
  * MediaWiki message cache structure version.
@@ -50,6 +53,11 @@ class MessageCache {
         */
        protected $mCache;
 
+       /**
+        * @var bool[] Map of (language code => boolean)
+        */
+       protected $mCacheVolatile = [];
+
        /**
         * Should mean that database cannot be used, but check
         * @var bool $mDisable
@@ -63,10 +71,12 @@ class MessageCache {
        protected $mExpiry;
 
        /**
-        * Message cache has its own parser which it uses to transform
-        * messages.
+        * Message cache has its own parser which it uses to transform messages
+        * @var ParserOptions
         */
-       protected $mParserOptions, $mParser;
+       protected $mParserOptions;
+       /** @var Parser */
+       protected $mParser;
 
        /**
         * Variable for tracking which variables are already loaded
@@ -127,6 +137,7 @@ class MessageCache {
         */
        public static function normalizeKey( $key ) {
                global $wgContLang;
+
                $lckey = strtr( $key, ' ', '_' );
                if ( ord( $lckey ) < 128 ) {
                        $lckey[0] = strtolower( $lckey[0] );
@@ -154,9 +165,9 @@ class MessageCache {
                $this->mExpiry = $expiry;
 
                if ( $wgUseLocalMessageCache ) {
-                       $this->localCache = ObjectCache::getLocalServerInstance( CACHE_NONE );
+                       $this->localCache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
                } else {
-                       $this->localCache = wfGetCache( CACHE_NONE );
+                       $this->localCache = new EmptyBagOStuff();
                }
 
                $this->wanCache = ObjectCache::getMainWANInstance();
@@ -226,17 +237,14 @@ class MessageCache {
         * or false if populating empty cache fails. Also returns true if MessageCache
         * is disabled.
         *
-        * @param bool|string $code Language to which load messages
-        * @param integer $mode Use MessageCache::FOR_UPDATE to skip process cache
+        * @param string $code Language to which load messages
+        * @param integer $mode Use MessageCache::FOR_UPDATE to skip process cache [optional]
         * @throws MWException
         * @return bool
         */
-       function load( $code = false, $mode = null ) {
+       protected function load( $code, $mode = null ) {
                if ( !is_string( $code ) ) {
-                       # This isn't really nice, so at least make a note about it and try to
-                       # fall back
-                       wfDebug( __METHOD__ . " called without providing a language code\n" );
-                       $code = 'en';
+                       throw new InvalidArgumentException( "Missing language code" );
                }
 
                # Don't do double loading...
@@ -263,6 +271,7 @@ class MessageCache {
                # Hash of the contents is stored in memcache, to detect if data-center cache
                # or local cache goes out of date (e.g. due to replace() on some other server)
                list( $hash, $hashVolatile ) = $this->getValidationHash( $code );
+               $this->mCacheVolatile[$code] = $hashVolatile;
 
                # Try the local cache and check against the cluster hash key...
                $cache = $this->getLocalCache( $code );
@@ -478,9 +487,16 @@ class MessageCache {
                $bigConds[] = 'page_len > ' . intval( $wgMaxMsgCacheEntrySize );
 
                # Load titles for all oversized pages in the MediaWiki namespace
-               $res = $dbr->select( 'page', 'page_title', $bigConds, __METHOD__ . "($code)-big" );
+               $res = $dbr->select(
+                       'page',
+                       [ 'page_title', 'page_latest' ],
+                       $bigConds,
+                       __METHOD__ . "($code)-big"
+               );
                foreach ( $res as $row ) {
                        $cache[$row->page_title] = '!TOO BIG';
+                       // At least include revision ID so page changes are reflected in the hash
+                       $cache['EXCESSIVE'][$row->page_title] = $row->page_latest;
                }
 
                # Conditions to load the remaining pages with their contents
@@ -525,7 +541,7 @@ class MessageCache {
         * Updates cache as necessary when message page is changed
         *
         * @param string|bool $title Name of the page changed (false if deleted)
-        * @param mixed $text New contents of the page.
+        * @param string|bool $text New contents of the page (false if deleted)
         */
        public function replace( $title, $text ) {
                global $wgMaxMsgCacheEntrySize, $wgContLang, $wgLanguageCode;
@@ -545,31 +561,32 @@ class MessageCache {
                // a self-deadlock. This is safe as no reads happen *directly* in this
                // method between getReentrantScopedLock() and load() below. There is
                // no risk of data "changing under our feet" for replace().
-               $cacheKey = wfMemcKey( 'messages', $code );
-               $scopedLock = $this->getReentrantScopedLock( $cacheKey );
+               $scopedLock = $this->getReentrantScopedLock( wfMemcKey( 'messages', $code ) );
+               // Load the messages from the master DB to avoid race conditions
                $this->load( $code, self::FOR_UPDATE );
 
-               $titleKey = wfMemcKey( 'messages', 'individual', $title );
+               // Load the new value into the process cache...
                if ( $text === false ) {
-                       // Article was deleted
                        $this->mCache[$code][$title] = '!NONEXISTENT';
-                       $this->wanCache->delete( $titleKey );
                } elseif ( strlen( $text ) > $wgMaxMsgCacheEntrySize ) {
-                       // Check for size
                        $this->mCache[$code][$title] = '!TOO BIG';
-                       $this->wanCache->set( $titleKey, ' ' . $text, $this->mExpiry );
+                       // Pre-fill the individual key cache with the known latest message text
+                       $key = $this->wanCache->makeKey( 'messages-big', $this->mCache[$code]['HASH'], $title );
+                       $this->wanCache->set( $key, " $text", $this->mExpiry );
                } else {
                        $this->mCache[$code][$title] = ' ' . $text;
-                       $this->wanCache->delete( $titleKey );
                }
-
-               // Mark this cache as definitely "latest" (non-volatile) so
-               // load() calls do try to refresh the cache with replica DB data
+               // Mark this cache as definitely being "latest" (non-volatile) so
+               // load() calls do not try to refresh the cache with replica DB data
                $this->mCache[$code]['LATEST'] = time();
 
                // Update caches if the lock was acquired
                if ( $scopedLock ) {
                        $this->saveToCaches( $this->mCache[$code], 'all', $code );
+               } else {
+                       LoggerFactory::getInstance( 'MessageCache' )->error(
+                               __METHOD__ . ': could not acquire lock to update {title} ({code})',
+                               [ 'title' => $title, 'code' => $code ] );
                }
 
                ScopedCallback::consume( $scopedLock );
@@ -630,11 +647,11 @@ class MessageCache {
                if ( $dest === 'all' ) {
                        $cacheKey = wfMemcKey( 'messages', $code );
                        $success = $this->mMemc->set( $cacheKey, $cache );
+                       $this->setValidationHash( $code, $cache );
                } else {
                        $success = true;
                }
 
-               $this->setValidationHash( $code, $cache );
                $this->saveToLocalCache( $code, $cache );
 
                return $success;
@@ -649,24 +666,26 @@ class MessageCache {
        protected function getValidationHash( $code ) {
                $curTTL = null;
                $value = $this->wanCache->get(
-                       wfMemcKey( 'messages', $code, 'hash', 'v1' ),
+                       $this->wanCache->makeKey( 'messages', $code, 'hash', 'v1' ),
                        $curTTL,
                        [ wfMemcKey( 'messages', $code ) ]
                );
 
-               if ( !$value ) {
-                       // No hash found at all; cache must regenerate to be safe
-                       $hash = false;
-                       $expired = true;
-               } else {
+               if ( $value ) {
                        $hash = $value['hash'];
-                       if ( ( time() - $value['latest'] ) < WANObjectCache::HOLDOFF_TTL ) {
-                               // Cache was recently updated via replace() and should be up-to-date
+                       if ( ( time() - $value['latest'] ) < WANObjectCache::TTL_MINUTE ) {
+                               // Cache was recently updated via replace() and should be up-to-date.
+                               // That method is only called in the primary datacenter and uses FOR_UPDATE.
+                               // Also, it is unlikely that the current datacenter is *now* secondary one.
                                $expired = false;
                        } else {
                                // See if the "check" key was bumped after the hash was generated
                                $expired = ( $curTTL < 0 );
                        }
+               } else {
+                       // No hash found at all; cache must regenerate to be safe
+                       $hash = false;
+                       $expired = true;
                }
 
                return [ $hash, $expired ];
@@ -676,14 +695,15 @@ class MessageCache {
         * Set the md5 used to validate the local disk cache
         *
         * If $cache has a 'LATEST' UNIX timestamp key, then the hash will not
-        * be treated as "volatile" by getValidationHash() for the next few seconds
+        * be treated as "volatile" by getValidationHash() for the next few seconds.
+        * This is triggered when $cache is generated using FOR_UPDATE mode.
         *
         * @param string $code
         * @param array $cache Cached messages with a version
         */
        protected function setValidationHash( $code, array $cache ) {
                $this->wanCache->set(
-                       wfMemcKey( 'messages', $code, 'hash', 'v1' ),
+                       $this->wanCache->makeKey( 'messages', $code, 'hash', 'v1' ),
                        [
                                'hash' => $cache['HASH'],
                                'latest' => isset( $cache['LATEST'] ) ? $cache['LATEST'] : 0
@@ -846,6 +866,7 @@ class MessageCache {
         */
        private function getMessageForLang( $lang, $lckey, $useDB, &$alreadyTried ) {
                global $wgContLang;
+
                $langcode = $lang->getCode();
 
                // Try checking the database for the requested language
@@ -863,6 +884,8 @@ class MessageCache {
                                }
                                $alreadyTried[ $langcode ] = true;
                        }
+               } else {
+                       $uckey = null;
                }
 
                // Check the CDB cache
@@ -880,7 +903,8 @@ class MessageCache {
                                        continue;
                                }
 
-                               $message = $this->getMsgFromNamespace( $this->getMessagePageName( $code, $uckey ), $code );
+                               $message = $this->getMsgFromNamespace(
+                                       $this->getMessagePageName( $code, $uckey ), $code );
 
                                if ( $message !== false ) {
                                        return $message;
@@ -901,6 +925,7 @@ class MessageCache {
         */
        private function getMessagePageName( $langcode, $uckey ) {
                global $wgLanguageCode;
+
                if ( $langcode === $wgLanguageCode ) {
                        // Messages created in the content language will not have the /lang extension
                        return $uckey;
@@ -926,8 +951,7 @@ class MessageCache {
                if ( isset( $this->mCache[$code][$title] ) ) {
                        $entry = $this->mCache[$code][$title];
                        if ( substr( $entry, 0, 1 ) === ' ' ) {
-                               // The message exists, so make sure a string
-                               // is returned.
+                               // The message exists, so make sure a string is returned.
                                return (string)substr( $entry, 1 );
                        } elseif ( $entry === '!NONEXISTENT' ) {
                                return false;
@@ -945,56 +969,63 @@ class MessageCache {
                        return false;
                }
 
-               # Try the individual message cache
-               $titleKey = wfMemcKey( 'messages', 'individual', $title );
-               $entry = $this->wanCache->get( $titleKey );
-               if ( $entry ) {
+               // Try the individual message cache
+               $titleKey = $this->wanCache->makeKey( 'messages-big', $this->mCache[$code]['HASH'], $title );
+
+               if ( $this->mCacheVolatile[$code] ) {
+                       $entry = false;
+                       // Make sure that individual keys respect the WAN cache holdoff period too
+                       LoggerFactory::getInstance( 'MessageCache' )->debug(
+                               __METHOD__ . ': loading volatile key \'{titleKey}\'',
+                               [ 'titleKey' => $titleKey, 'code' => $code ] );
+               } else {
+                       $entry = $this->wanCache->get( $titleKey );
+               }
+
+               if ( $entry !== false ) {
                        if ( substr( $entry, 0, 1 ) === ' ' ) {
                                $this->mCache[$code][$title] = $entry;
-
-                               // The message exists, so make sure a string
-                               // is returned.
+                               // The message exists, so make sure a string is returned
                                return (string)substr( $entry, 1 );
                        } elseif ( $entry === '!NONEXISTENT' ) {
                                $this->mCache[$code][$title] = '!NONEXISTENT';
 
                                return false;
                        } else {
-                               # Corrupt/obsolete entry, delete it
+                               // Corrupt/obsolete entry, delete it
                                $this->wanCache->delete( $titleKey );
                        }
                }
 
-               # Try loading it from the database
-               $revision = Revision::newFromTitle( Title::makeTitle( NS_MEDIAWIKI, $title ) );
+               // Try loading the message from the database
+               $dbr = wfGetDB( DB_REPLICA );
+               $cacheOpts = Database::getCacheSetOptions( $dbr );
+               // Use newKnownCurrent() to avoid querying revision/user tables
+               $titleObj = Title::makeTitle( NS_MEDIAWIKI, $title );
+               if ( $titleObj->getLatestRevID() ) {
+                       $revision = Revision::newKnownCurrent(
+                               $dbr,
+                               $titleObj->getArticleID(),
+                               $titleObj->getLatestRevID()
+                       );
+               } else {
+                       $revision = false;
+               }
+
                if ( $revision ) {
                        $content = $revision->getContent();
-                       if ( !$content ) {
-                               // A possibly temporary loading failure.
-                               wfDebugLog(
-                                       'MessageCache',
-                                       __METHOD__ . ": failed to load message page text for {$title} ($code)"
-                               );
-                               $message = null; // no negative caching
-                       } else {
-                               // XXX: Is this the right way to turn a Content object into a message?
-                               // NOTE: $content is typically either WikitextContent, JavaScriptContent or
-                               //       CssContent. MessageContent is *not* used for storing messages, it's
-                               //       only used for wrapping them when needed.
-                               $message = $content->getWikitextForTransclusion();
-
-                               if ( $message === false || $message === null ) {
-                                       wfDebugLog(
-                                               'MessageCache',
-                                               __METHOD__ . ": message content doesn't provide wikitext "
-                                                       . "(content model: " . $content->getModel() . ")"
-                                       );
-
-                                       $message = false; // negative caching
-                               } else {
+                       if ( $content ) {
+                               $message = $this->getMessageTextFromContent( $content );
+                               if ( is_string( $message ) ) {
                                        $this->mCache[$code][$title] = ' ' . $message;
-                                       $this->wanCache->set( $titleKey, ' ' . $message, $this->mExpiry );
+                                       $this->wanCache->set( $titleKey, ' ' . $message, $this->mExpiry, $cacheOpts );
                                }
+                       } else {
+                               // A possibly temporary loading failure
+                               LoggerFactory::getInstance( 'MessageCache' )->warning(
+                                       __METHOD__ . ': failed to load message page text for \'{titleKey}\'',
+                                       [ 'titleKey' => $titleKey, 'code' => $code ] );
+                               $message = null; // no negative caching
                        }
                } else {
                        $message = false; // negative caching
@@ -1002,7 +1033,7 @@ class MessageCache {
 
                if ( $message === false ) { // negative caching
                        $this->mCache[$code][$title] = '!NONEXISTENT';
-                       $this->wanCache->set( $titleKey, '!NONEXISTENT', $this->mExpiry );
+                       $this->wanCache->set( $titleKey, '!NONEXISTENT', $this->mExpiry, $cacheOpts );
                }
 
                return $message;
@@ -1046,6 +1077,7 @@ class MessageCache {
         */
        function getParser() {
                global $wgParser, $wgParserConf;
+
                if ( !$this->mParser && isset( $wgParser ) ) {
                        # Do some initialisation so that we don't have to do it twice
                        $wgParser->firstCallInit();
@@ -1073,6 +1105,8 @@ class MessageCache {
        public function parse( $text, $title = null, $linestart = true,
                $interface = false, $language = null
        ) {
+               global $wgTitle;
+
                if ( $this->mInParser ) {
                        return htmlspecialchars( $text );
                }
@@ -1087,7 +1121,6 @@ class MessageCache {
                $popts->setTargetLanguage( $language );
 
                if ( !$title || !$title instanceof Title ) {
-                       global $wgTitle;
                        wfDebugLog( 'GlobalTitleFail', __METHOD__ . ' called by ' .
                                wfGetAllCallers( 6 ) . ' with no title set.' );
                        $title = $wgTitle;
@@ -1175,6 +1208,7 @@ class MessageCache {
         */
        public function getAllMessageKeys( $code ) {
                global $wgContLang;
+
                $this->load( $code );
                if ( !isset( $this->mCache[$code] ) ) {
                        // Apparently load() failed
@@ -1184,10 +1218,61 @@ class MessageCache {
                $cache = $this->mCache[$code];
                unset( $cache['VERSION'] );
                unset( $cache['EXPIRY'] );
+               unset( $cache['EXCESSIVE'] );
                // Remove any !NONEXISTENT keys
                $cache = array_diff( $cache, [ '!NONEXISTENT' ] );
 
                // Keys may appear with a capital first letter. lcfirst them.
                return array_map( [ $wgContLang, 'lcfirst' ], array_keys( $cache ) );
        }
+
+       /**
+        * Purge message caches when a MediaWiki: page is created, updated, or deleted
+        *
+        * @param Title $title Message page title
+        * @param Content|null $content New content for edit/create, null on deletion
+        * @since 1.29
+        */
+       public function updateMessageOverride( Title $title, Content $content = null ) {
+               global $wgContLang;
+
+               $msgText = $this->getMessageTextFromContent( $content );
+               if ( $msgText === null ) {
+                       $msgText = false; // treat as not existing
+               }
+
+               $this->replace( $title->getDBkey(), $msgText );
+
+               if ( $wgContLang->hasVariants() ) {
+                       $wgContLang->updateConversionTable( $title );
+               }
+       }
+
+       /**
+        * @param Content|null $content Content or null if the message page does not exist
+        * @return string|bool|null Returns false if $content is null and null on error
+        */
+       private function getMessageTextFromContent( Content $content = null ) {
+               // @TODO: could skip pseudo-messages like js/css here, based on content model
+               if ( $content ) {
+                       // Message page exists...
+                       // XXX: Is this the right way to turn a Content object into a message?
+                       // NOTE: $content is typically either WikitextContent, JavaScriptContent or
+                       //       CssContent. MessageContent is *not* used for storing messages, it's
+                       //       only used for wrapping them when needed.
+                       $msgText = $content->getWikitextForTransclusion();
+                       if ( $msgText === false || $msgText === null ) {
+                               // This might be due to some kind of misconfiguration...
+                               $msgText = null;
+                               LoggerFactory::getInstance( 'MessageCache' )->warning(
+                                       __METHOD__ . ": message content doesn't provide wikitext "
+                                       . "(content model: " . $content->getModel() . ")" );
+                       }
+               } else {
+                       // Message page does not exist...
+                       $msgText = false;
+               }
+
+               return $msgText;
+       }
 }
index 016306a..5c75292 100644 (file)
@@ -80,7 +80,6 @@ class UserCache {
         * @param string $caller The calling method
         */
        public function doQuery( array $userIds, $options = [], $caller = '' ) {
-
                $usersToCheck = [];
                $usersToQuery = [];
 
@@ -132,7 +131,6 @@ class UserCache {
                        }
                }
                $lb->execute();
-
        }
 
        /**
index 2c3f58f..78a4863 100644 (file)
@@ -31,7 +31,7 @@ use Cdb\Writer;
  * space. The performance advantage is greater when the DBA extension is
  * available than it is with the PHP port.
  *
- * See Cdb.php and http://cr.yp.to/cdb.html
+ * See Cdb.php and https://cr.yp.to/cdb.html
  */
 class LCStoreCDB implements LCStore {
 
index 4970a2b..4b6362f 100644 (file)
@@ -549,7 +549,6 @@ class LocalisationCache {
         * @return array Array with a 'messages' key, or empty array if the file doesn't exist
         */
        public function readJSONFile( $fileName ) {
-
                if ( !is_readable( $fileName ) ) {
                        return [];
                }
@@ -561,7 +560,6 @@ class LocalisationCache {
 
                $data = FormatJson::decode( $json, true );
                if ( $data === null ) {
-
                        throw new MWException( __METHOD__ . ": Invalid JSON file: $fileName" );
                }
 
@@ -1036,7 +1034,6 @@ class LocalisationCache {
                        $blobStore = new MessageBlobStore();
                        $blobStore->clear();
                }
-
        }
 
        /**
index 7ae1f29..1262f2c 100644 (file)
@@ -333,7 +333,7 @@ class RecentChange {
 
                if ( count( $this->tags ) ) {
                        ChangeTags::addTags( $this->tags, $this->mAttribs['rc_id'],
-                               $this->mAttribs['rc_this_oldid'], $this->mAttribs['rc_logid'], null );
+                               $this->mAttribs['rc_this_oldid'], $this->mAttribs['rc_logid'], null, $this );
                }
 
                # Notify external application via UDP
@@ -1037,9 +1037,13 @@ class RecentChange {
         *
         * @since 1.28
         *
-        * @param array $tags
+        * @param string|array $tags
         */
        public function addTags( $tags ) {
-               $this->tags = array_merge( $tags, $this->tags );
+               if ( is_string( $tags ) ) {
+                       $this->tags[] = $tags;
+               } else {
+                       $this->tags = array_merge( $tags, $this->tags );
+               }
        }
 }
index 955e972..e3035be 100644 (file)
@@ -63,7 +63,7 @@ class ChangeTags {
                        if ( !$tag ) {
                                continue;
                        }
-                       $description = self::tagDescription( $tag );
+                       $description = self::tagDescription( $tag, $context );
                        if ( $description === false ) {
                                continue;
                        }
@@ -98,11 +98,12 @@ class ChangeTags {
         * we consider the tag hidden, and return false.
         *
         * @param string $tag Tag
+        * @param IContextSource $context
         * @return string|bool Tag description or false if tag is to be hidden.
         * @since 1.25 Returns false if tag is to be hidden.
         */
-       public static function tagDescription( $tag ) {
-               $msg = wfMessage( "tag-$tag" );
+       public static function tagDescription( $tag, IContextSource $context ) {
+               $msg = $context->msg( "tag-$tag" );
                if ( !$msg->exists() ) {
                        // No such message, so return the HTML-escaped tag name.
                        return htmlspecialchars( $tag );
@@ -124,14 +125,16 @@ class ChangeTags {
         * @param int|null $rev_id The rev_id of the change to add the tags to
         * @param int|null $log_id The log_id of the change to add the tags to
         * @param string $params Params to put in the ct_params field of table 'change_tag'
+        * @param RecentChange|null $rc Recent change, in case the tagging accompanies the action
+        * (this should normally be the case)
         *
         * @throws MWException
         * @return bool False if no changes are made, otherwise true
         */
        public static function addTags( $tags, $rc_id = null, $rev_id = null,
-               $log_id = null, $params = null
+               $log_id = null, $params = null, RecentChange $rc = null
        ) {
-               $result = self::updateTags( $tags, null, $rc_id, $rev_id, $log_id, $params );
+               $result = self::updateTags( $tags, null, $rc_id, $rev_id, $log_id, $params, $rc );
                return (bool)$result[0];
        }
 
@@ -154,6 +157,9 @@ class ChangeTags {
         * Pass a variable whose value is null if the log_id is not relevant or unknown.
         * @param string $params Params to put in the ct_params field of table
         * 'change_tag' when adding tags
+        * @param RecentChange|null $rc Recent change being tagged, in case the tagging accompanies
+        * the action
+        * @param User|null $user Tagging user, in case the tagging is subsequent to the tagged action
         *
         * @throws MWException When $rc_id, $rev_id and $log_id are all null
         * @return array Index 0 is an array of tags actually added, index 1 is an
@@ -162,9 +168,9 @@ class ChangeTags {
         *
         * @since 1.25
         */
-       public static function updateTags(
-               $tagsToAdd, $tagsToRemove,
-               &$rc_id = null, &$rev_id = null, &$log_id = null, $params = null
+       public static function updateTags( $tagsToAdd, $tagsToRemove, &$rc_id = null,
+               &$rev_id = null, &$log_id = null, $params = null, RecentChange $rc = null,
+               User $user = null
        ) {
 
                $tagsToAdd = array_filter( (array)$tagsToAdd ); // Make sure we're submitting all tags...
@@ -284,6 +290,10 @@ class ChangeTags {
                }
 
                self::purgeTagUsageCache();
+
+               Hooks::run( 'ChangeTagsAfterUpdateTags', [ $tagsToAdd, $tagsToRemove, $prevTags,
+                       $rc_id, $rev_id, $log_id, $params, $rc, $user ] );
+
                return [ $tagsToAdd, $tagsToRemove, $prevTags ];
        }
 
@@ -387,7 +397,7 @@ class ChangeTags {
                        if ( !$user->isAllowed( 'applychangetags' ) ) {
                                return Status::newFatal( 'tags-apply-no-permission' );
                        } elseif ( $user->isBlocked() ) {
-                               return Status::newFatal( 'tags-apply-blocked' );
+                               return Status::newFatal( 'tags-apply-blocked', $user->getName() );
                        }
                }
 
@@ -458,7 +468,7 @@ class ChangeTags {
                        if ( !$user->isAllowed( 'changetags' ) ) {
                                return Status::newFatal( 'tags-update-no-permission' );
                        } elseif ( $user->isBlocked() ) {
-                               return Status::newFatal( 'tags-update-blocked' );
+                               return Status::newFatal( 'tags-update-blocked', $user->getName() );
                        }
                }
 
@@ -546,7 +556,7 @@ class ChangeTags {
 
                // do it!
                list( $tagsAdded, $tagsRemoved, $initialTags ) = self::updateTags( $tagsToAdd,
-                       $tagsToRemove, $rc_id, $rev_id, $log_id, $params );
+                       $tagsToRemove, $rc_id, $rev_id, $log_id, $params, null, $user );
                if ( !$tagsAdded && !$tagsRemoved ) {
                        // no-op, don't log it
                        return Status::newGood( (object)[
@@ -656,21 +666,15 @@ class ChangeTags {
         * Build a text box to select a change tag
         *
         * @param string $selected Tag to select by default
-        * @param bool $fullForm Affects return value, see below
-        * @param Title $title Title object to send the form to. Used only if $fullForm is true.
         * @param bool $ooui Use an OOUI TextInputWidget as selector instead of a non-OOUI input field
         *        You need to call OutputPage::enableOOUI() yourself.
-        * @return string|array
-        *        - if $fullForm is false: an array of (label, selector).
-        *        - if $fullForm is true: HTML of entire form built around the selector.
+        * @return array an array of (label, selector)
         */
-       public static function buildTagFilterSelector( $selected = '',
-               $fullForm = false, Title $title = null, $ooui = false
-       ) {
+       public static function buildTagFilterSelector( $selected = '', $ooui = false ) {
                global $wgUseTagFilter;
 
                if ( !$wgUseTagFilter || !count( self::listDefinedTags() ) ) {
-                       return $fullForm ? '' : [];
+                       return [];
                }
 
                $data = [
@@ -697,24 +701,7 @@ class ChangeTags {
                        );
                }
 
-               if ( !$fullForm ) {
-                       return $data;
-               }
-
-               $html = implode( '&#160;', $data );
-               $html .= "\n" .
-                       Xml::element(
-                               'input',
-                               [ 'type' => 'submit', 'value' => wfMessage( 'tag-filter-submit' )->text() ]
-                       );
-               $html .= "\n" . Html::hidden( 'title', $title->getPrefixedText() );
-               $html = Xml::tags(
-                       'form',
-                       [ 'action' => $title->getLocalURL(), 'class' => 'mw-tagfilter-form', 'method' => 'get' ],
-                       $html
-               );
-
-               return $html;
+               return $data;
        }
 
        /**
@@ -803,7 +790,7 @@ class ChangeTags {
                        if ( !$user->isAllowed( 'managechangetags' ) ) {
                                return Status::newFatal( 'tags-manage-no-permission' );
                        } elseif ( $user->isBlocked() ) {
-                               return Status::newFatal( 'tags-manage-blocked' );
+                               return Status::newFatal( 'tags-manage-blocked', $user->getName() );
                        }
                }
 
@@ -871,7 +858,7 @@ class ChangeTags {
                        if ( !$user->isAllowed( 'managechangetags' ) ) {
                                return Status::newFatal( 'tags-manage-no-permission' );
                        } elseif ( $user->isBlocked() ) {
-                               return Status::newFatal( 'tags-manage-blocked' );
+                               return Status::newFatal( 'tags-manage-blocked', $user->getName() );
                        }
                }
 
@@ -930,7 +917,7 @@ class ChangeTags {
                        if ( !$user->isAllowed( 'managechangetags' ) ) {
                                return Status::newFatal( 'tags-manage-no-permission' );
                        } elseif ( $user->isBlocked() ) {
-                               return Status::newFatal( 'tags-manage-blocked' );
+                               return Status::newFatal( 'tags-manage-blocked', $user->getName() );
                        }
                }
 
@@ -1063,7 +1050,7 @@ class ChangeTags {
                        if ( !$user->isAllowed( 'deletechangetags' ) ) {
                                return Status::newFatal( 'tags-delete-no-permission' );
                        } elseif ( $user->isBlocked() ) {
-                               return Status::newFatal( 'tags-manage-blocked' );
+                               return Status::newFatal( 'tags-manage-blocked', $user->getName() );
                        }
                }
 
index 881c8c2..9950a11 100644 (file)
@@ -46,11 +46,13 @@ abstract class Collation {
         * @return Collation
         */
        public static function factory( $collationName ) {
+               global $wgContLang;
+
                switch ( $collationName ) {
                        case 'uppercase':
                                return new UppercaseCollation;
                        case 'numeric':
-                               return new NumericUppercaseCollation;
+                               return new NumericUppercaseCollation( $wgContLang );
                        case 'identity':
                                return new IdentityCollation;
                        case 'uca-default':
index 9c0b96e..7b4fce6 100644 (file)
@@ -91,13 +91,41 @@ class IcuCollation extends Collation {
         * available and that there are, in fact, no additional letters to consider.
         */
        private static $tailoringFirstLetters = [
-               // Verified by native speakers
+               'af' => [],
+               'am' => [],
+               'ar' => [],
+               'as' => [ "\xe0\xa6\x82", "\xe0\xa6\x81", "\xe0\xa6\x83", "\xe0\xa7\x8e", "ক্ষ " ],
+               'ast' => [ "Ch", "Ll", "Ñ" ], // not in libicu
+               'az' => [ "Ç", "Ə", "Ğ", "İ", "Ö", "Ş", "Ü" ],
                'be' => [ "Ё" ],
                'be-tarask' => [ "Ё" ],
+               'bg' => [],
+               'bn' => [ 'ং', 'ঃ', 'ঁ' ],
+               'bn@collation=traditional' => [
+                       'ং', 'ঃ', 'ঁ', 'ক্', 'খ্', 'গ্', 'ঘ্', 'ঙ্', 'চ্', 'ছ্', 'জ্', 'ঝ্',
+                       'ঞ্', 'ট্', 'ঠ্', 'ড্', 'ঢ্', 'ণ্', 'ৎ', 'থ্', 'দ্', 'ধ্', 'ন্', 'প্',
+                       'ফ্', 'ব্', 'ভ্', 'ম্', 'য্', 'র্', 'ৰ্', 'ল্', 'ৱ্', 'শ্', 'ষ্', 'স্', 'হ্'
+               ],
+               'bo' => [],
+               'br' => [ "Ch", "C'h" ],
                'bs' => [ "Č", "Ć", "Dž", "Đ", "Lj", "Nj", "Š", "Ž" ],
+               'bs-Cyrl' => [],
+               'ca' => [],
+               'chr' => [],
+               'co' => [], // not in libicu
                'cs' => [ "Č", "Ch", "Ř", "Š", "Ž" ],
                'cy' => [ "Ch", "Dd", "Ff", "Ng", "Ll", "Ph", "Rh", "Th" ],
+               'da' => [ "Æ", "Ø", "Å" ],
+               'de' => [],
+               'de-AT@collation=phonebook' => [ 'ä', 'ö', 'ü', 'ß' ],
+               'dsb' => [ "Č", "Ć", "Dź", "Ě", "Ch", "Ł", "Ń", "Ŕ", "Š", "Ś", "Ž", "Ź" ],
+               'ee' => [ "Dz", "Ɖ", "Ɛ", "Ƒ", "Gb", "Ɣ", "Kp", "Ny", "Ŋ", "Ɔ", "Ts", "Ʋ" ],
+               'el' => [],
                'en' => [],
+               'eo' => [ "Ĉ", "Ĝ", "Ĥ", "Ĵ", "Ŝ", "Ŭ" ],
+               'es' => [ "Ñ" ],
+               'et' => [ "Š", "Ž", "Õ", "Ä", "Ö", "Ü", "W" ], // added W for CollationEt (xx-uca-et)
+               'eu' => [ "Ñ" ], // not in libicu
                'fa' => [
                        // RTL, let's put each letter on a new line
                        "آ",
@@ -107,74 +135,107 @@ class IcuCollation extends Collation {
                        "و"
                ],
                'fi' => [ "Å", "Ä", "Ö" ],
+               'fil' => [ "Ñ", "Ng" ],
+               'fo' => [ "Á", "Ð", "Í", "Ó", "Ú", "Ý", "Æ", "Ø", "Å" ],
                'fr' => [],
+               'fr-CA' => [], // fr-CA sorts accents slightly different from fr.
+               'fur' => [ "À", "Á", "Â", "È", "Ì", "Ò", "Ù" ], // not in libicu
+               'fy' => [], // not in libicu
+               'ga' => [],
+               'gd' => [], // not in libicu
+               'gl' => [ "Ch", "Ll", "Ñ" ],
+               'gu' => [ "\xe0\xaa\x82", "\xe0\xaa\x83", "\xe0\xaa\x81", "\xe0\xaa\xb3" ],
+               'ha' => [ 'Ɓ', 'Ɗ', 'Ƙ', 'Sh', 'Ts', 'Ƴ' ],
+               'haw' => [ 'ʻ' ],
+               'he' => [],
+               'hi' => [ "\xe0\xa4\x82", "\xe0\xa4\x83" ],
                'hr' => [ "Č", "Ć", "Dž", "Đ", "Lj", "Nj", "Š", "Ž" ],
                'hsb' => [ "Č", "Dź", "Ě", "Ch", "Ł", "Ń", "Ř", "Š", "Ć", "Ž" ],
                'hu' => [ "Cs", "Dz", "Dzs", "Gy", "Ly", "Ny", "Ö", "Sz", "Ty", "Ü", "Zs" ],
+               'hy' => [ "և" ],
+               'id' => [],
+               'ig' => [ "Ch", "Gb", "Gh", "Gw", "Ị", "Kp", "Kw", "Ṅ", "Nw", "Ny", "Ọ", "Sh", "Ụ" ],
                'is' => [ "Á", "Ð", "É", "Í", "Ó", "Ú", "Ý", "Þ", "Æ", "Ö", "Å" ],
                'it' => [],
+               'ka' => [],
+               'kk' => [ "Ү", "І" ],
+               'kl' => [ "Æ", "Ø", "Å" ],
+               'km' => [
+                       "រ", "ឫ", "ឬ", "ល", "ឭ", "ឮ", "\xe1\x9e\xbb\xe1\x9f\x86",
+                       "\xe1\x9f\x86", "\xe1\x9e\xb6\xe1\x9f\x86", "\xe1\x9f\x87",
+                       "\xe1\x9e\xb7\xe1\x9f\x87", "\xe1\x9e\xbb\xe1\x9f\x87",
+                       "\xe1\x9f\x81\xe1\x9f\x87", "\xe1\x9f\x84\xe1\x9f\x87",
+               ],
+               'kn' => [ "\xe0\xb2\x81", "\xe0\xb2\x83", "\xe0\xb3\xb1", "\xe0\xb3\xb2" ],
+               'kok' => [ "\xe0\xa4\x82", "\xe0\xa4\x83", "ळ", "क्ष" ],
+               'ku' => [ "Ç", "Ê", "Î", "Ş", "Û" ], // not in libicu
+               'ky' => [ "Ё" ],
+               'la' => [], // not in libicu
+               'lb' => [],
+               'lkt' => [ 'Č', 'Ǧ', 'Ȟ', 'Š', 'Ž' ],
+               'ln' => [ 'Ɛ' ],
+               'lo' => [],
                'lt' => [ "Č", "Š", "Ž" ],
                'lv' => [ "Č", "Ģ", "Ķ", "Ļ", "Ņ", "Š", "Ž" ],
                'mk' => [ "Ѓ", "Ќ" ],
+               'ml' => [],
+               'mn' => [],
+               'mo' => [ "Ă", "Â", "Î", "Ş", "Ţ" ], // not in libicu
+               'mr' => [ "\xe0\xa4\x82", "\xe0\xa4\x83", "ळ", "क्ष", "ज्ञ" ],
+               'ms' => [],
+               'mt' => [ "Ċ", "Ġ", "Għ", "Ħ", "Ż" ],
+               'nb' => [ "Æ", "Ø", "Å" ],
+               'ne' => [],
                'nl' => [],
+               'nn' => [ "Æ", "Ø", "Å" ],
+               'no' => [ "Æ", "Ø", "Å" ], // not in libicu. You should probably use nb or nn instead.
+               'oc' => [], // not in libicu
+               'om' => [ 'Ch', 'Dh', 'Kh', 'Ny', 'Ph', 'Sh' ],
+               'or' => [ "\xe0\xac\x81", "\xe0\xac\x82", "\xe0\xac\x83", "କ୍ଷ" ],
+               'pa' => [ "\xe0\xa9\x8d" ],
                'pl' => [ "Ą", "Ć", "Ę", "Ł", "Ń", "Ó", "Ś", "Ź", "Ż" ],
                'pt' => [],
+               'rm' => [], // not in libicu
+               'ro' => [ "Ă", "Â", "Î", "Ş", "Ţ" ],
                'ru' => [],
+               'rup' => [ "Ă", "Â", "Î", "Ľ", "Ń", "Ş", "Ţ" ], // not in libicu
+               'sco' => [],
+               'se' => [
+                       'Á', 'Č', 'Ʒ', 'Ǯ', 'Đ', 'Ǧ', 'Ǥ', 'Ǩ', 'Ŋ',
+                       'Š', 'Ŧ', 'Ž', 'Ø', 'Æ', 'Ȧ', 'Ä', 'Ö'
+               ],
+               'si' => [ "\xe0\xb6\x82", "\xe0\xb6\x83", "\xe0\xb6\xa4" ],
                'sk' => [ "Ä", "Č", "Ch", "Ô", "Š", "Ž" ],
+               'sl' => [ "Č", "Š", "Ž" ],
+               'smn' => [ "Á", "Č", "Đ", "Ŋ", "Š", "Ŧ", "Ž", "Æ", "Ø", "Å", "Ä", "Ö" ],
+               'sq' => [ "Ç", "Dh", "Ë", "Gj", "Ll", "Nj", "Rr", "Sh", "Th", "Xh", "Zh" ],
                'sr' => [],
+               'sr-Latn' => [ "Č", "Ć", "Dž", "Đ", "Lj", "Nj", "Š", "Ž" ],
                'sv' => [ "Å", "Ä", "Ö" ],
                'sv@collation=standard' => [ "Å", "Ä", "Ö" ],
+               'sw' => [],
                'ta' => [
                        "\xE0\xAE\x82", "ஃ", "க்ஷ", "க்", "ங்", "ச்", "ஞ்", "ட்", "ண்", "த்", "ந்",
                        "ப்", "ம்", "ய்", "ர்", "ல்", "வ்", "ழ்", "ள்", "ற்", "ன்", "ஜ்", "ஶ்", "ஷ்",
                        "ஸ்", "ஹ்", "க்ஷ்"
                ],
-               'uk' => [ "Ґ", "Ь" ],
-               'vi' => [ "Ă", "Â", "Đ", "Ê", "Ô", "Ơ", "Ư" ],
-               // Not verified, but likely correct
-               'af' => [],
-               'ast' => [ "Ch", "Ll", "Ñ" ],
-               'az' => [ "Ç", "Ə", "Ğ", "İ", "Ö", "Ş", "Ü" ],
-               'bg' => [],
-               'br' => [ "Ch", "C'h" ],
-               'ca' => [],
-               'co' => [],
-               'da' => [ "Æ", "Ø", "Å" ],
-               'de' => [],
-               'dsb' => [ "Č", "Ć", "Dź", "Ě", "Ch", "Ł", "Ń", "Ŕ", "Š", "Ś", "Ž", "Ź" ],
-               'el' => [],
-               'eo' => [ "Ĉ", "Ĝ", "Ĥ", "Ĵ", "Ŝ", "Ŭ" ],
-               'es' => [ "Ñ" ],
-               'et' => [ "Š", "Ž", "Õ", "Ä", "Ö", "Ü", "W" ], // added W for CollationEt (xx-uca-et)
-               'eu' => [ "Ñ" ],
-               'fo' => [ "Á", "Ð", "Í", "Ó", "Ú", "Ý", "Æ", "Ø", "Å" ],
-               'fur' => [ "À", "Á", "Â", "È", "Ì", "Ò", "Ù" ],
-               'fy' => [],
-               'ga' => [],
-               'gd' => [],
-               'gl' => [ "Ch", "Ll", "Ñ" ],
-               'kk' => [ "Ү", "І" ],
-               'kl' => [ "Æ", "Ø", "Å" ],
-               'ku' => [ "Ç", "Ê", "Î", "Ş", "Û" ],
-               'ky' => [ "Ё" ],
-               'la' => [],
-               'lb' => [],
-               'mo' => [ "Ă", "Â", "Î", "Ş", "Ţ" ],
-               'mt' => [ "Ċ", "Ġ", "Għ", "Ħ", "Ż" ],
-               'no' => [ "Æ", "Ø", "Å" ],
-               'oc' => [],
-               'rm' => [],
-               'ro' => [ "Ă", "Â", "Î", "Ş", "Ţ" ],
-               'rup' => [ "Ă", "Â", "Î", "Ľ", "Ń", "Ş", "Ţ" ],
-               'sco' => [],
-               'sl' => [ "Č", "Š", "Ž" ],
-               'smn' => [ "Á", "Č", "Đ", "Ŋ", "Š", "Ŧ", "Ž", "Æ", "Ø", "Å", "Ä", "Ö" ],
-               'sq' => [ "Ç", "Dh", "Ë", "Gj", "Ll", "Nj", "Rr", "Sh", "Th", "Xh", "Zh" ],
+               'te' => [ "\xe0\xb0\x81", "\xe0\xb0\x82", "\xe0\xb0\x83" ],
+               'th' => [ "ฯ", "\xe0\xb9\x86", "\xe0\xb9\x8d", "\xe0\xb8\xba" ],
                'tk' => [ "Ç", "Ä", "Ž", "Ň", "Ö", "Ş", "Ü", "Ý" ],
-               'tl' => [ "Ñ", "Ng" ],
+               'tl' => [ "Ñ", "Ng" ], // not in libicu
+               'to' => [ "Ng", "ʻ" ],
                'tr' => [ "Ç", "Ğ", "İ", "Ö", "Ş", "Ü" ],
-               'tt' => [ "Ә", "Ө", "Ү", "Җ", "Ң", "Һ" ],
-               'uz' => [ "Ch", "G'", "Ng", "O'", "Sh" ],
+               'tt' => [ "Ә", "Ө", "Ү", "Җ", "Ң", "Һ" ], // not in libicu
+               'uk' => [ "Ґ", "Ь" ],
+               'uz' => [ "Ch", "G'", "Ng", "O'", "Sh" ], // not in libicu
+               'vi' => [ "Ă", "Â", "Đ", "Ê", "Ô", "Ơ", "Ư" ],
+               'vo' => [ "Ä", "Ö", "Ü" ],
+               'yi' => [
+                       "\xd7\x91\xd6\xbf", "\xd7\x9b\xd6\xbc", "\xd7\xa4\xd6\xbc",
+                       "\xd7\xa9\xd7\x82", "\xd7\xaa\xd6\xbc"
+               ],
+               'yo' => [ "Ẹ", "Gb", "Ọ", "Ṣ" ],
+               'zu' => [],
        ];
 
        /**
index 4bf2f73..2d2ca47 100644 (file)
  * Note that this only works in terms of sequences of digits, and the behavior for decimal fractions
  * or pretty-formatted numbers may be unexpected.
  *
+ * Digits will be based on the wiki's content language settings. If
+ * you change the content langauge of a wiki you will need to run
+ * updateCollation.php --force. Only English (ASCII 0-9) and the
+ * localized version will be counted. Localized digits from other languages
+ * or weird unicode digit equivalents (e.g. 4, 𝟜, ⓸ , ⁴, etc) will not count.
+ *
  * @since 1.28
  */
 class NumericUppercaseCollation extends UppercaseCollation {
+
+       /**
+        * @var $digitTransformLang Language How to convert digits (usually $wgContLang)
+        */
+       private $digitTransformLang;
+
+       /**
+        * Constructor
+        *
+        * @param $lang Language How to convert digits.
+        *  For example, if given language "my" than ၇ is treated like 7.
+        *
+        * It is expected that usually this is given $wgContLang.
+        */
+       public function __construct( Language $lang ) {
+               $this->digitTransformLang = $lang;
+               parent::__construct();
+       }
+
        public function getSortKey( $string ) {
                $sortkey = parent::getSortKey( $string );
-
+               $sortkey = $this->convertDigits( $sortkey );
                // For each sequence of digits, insert the digit '0' and then the length of the sequence
                // (encoded in two bytes) before it. That's all folks, it sorts correctly now! The '0' ensures
                // correct position (where digits would normally sort), then the length will be compared putting
                // shorter numbers before longer ones; if identical, then the characters will be compared, which
                // generates the correct results for numbers of equal length.
                $sortkey = preg_replace_callback( '/\d+/', function ( $matches ) {
-                       $len = strlen( $matches[0] );
+                       // Strip any leading zeros
+                       $number = ltrim( $matches[0], '0' );
+                       $len = strlen( $number );
                        // This allows sequences of up to 65536 numeric characters to be handled correctly. One byte
                        // would allow only for 256, which doesn't feel future-proof.
                        $prefix = chr( floor( $len / 256 ) ) . chr( $len % 256 );
-                       return '0' . $prefix . $matches[0];
+                       return '0' . $prefix . $number;
                }, $sortkey );
 
                return $sortkey;
        }
 
+       /**
+        * Convert localized digits to english digits.
+        *
+        * based on Language::parseFormattedNumber but without commas.
+        *
+        * @param $string String sortkey to unlocalize digits of
+        * @return String Sortkey with all localized digits replaced with ASCII digits.
+        */
+       private function convertDigits( $string ) {
+               $table = $this->digitTransformLang->digitTransformTable();
+               if ( $table ) {
+                       $table = array_filter( $table );
+                       $flipped = array_flip( $table );
+                       // Some languages seem to also have commas in this table.
+                       $flipped = array_filter( $flipped, 'is_numeric' );
+                       $string = strtr( $string, $flipped );
+               }
+               return $string;
+       }
+
        public function getFirstLetter( $string ) {
-               if ( preg_match( '/^\d/', $string ) ) {
-                       // Note that we pass 0 and 9 as normal params, not numParams(). This only works for 0-9
-                       // and not localised digits, so we don't want them to be converted.
-                       return wfMessage( 'category-header-numerals' )->params( 0, 9 )->text();
+               $convertedString = $this->convertDigits( $string );
+
+               if ( preg_match( '/^\d/', $convertedString ) ) {
+                       return wfMessage( 'category-header-numerals' )
+                               ->numParams( 0, 9 )
+                               ->text();
                } else {
                        return parent::getFirstLetter( $string );
                }
diff --git a/includes/compat/ScopedCallback.php b/includes/compat/ScopedCallback.php
new file mode 100644 (file)
index 0000000..4fd4bc7
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Compatibility class for pre-namespace, pre-library class name
+ *
+ * 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
+ */
+
+/**
+ * @deprecated since 1.28 use Wikimedia\ScopedCallback
+ *
+ * @since 1.21
+ */
+class ScopedCallback extends Wikimedia\ScopedCallback {
+}
index feef87d..4d6c68c 100644 (file)
@@ -67,7 +67,7 @@ class HashConfig implements Config, MutableConfig {
        }
 
        /**
-        * @see Config::set
+        * @see MutableConfig::set
         */
        public function set( $name, $value ) {
                $this->settings[$name] = $value;
index d709c5c..3389a00 100644 (file)
@@ -82,15 +82,6 @@ class MWUnknownContentModelException extends MWException {
  * @ingroup Content
  */
 abstract class ContentHandler {
-       /**
-        * Switch for enabling deprecation warnings. Used by ContentHandler::deprecated()
-        * and ContentHandler::runLegacyHooks().
-        *
-        * Once the ContentHandler code has settled in a bit, this should be set to true to
-        * make extensions etc. show warnings when using deprecated functions and hooks.
-        */
-       protected static $enableDeprecationWarnings = false;
-
        /**
         * Convenience function for getting flat text from a Content object. This
         * should only be used in the context of backwards compatibility with code
@@ -243,7 +234,7 @@ abstract class ContentHandler {
                }
 
                // Hook can force JS/CSS
-               Hooks::run( 'TitleIsCssOrJsPage', [ $title, &$isCodePage ], '1.25' );
+               Hooks::run( 'TitleIsCssOrJsPage', [ $title, &$isCodePage ], '1.21' );
 
                // Is this a user subpage containing code?
                $isCodeSubpage = NS_USER == $ns
@@ -258,7 +249,7 @@ abstract class ContentHandler {
                $isWikitext = $isWikitext && !$isCodePage && !$isCodeSubpage;
 
                // Hook can override $isWikitext
-               Hooks::run( 'TitleIsWikitextPage', [ $title, &$isWikitext ], '1.25' );
+               Hooks::run( 'TitleIsWikitextPage', [ $title, &$isWikitext ], '1.21' );
 
                if ( !$isWikitext ) {
                        switch ( $ext ) {
@@ -1139,25 +1130,6 @@ abstract class ContentHandler {
                return $this->supportsDirectEditing();
        }
 
-       /**
-        * Logs a deprecation warning, visible if $wgDevelopmentWarnings, but only if
-        * self::$enableDeprecationWarnings is set to true.
-        *
-        * @param string $func The name of the deprecated function
-        * @param string $version The version since the method is deprecated. Usually 1.21
-        *   for ContentHandler related stuff.
-        * @param string|bool $component : Component to which the function belongs.
-        *   If false, it is assumed the function is in MediaWiki core.
-        *
-        * @see ContentHandler::$enableDeprecationWarnings
-        * @see wfDeprecated
-        */
-       public static function deprecated( $func, $version, $component = false ) {
-               if ( self::$enableDeprecationWarnings ) {
-                       wfDeprecated( $func, $version, $component, 3 );
-               }
-       }
-
        /**
         * Call a legacy hook that uses text instead of Content objects.
         * Will log a warning when a matching hook function is registered.
index fe12ff7..f4a6dc6 100644 (file)
@@ -77,7 +77,7 @@ class WikiTextStructure {
                        $heading = $heading[ 'line' ];
 
                        // Some wikis wrap the brackets in a span:
-                       // http://en.wikipedia.org/wiki/MediaWiki:Cite_reference_link
+                       // https://en.wikipedia.org/wiki/MediaWiki:Cite_reference_link
                        $heading = preg_replace( '/<\/?span>/', '', $heading );
                        // Normalize [] so the following regexp would work.
                        $heading = preg_replace( [ '/&#91;/', '/&#93;/' ], [ '[', ']' ], $heading );
index c87798e..ebedb7e 100644 (file)
@@ -25,6 +25,7 @@
 use Liuggio\StatsdClient\Factory\StatsdDataFactory;
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
+use Wikimedia\ScopedCallback;
 
 /**
  * Group all the pieces relevant to the context of a request into one instance
@@ -160,7 +161,7 @@ class RequestContext implements IContextSource, MutableContext {
        /**
         * Set the Title object
         *
-        * @param Title $title
+        * @param Title|null $title
         */
        public function setTitle( Title $title = null ) {
                $this->title = $title;
index ed617fe..6a1bbd6 100644 (file)
@@ -53,7 +53,7 @@ abstract class DBAccessBase implements IDBAccessObject {
         * @param int $id Which connection to use
         * @param array $groups Query groups
         *
-        * @return DatabaseBase
+        * @return Database
         */
        protected function getConnection( $id, $groups = [] ) {
                $loadBalancer = wfGetLB( $this->wiki );
index 6d07216..7208b7e 100644 (file)
@@ -1134,7 +1134,7 @@ class DatabaseMssql extends DatabaseBase {
        /**
         * MS SQL requires specifying the escape character used in a LIKE query
         * or using Square brackets to surround characters that are to be escaped
-        * http://msdn.microsoft.com/en-us/library/ms179859.aspx
+        * https://msdn.microsoft.com/en-us/library/ms179859.aspx
         * Here we take the Specify-Escape-Character approach since it's less
         * invasive, renders a query that is closer to other DB's and better at
         * handling square bracket escaping
diff --git a/includes/db/MWLBFactory.php b/includes/db/MWLBFactory.php
new file mode 100644 (file)
index 0000000..42ef685
--- /dev/null
@@ -0,0 +1,165 @@
+<?php
+/**
+ * Generator of database load balancing objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Database
+ */
+
+use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
+
+/**
+ * MediaWiki-specific class for generating database load balancers
+ * @ingroup Database
+ */
+abstract class MWLBFactory {
+       /**
+        * @param array $lbConf Config for LBFactory::__construct()
+        * @param Config $mainConfig Main config object from MediaWikiServices
+        * @return array
+        */
+       public static function applyDefaultConfig( array $lbConf, Config $mainConfig ) {
+               global $wgCommandLineMode;
+
+               $lbConf += [
+                       'localDomain' => new DatabaseDomain(
+                               $mainConfig->get( 'DBname' ),
+                               null,
+                               $mainConfig->get( 'DBprefix' )
+                       ),
+                       'profiler' => Profiler::instance(),
+                       'trxProfiler' => Profiler::instance()->getTransactionProfiler(),
+                       'replLogger' => LoggerFactory::getInstance( 'DBReplication' ),
+                       'queryLogger' => LoggerFactory::getInstance( 'DBQuery' ),
+                       'connLogger' => LoggerFactory::getInstance( 'DBConnection' ),
+                       'perfLogger' => LoggerFactory::getInstance( 'DBPerformance' ),
+                       'errorLogger' => [ MWExceptionHandler::class, 'logException' ],
+                       'cliMode' => $wgCommandLineMode,
+                       'hostname' => wfHostname(),
+                       // TODO: replace the global wfConfiguredReadOnlyReason() with a service.
+                       'readOnlyReason' => wfConfiguredReadOnlyReason(),
+               ];
+
+               if ( $lbConf['class'] === 'LBFactorySimple' ) {
+                       if ( isset( $lbConf['servers'] ) ) {
+                               // Server array is already explicitly configured; leave alone
+                       } elseif ( is_array( $mainConfig->get( 'DBservers' ) ) ) {
+                               foreach ( $mainConfig->get( 'DBservers' ) as $i => $server ) {
+                                       if ( $server['type'] === 'sqlite' ) {
+                                               $server += [ 'dbDirectory' => $mainConfig->get( 'SQLiteDataDir' ) ];
+                                       } elseif ( $server['type'] === 'postgres' ) {
+                                               $server += [
+                                                       'port' => $mainConfig->get( 'DBport' ),
+                                                       // Work around the reserved word usage in MediaWiki schema
+                                                       'keywordTableMap' => [ 'user' => 'mwuser', 'text' => 'pagecontent' ]
+                                               ];
+                                       }
+                                       $lbConf['servers'][$i] = $server + [
+                                               'schema' => $mainConfig->get( 'DBmwschema' ),
+                                               'tablePrefix' => $mainConfig->get( 'DBprefix' ),
+                                               'flags' => DBO_DEFAULT,
+                                               'sqlMode' => $mainConfig->get( 'SQLMode' ),
+                                               'utf8Mode' => $mainConfig->get( 'DBmysql5' )
+                                       ];
+                               }
+                       } else {
+                               $flags = DBO_DEFAULT;
+                               $flags |= $mainConfig->get( 'DebugDumpSql' ) ? DBO_DEBUG : 0;
+                               $flags |= $mainConfig->get( 'DBssl' ) ? DBO_SSL : 0;
+                               $flags |= $mainConfig->get( 'DBcompress' ) ? DBO_COMPRESS : 0;
+                               $server = [
+                                       'host' => $mainConfig->get( 'DBserver' ),
+                                       'user' => $mainConfig->get( 'DBuser' ),
+                                       'password' => $mainConfig->get( 'DBpassword' ),
+                                       'dbname' => $mainConfig->get( 'DBname' ),
+                                       'schema' => $mainConfig->get( 'DBmwschema' ),
+                                       'tablePrefix' => $mainConfig->get( 'DBprefix' ),
+                                       'type' => $mainConfig->get( 'DBtype' ),
+                                       'load' => 1,
+                                       'flags' => $flags,
+                                       'sqlMode' => $mainConfig->get( 'SQLMode' ),
+                                       'utf8Mode' => $mainConfig->get( 'DBmysql5' )
+                               ];
+                               if ( $server['type'] === 'sqlite' ) {
+                                       $server[ 'dbDirectory'] = $mainConfig->get( 'SQLiteDataDir' );
+                               } elseif ( $server['type'] === 'postgres' ) {
+                                       $server['port'] = $mainConfig->get( 'DBport' );
+                                       // Work around the reserved word usage in MediaWiki schema
+                                       $server['keywordTableMap'] = [ 'user' => 'mwuser', 'text' => 'pagecontent' ];
+                               }
+                               $lbConf['servers'] = [ $server ];
+                       }
+                       if ( !isset( $lbConf['externalClusters'] ) ) {
+                               $lbConf['externalClusters'] = $mainConfig->get( 'ExternalServers' );
+                       }
+               } elseif ( $lbConf['class'] === 'LBFactoryMulti' ) {
+                       if ( isset( $lbConf['serverTemplate'] ) ) {
+                               $lbConf['serverTemplate']['schema'] = $mainConfig->get( 'DBmwschema' );
+                               $lbConf['serverTemplate']['sqlMode'] = $mainConfig->get( 'SQLMode' );
+                               $lbConf['serverTemplate']['utf8Mode'] = $mainConfig->get( 'DBmysql5' );
+                       }
+               }
+
+               // Use APC/memcached style caching, but avoids loops with CACHE_DB (T141804)
+               $sCache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
+               if ( $sCache->getQoS( $sCache::ATTR_EMULATION ) > $sCache::QOS_EMULATION_SQL ) {
+                       $lbConf['srvCache'] = $sCache;
+               }
+               $cCache = ObjectCache::getLocalClusterInstance();
+               if ( $cCache->getQoS( $cCache::ATTR_EMULATION ) > $cCache::QOS_EMULATION_SQL ) {
+                       $lbConf['memCache'] = $cCache;
+               }
+               $wCache = MediaWikiServices::getInstance()->getMainWANObjectCache();
+               if ( $wCache->getQoS( $wCache::ATTR_EMULATION ) > $wCache::QOS_EMULATION_SQL ) {
+                       $lbConf['wanCache'] = $wCache;
+               }
+
+               return $lbConf;
+       }
+
+       /**
+        * 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
+        */
+       public static function getLBFactoryClass( array $config ) {
+               // For configuration backward compatibility after removing
+               // underscores from class names in MediaWiki 1.23.
+               $bcClasses = [
+                       'LBFactory_Simple' => 'LBFactorySimple',
+                       'LBFactory_Single' => 'LBFactorySingle',
+                       'LBFactory_Multi' => 'LBFactoryMulti'
+               ];
+
+               $class = $config['class'];
+
+               if ( isset( $bcClasses[$class] ) ) {
+                       $class = $bcClasses[$class];
+                       wfDeprecated(
+                               '$wgLBFactoryConf must be updated. See RELEASE-NOTES for details',
+                               '1.23'
+                       );
+               }
+
+               return $class;
+       }
+}
diff --git a/includes/db/loadbalancer/LBFactoryMW.php b/includes/db/loadbalancer/LBFactoryMW.php
deleted file mode 100644 (file)
index 9821da1..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-<?php
-/**
- * Generator of database load balancing objects.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Database
- */
-
-use MediaWiki\Logger\LoggerFactory;
-
-/**
- * Legacy MediaWiki-specific class for generating database load balancers
- * @ingroup Database
- */
-abstract class LBFactoryMW {
-       /**
-        * @param array $lbConf Config for LBFactory::__construct()
-        * @param Config $mainConfig Main config object from MediaWikiServices
-        * @return array
-        */
-       public static function applyDefaultConfig( array $lbConf, Config $mainConfig ) {
-               global $wgCommandLineMode;
-
-               $lbConf += [
-                       'localDomain' => new DatabaseDomain(
-                               $mainConfig->get( 'DBname' ),
-                               null,
-                               $mainConfig->get( 'DBprefix' )
-                       ),
-                       'profiler' => Profiler::instance(),
-                       'trxProfiler' => Profiler::instance()->getTransactionProfiler(),
-                       'replLogger' => LoggerFactory::getInstance( 'DBReplication' ),
-                       'queryLogger' => LoggerFactory::getInstance( 'DBQuery' ),
-                       'connLogger' => LoggerFactory::getInstance( 'DBConnection' ),
-                       'perfLogger' => LoggerFactory::getInstance( 'DBPerformance' ),
-                       'errorLogger' => [ MWExceptionHandler::class, 'logException' ],
-                       'cliMode' => $wgCommandLineMode,
-                       'hostname' => wfHostname(),
-                       // TODO: replace the global wfConfiguredReadOnlyReason() with a service.
-                       'readOnlyReason' => wfConfiguredReadOnlyReason(),
-               ];
-
-               if ( $lbConf['class'] === 'LBFactorySimple' ) {
-                       if ( isset( $lbConf['servers'] ) ) {
-                               // Server array is already explicitly configured; leave alone
-                       } elseif ( is_array( $mainConfig->get( 'DBservers' ) ) ) {
-                               foreach ( $mainConfig->get( 'DBservers' ) as $i => $server ) {
-                                       if ( $server['type'] === 'sqlite' ) {
-                                               $server += [ 'dbDirectory' => $mainConfig->get( 'SQLiteDataDir' ) ];
-                                       } elseif ( $server['type'] === 'postgres' ) {
-                                               $server += [ 'port' => $mainConfig->get( 'DBport' ) ];
-                                       }
-                                       $lbConf['servers'][$i] = $server + [
-                                               'schema' => $mainConfig->get( 'DBmwschema' ),
-                                               'tablePrefix' => $mainConfig->get( 'DBprefix' ),
-                                               'flags' => DBO_DEFAULT,
-                                               'sqlMode' => $mainConfig->get( 'SQLMode' ),
-                                               'utf8Mode' => $mainConfig->get( 'DBmysql5' )
-                                       ];
-                               }
-                       } else {
-                               $flags = DBO_DEFAULT;
-                               $flags |= $mainConfig->get( 'DebugDumpSql' ) ? DBO_DEBUG : 0;
-                               $flags |= $mainConfig->get( 'DBssl' ) ? DBO_SSL : 0;
-                               $flags |= $mainConfig->get( 'DBcompress' ) ? DBO_COMPRESS : 0;
-                               $server = [
-                                       'host' => $mainConfig->get( 'DBserver' ),
-                                       'user' => $mainConfig->get( 'DBuser' ),
-                                       'password' => $mainConfig->get( 'DBpassword' ),
-                                       'dbname' => $mainConfig->get( 'DBname' ),
-                                       'schema' => $mainConfig->get( 'DBmwschema' ),
-                                       'tablePrefix' => $mainConfig->get( 'DBprefix' ),
-                                       'type' => $mainConfig->get( 'DBtype' ),
-                                       'load' => 1,
-                                       'flags' => $flags,
-                                       'sqlMode' => $mainConfig->get( 'SQLMode' ),
-                                       'utf8Mode' => $mainConfig->get( 'DBmysql5' )
-                               ];
-                               if ( $server['type'] === 'sqlite' ) {
-                                       $server[ 'dbDirectory'] = $mainConfig->get( 'SQLiteDataDir' );
-                               } elseif ( $server['type'] === 'postgres' ) {
-                                       $server['port'] = $mainConfig->get( 'DBport' );
-                               }
-                               $lbConf['servers'] = [ $server ];
-                       }
-                       if ( !isset( $lbConf['externalClusters'] ) ) {
-                               $lbConf['externalClusters'] = $mainConfig->get( 'ExternalServers' );
-                       }
-               } elseif ( $lbConf['class'] === 'LBFactoryMulti' ) {
-                       if ( isset( $lbConf['serverTemplate'] ) ) {
-                               $lbConf['serverTemplate']['schema'] = $mainConfig->get( 'DBmwschema' );
-                               $lbConf['serverTemplate']['sqlMode'] = $mainConfig->get( 'SQLMode' );
-                               $lbConf['serverTemplate']['utf8Mode'] = $mainConfig->get( 'DBmysql5' );
-                       }
-               }
-
-               // Use APC/memcached style caching, but avoids loops with CACHE_DB (T141804)
-               $sCache = ObjectCache::getLocalServerInstance();
-               if ( $sCache->getQoS( $sCache::ATTR_EMULATION ) > $sCache::QOS_EMULATION_SQL ) {
-                       $lbConf['srvCache'] = $sCache;
-               }
-               $cCache = ObjectCache::getLocalClusterInstance();
-               if ( $cCache->getQoS( $cCache::ATTR_EMULATION ) > $cCache::QOS_EMULATION_SQL ) {
-                       $lbConf['memCache'] = $cCache;
-               }
-               $wCache = ObjectCache::getMainWANInstance();
-               if ( $wCache->getQoS( $wCache::ATTR_EMULATION ) > $wCache::QOS_EMULATION_SQL ) {
-                       $lbConf['wanCache'] = $wCache;
-               }
-
-               return $lbConf;
-       }
-
-       /**
-        * 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
-        */
-       public static function getLBFactoryClass( array $config ) {
-               // For configuration backward compatibility after removing
-               // underscores from class names in MediaWiki 1.23.
-               $bcClasses = [
-                       'LBFactory_Simple' => 'LBFactorySimple',
-                       'LBFactory_Single' => 'LBFactorySingle',
-                       'LBFactory_Multi' => 'LBFactoryMulti'
-               ];
-
-               $class = $config['class'];
-
-               if ( isset( $bcClasses[$class] ) ) {
-                       $class = $bcClasses[$class];
-                       wfDeprecated(
-                               '$wgLBFactoryConf must be updated. See RELEASE-NOTES for details',
-                               '1.23'
-                       );
-               }
-
-               return $class;
-       }
-}
index 3318ceb..4614c46 100644 (file)
@@ -94,6 +94,9 @@ class LegacyLogger extends AbstractLogger {
         * @return null
         */
        public function log( $level, $message, array $context = [] ) {
+               if ( is_string( $level ) ) {
+                       $level = self::$levelMapping[$level];
+               }
                if ( $this->channel === 'DBQuery' && isset( $context['method'] )
                        && isset( $context['master'] ) && isset( $context['runtime'] )
                ) {
@@ -102,8 +105,7 @@ class LegacyLogger extends AbstractLogger {
                }
 
                if ( isset( self::$dbChannels[$this->channel] )
-                       && isset( self::$levelMapping[$level] )
-                       && self::$levelMapping[$level] >= LogLevel::ERROR
+                       && $level >= self::$levelMapping[LogLevel::ERROR]
                ) {
                        // Format and write DB errors to the legacy locations
                        $effectiveChannel = 'wfLogDBError';
@@ -127,7 +129,7 @@ class LegacyLogger extends AbstractLogger {
         *
         * @param string $channel
         * @param string $message
-        * @param string|int $level \Psr\Log\LogEvent constant or Monlog level int
+        * @param string|int $level \Psr\Log\LogEvent constant or Monolog level int
         * @param array $context
         * @return bool True if message should be sent to disk/network, false
         * otherwise
@@ -135,6 +137,10 @@ class LegacyLogger extends AbstractLogger {
        public static function shouldEmit( $channel, $message, $level, $context ) {
                global $wgDebugLogFile, $wgDBerrorLog, $wgDebugLogGroups;
 
+               if ( is_string( $level ) ) {
+                       $level = self::$levelMapping[$level];
+               }
+
                if ( $channel === 'wfLogDBError' ) {
                        // wfLogDBError messages are emitted if a database log location is
                        // specfied.
@@ -162,9 +168,6 @@ class LegacyLogger extends AbstractLogger {
                                }
 
                                if ( isset( $logConfig['level'] ) ) {
-                                       if ( is_string( $level ) ) {
-                                               $level = self::$levelMapping[$level];
-                                       }
                                        $shouldEmit = $level >= self::$levelMapping[$logConfig['level']];
                                }
                        } else {
@@ -324,7 +327,7 @@ class LegacyLogger extends AbstractLogger {
         * @param string $channel
         * @param string $message
         * @param array $context
-        * @return null
+        * @return string
         */
        protected static function formatAsWfDebugLog( $channel, $message, $context ) {
                $time = wfTimestamp( TS_DB );
index f1a01fe..ce0cda1 100644 (file)
@@ -155,7 +155,7 @@ class AvroFormatter implements FormatterInterface {
         */
        public function getSchemaRevisionId( $channel ) {
                if ( isset( $this->schemas[$channel]['revision'] ) ) {
-                       return (int) $this->schemas[$channel]['revision'];
+                       return (int)$this->schemas[$channel]['revision'];
                }
                return null;
        }
index 8a761f5..1ba6c1f 100644 (file)
@@ -52,6 +52,8 @@ class DeferredUpdates {
        private static $preSendUpdates = [];
        /** @var DeferrableUpdate[] Updates to be deferred until after request end */
        private static $postSendUpdates = [];
+       /** @var bool Whether to just run updates in addUpdate() */
+       private static $immediateMode = false;
 
        const ALL = 0; // all updates; in web requests, use only after flushing the output buffer
        const PRESEND = 1; // for updates that should run before flushing output buffer
@@ -85,6 +87,12 @@ class DeferredUpdates {
                        self::push( self::$postSendUpdates, $update );
                }
 
+               if ( self::$immediateMode ) {
+                       // No more explicit doUpdates() calls will happen, so run this now
+                       self::doUpdates( 'run' );
+                       return;
+               }
+
                // Try to run the updates now if in CLI mode and no transaction is active.
                // This covers scripts that don't/barely use the DB but make updates to other stores.
                if ( $wgCommandLineMode ) {
@@ -126,6 +134,14 @@ class DeferredUpdates {
                }
        }
 
+       /**
+        * @param bool $value Whether to just immediately run updates in addUpdate()
+        * @since 1.28
+        */
+       public static function setImmediateMode( $value ) {
+               self::$immediateMode = (bool)$value;
+       }
+
        /**
         * @param DeferrableUpdate[] $queue
         * @param DeferrableUpdate $update
index 93b3ef6..6aa3831 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  */
 use MediaWiki\MediaWikiServices;
+use Wikimedia\ScopedCallback;
 
 /**
  * Update object handling the cleanup of links tables after a page was deleted.
index 8954304..229a9a2 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\ScopedCallback;
 
 /**
  * Class the manages updates of *_link tables as well as similar extension-managed tables
@@ -204,64 +205,85 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
 
        protected function doIncrementalUpdate() {
                # Page links
-               $existing = $this->getExistingLinks();
-               $this->linkDeletions = $this->getLinkDeletions( $existing );
-               $this->linkInsertions = $this->getLinkInsertions( $existing );
+               $existingPL = $this->getExistingLinks();
+               $this->linkDeletions = $this->getLinkDeletions( $existingPL );
+               $this->linkInsertions = $this->getLinkInsertions( $existingPL );
                $this->incrTableUpdate( 'pagelinks', 'pl', $this->linkDeletions, $this->linkInsertions );
 
                # Image links
-               $existing = $this->getExistingImages();
-               $imageDeletes = $this->getImageDeletions( $existing );
-               $this->incrTableUpdate( 'imagelinks', 'il', $imageDeletes,
-                       $this->getImageInsertions( $existing ) );
+               $existingIL = $this->getExistingImages();
+               $imageDeletes = $this->getImageDeletions( $existingIL );
+               $this->incrTableUpdate(
+                       'imagelinks',
+                       'il',
+                       $imageDeletes,
+                       $this->getImageInsertions( $existingIL ) );
 
                # Invalidate all image description pages which had links added or removed
-               $imageUpdates = $imageDeletes + array_diff_key( $this->mImages, $existing );
+               $imageUpdates = $imageDeletes + array_diff_key( $this->mImages, $existingIL );
                $this->invalidateImageDescriptions( $imageUpdates );
 
                # External links
-               $existing = $this->getExistingExternals();
-               $this->incrTableUpdate( 'externallinks', 'el', $this->getExternalDeletions( $existing ),
-                       $this->getExternalInsertions( $existing ) );
+               $existingEL = $this->getExistingExternals();
+               $this->incrTableUpdate(
+                       'externallinks',
+                       'el',
+                       $this->getExternalDeletions( $existingEL ),
+                       $this->getExternalInsertions( $existingEL ) );
 
                # Language links
-               $existing = $this->getExistingInterlangs();
-               $this->incrTableUpdate( 'langlinks', 'll', $this->getInterlangDeletions( $existing ),
-                       $this->getInterlangInsertions( $existing ) );
+               $existingLL = $this->getExistingInterlangs();
+               $this->incrTableUpdate(
+                       'langlinks',
+                       'll',
+                       $this->getInterlangDeletions( $existingLL ),
+                       $this->getInterlangInsertions( $existingLL ) );
 
                # Inline interwiki links
-               $existing = $this->getExistingInterwikis();
-               $this->incrTableUpdate( 'iwlinks', 'iwl', $this->getInterwikiDeletions( $existing ),
-                       $this->getInterwikiInsertions( $existing ) );
+               $existingIW = $this->getExistingInterwikis();
+               $this->incrTableUpdate(
+                       'iwlinks',
+                       'iwl',
+                       $this->getInterwikiDeletions( $existingIW ),
+                       $this->getInterwikiInsertions( $existingIW ) );
 
                # Template links
-               $existing = $this->getExistingTemplates();
-               $this->incrTableUpdate( 'templatelinks', 'tl', $this->getTemplateDeletions( $existing ),
-                       $this->getTemplateInsertions( $existing ) );
+               $existingTL = $this->getExistingTemplates();
+               $this->incrTableUpdate(
+                       'templatelinks',
+                       'tl',
+                       $this->getTemplateDeletions( $existingTL ),
+                       $this->getTemplateInsertions( $existingTL ) );
 
                # Category links
-               $existing = $this->getExistingCategories();
-               $categoryDeletes = $this->getCategoryDeletions( $existing );
-               $this->incrTableUpdate( 'categorylinks', 'cl', $categoryDeletes,
-                       $this->getCategoryInsertions( $existing ) );
-
-               # Invalidate all categories which were added, deleted or changed (set symmetric difference)
-               $categoryInserts = array_diff_assoc( $this->mCategories, $existing );
+               $existingCL = $this->getExistingCategories();
+               $categoryDeletes = $this->getCategoryDeletions( $existingCL );
+               $this->incrTableUpdate(
+                       'categorylinks',
+                       'cl',
+                       $categoryDeletes,
+                       $this->getCategoryInsertions( $existingCL ) );
+               $categoryInserts = array_diff_assoc( $this->mCategories, $existingCL );
                $categoryUpdates = $categoryInserts + $categoryDeletes;
-               $this->invalidateCategories( $categoryUpdates );
-               $this->updateCategoryCounts( $categoryInserts, $categoryDeletes );
 
                # Page properties
-               $existing = $this->getExistingProperties();
-               $this->propertyDeletions = $this->getPropertyDeletions( $existing );
-               $this->incrTableUpdate( 'page_props', 'pp', $this->propertyDeletions,
-                       $this->getPropertyInsertions( $existing ) );
+               $existingPP = $this->getExistingProperties();
+               $this->propertyDeletions = $this->getPropertyDeletions( $existingPP );
+               $this->incrTableUpdate(
+                       'page_props',
+                       'pp',
+                       $this->propertyDeletions,
+                       $this->getPropertyInsertions( $existingPP ) );
 
                # Invalidate the necessary pages
-               $this->propertyInsertions = array_diff_assoc( $this->mProperties, $existing );
+               $this->propertyInsertions = array_diff_assoc( $this->mProperties, $existingPP );
                $changed = $this->propertyDeletions + $this->propertyInsertions;
                $this->invalidateProperties( $changed );
 
+               # Invalidate all categories which were added, deleted or changed (set symmetric difference)
+               $this->invalidateCategories( $categoryUpdates );
+               $this->updateCategoryCounts( $categoryInserts, $categoryDeletes );
+
                # Refresh links of all pages including this page
                # This will be in a separate transaction
                if ( $this->mRecursive ) {
@@ -323,7 +345,7 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
        /**
         * @param array $cats
         */
-       function invalidateCategories( $cats ) {
+       private function invalidateCategories( $cats ) {
                PurgeJobUtils::invalidatePages( $this->getDB(), NS_CATEGORY, array_keys( $cats ) );
        }
 
@@ -332,17 +354,31 @@ class LinksUpdate extends DataUpdate implements EnqueueableDataUpdate {
         * @param array $added Associative array of category name => sort key
         * @param array $deleted Associative array of category name => sort key
         */
-       function updateCategoryCounts( $added, $deleted ) {
-               $a = WikiPage::factory( $this->mTitle );
-               $a->updateCategoryCounts(
-                       array_keys( $added ), array_keys( $deleted )
-               );
+       private function updateCategoryCounts( array $added, array $deleted ) {
+               global $wgUpdateRowsPerQuery;
+
+               $wp = WikiPage::factory( $this->mTitle );
+               $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+
+               foreach ( array_chunk( array_keys( $added ), $wgUpdateRowsPerQuery ) as $addBatch ) {
+                       $wp->updateCategoryCounts( $addBatch, [], $this->mId );
+                       $factory->commitAndWaitForReplication(
+                               __METHOD__, $this->ticket, [ 'wiki' => $this->getDB()->getWikiID() ]
+                       );
+               }
+
+               foreach ( array_chunk( array_keys( $deleted ), $wgUpdateRowsPerQuery ) as $deleteBatch ) {
+                       $wp->updateCategoryCounts( [], $deleteBatch, $this->mId );
+                       $factory->commitAndWaitForReplication(
+                               __METHOD__, $this->ticket, [ 'wiki' => $this->getDB()->getWikiID() ]
+                       );
+               }
        }
 
        /**
         * @param array $images
         */
-       function invalidateImageDescriptions( $images ) {
+       private function invalidateImageDescriptions( $images ) {
                PurgeJobUtils::invalidatePages( $this->getDB(), NS_FILE, array_keys( $images ) );
        }
 
index 62c8b00..b9a259b 100644 (file)
@@ -108,7 +108,6 @@ class SearchUpdate implements DeferrableUpdate {
                        # Perform the actual update
                        $search->update( $this->id, $normalTitle, $search->normalizeText( $text ) );
                }
-
        }
 
        /**
index 1537535..a5a8676 100644 (file)
@@ -21,7 +21,7 @@
  * @ingroup DifferenceEngine
  */
 
-// Deprecated, use class constant instead
+/** @deprecated use class constant instead */
 define( 'MW_DIFF_VERSION', '1.11a' );
 
 /**
@@ -176,7 +176,7 @@ class DifferenceEngine extends ContextSource {
         *
         * @param int $id Revision ID
         *
-        * @return mixed URL or false
+        * @return string|bool Link HTML or false
         */
        public function deletedLink( $id ) {
                if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
@@ -496,12 +496,11 @@ class DifferenceEngine extends ContextSource {
                                                [
                                                        'action' => 'markpatrolled',
                                                        'rcid' => $linkInfo['rcid'],
-                                                       'token' => $linkInfo['token'],
                                                ]
                                        ) . ']</span>';
                                // Allow extensions to change the markpatrolled link
                                Hooks::run( 'DifferenceEngineMarkPatrolledLink', [ $this,
-                                       &$this->mMarkPatrolledLink, $linkInfo['rcid'], $linkInfo['token'] ] );
+                                       &$this->mMarkPatrolledLink, $linkInfo['rcid'] ] );
                        }
                }
                return $this->mMarkPatrolledLink;
@@ -511,7 +510,7 @@ class DifferenceEngine extends ContextSource {
         * Returns an array of meta data needed to build a "mark as patrolled" link and
         * adds the mediawiki.page.patrol.ajax to the output.
         *
-        * @return array|false An array of meta data for a patrol link (rcid & token)
+        * @return array|false An array of meta data for a patrol link (rcid only)
         *  or false if no link is needed
         */
        protected function getMarkPatrolledLinkInfo() {
@@ -561,10 +560,8 @@ class DifferenceEngine extends ContextSource {
                                        $this->getOutput()->addModules( 'mediawiki.page.patrol.ajax' );
                                }
 
-                               $token = $user->getEditToken( $rcid );
                                return [
                                        'rcid' => $rcid,
-                                       'token' => $token,
                                ];
                        }
                }
@@ -609,7 +606,7 @@ class DifferenceEngine extends ContextSource {
                                // This needs to be synchronised with Article::showCssOrJsPage(), which sucks
                                // Give hooks a chance to customise the output
                                // @todo standardize this crap into one function
-                               if ( ContentHandler::runLegacyHooks( 'ShowRawCssJs', [ $this->mNewContent, $this->mNewPage, $out ] ) ) {
+                               if ( ContentHandler::runLegacyHooks( 'ShowRawCssJs', [ $this->mNewContent, $this->mNewPage, $out ], '1.24' ) ) {
                                        // NOTE: deprecated hook, B/C only
                                        // use the content object's own rendering
                                        $cnt = $this->mNewRev->getContent();
@@ -620,7 +617,11 @@ class DifferenceEngine extends ContextSource {
                                }
                        } elseif ( !Hooks::run( 'ArticleContentViewCustom', [ $this->mNewContent, $this->mNewPage, $out ] ) ) {
                                // Handled by extension
-                       } elseif ( !ContentHandler::runLegacyHooks( 'ArticleViewCustom', [ $this->mNewContent, $this->mNewPage, $out ] ) ) {
+                       } elseif ( !ContentHandler::runLegacyHooks(
+                               'ArticleViewCustom',
+                               [ $this->mNewContent, $this->mNewPage, $out ],
+                               '1.21'
+                       ) ) {
                                // NOTE: deprecated hook, B/C only
                                // Handled by extension
                        } else {
@@ -878,6 +879,10 @@ class DifferenceEngine extends ContextSource {
                        return $result;
                };
 
+               /**
+                * @param Status $status
+                * @throws FatalError
+                */
                $error = function( $status ) {
                        throw new FatalError( $status->getWikiText() );
                };
index 296e3b7..9c9b1c9 100644 (file)
@@ -42,7 +42,6 @@ class WordLevelDiff extends \Diff {
         * @param string[] $linesAfter
         */
        public function __construct( $linesBefore, $linesAfter ) {
-
                list( $wordsBefore, $wordsBeforeStripped ) = $this->split( $linesBefore );
                list( $wordsAfter, $wordsAfterStripped ) = $this->split( $linesAfter );
 
@@ -68,7 +67,6 @@ class WordLevelDiff extends \Diff {
                                $yi += count( $closing );
                        }
                }
-
        }
 
        /**
@@ -77,7 +75,6 @@ class WordLevelDiff extends \Diff {
         * @return array[]
         */
        private function split( $lines ) {
-
                $words = [];
                $stripped = [];
                $first = true;
index 5496cb6..e958c94 100644 (file)
@@ -199,7 +199,26 @@ class MWException extends Exception {
         * It will be either HTML or plain text based on isCommandLine().
         */
        public function report() {
-               MWExceptionRenderer::output( $this, MWExceptionRenderer::AS_PRETTY );
+               global $wgMimeType;
+
+               if ( defined( 'MW_API' ) ) {
+                       // Unhandled API exception, we can't be sure that format printer is alive
+                       self::header( 'MediaWiki-API-Error: internal_api_error_' . get_class( $this ) );
+                       wfHttpError( 500, 'Internal Server Error', $this->getText() );
+               } elseif ( self::isCommandLine() ) {
+                       $message = $this->getText();
+                       // T17602: STDERR may not be available
+                       if ( defined( 'STDERR' ) ) {
+                               fwrite( STDERR, $message );
+                       } else {
+                               echo $message;
+                       }
+               } else {
+                       self::statusHeader( 500 );
+                       self::header( "Content-Type: $wgMimeType; charset=utf-8" );
+
+                       $this->reportHTML();
+               }
        }
 
        /**
index 8359846..3d8ddb8 100644 (file)
@@ -62,12 +62,19 @@ class MWExceptionHandler {
        protected static function report( $e ) {
                try {
                        // Try and show the exception prettily, with the normal skin infrastructure
-                       MWExceptionRenderer::output( $e, MWExceptionRenderer::AS_PRETTY );
+                       if ( $e instanceof MWException ) {
+                               // Delegate to MWException until all subclasses are handled by
+                               // MWExceptionRenderer and MWException::report() has been
+                               // removed.
+                               $e->report();
+                       } else {
+                               MWExceptionRenderer::output( $e, MWExceptionRenderer::AS_PRETTY );
+                       }
                } catch ( Exception $e2 ) {
                        // Exception occurred from within exception handler
                        // Show a simpler message for the original exception,
                        // don't try to invoke report()
-                       MWExceptionRenderer::output( $e, MWExceptionRenderer::AS_PRETTY, $e2 );
+                       MWExceptionRenderer::output( $e, MWExceptionRenderer::AS_RAW, $e2 );
                }
        }
 
@@ -80,7 +87,12 @@ class MWExceptionHandler {
         * @param Exception|Throwable $e
         */
        public static function rollbackMasterChangesAndLog( $e ) {
-               $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+               $services = MediaWikiServices::getInstance();
+               if ( $services->isServiceDisabled( 'DBLoadBalancerFactory' ) ) {
+                       return; // T147599
+               }
+
+               $lbFactory = $services->getDBLoadBalancerFactory();
                if ( $lbFactory->hasMasterChanges() ) {
                        $logger = LoggerFactory::getInstance( 'Bug56269' );
                        $logger->warning(
@@ -272,7 +284,7 @@ TXT;
                $trace = $trace ?: debug_backtrace();
                $logger = LoggerFactory::getInstance( 'fatal' );
                $logger->error( $msg, [
-                       'exception' => [
+                       'fatal_exception' => [
                                'class' => 'ErrorException',
                                'message' => "PHP Fatal Error: {$message}",
                                'code' => $level,
index aba131d..8fdc417 100644 (file)
@@ -35,11 +35,6 @@ class MWExceptionRenderer {
        public static function output( $e, $mode, $eNew = null ) {
                global $wgMimeType;
 
-               if ( $e instanceof DBConnectionError ) {
-                       self::reportOutageHTML( $e );
-                       return;
-               }
-
                if ( defined( 'MW_API' ) ) {
                        // Unhandled API exception, we can't be sure that format printer is alive
                        self::header( 'MediaWiki-API-Error: internal_api_error_' . get_class( $e ) );
@@ -47,9 +42,13 @@ class MWExceptionRenderer {
                } elseif ( self::isCommandLine() ) {
                        self::printError( self::getText( $e ) );
                } elseif ( $mode === self::AS_PRETTY ) {
-                       self::statusHeader( 500 );
-                       self::header( "Content-Type: $wgMimeType; charset=utf-8" );
-                       self::reportHTML( $e );
+                       if ( $e instanceof DBConnectionError ) {
+                               self::reportOutageHTML( $e );
+                       } else {
+                               self::statusHeader( 500 );
+                               self::header( "Content-Type: $wgMimeType; charset=utf-8" );
+                               self::reportHTML( $e );
+                       }
                } else {
                        if ( $eNew ) {
                                $message = "MediaWiki internal error.\n\n";
index bd0b120..e31374c 100644 (file)
@@ -29,12 +29,19 @@ class PermissionsError extends ErrorPageError {
        public $permission, $errors;
 
        /**
-        * @param string $permission A permission name.
-        * @param string[] $errors Error message keys
+        * @param string|null $permission A permission name or null if unknown
+        * @param array $errors Error message keys or [key, param...] arrays; must not be empty if
+        *   $permission is null
+        * @throws \InvalidArgumentException
         */
        public function __construct( $permission, $errors = [] ) {
                global $wgLang;
 
+               if ( $permission === null && !$errors ) {
+                       throw new \InvalidArgumentException( __METHOD__ .
+                               ': $permission and $errors cannot both be empty' );
+               }
+
                $this->permission = $permission;
 
                if ( !count( $errors ) ) {
index 42168d7..ab26803 100644 (file)
@@ -51,7 +51,7 @@ class XmlDumpWriter {
                         * you copy in the new xsd file.
                         *
                         * After it is reviewed, merged and deployed (sync-docroot), the index.html needs purging.
-                        * echo "http://www.mediawiki.org/xml/index.html" | mwscript purgeList.php --wiki=aawiki
+                        * echo "https://www.mediawiki.org/xml/index.html" | mwscript purgeList.php --wiki=aawiki
                         */
                        'xsi:schemaLocation' => "http://www.mediawiki.org/xml/export-$ver/ " .
                                "http://www.mediawiki.org/xml/export-$ver.xsd",
index ede73aa..e65a594 100644 (file)
@@ -22,6 +22,7 @@
  * @author Aaron Schulz
  */
 use \MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
 
 /**
  * Class to handle file backend registration
@@ -149,30 +150,11 @@ class FileBackendGroup {
         * @throws InvalidArgumentException
         */
        public function get( $name ) {
-               if ( !isset( $this->backends[$name] ) ) {
-                       throw new InvalidArgumentException( "No backend defined with the name `$name`." );
-               }
                // Lazy-load the actual backend instance
                if ( !isset( $this->backends[$name]['instance'] ) ) {
-                       $class = $this->backends[$name]['class'];
-                       $config = $this->backends[$name]['config'];
-                       $config += [
-                               'wikiId' => wfWikiID(), // e.g. "my_wiki-en_"
-                               'mimeCallback' => [ $this, 'guessMimeInternal' ],
-                               'obResetFunc' => 'wfResetOutputBuffers',
-                               'streamMimeFunc' => [ 'StreamFile', 'contentTypeFromPath' ]
-                       ];
-                       $config['lockManager'] =
-                               LockManagerGroup::singleton( $config['wikiId'] )->get( $config['lockManager'] );
-                       $config['fileJournal'] = isset( $config['fileJournal'] )
-                               ? FileJournal::factory( $config['fileJournal'], $name )
-                               : FileJournal::factory( [ 'class' => 'NullFileJournal' ], $name );
-                       $config['wanCache'] = ObjectCache::getMainWANInstance();
-                       $config['srvCache'] = ObjectCache::getLocalServerInstance( 'hash' );
-                       $config['statusWrapper'] = [ 'Status', 'wrap' ];
-                       $config['tmpDirectory'] = wfTempDir();
-                       $config['logger'] = LoggerFactory::getInstance( 'FileOperation' );
-                       $config['profiler'] = Profiler::instance();
+                       $config = $this->config( $name );
+
+                       $class = $config['class'];
                        if ( $class === 'FileBackendMultiWrite' ) {
                                foreach ( $config['backends'] as $index => $beConfig ) {
                                        if ( isset( $beConfig['template'] ) ) {
@@ -193,7 +175,7 @@ class FileBackendGroup {
         * Get the config array for a backend object with a given name
         *
         * @param string $name
-        * @return array
+        * @return array Parameters to FileBackend::__construct()
         * @throws InvalidArgumentException
         */
        public function config( $name ) {
@@ -202,7 +184,27 @@ class FileBackendGroup {
                }
                $class = $this->backends[$name]['class'];
 
-               return [ 'class' => $class ] + $this->backends[$name]['config'];
+               $config = $this->backends[$name]['config'];
+               $config['class'] = $class;
+               $config += [ // set defaults
+                       'wikiId' => wfWikiID(), // e.g. "my_wiki-en_"
+                       'mimeCallback' => [ $this, 'guessMimeInternal' ],
+                       'obResetFunc' => 'wfResetOutputBuffers',
+                       'streamMimeFunc' => [ 'StreamFile', 'contentTypeFromPath' ],
+                       'tmpDirectory' => wfTempDir(),
+                       'statusWrapper' => [ 'Status', 'wrap' ],
+                       'wanCache' => MediaWikiServices::getInstance()->getMainWANObjectCache(),
+                       'srvCache' => ObjectCache::getLocalServerInstance( 'hash' ),
+                       'logger' => LoggerFactory::getInstance( 'FileOperation' ),
+                       'profiler' => Profiler::instance()
+               ];
+               $config['lockManager'] =
+                       LockManagerGroup::singleton( $config['wikiId'] )->get( $config['lockManager'] );
+               $config['fileJournal'] = isset( $config['fileJournal'] )
+                       ? FileJournal::factory( $config['fileJournal'], $name )
+                       : FileJournal::factory( [ 'class' => 'NullFileJournal' ], $name );
+
+               return $config;
        }
 
        /**
diff --git a/includes/filebackend/lockmanager/MemcLockManager.php b/includes/filebackend/lockmanager/MemcLockManager.php
deleted file mode 100644 (file)
index 81ce424..0000000
+++ /dev/null
@@ -1,386 +0,0 @@
-<?php
-/**
- * Version of LockManager based on using memcached servers.
- *
- * 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 LockManager
- */
-
-/**
- * Manage locks using memcached servers.
- *
- * Version of LockManager based on using memcached servers.
- * This is meant for multi-wiki systems that may share files.
- * All locks are non-blocking, which avoids deadlocks.
- *
- * All lock requests for a resource, identified by a hash string, will map to one
- * bucket. Each bucket maps to one or several peer servers, each running memcached.
- * A majority of peers must agree for a lock to be acquired.
- *
- * @ingroup LockManager
- * @since 1.20
- */
-class MemcLockManager extends QuorumLockManager {
-       /** @var array Mapping of lock types to the type actually used */
-       protected $lockTypeMap = [
-               self::LOCK_SH => self::LOCK_SH,
-               self::LOCK_UW => self::LOCK_SH,
-               self::LOCK_EX => self::LOCK_EX
-       ];
-
-       /** @var array Map server names to MemcachedBagOStuff objects */
-       protected $bagOStuffs = [];
-
-       /** @var array (server name => bool) */
-       protected $serversUp = [];
-
-       /** @var string Random UUID */
-       protected $session = '';
-
-       /**
-        * Construct a new instance from configuration.
-        *
-        * @param array $config Parameters include:
-        *   - lockServers  : Associative array of server names to "<IP>:<port>" strings.
-        *   - srvsByBucket : Array of 1-16 consecutive integer keys, starting from 0,
-        *                    each having an odd-numbered list of server names (peers) as values.
-        *   - memcConfig   : Configuration array for ObjectCache::newFromParams. [optional]
-        *                    If set, this must use one of the memcached classes.
-        * @throws Exception
-        */
-       public function __construct( array $config ) {
-               parent::__construct( $config );
-
-               // Sanitize srvsByBucket config to prevent PHP errors
-               $this->srvsByBucket = array_filter( $config['srvsByBucket'], 'is_array' );
-               $this->srvsByBucket = array_values( $this->srvsByBucket ); // consecutive
-
-               $memcConfig = isset( $config['memcConfig'] )
-                       ? $config['memcConfig']
-                       : [ 'class' => 'MemcachedPhpBagOStuff' ];
-
-               foreach ( $config['lockServers'] as $name => $address ) {
-                       $params = [ 'servers' => [ $address ] ] + $memcConfig;
-                       $cache = ObjectCache::newFromParams( $params );
-                       if ( $cache instanceof MemcachedBagOStuff ) {
-                               $this->bagOStuffs[$name] = $cache;
-                       } else {
-                               throw new Exception(
-                                       'Only MemcachedBagOStuff classes are supported by MemcLockManager.' );
-                       }
-               }
-
-               $this->session = wfRandomString( 32 );
-       }
-
-       // @todo Change this code to work in one batch
-       protected function getLocksOnServer( $lockSrv, array $pathsByType ) {
-               $status = StatusValue::newGood();
-
-               $lockedPaths = [];
-               foreach ( $pathsByType as $type => $paths ) {
-                       $status->merge( $this->doGetLocksOnServer( $lockSrv, $paths, $type ) );
-                       if ( $status->isOK() ) {
-                               $lockedPaths[$type] = isset( $lockedPaths[$type] )
-                                       ? array_merge( $lockedPaths[$type], $paths )
-                                       : $paths;
-                       } else {
-                               foreach ( $lockedPaths as $lType => $lPaths ) {
-                                       $status->merge( $this->doFreeLocksOnServer( $lockSrv, $lPaths, $lType ) );
-                               }
-                               break;
-                       }
-               }
-
-               return $status;
-       }
-
-       // @todo Change this code to work in one batch
-       protected function freeLocksOnServer( $lockSrv, array $pathsByType ) {
-               $status = StatusValue::newGood();
-
-               foreach ( $pathsByType as $type => $paths ) {
-                       $status->merge( $this->doFreeLocksOnServer( $lockSrv, $paths, $type ) );
-               }
-
-               return $status;
-       }
-
-       /**
-        * @see QuorumLockManager::getLocksOnServer()
-        * @param string $lockSrv
-        * @param array $paths
-        * @param string $type
-        * @return StatusValue
-        */
-       protected function doGetLocksOnServer( $lockSrv, array $paths, $type ) {
-               $status = StatusValue::newGood();
-
-               $memc = $this->getCache( $lockSrv );
-               $keys = array_map( [ $this, 'recordKeyForPath' ], $paths ); // lock records
-
-               // Lock all of the active lock record keys...
-               if ( !$this->acquireMutexes( $memc, $keys ) ) {
-                       foreach ( $paths as $path ) {
-                               $status->fatal( 'lockmanager-fail-acquirelock', $path );
-                       }
-
-                       return $status;
-               }
-
-               // Fetch all the existing lock records...
-               $lockRecords = $memc->getMulti( $keys );
-
-               $now = time();
-               // Check if the requested locks conflict with existing ones...
-               foreach ( $paths as $path ) {
-                       $locksKey = $this->recordKeyForPath( $path );
-                       $locksHeld = isset( $lockRecords[$locksKey] )
-                               ? self::sanitizeLockArray( $lockRecords[$locksKey] )
-                               : self::newLockArray(); // init
-                       foreach ( $locksHeld[self::LOCK_EX] as $session => $expiry ) {
-                               if ( $expiry < $now ) { // stale?
-                                       unset( $locksHeld[self::LOCK_EX][$session] );
-                               } elseif ( $session !== $this->session ) {
-                                       $status->fatal( 'lockmanager-fail-acquirelock', $path );
-                               }
-                       }
-                       if ( $type === self::LOCK_EX ) {
-                               foreach ( $locksHeld[self::LOCK_SH] as $session => $expiry ) {
-                                       if ( $expiry < $now ) { // stale?
-                                               unset( $locksHeld[self::LOCK_SH][$session] );
-                                       } elseif ( $session !== $this->session ) {
-                                               $status->fatal( 'lockmanager-fail-acquirelock', $path );
-                                       }
-                               }
-                       }
-                       if ( $status->isOK() ) {
-                               // Register the session in the lock record array
-                               $locksHeld[$type][$this->session] = $now + $this->lockTTL;
-                               // We will update this record if none of the other locks conflict
-                               $lockRecords[$locksKey] = $locksHeld;
-                       }
-               }
-
-               // If there were no lock conflicts, update all the lock records...
-               if ( $status->isOK() ) {
-                       foreach ( $paths as $path ) {
-                               $locksKey = $this->recordKeyForPath( $path );
-                               $locksHeld = $lockRecords[$locksKey];
-                               $ok = $memc->set( $locksKey, $locksHeld, 7 * 86400 );
-                               if ( !$ok ) {
-                                       $status->fatal( 'lockmanager-fail-acquirelock', $path );
-                               } else {
-                                       wfDebug( __METHOD__ . ": acquired lock on key $locksKey.\n" );
-                               }
-                       }
-               }
-
-               // Unlock all of the active lock record keys...
-               $this->releaseMutexes( $memc, $keys );
-
-               return $status;
-       }
-
-       /**
-        * @see QuorumLockManager::freeLocksOnServer()
-        * @param string $lockSrv
-        * @param array $paths
-        * @param string $type
-        * @return StatusValue
-        */
-       protected function doFreeLocksOnServer( $lockSrv, array $paths, $type ) {
-               $status = StatusValue::newGood();
-
-               $memc = $this->getCache( $lockSrv );
-               $keys = array_map( [ $this, 'recordKeyForPath' ], $paths ); // lock records
-
-               // Lock all of the active lock record keys...
-               if ( !$this->acquireMutexes( $memc, $keys ) ) {
-                       foreach ( $paths as $path ) {
-                               $status->fatal( 'lockmanager-fail-releaselock', $path );
-                       }
-
-                       return $status;
-               }
-
-               // Fetch all the existing lock records...
-               $lockRecords = $memc->getMulti( $keys );
-
-               // Remove the requested locks from all records...
-               foreach ( $paths as $path ) {
-                       $locksKey = $this->recordKeyForPath( $path ); // lock record
-                       if ( !isset( $lockRecords[$locksKey] ) ) {
-                               $status->warning( 'lockmanager-fail-releaselock', $path );
-                               continue; // nothing to do
-                       }
-                       $locksHeld = self::sanitizeLockArray( $lockRecords[$locksKey] );
-                       if ( isset( $locksHeld[$type][$this->session] ) ) {
-                               unset( $locksHeld[$type][$this->session] ); // unregister this session
-                               if ( $locksHeld === self::newLockArray() ) {
-                                       $ok = $memc->delete( $locksKey );
-                               } else {
-                                       $ok = $memc->set( $locksKey, $locksHeld );
-                               }
-                               if ( !$ok ) {
-                                       $status->fatal( 'lockmanager-fail-releaselock', $path );
-                               }
-                       } else {
-                               $status->warning( 'lockmanager-fail-releaselock', $path );
-                       }
-                       wfDebug( __METHOD__ . ": released lock on key $locksKey.\n" );
-               }
-
-               // Unlock all of the active lock record keys...
-               $this->releaseMutexes( $memc, $keys );
-
-               return $status;
-       }
-
-       /**
-        * @see QuorumLockManager::releaseAllLocks()
-        * @return StatusValue
-        */
-       protected function releaseAllLocks() {
-               return StatusValue::newGood(); // not supported
-       }
-
-       /**
-        * @see QuorumLockManager::isServerUp()
-        * @param string $lockSrv
-        * @return bool
-        */
-       protected function isServerUp( $lockSrv ) {
-               return (bool)$this->getCache( $lockSrv );
-       }
-
-       /**
-        * Get the MemcachedBagOStuff object for a $lockSrv
-        *
-        * @param string $lockSrv Server name
-        * @return MemcachedBagOStuff|null
-        */
-       protected function getCache( $lockSrv ) {
-               /** @var BagOStuff $memc */
-               $memc = null;
-               if ( isset( $this->bagOStuffs[$lockSrv] ) ) {
-                       $memc = $this->bagOStuffs[$lockSrv];
-                       if ( !isset( $this->serversUp[$lockSrv] ) ) {
-                               $this->serversUp[$lockSrv] = $memc->set( __CLASS__ . ':ping', 1, 1 );
-                               if ( !$this->serversUp[$lockSrv] ) {
-                                       trigger_error( __METHOD__ . ": Could not contact $lockSrv.", E_USER_WARNING );
-                               }
-                       }
-                       if ( !$this->serversUp[$lockSrv] ) {
-                               return null; // server appears to be down
-                       }
-               }
-
-               return $memc;
-       }
-
-       /**
-        * @param string $path
-        * @return string
-        */
-       protected function recordKeyForPath( $path ) {
-               return implode( ':', [ __CLASS__, 'locks', $this->sha1Base36Absolute( $path ) ] );
-       }
-
-       /**
-        * @return array An empty lock structure for a key
-        */
-       protected static function newLockArray() {
-               return [ self::LOCK_SH => [], self::LOCK_EX => [] ];
-       }
-
-       /**
-        * @param array $a
-        * @return array An empty lock structure for a key
-        */
-       protected static function sanitizeLockArray( $a ) {
-               if ( is_array( $a ) && isset( $a[self::LOCK_EX] ) && isset( $a[self::LOCK_SH] ) ) {
-                       return $a;
-               } else {
-                       trigger_error( __METHOD__ . ": reset invalid lock array.", E_USER_WARNING );
-
-                       return self::newLockArray();
-               }
-       }
-
-       /**
-        * @param MemcachedBagOStuff $memc
-        * @param array $keys List of keys to acquire
-        * @return bool
-        */
-       protected function acquireMutexes( MemcachedBagOStuff $memc, array $keys ) {
-               $lockedKeys = [];
-
-               // Acquire the keys in lexicographical order, to avoid deadlock problems.
-               // If P1 is waiting to acquire a key P2 has, P2 can't also be waiting for a key P1 has.
-               sort( $keys );
-
-               // Try to quickly loop to acquire the keys, but back off after a few rounds.
-               // This reduces memcached spam, especially in the rare case where a server acquires
-               // some lock keys and dies without releasing them. Lock keys expire after a few minutes.
-               $loop = new WaitConditionLoop(
-                       function () use ( $memc, $keys, &$lockedKeys ) {
-                               foreach ( array_diff( $keys, $lockedKeys ) as $key ) {
-                                       if ( $memc->add( "$key:mutex", 1, 180 ) ) { // lock record
-                                               $lockedKeys[] = $key;
-                                       }
-                               }
-
-                               return array_diff( $keys, $lockedKeys )
-                                       ? WaitConditionLoop::CONDITION_CONTINUE
-                                       : true;
-                       },
-                       3.0 // timeout
-               );
-               $loop->invoke();
-
-               if ( count( $lockedKeys ) != count( $keys ) ) {
-                       $this->releaseMutexes( $memc, $lockedKeys ); // failed; release what was locked
-                       return false;
-               }
-
-               return true;
-       }
-
-       /**
-        * @param MemcachedBagOStuff $memc
-        * @param array $keys List of acquired keys
-        */
-       protected function releaseMutexes( MemcachedBagOStuff $memc, array $keys ) {
-               foreach ( $keys as $key ) {
-                       $memc->delete( "$key:mutex" );
-               }
-       }
-
-       /**
-        * Make sure remaining locks get cleared for sanity
-        */
-       function __destruct() {
-               while ( count( $this->locksHeld ) ) {
-                       foreach ( $this->locksHeld as $path => $locks ) {
-                               $this->doUnlock( [ $path ], self::LOCK_EX );
-                               $this->doUnlock( [ $path ], self::LOCK_SH );
-                       }
-               }
-       }
-}
index fc23f76..5936e7d 100644 (file)
@@ -34,7 +34,7 @@ class MySqlLockManager extends DBLockManager {
 
        /**
         * Get a connection to a lock DB and acquire locks on $paths.
-        * This does not use GET_LOCK() per http://bugs.mysql.com/bug.php?id=1118.
+        * This does not use GET_LOCK() per https://bugs.mysql.com/bug.php?id=1118.
         *
         * @see DBLockManager::getLocksOnServer()
         * @param string $lockSrv
index 1a6c818..66dab99 100644 (file)
@@ -393,7 +393,7 @@ class FileRepo {
                        if ( $this->oldFileFactory ) {
                                return call_user_func( $this->oldFileFactory, $title, $this, $time );
                        } else {
-                               return false;
+                               return null;
                        }
                } else {
                        return call_user_func( $this->fileFactory, $title, $this );
@@ -818,7 +818,7 @@ class FileRepo {
         *   self::OVERWRITE_SAME    Overwrite the file if the destination exists and has the
         *                           same contents as the source
         *   self::SKIP_LOCKING      Skip any file locking when doing the store
-        * @return FileRepoStatus
+        * @return Status
         */
        public function store( $srcPath, $dstZone, $dstRel, $flags = 0 ) {
                $this->assertWritableRepo(); // fail out if read-only
@@ -841,7 +841,7 @@ class FileRepo {
         *                           same contents as the source
         *   self::SKIP_LOCKING      Skip any file locking when doing the store
         * @throws MWException
-        * @return FileRepoStatus
+        * @return Status
         */
        public function storeBatch( array $triplets, $flags = 0 ) {
                $this->assertWritableRepo(); // fail out if read-only
@@ -912,7 +912,7 @@ class FileRepo {
         * @param array $files List of files to delete
         * @param int $flags Bitwise combination of the following flags:
         *   self::SKIP_LOCKING      Skip any file locking when doing the deletions
-        * @return FileRepoStatus
+        * @return Status
         */
        public function cleanupBatch( array $files, $flags = 0 ) {
                $this->assertWritableRepo(); // fail out if read-only
@@ -952,7 +952,7 @@ class FileRepo {
         * @param array|string|null $options An array consisting of a key named headers
         *   listing extra headers. If a string, taken as content-disposition header.
         *   (Support for array of options new in 1.23)
-        * @return FileRepoStatus
+        * @return Status
         */
        final public function quickImport( $src, $dst, $options = null ) {
                return $this->quickImportBatch( [ [ $src, $dst, $options ] ] );
@@ -964,7 +964,7 @@ class FileRepo {
         * This is intended for purging thumbnails.
         *
         * @param string $path Virtual URL or storage path
-        * @return FileRepoStatus
+        * @return Status
         */
        final public function quickPurge( $path ) {
                return $this->quickPurgeBatch( [ $path ] );
@@ -995,7 +995,7 @@ class FileRepo {
         * When "headers" are given they are used as HTTP headers if supported.
         *
         * @param array $triples List of (source path or FSFile, destination path, disposition)
-        * @return FileRepoStatus
+        * @return Status
         */
        public function quickImportBatch( array $triples ) {
                $status = $this->newGood();
@@ -1040,7 +1040,7 @@ class FileRepo {
         * This does no locking nor journaling and is intended for purging thumbnails.
         *
         * @param array $paths List of virtual URLs or storage paths
-        * @return FileRepoStatus
+        * @return Status
         */
        public function quickPurgeBatch( array $paths ) {
                $status = $this->newGood();
@@ -1065,7 +1065,7 @@ class FileRepo {
         * @param string $originalName The base name of the file as specified
         *   by the user. The file extension will be maintained.
         * @param string $srcPath The current location of the file.
-        * @return FileRepoStatus Object with the URL in the value.
+        * @return Status Object with the URL in the value.
         */
        public function storeTemp( $originalName, $srcPath ) {
                $this->assertWritableRepo(); // fail out if read-only
@@ -1107,7 +1107,7 @@ class FileRepo {
         * @param string $dstPath Target file system path
         * @param int $flags Bitwise combination of the following flags:
         *   self::DELETE_SOURCE     Delete the source files on success
-        * @return FileRepoStatus
+        * @return Status
         */
        public function concatenate( array $srcPaths, $dstPath, $flags = 0 ) {
                $this->assertWritableRepo(); // fail out if read-only
@@ -1156,7 +1156,7 @@ class FileRepo {
         * @param int $flags Bitfield, may be FileRepo::DELETE_SOURCE to indicate
         *   that the source file should be deleted if possible
         * @param array $options Optional additional parameters
-        * @return FileRepoStatus
+        * @return Status
         */
        public function publish(
                $src, $dstRel, $archiveRel, $flags = 0, array $options = []
@@ -1185,7 +1185,7 @@ class FileRepo {
         * @param int $flags Bitfield, may be FileRepo::DELETE_SOURCE to indicate
         *   that the source files should be deleted if possible
         * @throws MWException
-        * @return FileRepoStatus
+        * @return Status
         */
        public function publishBatch( array $ntuples, $flags = 0 ) {
                $this->assertWritableRepo(); // fail out if read-only
@@ -1322,7 +1322,10 @@ class FileRepo {
                        $params = [ 'noAccess' => true, 'noListing' => true ] + $params;
                }
 
-               return $this->backend->prepare( $params );
+               $status = $this->newGood();
+               $status->merge( $this->backend->prepare( $params ) );
+
+               return $status;
        }
 
        /**
@@ -1380,7 +1383,7 @@ class FileRepo {
         * @param mixed $srcRel Relative path for the file to be deleted
         * @param mixed $archiveRel Relative path for the archive location.
         *   Relative to a private archive directory.
-        * @return FileRepoStatus
+        * @return Status
         */
        public function delete( $srcRel, $archiveRel ) {
                $this->assertWritableRepo(); // fail out if read-only
@@ -1403,7 +1406,7 @@ class FileRepo {
         *   public root in the first element, and the archive file path relative
         *   to the deleted zone root in the second element.
         * @throws MWException
-        * @return FileRepoStatus
+        * @return Status
         */
        public function deleteBatch( array $sourceDestPairs ) {
                $this->assertWritableRepo(); // fail out if read-only
@@ -1599,7 +1602,10 @@ class FileRepo {
                $path = $this->resolveToStoragePath( $virtualUrl );
                $params = [ 'src' => $path, 'headers' => $headers, 'options' => $optHeaders ];
 
-               return $this->backend->streamFile( $params );
+               $status = $this->newGood();
+               $status->merge( $this->backend->streamFile( $params ) );
+
+               return $status;
        }
 
        /**
index be046bd..f49ef88 100644 (file)
@@ -51,9 +51,12 @@ class ForeignDBRepo extends LocalRepo {
        /** @var bool */
        protected $hasSharedCache;
 
-       # Other stuff
+       /** @var IDatabase */
        protected $dbConn;
+
+       /** @var callable */
        protected $fileFactory = [ 'ForeignDBFile', 'newFromTitle' ];
+       /** @var callable */
        protected $fileFromRowFactory = [ 'ForeignDBFile', 'newFromRow' ];
 
        /**
@@ -86,7 +89,7 @@ class ForeignDBRepo extends LocalRepo {
        /**
         * @return IDatabase
         */
-       function getSlaveDB() {
+       function getReplicaDB() {
                return $this->getMasterDB();
        }
 
index 55df1af..a9cd030 100644 (file)
@@ -59,23 +59,22 @@ class ForeignDBViaLBRepo extends LocalRepo {
         * @return IDatabase
         */
        function getMasterDB() {
-               return wfGetDB( DB_MASTER, [], $this->wiki );
+               return wfGetLB( $this->wiki )->getConnectionRef( DB_MASTER, [], $this->wiki );
        }
 
        /**
         * @return IDatabase
         */
-       function getSlaveDB() {
-               return wfGetDB( DB_REPLICA, [], $this->wiki );
+       function getReplicaDB() {
+               return wfGetLB( $this->wiki )->getConnectionRef( DB_REPLICA, [], $this->wiki );
        }
 
        /**
         * @return Closure
         */
        protected function getDBFactory() {
-               $wiki = $this->wiki;
-               return function( $index ) use ( $wiki ) {
-                       return wfGetDB( $index, [], $wiki );
+               return function( $index ) {
+                       return wfGetLB( $this->wiki )->getConnectionRef( $index, [], $this->wiki );
                };
        }
 
index 7b40a7b..d49ae7b 100644 (file)
  * @ingroup FileRepo
  */
 class LocalRepo extends FileRepo {
-       /** @var array */
+       /** @var callable */
        protected $fileFactory = [ 'LocalFile', 'newFromTitle' ];
-
-       /** @var array */
+       /** @var callable */
        protected $fileFactoryKey = [ 'LocalFile', 'newFromKey' ];
-
-       /** @var array */
+       /** @var callable */
        protected $fileFromRowFactory = [ 'LocalFile', 'newFromRow' ];
-
-       /** @var array */
+       /** @var callable */
        protected $oldFileFromRowFactory = [ 'OldLocalFile', 'newFromRow' ];
-
-       /** @var array */
+       /** @var callable */
        protected $oldFileFactory = [ 'OldLocalFile', 'newFromTitle' ];
-
-       /** @var array */
+       /** @var callable */
        protected $oldFileFactoryKey = [ 'OldLocalFile', 'newFromKey' ];
 
        function __construct( array $info = null ) {
                parent::__construct( $info );
 
-               $this->hasSha1Storage = isset( $info['storageLayout'] ) && $info['storageLayout'] === 'sha1';
+               $this->hasSha1Storage = isset( $info['storageLayout'] )
+                       && $info['storageLayout'] === 'sha1';
 
                if ( $this->hasSha1Storage() ) {
                        $this->backend = new FileBackendDBRepoWrapper( [
@@ -93,7 +89,7 @@ class LocalRepo extends FileRepo {
         *
         * @param array $storageKeys
         *
-        * @return FileRepoStatus
+        * @return Status
         */
        function cleanupDeletedBatch( array $storageKeys ) {
                if ( $this->hasSha1Storage() ) {
@@ -199,12 +195,12 @@ class LocalRepo extends FileRepo {
                        $expiry = 86400; // has invalidation, 1 day
                }
 
-               $that = $this;
+               $method = __METHOD__;
                $redirDbKey = ObjectCache::getMainWANInstance()->getWithSetCallback(
                        $memcKey,
                        $expiry,
-                       function ( $oldValue, &$ttl, array &$setOpts ) use ( $that, $title ) {
-                               $dbr = $that->getSlaveDB(); // possibly remote DB
+                       function ( $oldValue, &$ttl, array &$setOpts ) use ( $method, $title ) {
+                               $dbr = $this->getReplicaDB(); // possibly remote DB
 
                                $setOpts += Database::getCacheSetOptions( $dbr );
 
@@ -217,7 +213,7 @@ class LocalRepo extends FileRepo {
                                                        'page_title' => $title->getDBkey(),
                                                        'rd_from = page_id'
                                                ],
-                                               __METHOD__
+                                               $method
                                        );
                                } else {
                                        $row = false;
@@ -302,7 +298,7 @@ class LocalRepo extends FileRepo {
                        }
                };
 
-               $dbr = $this->getSlaveDB();
+               $dbr = $this->getReplicaDB();
 
                // Query image table
                $imgNames = [];
@@ -372,7 +368,7 @@ class LocalRepo extends FileRepo {
         * @return File[]
         */
        function findBySha1( $hash ) {
-               $dbr = $this->getSlaveDB();
+               $dbr = $this->getReplicaDB();
                $res = $dbr->select(
                        'image',
                        LocalFile::selectFields(),
@@ -404,7 +400,7 @@ class LocalRepo extends FileRepo {
                        return []; // empty parameter
                }
 
-               $dbr = $this->getSlaveDB();
+               $dbr = $this->getReplicaDB();
                $res = $dbr->select(
                        'image',
                        LocalFile::selectFields(),
@@ -434,7 +430,7 @@ class LocalRepo extends FileRepo {
                $selectOptions = [ 'ORDER BY' => 'img_name', 'LIMIT' => intval( $limit ) ];
 
                // Query database
-               $dbr = $this->getSlaveDB();
+               $dbr = $this->getReplicaDB();
                $res = $dbr->select(
                        'image',
                        LocalFile::selectFields(),
@@ -454,15 +450,25 @@ class LocalRepo extends FileRepo {
 
        /**
         * Get a connection to the replica DB
-        * @return DatabaseBase
+        * @return IDatabase
         */
-       function getSlaveDB() {
+       function getReplicaDB() {
                return wfGetDB( DB_REPLICA );
        }
 
+       /**
+        * Alias for getReplicaDB()
+        *
+        * @return IDatabase
+        * @deprecated Since 1.29
+        */
+       function getSlaveDB() {
+               return $this->getReplicaDB();
+       }
+
        /**
         * Get a connection to the master DB
-        * @return DatabaseBase
+        * @return IDatabase
         */
        function getMasterDB() {
                return wfGetDB( DB_MASTER );
@@ -562,7 +568,7 @@ class LocalRepo extends FileRepo {
         *
         * @param string $function
         * @param array $args
-        * @return FileRepoStatus
+        * @return Status
         */
        protected function skipWriteOperationIfSha1( $function, array $args ) {
                $this->assertWritableRepo(); // fail out if read-only
index c48866b..c1d5573 100644 (file)
@@ -1805,7 +1805,7 @@ abstract class File implements IDBAccessObject {
         * @param int $flags A bitwise combination of:
         *   File::DELETE_SOURCE    Delete the source file, i.e. move rather than copy
         * @param array $options Optional additional parameters
-        * @return FileRepoStatus On success, the value member contains the
+        * @return Status On success, the value member contains the
         *   archive name, or an empty string if it was a new file.
         *
         * STUB
@@ -1905,7 +1905,7 @@ abstract class File implements IDBAccessObject {
         * and logging are caller's responsibility
         *
         * @param Title $target New file name
-        * @return FileRepoStatus
+        * @return Status
         */
        function move( $target ) {
                $this->readOnlyError();
@@ -1922,7 +1922,7 @@ abstract class File implements IDBAccessObject {
         * @param string $reason
         * @param bool $suppress Hide content from sysops?
         * @param User|null $user
-        * @return FileRepoStatus
+        * @return Status
         * STUB
         * Overridden by LocalFile
         */
index cf0045e..df50a67 100644 (file)
@@ -57,7 +57,7 @@ class ForeignDBFile extends LocalFile {
         * @param string $srcPath
         * @param int $flags
         * @param array $options
-        * @return FileRepoStatus
+        * @return Status
         * @throws MWException
         */
        function publish( $srcPath, $flags = 0, array $options = [] ) {
@@ -84,7 +84,7 @@ class ForeignDBFile extends LocalFile {
        /**
         * @param array $versions
         * @param bool $unsuppress
-        * @return FileRepoStatus
+        * @return Status
         * @throws MWException
         */
        function restore( $versions = [], $unsuppress = false ) {
@@ -95,7 +95,7 @@ class ForeignDBFile extends LocalFile {
         * @param string $reason
         * @param bool $suppress
         * @param User|null $user
-        * @return FileRepoStatus
+        * @return Status
         * @throws MWException
         */
        function delete( $reason, $suppress = false, $user = null ) {
@@ -104,7 +104,7 @@ class ForeignDBFile extends LocalFile {
 
        /**
         * @param Title $target
-        * @return FileRepoStatus
+        * @return Status
         * @throws MWException
         */
        function move( $target ) {
@@ -136,7 +136,7 @@ class ForeignDBFile extends LocalFile {
                        return false;
                }
 
-               $touched = $this->repo->getSlaveDB()->selectField(
+               $touched = $this->repo->getReplicaDB()->selectField(
                        'page',
                        'page_touched',
                        [
@@ -179,7 +179,7 @@ class ForeignDBFile extends LocalFile {
         * @since 1.27
         */
        public function getDescriptionShortUrl() {
-               $dbr = $this->repo->getSlaveDB();
+               $dbr = $this->repo->getReplicaDB();
                $pageId = $dbr->selectField(
                        'page',
                        'page_id',
index 7ffb147..011ba87 100644 (file)
@@ -174,7 +174,7 @@ class LocalFile extends File {
         * @return bool|LocalFile
         */
        static function newFromKey( $sha1, $repo, $timestamp = false ) {
-               $dbr = $repo->getSlaveDB();
+               $dbr = $repo->getReplicaDB();
 
                $conds = [ 'img_sha1' => $sha1 ];
                if ( $timestamp ) {
@@ -259,7 +259,7 @@ class LocalFile extends File {
                        $key,
                        $cache::TTL_WEEK,
                        function ( $oldValue, &$ttl, array &$setOpts ) use ( $cache ) {
-                               $setOpts += Database::getCacheSetOptions( $this->repo->getSlaveDB() );
+                               $setOpts += Database::getCacheSetOptions( $this->repo->getReplicaDB() );
 
                                $this->loadFromDB( self::READ_NORMAL );
 
@@ -390,7 +390,7 @@ class LocalFile extends File {
 
                $dbr = ( $flags & self::READ_LATEST )
                        ? $this->repo->getMasterDB()
-                       : $this->repo->getSlaveDB();
+                       : $this->repo->getReplicaDB();
 
                $row = $dbr->selectRow( 'image', $this->getCacheFields( 'img_' ),
                        [ 'img_name' => $this->getName() ], $fname );
@@ -412,7 +412,7 @@ class LocalFile extends File {
                # Unconditionally set loaded=true, we don't want the accessors constantly rechecking
                $this->extraDataLoaded = true;
 
-               $fieldMap = $this->loadFieldsWithTimestamp( $this->repo->getSlaveDB(), $fname );
+               $fieldMap = $this->loadFieldsWithTimestamp( $this->repo->getReplicaDB(), $fname );
                if ( !$fieldMap ) {
                        $fieldMap = $this->loadFieldsWithTimestamp( $this->repo->getMasterDB(), $fname );
                }
@@ -490,7 +490,7 @@ class LocalFile extends File {
 
                $decoded['timestamp'] = wfTimestamp( TS_MW, $decoded['timestamp'] );
 
-               $decoded['metadata'] = $this->repo->getSlaveDB()->decodeBlob( $decoded['metadata'] );
+               $decoded['metadata'] = $this->repo->getReplicaDB()->decodeBlob( $decoded['metadata'] );
 
                if ( empty( $decoded['major_mime'] ) ) {
                        $decoded['mime'] = 'unknown/unknown';
@@ -1037,7 +1037,7 @@ class LocalFile extends File {
         * @return OldLocalFile[]
         */
        function getHistory( $limit = null, $start = null, $end = null, $inc = true ) {
-               $dbr = $this->repo->getSlaveDB();
+               $dbr = $this->repo->getReplicaDB();
                $tables = [ 'oldimage' ];
                $fields = OldLocalFile::selectFields();
                $conds = $opts = $join_conds = [];
@@ -1091,7 +1091,7 @@ class LocalFile extends File {
                # Polymorphic function name to distinguish foreign and local fetches
                $fname = get_class( $this ) . '::' . __FUNCTION__;
 
-               $dbr = $this->repo->getSlaveDB();
+               $dbr = $this->repo->getReplicaDB();
 
                if ( $this->historyLine == 0 ) { // called for the first time, return line from cur
                        $this->historyRes = $dbr->select( 'image',
@@ -1160,7 +1160,7 @@ class LocalFile extends File {
         * @param User|null $user User object or null to use $wgUser
         * @param string[] $tags Change tags to add to the log entry and page revision.
         *   (This doesn't check $user's permissions.)
-        * @return FileRepoStatus On success, the value member contains the
+        * @return Status On success, the value member contains the
         *     archive name, or an empty string if it was a new file.
         */
        function upload( $src, $comment, $pageText, $flags = 0, $props = false,
@@ -1582,7 +1582,7 @@ class LocalFile extends File {
         * @param int $flags A bitwise combination of:
         *     File::DELETE_SOURCE    Delete the source file, i.e. move rather than copy
         * @param array $options Optional additional parameters
-        * @return FileRepoStatus On success, the value member contains the
+        * @return Status On success, the value member contains the
         *     archive name, or an empty string if it was a new file.
         */
        function publish( $src, $flags = 0, array $options = [] ) {
@@ -1601,7 +1601,7 @@ class LocalFile extends File {
         * @param int $flags A bitwise combination of:
         *     File::DELETE_SOURCE    Delete the source file, i.e. move rather than copy
         * @param array $options Optional additional parameters
-        * @return FileRepoStatus On success, the value member contains the
+        * @return Status On success, the value member contains the
         *     archive name, or an empty string if it was a new file.
         */
        function publishTo( $src, $dstRel, $flags = 0, array $options = [] ) {
@@ -1663,7 +1663,7 @@ class LocalFile extends File {
         * and logging are caller's responsibility
         *
         * @param Title $target New file name
-        * @return FileRepoStatus
+        * @return Status
         */
        function move( $target ) {
                if ( $this->getRepo()->getReadOnlyReason() !== false ) {
@@ -1722,7 +1722,7 @@ class LocalFile extends File {
         * @param string $reason
         * @param bool $suppress
         * @param User|null $user
-        * @return FileRepoStatus
+        * @return Status
         */
        function delete( $reason, $suppress = false, $user = null ) {
                if ( $this->getRepo()->getReadOnlyReason() !== false ) {
@@ -1780,7 +1780,7 @@ class LocalFile extends File {
         * @param bool $suppress
         * @param User|null $user
         * @throws MWException Exception on database or file store failure
-        * @return FileRepoStatus
+        * @return Status
         */
        function deleteOld( $archiveName, $reason, $suppress = false, $user = null ) {
                if ( $this->getRepo()->getReadOnlyReason() !== false ) {
@@ -1816,7 +1816,7 @@ class LocalFile extends File {
         * @param array $versions Set of record ids of deleted items to restore,
         *   or empty to restore all revisions.
         * @param bool $unsuppress
-        * @return FileRepoStatus
+        * @return Status
         */
        function restore( $versions = [], $unsuppress = false ) {
                if ( $this->getRepo()->getReadOnlyReason() !== false ) {
@@ -1917,7 +1917,7 @@ class LocalFile extends File {
                                'page_namespace' => $this->title->getNamespace(),
                                'page_title' => $this->title->getDBkey()
                        ];
-                       $touched = $this->repo->getSlaveDB()->selectField( 'page', 'page_touched', $cond, __METHOD__ );
+                       $touched = $this->repo->getReplicaDB()->selectField( 'page', 'page_touched', $cond, __METHOD__ );
                        $this->descriptionTouched = $touched ? wfTimestamp( TS_MW, $touched ) : false;
                }
 
@@ -2234,12 +2234,7 @@ class LocalFileDeleteBatch {
 
                // Bitfields to further suppress the content
                if ( $this->suppress ) {
-                       $bitfield = 0;
-                       // This should be 15...
-                       $bitfield |= Revision::DELETED_TEXT;
-                       $bitfield |= Revision::DELETED_COMMENT;
-                       $bitfield |= Revision::DELETED_USER;
-                       $bitfield |= Revision::DELETED_RESTRICTED;
+                       $bitfield = Revision::SUPPRESSED_ALL;
                } else {
                        $bitfield = 'oi_deleted';
                }
@@ -2259,7 +2254,6 @@ class LocalFileDeleteBatch {
                                        'fa_deleted_timestamp' => $encTimestamp,
                                        'fa_deleted_reason' => $encReason,
                                        'fa_deleted' => $this->suppress ? $bitfield : 0,
-
                                        'fa_name' => 'img_name',
                                        'fa_archive_name' => 'NULL',
                                        'fa_size' => 'img_size',
@@ -2346,7 +2340,7 @@ class LocalFileDeleteBatch {
 
        /**
         * Run the transaction
-        * @return FileRepoStatus
+        * @return Status
         */
        public function execute() {
                $repo = $this->file->getRepo();
@@ -2494,7 +2488,7 @@ class LocalFileRestoreBatch {
         * rows and there's no need to keep the image row locked while it's acquiring those locks
         * The caller may have its own transaction open.
         * So we save the batch and let the caller call cleanup()
-        * @return FileRepoStatus
+        * @return Status
         */
        public function execute() {
                /** @var Language */
@@ -2795,7 +2789,7 @@ class LocalFileRestoreBatch {
        /**
         * Delete unused files in the deleted zone.
         * This should be called from outside the transaction in which execute() was called.
-        * @return FileRepoStatus
+        * @return Status
         */
        public function cleanup() {
                if ( !$this->cleanupBatch ) {
@@ -2930,7 +2924,7 @@ class LocalFileMoveBatch {
 
        /**
         * Perform the move.
-        * @return FileRepoStatus
+        * @return Status
         */
        public function execute() {
                $repo = $this->file->repo;
@@ -3002,7 +2996,7 @@ class LocalFileMoveBatch {
         * Verify the database updates and return a new FileRepoStatus indicating how
         * many rows would be updated.
         *
-        * @return FileRepoStatus
+        * @return Status
         */
        protected function verifyDBUpdates() {
                $repo = $this->file->repo;
index 31e62ec..dfaae73 100644 (file)
@@ -86,7 +86,7 @@ class OldLocalFile extends LocalFile {
         * @return bool|OldLocalFile
         */
        static function newFromKey( $sha1, $repo, $timestamp = false ) {
-               $dbr = $repo->getSlaveDB();
+               $dbr = $repo->getReplicaDB();
 
                $conds = [ 'oi_sha1' => $sha1 ];
                if ( $timestamp ) {
@@ -179,7 +179,7 @@ class OldLocalFile extends LocalFile {
 
                $dbr = ( $flags & self::READ_LATEST )
                        ? $this->repo->getMasterDB()
-                       : $this->repo->getSlaveDB();
+                       : $this->repo->getReplicaDB();
 
                $conds = [ 'oi_name' => $this->getName() ];
                if ( is_null( $this->requestedTime ) ) {
@@ -194,16 +194,14 @@ class OldLocalFile extends LocalFile {
                } else {
                        $this->fileExists = false;
                }
-
        }
 
        /**
         * Load lazy file metadata from the DB
         */
        protected function loadExtraFromDB() {
-
                $this->extraDataLoaded = true;
-               $dbr = $this->repo->getSlaveDB();
+               $dbr = $this->repo->getReplicaDB();
                $conds = [ 'oi_name' => $this->getName() ];
                if ( is_null( $this->requestedTime ) ) {
                        $conds['oi_archive_name'] = $this->archive_name;
@@ -227,7 +225,6 @@ class OldLocalFile extends LocalFile {
                } else {
                        throw new MWException( "Could not find data for image '{$this->archive_name}'." );
                }
-
        }
 
        /**
@@ -332,7 +329,7 @@ class OldLocalFile extends LocalFile {
         * @param string $timestamp
         * @param string $comment
         * @param User $user
-        * @return FileRepoStatus
+        * @return Status
         */
        function uploadOld( $srcPath, $archiveName, $timestamp, $comment, $user ) {
                $this->lock();
index c65d97f..cadb502 100644 (file)
@@ -147,6 +147,7 @@ class HTMLForm extends ContextSource {
                'namespaceselect' => 'HTMLSelectNamespace',
                'namespaceselectwithbutton' => 'HTMLSelectNamespaceWithButton',
                'tagfilter' => 'HTMLTagFilter',
+               'sizefilter' => 'HTMLSizeFilterField',
                'submit' => 'HTMLSubmitField',
                'hidden' => 'HTMLHiddenField',
                'edittools' => 'HTMLEditTools',
@@ -176,7 +177,7 @@ class HTMLForm extends ContextSource {
        protected $mFieldTree;
        protected $mShowReset = false;
        protected $mShowSubmit = true;
-       protected $mSubmitFlags = [ 'constructive', 'primary' ];
+       protected $mSubmitFlags = [ 'primary', 'progressive' ];
        protected $mShowCancel = false;
        protected $mCancelTarget;
 
index 4afdea7..8390a0b 100644 (file)
@@ -42,7 +42,7 @@ abstract class HTMLFormField {
         *
         * @return string Valid HTML.
         */
-       abstract function getInputHTML( $value );
+       abstract public function getInputHTML( $value );
 
        /**
         * Same as getInputHTML, but returns an OOUI object.
@@ -51,7 +51,7 @@ abstract class HTMLFormField {
         * @param string $value
         * @return OOUI\Widget|false
         */
-       function getInputOOUI( $value ) {
+       public function getInputOOUI( $value ) {
                return false;
        }
 
@@ -74,7 +74,7 @@ abstract class HTMLFormField {
         *
         * @return Message
         */
-       function msg() {
+       public function msg() {
                $args = func_get_args();
 
                if ( $this->mParent ) {
@@ -266,7 +266,7 @@ abstract class HTMLFormField {
         * @param array $alldata The data collected from the form
         * @return bool
         */
-       function isHidden( $alldata ) {
+       public function isHidden( $alldata ) {
                if ( !$this->mHideIf ) {
                        return false;
                }
@@ -284,7 +284,7 @@ abstract class HTMLFormField {
         *
         * @return bool True to cancel the submission
         */
-       function cancelSubmit( $value, $alldata ) {
+       public function cancelSubmit( $value, $alldata ) {
                return false;
        }
 
@@ -299,7 +299,7 @@ abstract class HTMLFormField {
         * @return bool|string True on success, or String error to display, or
         *   false to fail validation without displaying an error.
         */
-       function validate( $value, $alldata ) {
+       public function validate( $value, $alldata ) {
                if ( $this->isHidden( $alldata ) ) {
                        return true;
                }
@@ -318,7 +318,7 @@ abstract class HTMLFormField {
                return true;
        }
 
-       function filter( $value, $alldata ) {
+       public function filter( $value, $alldata ) {
                if ( isset( $this->mFilterCallback ) ) {
                        $value = call_user_func( $this->mFilterCallback, $value, $alldata, $this->mParent );
                }
@@ -370,7 +370,7 @@ abstract class HTMLFormField {
         * @param WebRequest $request
         * @return string The value
         */
-       function loadDataFromRequest( $request ) {
+       public function loadDataFromRequest( $request ) {
                if ( $request->getCheck( $this->mName ) ) {
                        return $request->getText( $this->mName );
                } else {
@@ -386,7 +386,7 @@ abstract class HTMLFormField {
         * @since 1.22 The 'label' attribute no longer accepts raw HTML, use 'label-raw' instead
         * @throws MWException
         */
-       function __construct( $params ) {
+       public function __construct( $params ) {
                $this->mParams = $params;
 
                if ( isset( $params['parent'] ) && $params['parent'] instanceof HTMLForm ) {
@@ -472,7 +472,7 @@ abstract class HTMLFormField {
         *
         * @return string Complete HTML table row.
         */
-       function getTableRow( $value ) {
+       public function getTableRow( $value ) {
                list( $errors, $errorClass ) = $this->getErrorsAndErrorClass( $value );
                $inputHtml = $this->getInputHTML( $value );
                $fieldType = get_class( $this );
@@ -903,7 +903,7 @@ abstract class HTMLFormField {
         * @since 1.28
         * @return string[]
         */
-       function getNotices() {
+       public function getNotices() {
                $notices = [];
 
                if ( isset( $this->mParams['notice-message'] ) ) {
@@ -924,11 +924,11 @@ abstract class HTMLFormField {
        /**
         * @return string HTML
         */
-       function getLabel() {
+       public function getLabel() {
                return is_null( $this->mLabel ) ? '' : $this->mLabel;
        }
 
-       function getLabelHtml( $cellAttributes = [] ) {
+       public function getLabelHtml( $cellAttributes = [] ) {
                # Don't output a for= attribute for labels with no associated input.
                # Kind of hacky here, possibly we don't want these to be <label>s at all.
                $for = [];
@@ -967,7 +967,7 @@ abstract class HTMLFormField {
                return $html;
        }
 
-       function getDefault() {
+       public function getDefault() {
                if ( isset( $this->mDefault ) ) {
                        return $this->mDefault;
                } else {
@@ -1036,7 +1036,7 @@ abstract class HTMLFormField {
         * @param array $array
         * @return array
         */
-       static function forceToStringRecursive( $array ) {
+       public static function forceToStringRecursive( $array ) {
                if ( is_array( $array ) ) {
                        return array_map( [ __CLASS__, 'forceToStringRecursive' ], $array );
                } else {
index 2c09ea4..d44fc60 100644 (file)
@@ -7,5 +7,5 @@ interface HTMLNestedFilterable {
         *
         * @param array $data
         */
-       function filterDataForSubmit( $data );
+       public function filterDataForSubmit( $data );
 }
index 6fbf15b..46b570d 100644 (file)
@@ -48,7 +48,7 @@ class OOUIHTMLForm extends HTMLForm {
                return $field;
        }
 
-       function getButtons() {
+       public function getButtons() {
                $buttons = '';
 
                // IE<8 has bugs with <button>, so we'll need to avoid them.
@@ -190,7 +190,7 @@ class OOUIHTMLForm extends HTMLForm {
         * @param string $elementsType
         * @return string
         */
-       function getErrorsOrWarnings( $elements, $elementsType ) {
+       public function getErrorsOrWarnings( $elements, $elementsType ) {
                if ( !in_array( $elementsType, [ 'error', 'warning' ] ) ) {
                        throw new DomainException( $elementsType . ' is not a valid type.' );
                }
@@ -230,7 +230,7 @@ class OOUIHTMLForm extends HTMLForm {
                return '';
        }
 
-       function getHeaderText( $section = null ) {
+       public function getHeaderText( $section = null ) {
                if ( is_null( $section ) ) {
                        // We handle $this->mHeader elsewhere, in getBody()
                        return '';
@@ -239,7 +239,7 @@ class OOUIHTMLForm extends HTMLForm {
                }
        }
 
-       function getBody() {
+       public function getBody() {
                $fieldset = parent::getBody();
                // FIXME This only works for forms with no subsections
                if ( $fieldset instanceof OOUI\FieldsetLayout ) {
@@ -273,7 +273,7 @@ class OOUIHTMLForm extends HTMLForm {
                return $fieldset;
        }
 
-       function wrapForm( $html ) {
+       public function wrapForm( $html ) {
                $form = new OOUI\FormLayout( $this->getFormAttributes() + [
                        'classes' => [ 'mw-htmlform-ooui' ],
                        'content' => new OOUI\HtmlSnippet( $html ),
index c920ac3..5d9f7a0 100644 (file)
@@ -50,7 +50,7 @@ class VFormHTMLForm extends HTMLForm {
                return $field;
        }
 
-       function getHTML( $submitResult ) {
+       public function getHTML( $submitResult ) {
                // This is required for VForm HTMLForms that use that style regardless
                // of wgUseMediaWikiUIEverywhere (since they pre-date it).
                // When wgUseMediaWikiUIEverywhere is removed, this should be consolidated
@@ -71,12 +71,12 @@ class VFormHTMLForm extends HTMLForm {
                return $attribs;
        }
 
-       function wrapForm( $html ) {
+       public function wrapForm( $html ) {
                // Always discard $this->mWrapperLegend
                return Html::rawElement( 'form', $this->getFormAttributes(), $html );
        }
 
-       function getButtons() {
+       public function getButtons() {
                $buttons = '';
 
                if ( $this->mShowSubmit ) {
index 76a88d5..b0890c6 100644 (file)
  *   options-messages - As for HTMLSelectField
  *   options - As for HTMLSelectField
  *   options-message - As for HTMLSelectField
- *   autocomplete - Associative array mapping display text to values.
- *   autocomplete-messages - Like autocomplete, but keys are message names.
+ *   autocomplete-data - Associative array mapping display text to values.
+ *   autocomplete-data-messages - Like autocomplete, but keys are message names.
  *   require-match - Boolean, if true the value must be in the options or the
  *     autocomplete.
  *   other-message - Message to use instead of htmlform-selectorother-other for
  *      the 'other' message.
  *   other - Raw text to use for the 'other' message
+ *
+ * The old name of autocomplete-data[-messages] was autocomplete[-messages] which is still
+ * recognized but deprecated since MediaWiki 1.29 since it conflicts with how autocomplete is
+ * used in HTMLTextField.
  */
 class HTMLAutoCompleteSelectField extends HTMLTextField {
-       protected $autocomplete = [];
+       protected $autocompleteData = [];
 
-       function __construct( $params ) {
+       public function __construct( $params ) {
                $params += [
                        'require-match' => false,
                ];
 
+               // FIXME B/C, remove in 1.30
+               if (
+                       array_key_exists( 'autocomplete', $params )
+                       && !array_key_exists( 'autocomplete-data', $params )
+               ) {
+                       $params['autocomplete-data'] = $params['autocomplete'];
+                       unset( $params['autocomplete'] );
+               }
+               if (
+                       array_key_exists( 'autocomplete-messages', $params )
+                       && !array_key_exists( 'autocomplete-data-messages', $params )
+               ) {
+                       $params['autocomplete-data-messages'] = $params['autocomplete-messages'];
+                       unset( $params['autocomplete-messages'] );
+               }
+
                parent::__construct( $params );
 
-               if ( array_key_exists( 'autocomplete-messages', $this->mParams ) ) {
-                       foreach ( $this->mParams['autocomplete-messages'] as $key => $value ) {
+               if ( array_key_exists( 'autocomplete-data-messages', $this->mParams ) ) {
+                       foreach ( $this->mParams['autocomplete-data-messages'] as $key => $value ) {
                                $key = $this->msg( $key )->plain();
-                               $this->autocomplete[$key] = strval( $value );
+                               $this->autocompleteData[$key] = strval( $value );
                        }
-               } elseif ( array_key_exists( 'autocomplete', $this->mParams ) ) {
-                       foreach ( $this->mParams['autocomplete'] as $key => $value ) {
-                               $this->autocomplete[$key] = strval( $value );
+               } elseif ( array_key_exists( 'autocomplete-data', $this->mParams ) ) {
+                       foreach ( $this->mParams['autocomplete-data'] as $key => $value ) {
+                               $this->autocompleteData[$key] = strval( $value );
                        }
                }
-               if ( !is_array( $this->autocomplete ) || !$this->autocomplete ) {
+               if ( !is_array( $this->autocompleteData ) || !$this->autocompleteData ) {
                        throw new MWException( 'HTMLAutoCompleteSelectField called without any autocompletions' );
                }
 
@@ -63,14 +83,14 @@ class HTMLAutoCompleteSelectField extends HTMLTextField {
                }
        }
 
-       function loadDataFromRequest( $request ) {
+       public function loadDataFromRequest( $request ) {
                if ( $request->getCheck( $this->mName ) ) {
                        $val = $request->getText( $this->mName . '-select', 'other' );
 
                        if ( $val === 'other' ) {
                                $val = $request->getText( $this->mName );
-                               if ( isset( $this->autocomplete[$val] ) ) {
-                                       $val = $this->autocomplete[$val];
+                               if ( isset( $this->autocompleteData[$val] ) ) {
+                                       $val = $this->autocompleteData[$val];
                                }
                        }
 
@@ -80,18 +100,18 @@ class HTMLAutoCompleteSelectField extends HTMLTextField {
                }
        }
 
-       function validate( $value, $alldata ) {
+       public function validate( $value, $alldata ) {
                $p = parent::validate( $value, $alldata );
 
                if ( $p !== true ) {
                        return $p;
                }
 
-               $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
+               $validOptions = HTMLFormField::flattenOptions( $this->getOptions() ?: [] );
 
                if ( in_array( strval( $value ), $validOptions, true ) ) {
                        return true;
-               } elseif ( in_array( strval( $value ), $this->autocomplete, true ) ) {
+               } elseif ( in_array( strval( $value ), $this->autocompleteData, true ) ) {
                        return true;
                } elseif ( $this->mParams['require-match'] ) {
                        return $this->msg( 'htmlform-select-badoption' )->parse();
@@ -104,7 +124,7 @@ class HTMLAutoCompleteSelectField extends HTMLTextField {
        public function getAttributes( array $list ) {
                $attribs = [
                        'type' => 'text',
-                       'data-autocomplete' => FormatJson::encode( array_keys( $this->autocomplete ) ),
+                       'data-autocomplete' => FormatJson::encode( array_keys( $this->autocompleteData ) ),
                ] + parent::getAttributes( $list );
 
                if ( $this->getOptions() ) {
@@ -116,7 +136,7 @@ class HTMLAutoCompleteSelectField extends HTMLTextField {
                return $attribs;
        }
 
-       function getInputHTML( $value ) {
+       public function getInputHTML( $value ) {
                $oldClass = $this->mClass;
                $this->mClass = (array)$this->mClass;
 
@@ -152,7 +172,7 @@ class HTMLAutoCompleteSelectField extends HTMLTextField {
                if ( $valInSelect ) {
                        $value = '';
                } else {
-                       $key = array_search( strval( $value ), $this->autocomplete, true );
+                       $key = array_search( strval( $value ), $this->autocompleteData, true );
                        if ( $key !== false ) {
                                $value = $key;
                        }
@@ -170,7 +190,7 @@ class HTMLAutoCompleteSelectField extends HTMLTextField {
         * @param string $value
         * @return false
         */
-       function getInputOOUI( $value ) {
+       public function getInputOOUI( $value ) {
                // To be implemented, for now override the function from HTMLTextField
                return false;
        }
index a553839..b080e18 100644 (file)
@@ -4,7 +4,7 @@
  * A checkbox field
  */
 class HTMLCheckField extends HTMLFormField {
-       function getInputHTML( $value ) {
+       public function getInputHTML( $value ) {
                global $wgUseMediaWikiUIEverywhere;
 
                if ( !empty( $this->mParams['invert'] ) ) {
@@ -79,7 +79,7 @@ class HTMLCheckField extends HTMLFormField {
         *
         * @return string
         */
-       function getLabel() {
+       public function getLabel() {
                if ( $this->mParent instanceof OOUIHTMLForm ) {
                        return $this->mLabel;
                } elseif (
@@ -113,7 +113,7 @@ class HTMLCheckField extends HTMLFormField {
         *
         * @return bool
         */
-       function loadDataFromRequest( $request ) {
+       public function loadDataFromRequest( $request ) {
                $invert = isset( $this->mParams['invert'] ) && $this->mParams['invert'];
 
                // GetCheck won't work like we want for checks.
index b324fb6..890cd7c 100644 (file)
@@ -38,7 +38,7 @@ class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
                parent::__construct( $params );
        }
 
-       function validate( $value, $alldata ) {
+       public function validate( $value, $alldata ) {
                $rows = $this->mParams['rows'];
                $columns = $this->mParams['columns'];
 
@@ -79,7 +79,7 @@ class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
         *
         * @return string
         */
-       function getInputHTML( $value ) {
+       public function getInputHTML( $value ) {
                $html = '';
                $tableContents = '';
                $rows = $this->mParams['rows'];
@@ -186,7 +186,7 @@ class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
         *
         * @return string Complete HTML table row
         */
-       function getTableRow( $value ) {
+       public function getTableRow( $value ) {
                list( $errors, $errorClass ) = $this->getErrorsAndErrorClass( $value );
                $inputHtml = $this->getInputHTML( $value );
                $fieldType = get_class( $this );
@@ -224,7 +224,7 @@ class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
         *
         * @return array
         */
-       function loadDataFromRequest( $request ) {
+       public function loadDataFromRequest( $request ) {
                if ( $this->isSubmitAttempt( $request ) ) {
                        // Checkboxes are just not added to the request arrays if they're not checked,
                        // so it's perfectly possible for there not to be an entry at all
@@ -235,7 +235,7 @@ class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
                }
        }
 
-       function getDefault() {
+       public function getDefault() {
                if ( isset( $this->mDefault ) ) {
                        return $this->mDefault;
                } else {
@@ -243,7 +243,7 @@ class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
                }
        }
 
-       function filterDataForSubmit( $data ) {
+       public function filterDataForSubmit( $data ) {
                $columns = HTMLFormField::flattenOptions( $this->mParams['columns'] );
                $rows = HTMLFormField::flattenOptions( $this->mParams['rows'] );
                $res = [];
index 0c3bc5a..3f63c18 100644 (file)
@@ -25,7 +25,7 @@ class HTMLComboboxField extends HTMLTextField {
                return $attribs;
        }
 
-       function getInputHTML( $value ) {
+       public function getInputHTML( $value ) {
                $datalist = new XmlSelect( false, $this->mName . '-datalist' );
                $datalist->setTagName( 'datalist' );
                $datalist->addOptions( $this->getOptions() );
@@ -33,7 +33,7 @@ class HTMLComboboxField extends HTMLTextField {
                return parent::getInputHTML( $value ) . $datalist->getHTML();
        }
 
-       function getInputOOUI( $value ) {
+       public function getInputOOUI( $value ) {
                $disabled = false;
                $allowedParams = [ 'tabindex' ];
                $attribs = OOUI\Element::configFromHtmlAttributes(
index 66f89f9..88dcd24 100644 (file)
@@ -75,7 +75,7 @@ class HTMLDateTimeField extends HTMLTextField {
                return $ret;
        }
 
-       function loadDataFromRequest( $request ) {
+       public function loadDataFromRequest( $request ) {
                if ( !$request->getCheck( $this->mName ) ) {
                        return $this->getDefault();
                }
@@ -85,7 +85,7 @@ class HTMLDateTimeField extends HTMLTextField {
                return $date ? $this->formatDate( $date ) : $value;
        }
 
-       function validate( $value, $alldata ) {
+       public function validate( $value, $alldata ) {
                $p = parent::validate( $value, $alldata );
 
                if ( $p !== true ) {
@@ -126,6 +126,9 @@ class HTMLDateTimeField extends HTMLTextField {
 
        protected function parseDate( $value ) {
                $value = trim( $value );
+               if ( $value === '' ) {
+                       return false;
+               }
 
                if ( $this->mType === 'date' ) {
                        $value .= ' T00:00:00+0000';
@@ -138,7 +141,7 @@ class HTMLDateTimeField extends HTMLTextField {
                        $date = new DateTime( $value, new DateTimeZone( 'GMT' ) );
                        return $date->getTimestamp();
                } catch ( Exception $ex ) {
-                       return 0;
+                       return false;
                }
        }
 
index 2ef4978..d1250c0 100644 (file)
@@ -4,11 +4,11 @@
  * A field that will contain a numeric value
  */
 class HTMLFloatField extends HTMLTextField {
-       function getSize() {
+       public function getSize() {
                return isset( $this->mParams['size'] ) ? $this->mParams['size'] : 20;
        }
 
-       function validate( $value, $alldata ) {
+       public function validate( $value, $alldata ) {
                $p = parent::validate( $value, $alldata );
 
                if ( $p !== true ) {
@@ -17,7 +17,7 @@ class HTMLFloatField extends HTMLTextField {
 
                $value = trim( $value );
 
-               # http://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers
+               # https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers
                # with the addition that a leading '+' sign is ok.
                if ( !preg_match( '/^((\+|\-)?\d+(\.\d+)?(E(\+|\-)?\d+)?)?$/i', $value ) ) {
                        return $this->msg( 'htmlform-float-invalid' )->parseAsBlock();
index c0fce2b..02562c4 100644 (file)
@@ -11,7 +11,7 @@ class HTMLHiddenField extends HTMLFormField {
                }
 
                # Per HTML5 spec, hidden fields cannot be 'required'
-               # http://www.w3.org/TR/html5/forms.html#hidden-state-%28type=hidden%29
+               # https://www.w3.org/TR/html5/forms.html#hidden-state-%28type=hidden%29
                unset( $this->mParams['required'] );
        }
 
index 6dc5d08..1376d0c 100644 (file)
@@ -19,7 +19,7 @@ class HTMLInfoField extends HTMLFormField {
                parent::__construct( $info );
        }
 
-       function getDefault() {
+       public function getDefault() {
                $default = parent::getDefault();
                if ( $default instanceof Closure ) {
                        $default = call_user_func( $default, $this->mParams );
index b0148d9..c87a778 100644 (file)
@@ -4,14 +4,14 @@
  * A field that must contain a number
  */
 class HTMLIntField extends HTMLFloatField {
-       function validate( $value, $alldata ) {
+       public function validate( $value, $alldata ) {
                $p = parent::validate( $value, $alldata );
 
                if ( $p !== true ) {
                        return $p;
                }
 
-               # http://www.w3.org/TR/html5/infrastructure.html#signed-integers
+               # https://www.w3.org/TR/html5/infrastructure.html#signed-integers
                # with the addition that a leading '+' sign is ok. Note that leading zeros
                # are fine, and will be left in the input, which is useful for things like
                # phone numbers when you know that they are integers (the HTML5 type=tel
index c9fcb09..58de763 100644 (file)
@@ -27,7 +27,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
                }
        }
 
-       function validate( $value, $alldata ) {
+       public function validate( $value, $alldata ) {
                $p = parent::validate( $value, $alldata );
 
                if ( $p !== true ) {
@@ -50,7 +50,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
                }
        }
 
-       function getInputHTML( $value ) {
+       public function getInputHTML( $value ) {
                if ( isset( $this->mParams['dropdown'] ) ) {
                        $this->mParent->getOutput()->addModules( 'jquery.chosen' );
                }
@@ -61,7 +61,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
                return $html;
        }
 
-       function formatOptions( $options, $value ) {
+       public function formatOptions( $options, $value ) {
                $html = '';
 
                $attribs = $this->getAttributes( [ 'disabled', 'tabindex' ] );
@@ -120,6 +120,8 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
         * @return OOUI\CheckboxMultiselectInputWidget
         */
        public function getInputOOUI( $value ) {
+               $this->mParent->getOutput()->addModules( 'oojs-ui-widgets' );
+
                $attr = $this->getTooltipAndAccessKey();
                $attr['id'] = $this->mID;
                $attr['name'] = "{$this->mName}[]";
@@ -149,7 +151,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
         *
         * @return string
         */
-       function loadDataFromRequest( $request ) {
+       public function loadDataFromRequest( $request ) {
                if ( $this->isSubmitAttempt( $request ) ) {
                        // Checkboxes are just not added to the request arrays if they're not checked,
                        // so it's perfectly possible for there not to be an entry at all
@@ -160,7 +162,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
                }
        }
 
-       function getDefault() {
+       public function getDefault() {
                if ( isset( $this->mDefault ) ) {
                        return $this->mDefault;
                } else {
@@ -168,7 +170,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
                }
        }
 
-       function filterDataForSubmit( $data ) {
+       public function filterDataForSubmit( $data ) {
                $data = HTMLFormField::forceToStringRecursive( $data );
                $options = HTMLFormField::flattenOptions( $this->getOptions() );
 
index 42c2fdf..69dc617 100644 (file)
@@ -19,7 +19,7 @@ class HTMLRadioField extends HTMLFormField {
                }
        }
 
-       function validate( $value, $alldata ) {
+       public function validate( $value, $alldata ) {
                $p = parent::validate( $value, $alldata );
 
                if ( $p !== true ) {
@@ -47,13 +47,13 @@ class HTMLRadioField extends HTMLFormField {
         *
         * @return string
         */
-       function getInputHTML( $value ) {
+       public function getInputHTML( $value ) {
                $html = $this->formatOptions( $this->getOptions(), strval( $value ) );
 
                return $html;
        }
 
-       function getInputOOUI( $value ) {
+       public function getInputOOUI( $value ) {
                $options = [];
                foreach ( $this->getOptions() as $label => $data ) {
                        $options[] = [
@@ -76,7 +76,7 @@ class HTMLRadioField extends HTMLFormField {
                return true;
        }
 
-       function formatOptions( $options, $value ) {
+       public function formatOptions( $options, $value ) {
                global $wgUseMediaWikiUIEverywhere;
 
                $html = '';
index 8dc16bf..5a18025 100644 (file)
@@ -32,7 +32,7 @@ class HTMLRestrictionsField extends HTMLTextAreaField {
         * @param WebRequest $request
         * @return string|MWRestrictions Restrictions object or original string if invalid
         */
-       function loadDataFromRequest( $request ) {
+       public function loadDataFromRequest( $request ) {
                if ( !$request->getCheck( $this->mName ) ) {
                        return $this->getDefault();
                }
index e75c2b2..86e8e75 100644 (file)
@@ -11,7 +11,7 @@
  * @todo FIXME: If made 'required', only the text field should be compulsory.
  */
 class HTMLSelectAndOtherField extends HTMLSelectField {
-       function __construct( $params ) {
+       public function __construct( $params ) {
                if ( array_key_exists( 'other', $params ) ) {
                        // Do nothing
                } elseif ( array_key_exists( 'other-message', $params ) ) {
@@ -31,10 +31,9 @@ class HTMLSelectAndOtherField extends HTMLSelectField {
                        $this->mOptions = [ $params['other'] => 'other' ] + $this->mOptions;
                }
                $this->mFlatOptions = self::flattenOptions( $this->getOptions() );
-
        }
 
-       function getInputHTML( $value ) {
+       public function getInputHTML( $value ) {
                $select = parent::getInputHTML( $value[1] );
 
                $textAttribs = [
@@ -64,7 +63,7 @@ class HTMLSelectAndOtherField extends HTMLSelectField {
                return "$select<br />\n$textbox";
        }
 
-       function getInputOOUI( $value ) {
+       public function getInputOOUI( $value ) {
                return false;
        }
 
@@ -73,7 +72,7 @@ class HTMLSelectAndOtherField extends HTMLSelectField {
         *
         * @return array("<overall message>","<select value>","<text field value>")
         */
-       function loadDataFromRequest( $request ) {
+       public function loadDataFromRequest( $request ) {
                if ( $request->getCheck( $this->mName ) ) {
                        $list = $request->getText( $this->mName );
                        $text = $request->getText( $this->mName . '-other' );
@@ -108,11 +107,11 @@ class HTMLSelectAndOtherField extends HTMLSelectField {
                return [ $final, $list, $text ];
        }
 
-       function getSize() {
+       public function getSize() {
                return isset( $this->mParams['size'] ) ? $this->mParams['size'] : 45;
        }
 
-       function validate( $value, $alldata ) {
+       public function validate( $value, $alldata ) {
                # HTMLSelectField forces $value to be one of the options in the select
                # field, which is not useful here.  But we do want the validation further up
                # the chain
index 40b31b5..c1f8e42 100644 (file)
@@ -4,7 +4,7 @@
  * A select dropdown field.  Basically a wrapper for Xmlselect class
  */
 class HTMLSelectField extends HTMLFormField {
-       function validate( $value, $alldata ) {
+       public function validate( $value, $alldata ) {
                $p = parent::validate( $value, $alldata );
 
                if ( $p !== true ) {
@@ -20,7 +20,7 @@ class HTMLSelectField extends HTMLFormField {
                }
        }
 
-       function getInputHTML( $value ) {
+       public function getInputHTML( $value ) {
                $select = new XmlSelect( $this->mName, $this->mID, strval( $value ) );
 
                if ( !empty( $this->mParams['disabled'] ) ) {
@@ -42,7 +42,7 @@ class HTMLSelectField extends HTMLFormField {
                return $select->getHTML();
        }
 
-       function getInputOOUI( $value ) {
+       public function getInputOOUI( $value ) {
                $disabled = false;
                $allowedParams = [ 'tabindex' ];
                $attribs = OOUI\Element::configFromHtmlAttributes(
index e7f1c04..45191d0 100644 (file)
@@ -12,7 +12,7 @@ class HTMLSelectLimitField extends HTMLSelectField {
         * @param array $alldata
         * @return bool
         */
-       function validate( $value, $alldata ) {
+       public function validate( $value, $alldata ) {
                if ( $value == '' ) {
                        return true;
                }
index 230790d..f13aa17 100644 (file)
@@ -9,10 +9,9 @@ class HTMLSelectNamespace extends HTMLFormField {
                $this->mAllValue = array_key_exists( 'all', $params )
                        ? $params['all']
                        : 'all';
-
        }
 
-       function getInputHTML( $value ) {
+       public function getInputHTML( $value ) {
                return Html::namespaceSelector(
                        [
                                'selected' => $value,
index 8f7750c..bb41079 100644 (file)
@@ -7,7 +7,7 @@
  * and should be used instead.
  */
 class HTMLSelectOrOtherField extends HTMLTextField {
-       function __construct( $params ) {
+       public function __construct( $params ) {
                parent::__construct( $params );
                $this->getOptions();
                if ( !in_array( 'other', $this->mOptions, true ) ) {
@@ -18,10 +18,9 @@ class HTMLSelectOrOtherField extends HTMLTextField {
                        // Have 'other' always as first element
                        $this->mOptions = [ $msg => 'other' ] + $this->mOptions;
                }
-
        }
 
-       function getInputHTML( $value ) {
+       public function getInputHTML( $value ) {
                $valInSelect = false;
 
                if ( $value !== false ) {
@@ -65,7 +64,7 @@ class HTMLSelectOrOtherField extends HTMLTextField {
                return "$select<br />\n$textbox";
        }
 
-       function getInputOOUI( $value ) {
+       public function getInputOOUI( $value ) {
                return false;
        }
 
@@ -74,7 +73,7 @@ class HTMLSelectOrOtherField extends HTMLTextField {
         *
         * @return string
         */
-       function loadDataFromRequest( $request ) {
+       public function loadDataFromRequest( $request ) {
                if ( $request->getCheck( $this->mName ) ) {
                        $val = $request->getText( $this->mName );
 
diff --git a/includes/htmlform/fields/HTMLSizeFilterField.php b/includes/htmlform/fields/HTMLSizeFilterField.php
new file mode 100644 (file)
index 0000000..d94eb8d
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * A size filter field for use on query-type special pages. It looks a bit like:
+ *
+ *    (o) Min size  ( ) Max size:  [       ] bytes
+ *
+ * Minimum size limits are represented using a positive integer, while maximum
+ * size limits are represented using a negative integer.
+ */
+class HTMLSizeFilterField extends HTMLIntField {
+       public function getSize() {
+               return isset( $this->mParams['size'] ) ? $this->mParams['size'] : 9;
+       }
+
+       public function getInputHTML( $value ) {
+               $attribs = [];
+               if ( !empty( $this->mParams['disabled'] ) ) {
+                       $attribs['disabled'] = 'disabled';
+               }
+
+               $html = Xml::radioLabel(
+                       $this->msg( 'minimum-size' )->text(),
+                       $this->mName . '-mode',
+                       'min',
+                       $this->mID . '-mode-min',
+                       $value >= 0,
+                       $attribs
+               );
+               $html .= '&#160;' . Xml::radioLabel(
+                       $this->msg( 'maximum-size' )->text(),
+                       $this->mName . '-mode',
+                       'max',
+                       $this->mID . '-mode-max',
+                       $value < 0,
+                       $attribs
+               );
+               $html .= '&#160;' . parent::getInputHTML( $value ? abs( $value ) : '' );
+               $html .= '&#160;' . $this->msg( 'pagesize' )->parse();
+
+               return $html;
+       }
+
+       // No OOUI yet
+       public function getInputOOUI( $value ) {
+               return false;
+       }
+
+       /**
+        * @param WebRequest $request
+        *
+        * @return string
+        */
+       public function loadDataFromRequest( $request ) {
+               $size = $request->getInt( $this->mName );
+               if ( !$size ) {
+                       return $this->getDefault();
+               }
+               $size = abs( $size );
+
+               // negative numbers represent "max", positive numbers represent "min"
+               if ( $request->getVal( $this->mName . '-mode' ) === 'max' ) {
+                       return -$size;
+               } else {
+                       return $size;
+               }
+       }
+
+       protected function needsLabel() {
+               return false;
+       }
+}
index cb98549..0c33ad9 100644 (file)
@@ -7,7 +7,7 @@
 class HTMLSubmitField extends HTMLButtonField {
        protected $buttonType = 'submit';
 
-       protected $mFlags = [ 'primary', 'constructive' ];
+       protected $mFlags = [ 'primary', 'progressive' ];
 
        public function skipLoadData( $request ) {
                return !$request->getCheck( $this->mName );
index 8075de5..e24541c 100644 (file)
@@ -5,7 +5,7 @@
 class HTMLTagFilter extends HTMLFormField {
        protected $tagFilter;
 
-       function getTableRow( $value ) {
+       public function getTableRow( $value ) {
                $this->tagFilter = ChangeTags::buildTagFilterSelector( $value );
                if ( $this->tagFilter ) {
                        return parent::getTableRow( $value );
@@ -13,7 +13,7 @@ class HTMLTagFilter extends HTMLFormField {
                return '';
        }
 
-       function getDiv( $value ) {
+       public function getDiv( $value ) {
                $this->tagFilter = ChangeTags::buildTagFilterSelector( $value );
                if ( $this->tagFilter ) {
                        return parent::getDiv( $value );
@@ -21,7 +21,7 @@ class HTMLTagFilter extends HTMLFormField {
                return '';
        }
 
-       function getInputHTML( $value ) {
+       public function getInputHTML( $value ) {
                if ( $this->tagFilter ) {
                        // we only need the select field, HTMLForm should handle the label
                        return $this->tagFilter[1];
index 8ffff43..82ec3bf 100644 (file)
@@ -22,15 +22,15 @@ class HTMLTextAreaField extends HTMLFormField {
                }
        }
 
-       function getCols() {
+       public function getCols() {
                return isset( $this->mParams['cols'] ) ? $this->mParams['cols'] : static::DEFAULT_COLS;
        }
 
-       function getRows() {
+       public function getRows() {
                return isset( $this->mParams['rows'] ) ? $this->mParams['rows'] : static::DEFAULT_ROWS;
        }
 
-       function getSpellCheck() {
+       public function getSpellCheck() {
                $val = isset( $this->mParams['spellcheck'] ) ? $this->mParams['spellcheck'] : null;
                if ( is_bool( $val ) ) {
                        // "spellcheck" attribute literally requires "true" or "false" to work.
@@ -39,7 +39,7 @@ class HTMLTextAreaField extends HTMLFormField {
                return null;
        }
 
-       function getInputHTML( $value ) {
+       public function getInputHTML( $value ) {
                $attribs = [
                                'id' => $this->mID,
                                'cols' => $this->getCols(),
index 3ab7176..c3da746 100644 (file)
@@ -1,8 +1,19 @@
 <?php
 
+/**
+ * <input> field.
+ *
+ * Besides the parameters recognized by HTMLFormField, the following are
+ * recognized:
+ *   autocomplete - HTML autocomplete value (a boolean for on/off or a string according to
+ *     https://html.spec.whatwg.org/multipage/forms.html#autofill )
+ */
 class HTMLTextField extends HTMLFormField {
        protected $mPlaceholder = '';
 
+       /** @var bool HTML autocomplete attribute */
+       protected $autocomplete;
+
        /**
         * @param array $params
         *   - type: HTML textfield type
@@ -13,6 +24,10 @@ class HTMLTextField extends HTMLFormField {
         *     for password fields)
         */
        public function __construct( $params ) {
+               if ( isset( $params['autocomplete'] ) && is_bool( $params['autocomplete'] ) ) {
+                       $params['autocomplete'] = $params['autocomplete'] ? 'on' : 'off';
+               }
+
                parent::__construct( $params );
 
                if ( isset( $params['placeholder-message'] ) ) {
@@ -22,11 +37,11 @@ class HTMLTextField extends HTMLFormField {
                }
        }
 
-       function getSize() {
+       public function getSize() {
                return isset( $this->mParams['size'] ) ? $this->mParams['size'] : 45;
        }
 
-       function getSpellCheck() {
+       public function getSpellCheck() {
                $val = isset( $this->mParams['spellcheck'] ) ? $this->mParams['spellcheck'] : null;
                if ( is_bool( $val ) ) {
                        // "spellcheck" attribute literally requires "true" or "false" to work.
@@ -43,7 +58,7 @@ class HTMLTextField extends HTMLFormField {
                return !( isset( $this->mParams['type'] ) && $this->mParams['type'] === 'password' );
        }
 
-       function getInputHTML( $value ) {
+       public function getInputHTML( $value ) {
                if ( !$this->isPersistent() ) {
                        $value = '';
                }
@@ -80,7 +95,8 @@ class HTMLTextField extends HTMLFormField {
                        'required',
                        'autofocus',
                        'multiple',
-                       'readonly'
+                       'readonly',
+                       'autocomplete',
                ];
 
                $attribs += $this->getAttributes( $allowedParams );
@@ -119,7 +135,7 @@ class HTMLTextField extends HTMLFormField {
                return $type;
        }
 
-       function getInputOOUI( $value ) {
+       public function getInputOOUI( $value ) {
                if ( !$this->isPersistent() ) {
                        $value = '';
                }
@@ -146,12 +162,24 @@ class HTMLTextField extends HTMLFormField {
                        'required',
                        'tabindex',
                        'type',
+                       'autocomplete',
                ];
 
                $attribs += OOUI\Element::configFromHtmlAttributes(
                        $this->getAttributes( $allowedParams )
                );
 
+               // FIXME T150983 downgrade autocomplete
+               if ( isset( $attribs['autocomplete'] ) ) {
+                       if ( $attribs['autocomplete'] === 'on' ) {
+                               $attribs['autocomplete'] = true;
+                       } elseif ( $attribs['autocomplete'] === 'off' ) {
+                               $attribs['autocomplete'] = false;
+                       } else {
+                               unset( $attribs['autocomplete'] );
+                       }
+               }
+
                $type = $this->getType( $attribs );
 
                return $this->getInputWidget( [
diff --git a/includes/http/CurlHttpRequest.php b/includes/http/CurlHttpRequest.php
new file mode 100644 (file)
index 0000000..f58c3a9
--- /dev/null
@@ -0,0 +1,165 @@
+<?php
+/**
+ * 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
+ */
+
+/**
+ * MWHttpRequest implemented using internal curl compiled into PHP
+ */
+class CurlHttpRequest extends MWHttpRequest {
+       const SUPPORTS_FILE_POSTS = true;
+
+       protected $curlOptions = [];
+       protected $headerText = "";
+
+       /**
+        * @param resource $fh
+        * @param string $content
+        * @return int
+        */
+       protected function readHeader( $fh, $content ) {
+               $this->headerText .= $content;
+               return strlen( $content );
+       }
+
+       public function execute() {
+
+               parent::execute();
+
+               if ( !$this->status->isOK() ) {
+                       return $this->status;
+               }
+
+               $this->curlOptions[CURLOPT_PROXY] = $this->proxy;
+               $this->curlOptions[CURLOPT_TIMEOUT] = $this->timeout;
+
+               // Only supported in curl >= 7.16.2
+               if ( defined( 'CURLOPT_CONNECTTIMEOUT_MS' ) ) {
+                       $this->curlOptions[CURLOPT_CONNECTTIMEOUT_MS] = $this->connectTimeout * 1000;
+               }
+
+               $this->curlOptions[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0;
+               $this->curlOptions[CURLOPT_WRITEFUNCTION] = $this->callback;
+               $this->curlOptions[CURLOPT_HEADERFUNCTION] = [ $this, "readHeader" ];
+               $this->curlOptions[CURLOPT_MAXREDIRS] = $this->maxRedirects;
+               $this->curlOptions[CURLOPT_ENCODING] = ""; # Enable compression
+
+               $this->curlOptions[CURLOPT_USERAGENT] = $this->reqHeaders['User-Agent'];
+
+               $this->curlOptions[CURLOPT_SSL_VERIFYHOST] = $this->sslVerifyHost ? 2 : 0;
+               $this->curlOptions[CURLOPT_SSL_VERIFYPEER] = $this->sslVerifyCert;
+
+               if ( $this->caInfo ) {
+                       $this->curlOptions[CURLOPT_CAINFO] = $this->caInfo;
+               }
+
+               if ( $this->headersOnly ) {
+                       $this->curlOptions[CURLOPT_NOBODY] = true;
+                       $this->curlOptions[CURLOPT_HEADER] = true;
+               } elseif ( $this->method == 'POST' ) {
+                       $this->curlOptions[CURLOPT_POST] = true;
+                       $postData = $this->postData;
+                       // Don't interpret POST parameters starting with '@' as file uploads, because this
+                       // makes it impossible to POST plain values starting with '@' (and causes security
+                       // issues potentially exposing the contents of local files).
+                       // The PHP manual says this option was introduced in PHP 5.5 defaults to true in PHP 5.6,
+                       // but we support lower versions, and the option doesn't exist in HHVM 5.6.99.
+                       if ( defined( 'CURLOPT_SAFE_UPLOAD' ) ) {
+                               $this->curlOptions[CURLOPT_SAFE_UPLOAD] = true;
+                       } elseif ( is_array( $postData ) ) {
+                               // In PHP 5.2 and later, '@' is interpreted as a file upload if POSTFIELDS
+                               // is an array, but not if it's a string. So convert $req['body'] to a string
+                               // for safety.
+                               $postData = wfArrayToCgi( $postData );
+                       }
+                       $this->curlOptions[CURLOPT_POSTFIELDS] = $postData;
+
+                       // Suppress 'Expect: 100-continue' header, as some servers
+                       // will reject it with a 417 and Curl won't auto retry
+                       // with HTTP 1.0 fallback
+                       $this->reqHeaders['Expect'] = '';
+               } else {
+                       $this->curlOptions[CURLOPT_CUSTOMREQUEST] = $this->method;
+               }
+
+               $this->curlOptions[CURLOPT_HTTPHEADER] = $this->getHeaderList();
+
+               $curlHandle = curl_init( $this->url );
+
+               if ( !curl_setopt_array( $curlHandle, $this->curlOptions ) ) {
+                       throw new MWException( "Error setting curl options." );
+               }
+
+               if ( $this->followRedirects && $this->canFollowRedirects() ) {
+                       MediaWiki\suppressWarnings();
+                       if ( !curl_setopt( $curlHandle, CURLOPT_FOLLOWLOCATION, true ) ) {
+                               $this->logger->debug( __METHOD__ . ": Couldn't set CURLOPT_FOLLOWLOCATION. " .
+                                       "Probably open_basedir is set.\n" );
+                               // Continue the processing. If it were in curl_setopt_array,
+                               // processing would have halted on its entry
+                       }
+                       MediaWiki\restoreWarnings();
+               }
+
+               if ( $this->profiler ) {
+                       $profileSection = $this->profiler->scopedProfileIn(
+                               __METHOD__ . '-' . $this->profileName
+                       );
+               }
+
+               $curlRes = curl_exec( $curlHandle );
+               if ( curl_errno( $curlHandle ) == CURLE_OPERATION_TIMEOUTED ) {
+                       $this->status->fatal( 'http-timed-out', $this->url );
+               } elseif ( $curlRes === false ) {
+                       $this->status->fatal( 'http-curl-error', curl_error( $curlHandle ) );
+               } else {
+                       $this->headerList = explode( "\r\n", $this->headerText );
+               }
+
+               curl_close( $curlHandle );
+
+               if ( $this->profiler ) {
+                       $this->profiler->scopedProfileOut( $profileSection );
+               }
+
+               $this->parseHeader();
+               $this->setStatus();
+
+               return $this->status;
+       }
+
+       /**
+        * @return bool
+        */
+       public function canFollowRedirects() {
+               $curlVersionInfo = curl_version();
+               if ( $curlVersionInfo['version_number'] < 0x071304 ) {
+                       $this->logger->debug( "Cannot follow redirects with libcurl < 7.19.4 due to CVE-2009-0037\n" );
+                       return false;
+               }
+
+               if ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) {
+                       if ( strval( ini_get( 'open_basedir' ) ) !== '' ) {
+                               $this->logger->debug( "Cannot follow redirects when open_basedir is set\n" );
+                               return false;
+                       }
+               }
+
+               return true;
+       }
+}
diff --git a/includes/http/Http.php b/includes/http/Http.php
new file mode 100644 (file)
index 0000000..43ae2d0
--- /dev/null
@@ -0,0 +1,163 @@
+<?php
+/**
+ * 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
+ */
+
+use MediaWiki\Logger\LoggerFactory;
+
+/**
+ * Various HTTP related functions
+ * @ingroup HTTP
+ */
+class Http {
+       static public $httpEngine = false;
+
+       /**
+        * Perform an HTTP request
+        *
+        * @param string $method HTTP method. Usually GET/POST
+        * @param string $url Full URL to act on. If protocol-relative, will be expanded to an http:// URL
+        * @param array $options Options to pass to MWHttpRequest object.
+        *      Possible keys for the array:
+        *    - timeout             Timeout length in seconds
+        *    - connectTimeout      Timeout for connection, in seconds (curl only)
+        *    - postData            An array of key-value pairs or a url-encoded form data
+        *    - proxy               The proxy to use.
+        *                          Otherwise it will use $wgHTTPProxy (if set)
+        *                          Otherwise it will use the environment variable "http_proxy" (if set)
+        *    - noProxy             Don't use any proxy at all. Takes precedence over proxy value(s).
+        *    - sslVerifyHost       Verify hostname against certificate
+        *    - sslVerifyCert       Verify SSL certificate
+        *    - caInfo              Provide CA information
+        *    - maxRedirects        Maximum number of redirects to follow (defaults to 5)
+        *    - followRedirects     Whether to follow redirects (defaults to false).
+        *                                  Note: this should only be used when the target URL is trusted,
+        *                                  to avoid attacks on intranet services accessible by HTTP.
+        *    - userAgent           A user agent, if you want to override the default
+        *                          MediaWiki/$wgVersion
+        *    - logger              A \Psr\Logger\LoggerInterface instance for debug logging
+        * @param string $caller The method making this request, for profiling
+        * @return string|bool (bool)false on failure or a string on success
+        */
+       public static function request( $method, $url, $options = [], $caller = __METHOD__ ) {
+               wfDebug( "HTTP: $method: $url\n" );
+
+               $options['method'] = strtoupper( $method );
+
+               if ( !isset( $options['timeout'] ) ) {
+                       $options['timeout'] = 'default';
+               }
+               if ( !isset( $options['connectTimeout'] ) ) {
+                       $options['connectTimeout'] = 'default';
+               }
+
+               $req = MWHttpRequest::factory( $url, $options, $caller );
+               $status = $req->execute();
+
+               if ( $status->isOK() ) {
+                       return $req->getContent();
+               } else {
+                       $errors = $status->getErrorsByType( 'error' );
+                       $logger = LoggerFactory::getInstance( 'http' );
+                       $logger->warning( $status->getWikiText( false, false, 'en' ),
+                               [ 'error' => $errors, 'caller' => $caller, 'content' => $req->getContent() ] );
+                       return false;
+               }
+       }
+
+       /**
+        * Simple wrapper for Http::request( 'GET' )
+        * @see Http::request()
+        * @since 1.25 Second parameter $timeout removed. Second parameter
+        * is now $options which can be given a 'timeout'
+        *
+        * @param string $url
+        * @param array $options
+        * @param string $caller The method making this request, for profiling
+        * @return string|bool false on error
+        */
+       public static function get( $url, $options = [], $caller = __METHOD__ ) {
+               $args = func_get_args();
+               if ( isset( $args[1] ) && ( is_string( $args[1] ) || is_numeric( $args[1] ) ) ) {
+                       // Second was used to be the timeout
+                       // And third parameter used to be $options
+                       wfWarn( "Second parameter should not be a timeout.", 2 );
+                       $options = isset( $args[2] ) && is_array( $args[2] ) ?
+                               $args[2] : [];
+                       $options['timeout'] = $args[1];
+                       $caller = __METHOD__;
+               }
+               return Http::request( 'GET', $url, $options, $caller );
+       }
+
+       /**
+        * Simple wrapper for Http::request( 'POST' )
+        * @see Http::request()
+        *
+        * @param string $url
+        * @param array $options
+        * @param string $caller The method making this request, for profiling
+        * @return string|bool false on error
+        */
+       public static function post( $url, $options = [], $caller = __METHOD__ ) {
+               return Http::request( 'POST', $url, $options, $caller );
+       }
+
+       /**
+        * A standard user-agent we can use for external requests.
+        * @return string
+        */
+       public static function userAgent() {
+               global $wgVersion;
+               return "MediaWiki/$wgVersion";
+       }
+
+       /**
+        * Checks that the given URI is a valid one. Hardcoding the
+        * protocols, because we only want protocols that both cURL
+        * and php support.
+        *
+        * file:// should not be allowed here for security purpose (r67684)
+        *
+        * @todo FIXME this is wildly inaccurate and fails to actually check most stuff
+        *
+        * @param string $uri URI to check for validity
+        * @return bool
+        */
+       public static function isValidURI( $uri ) {
+               return preg_match(
+                       '/^https?:\/\/[^\/\s]\S*$/D',
+                       $uri
+               );
+       }
+
+       /**
+        * Gets the relevant proxy from $wgHTTPProxy
+        *
+        * @return mixed The proxy address or an empty string if not set.
+        */
+       public static function getProxy() {
+               global $wgHTTPProxy;
+
+               if ( $wgHTTPProxy ) {
+                       return $wgHTTPProxy;
+               }
+
+               return "";
+       }
+}
diff --git a/includes/http/MWHttpRequest.php b/includes/http/MWHttpRequest.php
new file mode 100644 (file)
index 0000000..08883ae
--- /dev/null
@@ -0,0 +1,612 @@
+<?php
+/**
+ * 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
+ */
+
+use MediaWiki\Logger\LoggerFactory;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\NullLogger;
+
+/**
+ * This wrapper class will call out to curl (if available) or fallback
+ * to regular PHP if necessary for handling internal HTTP requests.
+ *
+ * Renamed from HttpRequest to MWHttpRequest to avoid conflict with
+ * PHP's HTTP extension.
+ */
+class MWHttpRequest implements LoggerAwareInterface {
+       const SUPPORTS_FILE_POSTS = false;
+
+       protected $content;
+       protected $timeout = 'default';
+       protected $headersOnly = null;
+       protected $postData = null;
+       protected $proxy = null;
+       protected $noProxy = false;
+       protected $sslVerifyHost = true;
+       protected $sslVerifyCert = true;
+       protected $caInfo = null;
+       protected $method = "GET";
+       protected $reqHeaders = [];
+       protected $url;
+       protected $parsedUrl;
+       protected $callback;
+       protected $maxRedirects = 5;
+       protected $followRedirects = false;
+
+       /**
+        * @var CookieJar
+        */
+       protected $cookieJar;
+
+       protected $headerList = [];
+       protected $respVersion = "0.9";
+       protected $respStatus = "200 Ok";
+       protected $respHeaders = [];
+
+       public $status;
+
+       /**
+        * @var Profiler
+        */
+       protected $profiler;
+
+       /**
+        * @var string
+        */
+       protected $profileName;
+
+       /**
+        * @var LoggerInterface;
+        */
+       protected $logger;
+
+       /**
+        * @param string $url Url to use. If protocol-relative, will be expanded to an http:// URL
+        * @param array $options (optional) extra params to pass (see Http::request())
+        * @param string $caller The method making this request, for profiling
+        * @param Profiler $profiler An instance of the profiler for profiling, or null
+        */
+       protected function __construct(
+               $url, $options = [], $caller = __METHOD__, $profiler = null
+       ) {
+               global $wgHTTPTimeout, $wgHTTPConnectTimeout;
+
+               $this->url = wfExpandUrl( $url, PROTO_HTTP );
+               $this->parsedUrl = wfParseUrl( $this->url );
+
+               if ( isset( $options['logger'] ) ) {
+                       $this->logger = $options['logger'];
+               } else {
+                       $this->logger = new NullLogger();
+               }
+
+               if ( !$this->parsedUrl || !Http::isValidURI( $this->url ) ) {
+                       $this->status = Status::newFatal( 'http-invalid-url', $url );
+               } else {
+                       $this->status = Status::newGood( 100 ); // continue
+               }
+
+               if ( isset( $options['timeout'] ) && $options['timeout'] != 'default' ) {
+                       $this->timeout = $options['timeout'];
+               } else {
+                       $this->timeout = $wgHTTPTimeout;
+               }
+               if ( isset( $options['connectTimeout'] ) && $options['connectTimeout'] != 'default' ) {
+                       $this->connectTimeout = $options['connectTimeout'];
+               } else {
+                       $this->connectTimeout = $wgHTTPConnectTimeout;
+               }
+               if ( isset( $options['userAgent'] ) ) {
+                       $this->setUserAgent( $options['userAgent'] );
+               }
+
+               $members = [ "postData", "proxy", "noProxy", "sslVerifyHost", "caInfo",
+                               "method", "followRedirects", "maxRedirects", "sslVerifyCert", "callback" ];
+
+               foreach ( $members as $o ) {
+                       if ( isset( $options[$o] ) ) {
+                               // ensure that MWHttpRequest::method is always
+                               // uppercased. Bug 36137
+                               if ( $o == 'method' ) {
+                                       $options[$o] = strtoupper( $options[$o] );
+                               }
+                               $this->$o = $options[$o];
+                       }
+               }
+
+               if ( $this->noProxy ) {
+                       $this->proxy = ''; // noProxy takes precedence
+               }
+
+               // Profile based on what's calling us
+               $this->profiler = $profiler;
+               $this->profileName = $caller;
+       }
+
+       /**
+        * @param LoggerInterface $logger
+        */
+       public function setLogger( LoggerInterface $logger ) {
+               $this->logger = $logger;
+       }
+
+       /**
+        * Simple function to test if we can make any sort of requests at all, using
+        * cURL or fopen()
+        * @return bool
+        */
+       public static function canMakeRequests() {
+               return function_exists( 'curl_init' ) || wfIniGetBool( 'allow_url_fopen' );
+       }
+
+       /**
+        * Generate a new request object
+        * @param string $url Url to use
+        * @param array $options (optional) extra params to pass (see Http::request())
+        * @param string $caller The method making this request, for profiling
+        * @throws MWException
+        * @return CurlHttpRequest|PhpHttpRequest
+        * @see MWHttpRequest::__construct
+        */
+       public static function factory( $url, $options = null, $caller = __METHOD__ ) {
+               if ( !Http::$httpEngine ) {
+                       Http::$httpEngine = function_exists( 'curl_init' ) ? 'curl' : 'php';
+               } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) {
+                       throw new MWException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' .
+                               ' Http::$httpEngine is set to "curl"' );
+               }
+
+               if ( !is_array( $options ) ) {
+                       $options = [];
+               }
+
+               if ( !isset( $options['logger'] ) ) {
+                       $options['logger'] = LoggerFactory::getInstance( 'http' );
+               }
+
+               switch ( Http::$httpEngine ) {
+                       case 'curl':
+                               return new CurlHttpRequest( $url, $options, $caller, Profiler::instance() );
+                       case 'php':
+                               if ( !wfIniGetBool( 'allow_url_fopen' ) ) {
+                                       throw new MWException( __METHOD__ . ': allow_url_fopen ' .
+                                               'needs to be enabled for pure PHP http requests to ' .
+                                               'work. If possible, curl should be used instead. See ' .
+                                               'http://php.net/curl.'
+                                       );
+                               }
+                               return new PhpHttpRequest( $url, $options, $caller, Profiler::instance() );
+                       default:
+                               throw new MWException( __METHOD__ . ': The setting of Http::$httpEngine is not valid.' );
+               }
+       }
+
+       /**
+        * Get the body, or content, of the response to the request
+        *
+        * @return string
+        */
+       public function getContent() {
+               return $this->content;
+       }
+
+       /**
+        * Set the parameters of the request
+        *
+        * @param array $args
+        * @todo overload the args param
+        */
+       public function setData( $args ) {
+               $this->postData = $args;
+       }
+
+       /**
+        * Take care of setting up the proxy (do nothing if "noProxy" is set)
+        *
+        * @return void
+        */
+       public function proxySetup() {
+               // If there is an explicit proxy set and proxies are not disabled, then use it
+               if ( $this->proxy && !$this->noProxy ) {
+                       return;
+               }
+
+               // Otherwise, fallback to $wgHTTPProxy if this is not a machine
+               // local URL and proxies are not disabled
+               if ( self::isLocalURL( $this->url ) || $this->noProxy ) {
+                       $this->proxy = '';
+               } else {
+                       $this->proxy = Http::getProxy();
+               }
+       }
+
+       /**
+        * Check if the URL can be served by localhost
+        *
+        * @param string $url Full url to check
+        * @return bool
+        */
+       private static function isLocalURL( $url ) {
+               global $wgCommandLineMode, $wgLocalVirtualHosts;
+
+               if ( $wgCommandLineMode ) {
+                       return false;
+               }
+
+               // Extract host part
+               $matches = [];
+               if ( preg_match( '!^https?://([\w.-]+)[/:].*$!', $url, $matches ) ) {
+                       $host = $matches[1];
+                       // Split up dotwise
+                       $domainParts = explode( '.', $host );
+                       // Check if this domain or any superdomain is listed as a local virtual host
+                       $domainParts = array_reverse( $domainParts );
+
+                       $domain = '';
+                       $countParts = count( $domainParts );
+                       for ( $i = 0; $i < $countParts; $i++ ) {
+                               $domainPart = $domainParts[$i];
+                               if ( $i == 0 ) {
+                                       $domain = $domainPart;
+                               } else {
+                                       $domain = $domainPart . '.' . $domain;
+                               }
+
+                               if ( in_array( $domain, $wgLocalVirtualHosts ) ) {
+                                       return true;
+                               }
+                       }
+               }
+
+               return false;
+       }
+
+       /**
+        * Set the user agent
+        * @param string $UA
+        */
+       public function setUserAgent( $UA ) {
+               $this->setHeader( 'User-Agent', $UA );
+       }
+
+       /**
+        * Set an arbitrary header
+        * @param string $name
+        * @param string $value
+        */
+       public function setHeader( $name, $value ) {
+               // I feel like I should normalize the case here...
+               $this->reqHeaders[$name] = $value;
+       }
+
+       /**
+        * Get an array of the headers
+        * @return array
+        */
+       public function getHeaderList() {
+               $list = [];
+
+               if ( $this->cookieJar ) {
+                       $this->reqHeaders['Cookie'] =
+                               $this->cookieJar->serializeToHttpRequest(
+                                       $this->parsedUrl['path'],
+                                       $this->parsedUrl['host']
+                               );
+               }
+
+               foreach ( $this->reqHeaders as $name => $value ) {
+                       $list[] = "$name: $value";
+               }
+
+               return $list;
+       }
+
+       /**
+        * Set a read callback to accept data read from the HTTP request.
+        * By default, data is appended to an internal buffer which can be
+        * retrieved through $req->getContent().
+        *
+        * To handle data as it comes in -- especially for large files that
+        * would not fit in memory -- you can instead set your own callback,
+        * in the form function($resource, $buffer) where the first parameter
+        * is the low-level resource being read (implementation specific),
+        * and the second parameter is the data buffer.
+        *
+        * You MUST return the number of bytes handled in the buffer; if fewer
+        * bytes are reported handled than were passed to you, the HTTP fetch
+        * will be aborted.
+        *
+        * @param callable $callback
+        * @throws MWException
+        */
+       public function setCallback( $callback ) {
+               if ( !is_callable( $callback ) ) {
+                       throw new MWException( 'Invalid MwHttpRequest callback' );
+               }
+               $this->callback = $callback;
+       }
+
+       /**
+        * A generic callback to read the body of the response from a remote
+        * server.
+        *
+        * @param resource $fh
+        * @param string $content
+        * @return int
+        */
+       public function read( $fh, $content ) {
+               $this->content .= $content;
+               return strlen( $content );
+       }
+
+       /**
+        * Take care of whatever is necessary to perform the URI request.
+        *
+        * @return Status
+        */
+       public function execute() {
+               $this->content = "";
+
+               if ( strtoupper( $this->method ) == "HEAD" ) {
+                       $this->headersOnly = true;
+               }
+
+               $this->proxySetup(); // set up any proxy as needed
+
+               if ( !$this->callback ) {
+                       $this->setCallback( [ $this, 'read' ] );
+               }
+
+               if ( !isset( $this->reqHeaders['User-Agent'] ) ) {
+                       $this->setUserAgent( Http::userAgent() );
+               }
+       }
+
+       /**
+        * Parses the headers, including the HTTP status code and any
+        * Set-Cookie headers.  This function expects the headers to be
+        * found in an array in the member variable headerList.
+        */
+       protected function parseHeader() {
+               $lastname = "";
+
+               foreach ( $this->headerList as $header ) {
+                       if ( preg_match( "#^HTTP/([0-9.]+) (.*)#", $header, $match ) ) {
+                               $this->respVersion = $match[1];
+                               $this->respStatus = $match[2];
+                       } elseif ( preg_match( "#^[ \t]#", $header ) ) {
+                               $last = count( $this->respHeaders[$lastname] ) - 1;
+                               $this->respHeaders[$lastname][$last] .= "\r\n$header";
+                       } elseif ( preg_match( "#^([^:]*):[\t ]*(.*)#", $header, $match ) ) {
+                               $this->respHeaders[strtolower( $match[1] )][] = $match[2];
+                               $lastname = strtolower( $match[1] );
+                       }
+               }
+
+               $this->parseCookies();
+       }
+
+       /**
+        * Sets HTTPRequest status member to a fatal value with the error
+        * message if the returned integer value of the status code was
+        * not successful (< 300) or a redirect (>=300 and < 400).  (see
+        * RFC2616, section 10,
+        * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html for a
+        * list of status codes.)
+        */
+       protected function setStatus() {
+               if ( !$this->respHeaders ) {
+                       $this->parseHeader();
+               }
+
+               if ( (int)$this->respStatus > 399 ) {
+                       list( $code, $message ) = explode( " ", $this->respStatus, 2 );
+                       $this->status->fatal( "http-bad-status", $code, $message );
+               }
+       }
+
+       /**
+        * Get the integer value of the HTTP status code (e.g. 200 for "200 Ok")
+        * (see RFC2616, section 10, http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
+        * for a list of status codes.)
+        *
+        * @return int
+        */
+       public function getStatus() {
+               if ( !$this->respHeaders ) {
+                       $this->parseHeader();
+               }
+
+               return (int)$this->respStatus;
+       }
+
+       /**
+        * Returns true if the last status code was a redirect.
+        *
+        * @return bool
+        */
+       public function isRedirect() {
+               if ( !$this->respHeaders ) {
+                       $this->parseHeader();
+               }
+
+               $status = (int)$this->respStatus;
+
+               if ( $status >= 300 && $status <= 303 ) {
+                       return true;
+               }
+
+               return false;
+       }
+
+       /**
+        * Returns an associative array of response headers after the
+        * request has been executed.  Because some headers
+        * (e.g. Set-Cookie) can appear more than once the, each value of
+        * the associative array is an array of the values given.
+        *
+        * @return array
+        */
+       public function getResponseHeaders() {
+               if ( !$this->respHeaders ) {
+                       $this->parseHeader();
+               }
+
+               return $this->respHeaders;
+       }
+
+       /**
+        * Returns the value of the given response header.
+        *
+        * @param string $header
+        * @return string|null
+        */
+       public function getResponseHeader( $header ) {
+               if ( !$this->respHeaders ) {
+                       $this->parseHeader();
+               }
+
+               if ( isset( $this->respHeaders[strtolower( $header )] ) ) {
+                       $v = $this->respHeaders[strtolower( $header )];
+                       return $v[count( $v ) - 1];
+               }
+
+               return null;
+       }
+
+       /**
+        * Tells the MWHttpRequest object to use this pre-loaded CookieJar.
+        *
+        * @param CookieJar $jar
+        */
+       public function setCookieJar( $jar ) {
+               $this->cookieJar = $jar;
+       }
+
+       /**
+        * Returns the cookie jar in use.
+        *
+        * @return CookieJar
+        */
+       public function getCookieJar() {
+               if ( !$this->respHeaders ) {
+                       $this->parseHeader();
+               }
+
+               return $this->cookieJar;
+       }
+
+       /**
+        * Sets a cookie. Used before a request to set up any individual
+        * cookies. Used internally after a request to parse the
+        * Set-Cookie headers.
+        * @see Cookie::set
+        * @param string $name
+        * @param mixed $value
+        * @param array $attr
+        */
+       public function setCookie( $name, $value = null, $attr = null ) {
+               if ( !$this->cookieJar ) {
+                       $this->cookieJar = new CookieJar;
+               }
+
+               $this->cookieJar->setCookie( $name, $value, $attr );
+       }
+
+       /**
+        * Parse the cookies in the response headers and store them in the cookie jar.
+        */
+       protected function parseCookies() {
+               if ( !$this->cookieJar ) {
+                       $this->cookieJar = new CookieJar;
+               }
+
+               if ( isset( $this->respHeaders['set-cookie'] ) ) {
+                       $url = parse_url( $this->getFinalUrl() );
+                       foreach ( $this->respHeaders['set-cookie'] as $cookie ) {
+                               $this->cookieJar->parseCookieResponseHeader( $cookie, $url['host'] );
+                       }
+               }
+       }
+
+       /**
+        * Returns the final URL after all redirections.
+        *
+        * Relative values of the "Location" header are incorrect as
+        * stated in RFC, however they do happen and modern browsers
+        * support them.  This function loops backwards through all
+        * locations in order to build the proper absolute URI - Marooned
+        * at wikia-inc.com
+        *
+        * Note that the multiple Location: headers are an artifact of
+        * CURL -- they shouldn't actually get returned this way. Rewrite
+        * this when bug 29232 is taken care of (high-level redirect
+        * handling rewrite).
+        *
+        * @return string
+        */
+       public function getFinalUrl() {
+               $headers = $this->getResponseHeaders();
+
+               // return full url (fix for incorrect but handled relative location)
+               if ( isset( $headers['location'] ) ) {
+                       $locations = $headers['location'];
+                       $domain = '';
+                       $foundRelativeURI = false;
+                       $countLocations = count( $locations );
+
+                       for ( $i = $countLocations - 1; $i >= 0; $i-- ) {
+                               $url = parse_url( $locations[$i] );
+
+                               if ( isset( $url['host'] ) ) {
+                                       $domain = $url['scheme'] . '://' . $url['host'];
+                                       break; // found correct URI (with host)
+                               } else {
+                                       $foundRelativeURI = true;
+                               }
+                       }
+
+                       if ( $foundRelativeURI ) {
+                               if ( $domain ) {
+                                       return $domain . $locations[$countLocations - 1];
+                               } else {
+                                       $url = parse_url( $this->url );
+                                       if ( isset( $url['host'] ) ) {
+                                               return $url['scheme'] . '://' . $url['host'] .
+                                                       $locations[$countLocations - 1];
+                                       }
+                               }
+                       } else {
+                               return $locations[$countLocations - 1];
+                       }
+               }
+
+               return $this->url;
+       }
+
+       /**
+        * Returns true if the backend can follow redirects. Overridden by the
+        * child classes.
+        * @return bool
+        */
+       public function canFollowRedirects() {
+               return true;
+       }
+}
diff --git a/includes/http/PhpHttpRequest.php b/includes/http/PhpHttpRequest.php
new file mode 100644 (file)
index 0000000..2af000f
--- /dev/null
@@ -0,0 +1,258 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+class PhpHttpRequest extends MWHttpRequest {
+
+       private $fopenErrors = [];
+
+       /**
+        * @param string $url
+        * @return string
+        */
+       protected function urlToTcp( $url ) {
+               $parsedUrl = parse_url( $url );
+
+               return 'tcp://' . $parsedUrl['host'] . ':' . $parsedUrl['port'];
+       }
+
+       /**
+        * Returns an array with a 'capath' or 'cafile' key
+        * that is suitable to be merged into the 'ssl' sub-array of
+        * a stream context options array.
+        * Uses the 'caInfo' option of the class if it is provided, otherwise uses the system
+        * default CA bundle if PHP supports that, or searches a few standard locations.
+        * @return array
+        * @throws DomainException
+        */
+       protected function getCertOptions() {
+               $certOptions = [];
+               $certLocations = [];
+               if ( $this->caInfo ) {
+                       $certLocations = [ 'manual' => $this->caInfo ];
+               } elseif ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) {
+                       // @codingStandardsIgnoreStart Generic.Files.LineLength
+                       // Default locations, based on
+                       // https://www.happyassassin.net/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/
+                       // PHP 5.5 and older doesn't have any defaults, so we try to guess ourselves.
+                       // PHP 5.6+ gets the CA location from OpenSSL as long as it is not set manually,
+                       // so we should leave capath/cafile empty there.
+                       // @codingStandardsIgnoreEnd
+                       $certLocations = array_filter( [
+                               getenv( 'SSL_CERT_DIR' ),
+                               getenv( 'SSL_CERT_PATH' ),
+                               '/etc/pki/tls/certs/ca-bundle.crt', # Fedora et al
+                               '/etc/ssl/certs',  # Debian et al
+                               '/etc/pki/tls/certs/ca-bundle.trust.crt',
+                               '/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem',
+                               '/System/Library/OpenSSL', # OSX
+                       ] );
+               }
+
+               foreach ( $certLocations as $key => $cert ) {
+                       if ( is_dir( $cert ) ) {
+                               $certOptions['capath'] = $cert;
+                               break;
+                       } elseif ( is_file( $cert ) ) {
+                               $certOptions['cafile'] = $cert;
+                               break;
+                       } elseif ( $key === 'manual' ) {
+                               // fail more loudly if a cert path was manually configured and it is not valid
+                               throw new DomainException( "Invalid CA info passed: $cert" );
+                       }
+               }
+
+               return $certOptions;
+       }
+
+       /**
+        * Custom error handler for dealing with fopen() errors.
+        * fopen() tends to fire multiple errors in succession, and the last one
+        * is completely useless (something like "fopen: failed to open stream")
+        * so normal methods of handling errors programmatically
+        * like get_last_error() don't work.
+        */
+       public function errorHandler( $errno, $errstr ) {
+               $n = count( $this->fopenErrors ) + 1;
+               $this->fopenErrors += [ "errno$n" => $errno, "errstr$n" => $errstr ];
+       }
+
+       public function execute() {
+
+               parent::execute();
+
+               if ( is_array( $this->postData ) ) {
+                       $this->postData = wfArrayToCgi( $this->postData );
+               }
+
+               if ( $this->parsedUrl['scheme'] != 'http'
+                       && $this->parsedUrl['scheme'] != 'https' ) {
+                       $this->status->fatal( 'http-invalid-scheme', $this->parsedUrl['scheme'] );
+               }
+
+               $this->reqHeaders['Accept'] = "*/*";
+               $this->reqHeaders['Connection'] = 'Close';
+               if ( $this->method == 'POST' ) {
+                       // Required for HTTP 1.0 POSTs
+                       $this->reqHeaders['Content-Length'] = strlen( $this->postData );
+                       if ( !isset( $this->reqHeaders['Content-Type'] ) ) {
+                               $this->reqHeaders['Content-Type'] = "application/x-www-form-urlencoded";
+                       }
+               }
+
+               // Set up PHP stream context
+               $options = [
+                       'http' => [
+                               'method' => $this->method,
+                               'header' => implode( "\r\n", $this->getHeaderList() ),
+                               'protocol_version' => '1.1',
+                               'max_redirects' => $this->followRedirects ? $this->maxRedirects : 0,
+                               'ignore_errors' => true,
+                               'timeout' => $this->timeout,
+                               // Curl options in case curlwrappers are installed
+                               'curl_verify_ssl_host' => $this->sslVerifyHost ? 2 : 0,
+                               'curl_verify_ssl_peer' => $this->sslVerifyCert,
+                       ],
+                       'ssl' => [
+                               'verify_peer' => $this->sslVerifyCert,
+                               'SNI_enabled' => true,
+                               'ciphers' => 'HIGH:!SSLv2:!SSLv3:-ADH:-kDH:-kECDH:-DSS',
+                               'disable_compression' => true,
+                       ],
+               ];
+
+               if ( $this->proxy ) {
+                       $options['http']['proxy'] = $this->urlToTcp( $this->proxy );
+                       $options['http']['request_fulluri'] = true;
+               }
+
+               if ( $this->postData ) {
+                       $options['http']['content'] = $this->postData;
+               }
+
+               if ( $this->sslVerifyHost ) {
+                       // PHP 5.6.0 deprecates CN_match, in favour of peer_name which
+                       // actually checks SubjectAltName properly.
+                       if ( version_compare( PHP_VERSION, '5.6.0', '>=' ) ) {
+                               $options['ssl']['peer_name'] = $this->parsedUrl['host'];
+                       } else {
+                               $options['ssl']['CN_match'] = $this->parsedUrl['host'];
+                       }
+               }
+
+               $options['ssl'] += $this->getCertOptions();
+
+               $context = stream_context_create( $options );
+
+               $this->headerList = [];
+               $reqCount = 0;
+               $url = $this->url;
+
+               $result = [];
+
+               if ( $this->profiler ) {
+                       $profileSection = $this->profiler->scopedProfileIn(
+                               __METHOD__ . '-' . $this->profileName
+                       );
+               }
+               do {
+                       $reqCount++;
+                       $this->fopenErrors = [];
+                       set_error_handler( [ $this, 'errorHandler' ] );
+                       $fh = fopen( $url, "r", false, $context );
+                       restore_error_handler();
+
+                       if ( !$fh ) {
+                               // HACK for instant commons.
+                               // If we are contacting (commons|upload).wikimedia.org
+                               // try again with CN_match for en.wikipedia.org
+                               // as php does not handle SubjectAltName properly
+                               // prior to "peer_name" option in php 5.6
+                               if ( isset( $options['ssl']['CN_match'] )
+                                       && ( $options['ssl']['CN_match'] === 'commons.wikimedia.org'
+                                               || $options['ssl']['CN_match'] === 'upload.wikimedia.org' )
+                               ) {
+                                       $options['ssl']['CN_match'] = 'en.wikipedia.org';
+                                       $context = stream_context_create( $options );
+                                       continue;
+                               }
+                               break;
+                       }
+
+                       $result = stream_get_meta_data( $fh );
+                       $this->headerList = $result['wrapper_data'];
+                       $this->parseHeader();
+
+                       if ( !$this->followRedirects ) {
+                               break;
+                       }
+
+                       # Handle manual redirection
+                       if ( !$this->isRedirect() || $reqCount > $this->maxRedirects ) {
+                               break;
+                       }
+                       # Check security of URL
+                       $url = $this->getResponseHeader( "Location" );
+
+                       if ( !Http::isValidURI( $url ) ) {
+                               $this->logger->debug( __METHOD__ . ": insecure redirection\n" );
+                               break;
+                       }
+               } while ( true );
+               if ( $this->profiler ) {
+                       $this->profiler->scopedProfileOut( $profileSection );
+               }
+
+               $this->setStatus();
+
+               if ( $fh === false ) {
+                       if ( $this->fopenErrors ) {
+                               $this->logger->warning( __CLASS__
+                                       . ': error opening connection: {errstr1}', $this->fopenErrors );
+                       }
+                       $this->status->fatal( 'http-request-error' );
+                       return $this->status;
+               }
+
+               if ( $result['timed_out'] ) {
+                       $this->status->fatal( 'http-timed-out', $this->url );
+                       return $this->status;
+               }
+
+               // If everything went OK, or we received some error code
+               // get the response body content.
+               if ( $this->status->isOK() || (int)$this->respStatus >= 300 ) {
+                       while ( !feof( $fh ) ) {
+                               $buf = fread( $fh, 8192 );
+
+                               if ( $buf === false ) {
+                                       $this->status->fatal( 'http-read-error' );
+                                       break;
+                               }
+
+                               if ( strlen( $buf ) ) {
+                                       call_user_func( $this->callback, $fh, $buf );
+                               }
+                       }
+               }
+               fclose( $fh );
+
+               return $this->status;
+       }
+}
index 2b84144..50d73de 100644 (file)
@@ -41,7 +41,7 @@ abstract class DatabaseInstaller {
        /**
         * The database connection.
         *
-        * @var DatabaseBase
+        * @var Database
         */
        public $db = null;
 
@@ -336,7 +336,6 @@ abstract class DatabaseInstaller {
                $services->redefineService( 'DBLoadBalancerFactory', function() use ( $connection ) {
                        return LBFactorySingle::newFromConnection( $connection );
                } );
-
        }
 
        /**
index fbdc934..6a702e9 100644 (file)
@@ -57,7 +57,7 @@ abstract class DatabaseUpdater {
        /**
         * Handle to the database subclass
         *
-        * @var DatabaseBase
+        * @var Database
         */
        protected $db;
 
@@ -77,6 +77,7 @@ abstract class DatabaseUpdater {
                PopulateBacklinkNamespace::class,
                FixDefaultJsonContentPages::class,
                CleanupEmptyCategories::class,
+               AddRFCAndPMIDInterwiki::class,
        ];
 
        /**
@@ -192,7 +193,7 @@ abstract class DatabaseUpdater {
        /**
         * Get a database connection to run updates
         *
-        * @return DatabaseBase
+        * @return Database
         */
        public function getDB() {
                return $this->db;
@@ -221,12 +222,11 @@ abstract class DatabaseUpdater {
         *
         * @since 1.17
         *
-        * @param array $update The update to run. Format is the following:
-        *                first item is the callback function, it also can be a
-        *                simple string with the name of a function in this class,
-        *                following elements are parameters to the function.
-        *                Note that callback functions will receive this object as
-        *                first parameter.
+        * @param array $update The update to run. Format is [ $callback, $params... ]
+        *   $callback is the method to call; either a DatabaseUpdater method name or a callable.
+        *   Must be serializable (ie. no anonymous functions allowed). The rest of the parameters
+        *   (if any) will be passed to the callback. The first parameter passed to the callback
+        *   is always this object.
         */
        public function addExtensionUpdate( array $update ) {
                $this->extensionUpdates[] = $update;
@@ -633,7 +633,11 @@ abstract class DatabaseUpdater {
         * @param string $filename File name to open
         */
        public function copyFile( $filename ) {
-               $this->db->sourceFile( $filename, false, false, false,
+               $this->db->sourceFile(
+                       $filename,
+                       null,
+                       null,
+                       __METHOD__,
                        [ $this, 'appendLine' ]
                );
        }
index eafb9d4..03f9974 100644 (file)
@@ -244,6 +244,7 @@ abstract class Installer {
        protected $objectCaches = [
                'xcache' => 'xcache_get',
                'apc' => 'apc_fetch',
+               'apcu' => 'apcu_fetch',
                'wincache' => 'wincache_ucache_get'
        ];
 
index 739be82..5e8ed3f 100644 (file)
@@ -182,7 +182,7 @@ class MssqlInstaller extends DatabaseInstaller {
                        return $status;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
 
@@ -240,7 +240,7 @@ class MssqlInstaller extends DatabaseInstaller {
                        return;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
                $conn->selectDB( $this->getVar( 'wgDBname' ) );
@@ -282,7 +282,7 @@ class MssqlInstaller extends DatabaseInstaller {
                // Check to ensure we can grant everything needed as well
                // We can't actually tell if we have WITH GRANT OPTION for a given permission, so we assume we do
                // and just check for the permission
-               // http://technet.microsoft.com/en-us/library/ms178569.aspx
+               // https://technet.microsoft.com/en-us/library/ms178569.aspx
                // The following array sets up which permissions imply whatever permissions we specify
                $implied = [
                        // schema           database  server
index 770d3bf..1175e9e 100644 (file)
@@ -92,6 +92,8 @@ class MssqlUpdater extends DatabaseUpdater {
                        // 1.28
                        [ 'addIndex', 'recentchanges', 'rc_name_type_patrolled_timestamp',
                                'patch-add-rc_name_type_patrolled_timestamp_index.sql' ],
+                       [ 'addField', 'change_tag', 'ct_id', 'patch-change_tag-ct_id.sql' ],
+                       [ 'addField', 'tag_summary', 'ts_id', 'patch-tag_summary-ts_id.sql' ],
                ];
        }
 
index 812742c..5ff47e9 100644 (file)
@@ -124,7 +124,7 @@ class MysqlInstaller extends DatabaseInstaller {
                        return $status;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
 
@@ -168,7 +168,7 @@ class MysqlInstaller extends DatabaseInstaller {
                        return;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
                $conn->selectDB( $this->getVar( 'wgDBname' ) );
@@ -226,7 +226,7 @@ class MysqlInstaller extends DatabaseInstaller {
                $status = $this->getConnection();
 
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
 
index 693b6ff..a637ce0 100644 (file)
@@ -288,6 +288,9 @@ class MysqlUpdater extends DatabaseUpdater {
                                'patch-add-rc_name_type_patrolled_timestamp_index.sql' ],
                        [ 'doRevisionPageRevIndexNonUnique' ],
                        [ 'doNonUniquePlTlIl' ],
+                       [ 'addField', 'change_tag', 'ct_id', 'patch-change_tag-ct_id.sql' ],
+                       [ 'addField', 'tag_summary', 'ts_id', 'patch-tag_summary-ts_id.sql' ],
+                       [ 'modifyField', 'recentchanges', 'rc_ip', 'patch-rc_ip_modify.sql' ],
                ];
        }
 
index 8610834..b8fc4e7 100644 (file)
@@ -150,7 +150,7 @@ class OracleInstaller extends DatabaseInstaller {
                }
 
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
 
index 8075aac..e1e0d0f 100644 (file)
@@ -116,6 +116,8 @@ class OracleUpdater extends DatabaseUpdater {
                        // 1.28
                        [ 'addIndex', 'recentchanges', 'rc_name_type_patrolled_timestamp',
                                'patch-add-rc_name_type_patrolled_timestamp_index.sql' ],
+                       [ 'addField', 'change_tag', 'ct_id', 'patch-change_tag-ct_id.sql' ],
+                       [ 'addField', 'tag_summary', 'ts_id', 'patch-tag_summary-ts_id.sql' ],
 
                        // KEEP THIS AT THE BOTTOM!!
                        [ 'doRebuildDuplicateFunction' ],
index 01327be..d412216 100644 (file)
@@ -24,7 +24,7 @@
 /**
  * Test for PHP+libxml2 bug which breaks XML input subtly with certain versions.
  * Known fixed with PHP 5.2.9 + libxml2-2.7.3
- * @see http://bugs.php.net/bug.php?id=45996
+ * @see https://bugs.php.net/bug.php?id=45996
  * @ingroup PHPBugTests
  */
 class PhpXmlBugTester {
index 7a2794d..6dfa28b 100644 (file)
@@ -114,7 +114,7 @@ class PostgresInstaller extends DatabaseInstaller {
                        return $status;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
 
@@ -181,7 +181,7 @@ class PostgresInstaller extends DatabaseInstaller {
 
                if ( $status->isOK() ) {
                        /**
-                        * @var $conn DatabaseBase
+                        * @var $conn Database
                         */
                        $conn = $status->value;
                        $conn->clearFlag( DBO_TRX );
@@ -233,7 +233,7 @@ class PostgresInstaller extends DatabaseInstaller {
                                $status = $this->openPgConnection( 'create-schema' );
                                if ( $status->isOK() ) {
                                        /**
-                                        * @var $conn DatabaseBase
+                                        * @var $conn Database
                                         */
                                        $conn = $status->value;
                                        $safeRole = $conn->addIdentifierQuotes( $this->getVar( 'wgDBuser' ) );
@@ -287,7 +287,7 @@ class PostgresInstaller extends DatabaseInstaller {
                        return false;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
                $superuser = $this->getVar( '_InstallUser' );
@@ -587,9 +587,7 @@ class PostgresInstaller extends DatabaseInstaller {
                        return $status;
                }
 
-               /**
-                * @var $conn DatabaseBase
-                */
+               /** @var $conn DatabasePostgres */
                $conn = $status->value;
 
                if ( $conn->tableExists( 'archive' ) ) {
@@ -606,7 +604,7 @@ class PostgresInstaller extends DatabaseInstaller {
 
                        return $status;
                }
-               $error = $conn->sourceFile( $conn->getSchemaPath() );
+               $error = $conn->sourceFile( $this->getSchemaPath( $conn ) );
                if ( $error !== true ) {
                        $conn->reportQueryError( $error, 0, '', __METHOD__ );
                        $conn->rollback( __METHOD__ );
@@ -638,7 +636,7 @@ class PostgresInstaller extends DatabaseInstaller {
                        return $status;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
 
index be94d91..790fbe7 100644 (file)
@@ -68,6 +68,8 @@ class PostgresUpdater extends DatabaseUpdater {
                        [ 'addSequence', 'archive', false, 'archive_ar_id_seq' ],
                        [ 'addSequence', 'externallinks', false, 'externallinks_el_id_seq' ],
                        [ 'addSequence', 'watchlist', false, 'watchlist_wl_id_seq' ],
+                       [ 'addSequence', 'change_tag', false, 'change_tag_ct_id_seq' ],
+                       [ 'addSequence', 'tag_summary', false, 'tag_summary_ts_id_seq' ],
 
                        # new tables
                        [ 'addTable', 'category', 'patch-category.sql' ],
@@ -437,6 +439,10 @@ class PostgresUpdater extends DatabaseUpdater {
                        // 1.28
                        [ 'addPgIndex', 'recentchanges', 'rc_name_type_patrolled_timestamp',
                                '( rc_namespace, rc_type, rc_patrolled, rc_timestamp )' ],
+                       [ 'addPgField', 'change_tag', 'ct_id',
+                               "INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('change_tag_ct_id_seq')" ],
+                       [ 'addPgField', 'tag_summary', 'ts_id',
+                               "INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('tag_summary_ts_id_seq')" ],
                ];
        }
 
@@ -969,7 +975,7 @@ END;
        protected function rebuildTextSearch() {
                if ( $this->updateRowExists( 'patch-textsearch_bug66650.sql' ) ) {
                        $this->output( "...bug 66650 already fixed or not applicable.\n" );
-                       return true;
+                       return;
                };
                $this->applyPatch( 'patch-textsearch_bug66650.sql', false,
                        'Rebuilding text search for bug 66650' );
index 1c6e6eb..388c034 100644 (file)
@@ -156,6 +156,8 @@ class SqliteUpdater extends DatabaseUpdater {
                        // 1.28
                        [ 'addIndex', 'recentchanges', 'rc_name_type_patrolled_timestamp',
                                'patch-add-rc_name_type_patrolled_timestamp_index.sql' ],
+                       [ 'addField', 'change_tag', 'ct_id', 'patch-change_tag-ct_id.sql' ],
+                       [ 'addField', 'tag_summary', 'ts_id', 'patch-tag_summary-ts_id.sql' ],
                ];
        }
 
index 239ad7e..8142abd 100644 (file)
@@ -8,7 +8,8 @@
                        "Claw eg",
                        "Kuwaity26",
                        "محمد أحمد عبد الفتاح",
-                       "Maroen1990"
+                       "Maroen1990",
+                       "Super ninja2"
                ]
        },
        "config-desc": "مثبت لميدياويكي",
@@ -47,6 +48,8 @@
        "config-page-existingwiki": "ويكي موجودة",
        "config-help-restart": "هل تريد إزالة البيانات المحفوظة التي قد قمت بإدخالها وإعادة تشغيل عملية التثبيت؟",
        "config-restart": "نعم، إعادة التشغيل",
+       "config-welcome": "=== التحقق من البيئة ===\nسوف يتم الآن التحقق من أن البيئة مناسبة لتنصيب ميديا ويكي.\nتذكر تضمين هذه المعلومات اذا اردت طلب المساعدة عن كيفية إكمال التنصيب.",
+       "config-copyright": "=== حقوق النسخ والشروط ===\n\n$1\n\nهذا البرنامج هو برنامج حر؛ يمكنك إعادة توزيعه و/أو تعديله تحت شروط رخصة جنو العامة على أن هذا البرنامج قد نُشر من قِبل مؤسسة البرمجيات الحرة؛ إما النسخة 2 من الرخصة، أو أي نسخة أخرى بعدها (من إختيارك)\n\nتم توزيع هذا البرنامج على أمل ان يكون مفيدًا ولكن <strong> دون أية ضمانات</strong>؛ دون حتى أية ضمانات مفهومة ضمنيًا أو رواجات أو أية أسباب محددة.\nأنظر رخصة جنو العامة لمزيد من المعلومات.\n\nمن المفترض أنك إستملت <doclink href=Copying> نسخة عن رخصة جنو العامة </doclink> مع هذا البرنامج؛ اذا لم تقعل إكتب رسالة إلى مؤسسة البرمجيات الحرة المحدودة، شارع 51 فرانكلين الطابق الخامس، بوسطن  MA 02110-1301 الولايات المتخدة أو [http://www.gnu.org/copyleft/gpl.html read it online].",
        "config-env-good": "جرى التحقق من البيئة. يمكنك تنصيب ميدياويكي.",
        "config-env-bad": "جرى التحقق من البيئة. لا يمكنك تنصيب ميدياويكي.",
        "config-env-php": "بي إتش بي $1 مثبت.",
index cd9574c..c591f1e 100644 (file)
@@ -62,6 +62,7 @@
        "config-memory-bad": "<strong>Alvertencia:</strong>: el parámetru <code>memory_limit</code> de PHP ye $1.\nProbablemente sía demasiáu baxu.\n¡La instalación puede fallar!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] ta instaláu",
        "config-apc": "[http://www.php.net/apc APC] ta instaláu",
+       "config-apcu": "[http://www.php.net/apcu APCu] ta instaláu",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] ta instaláu",
        "config-no-cache-apcu": "<strong>Warning:</strong> Non pudo atopase[http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] o [http://www.iis.net/download/WinCacheForPhp WinCache].\nEl caxé d'oxetos nun ta activáu.",
        "config-mod-security": "<strong>Alvertencia:</strong> El to servidor web tien activáu [http://modsecurity.org/mod_security]/mod_security2 .Munches de les sos configuraciones comunes pueden causar problemes a MediaWiki o otru software que dexe a los usuarios publicar conteníu arbitrario. De ser posible, tendríes de desactivalo. Si non, consulta la  [http://modsecurity.org/documentation/ mod_security documentation] o contacta col alministrador del to servidor si atopes erros aleatorios.",
        "config-db-username": "Nome d'usuariu de base de datos:",
        "config-db-password": "Contraseña de base de datos:",
        "config-db-install-username": "Introduz un nome d'usuariu que s'usará pa coneutase cola base de datos nel procesu d'instalación. Esti nun ye'l nome d'usuariu de la cuenta MediaWiki, ye'l nome d'usuariu de la to base de datos.",
+       "config-db-install-password": "Escribe la contraseña que se va utilizar pa conectase a la base de datos mientres el procesu d'instalación.\nEsta nun ye la contraseña de la cuenta de MediaWiki, sinón la contraseña de la base de datos.",
+       "config-db-install-help": "Escribe'l nome d'usuariu y la contraseña que se van utilizar pa conectase a la base de datos mientres el procesu d'instalación.",
+       "config-db-account-lock": "Usar el mesmu nome d'usuariu y contraseña demientres la operación normal",
+       "config-db-wiki-account": "Cuenta d'usuariu pa operar normalmente",
+       "config-db-wiki-help": "Escribe'l nome d'usuariu y la contraseña que se van utilizar p'aportar a la base de datos mientres la operación normal de la wiki.\nSi esta cuenta nun esiste y la cuenta d'instalación tien permisos bastante, va crease esta cuenta d'usuariu colos mínimos permisos necesarios pa operar normalmente la wiki.",
+       "config-db-prefix": "Prefixu de tables de la base de datos:",
+       "config-db-prefix-help": "Si precises compartir una base de datos ente múltiples wikis, o ente MediaWiki y otra aplicación web, puedes optar por amestar un prefixu a tolos nomes de tabla pa evitar conflictos.\nNun utilices espacios.\n\nDe normal déxase esti campu vacío.",
        "config-type-mysql": "MySQL (o compatible)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-invalid-db-type": "Triba non válida de base de datos.",
        "config-help": "Ayuda",
        "config-nofile": "Nun pudo atopase'l ficheru \"$1\". ¿Desaniciose?",
        "mainpagetext": "<strong>Instalóse MediaWiki.</strong>",
-       "mainpagedocfooter": "Consulta la [https://meta.wikimedia.org/wiki/Help:Contents Guía del usuariu] pa saber cómo usar el software wiki.\n\n== Primeros pasos ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Llista de les opciones de configuración]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ EMF de MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de corréu de llanzamientos de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Llocaliza MediaWiki na to llingua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Depriende como combatir la puxarra na to wiki]"
+       "mainpagedocfooter": "Consulta [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents] pa saber cómo usar el software wiki.\n\n== Primeros pasos ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Llista de les opciones de configuración]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ EMF de MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de corréu de llanzamientos de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Llocaliza MediaWiki na to llingua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Depriende como combatir la puxarra na to wiki]"
 }
index 77cd689..c17de3f 100644 (file)
@@ -65,6 +65,7 @@
        "config-memory-bad": "'''Папярэджаньне:''' памер PHP <code>memory_limit</code> складае $1.\nВерагодна, гэта вельмі мала.\nУсталяваньне можа быць няўдалым!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] усталяваны",
        "config-apc": "[http://www.php.net/apc APC] усталяваны",
+       "config-apcu": "[http://www.php.net/apcu APCu] ўсталяваны",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] усталяваны",
        "config-no-cache-apcu": "<strong>Папярэджаньне:</strong> ня знойдзеныя [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] ці [http://www.iis.net/download/WinCacheForPhp WinCache]. Кэшаваньне аб’ектаў адключанае.",
        "config-mod-security": "'''Папярэджаньне''': на Вашым ўэб-сэрверы ўключаны [http://modsecurity.org/ mod_security]. У выпадку няслушнай наладцы, ён можа стаць прычынай праблемаў для MediaWiki ці іншага праграмнага забесьпячэньня, якое дазваляе ўдзельнікам дасылаць на сэрвэр любы зьмест.\nГлядзіце [http://modsecurity.org/documentation/ дакумэнтацыю mod_security] ці зьвярніцеся ў падтрымку Вашага хосту, калі ў Вас узьнікаюць выпадковыя праблемы.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki падтрымлівае наступныя сыстэмы базаў зьвестак:\n\n$1\n\nКалі Вы ня бачыце сыстэму базаў зьвестак, якую Вы спрабуеце выкарыстоўваць ў сьпісе ніжэй, перайдзіце па спасылцы інструкцыі, якая знаходзіцца ніжэй, каб уключыць падтрымку.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] зьяўляецца галоўнай мэтай MediaWiki і падтрымліваецца лепей за ўсё. MediaWiki таксама працуе з [{{int:version-db-mariadb-url}} MariaDB] і [{{int:version-db-percona-url}} Percona Server], якія сумяшчальныя з MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Як скампіляваць PHP з падтрымкай MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] — папулярная сыстэма базы зьвестак з адкрытым кодам, якая зьяўляецца альтэрнатывай MySQL. Яна можа ўтрымліваць дробныя памылкі, і не рэкамэндуецца выкарыстоўваць яе для працуючых праектаў. ([http://www.php.net/manual/en/pgsql.installation.php Як кампіляваць PHP з падтрымкай PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] — папулярная сыстэма базы зьвестак з адкрытым кодам, якая зьяўляецца альтэрнатывай MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Як кампіляваць PHP з падтрымкай PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — невялікая сыстэма базы зьвестак, якая мае вельмі добрую падтрымку. ([http://www.php.net/manual/en/pdo.installation.php Як кампіляваць PHP з падтрымкай SQLite], выкарыстоўвае PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] зьяўляецца камэрцыйнай прафэсійнай базай зьвестак. ([http://www.php.net/manual/en/oci8.installation.php Як скампіляваць PHP з падтрымкай OCI8])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — камэрцыйная база зьвестак для Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Як скампіляваць PHP з падтрымкай SQLSRV])",
        "config-cache-options": "Налады кэшаваньня аб’ектаў:",
        "config-cache-help": "Кэшаваньне аб’ектаў павялічвае хуткасьць працы MediaWiki праз кэшаваньне зьвестак, якія часта выкарыстоўваюцца.\nВельмі рэкамэндуем уключыць гэта для сярэдніх і буйных сайтаў, таксама будзе карысна для дробных сайтаў.",
        "config-cache-none": "Без кэшаваньня (ніякія магчымасьці не страчваюцца, але хуткасьць працы буйных сайтаў можа зьнізіцца)",
-       "config-cache-accel": "Кэшаваньне аб’ектаў PHP (APC, XCache ці WinCache)",
+       "config-cache-accel": "Кэшаваньне аб’ектаў PHP (APC, APCu, XCache ці WinCache)",
        "config-cache-memcached": "Выкарыстоўваць Memcached (патрабуе дадатковай канфігурацыі)",
        "config-memcached-servers": "Сэрвэры memcached:",
        "config-memcached-help": "Сьпіс IP-адрасоў, якія будуць выкарыстоўвацца Memcached.\nАдрасы павінны быць у асобным радку з пазначэньнем порту, які будзе выкарыстоўвацца. Напрыклад:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-nofile": "Файл «$1» ня знойдзены. Ці быў ён выдалены?",
        "config-extension-link": "Ці ведаеце вы, што вашая вікі падтрымлівае [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions пашырэньні]?\n\nВы можаце праглядзець [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category пашырэньні паводле катэгорыяў] або [https://www.mediawiki.org/wiki/Extension_Matrix матрыцу пашырэньняў], каб пабачыць поўны сьпіс.",
        "mainpagetext": "<strong>MediaWiki была ўсталяваная.</strong>",
-       "mainpagedocfooter": "Глядзіце [https://meta.wikimedia.org/wiki/Help:Contents дапаможнік карыстальніка] для атрыманьня інфармацыі па карыстаньні вікі-праграмамі.\n\n== З чаго пачаць ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Сьпіс парамэтраў канфігурацыі]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Частыя пытаньні MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Рассылка паведамленьняў пра зьяўленьне новых вэрсіяў MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Пераклад MediaWiki на вашую мову]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Даведайцеся, як змагацца з спамам у вашай вікі]"
+       "mainpagedocfooter": "Глядзіце [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents дапаможнік карыстальніка] для атрыманьня інфармацыі па карыстаньні вікі-праграмамі.\n\n== З чаго пачаць ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Сьпіс парамэтраў канфігурацыі]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Частыя пытаньні MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Рассылка паведамленьняў пра зьяўленьне новых вэрсіяў MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Пераклад MediaWiki на вашую мову]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Даведайцеся, як змагацца з спамам у вашай вікі]"
 }
index 69891ea..5cdb83f 100644 (file)
@@ -62,6 +62,7 @@
        "config-memory-bad": "<strong>Предупреждение:<strong> <code>memory_limit</code> на PHP е $1.\nСтойността вероятно е твърде ниска.\nВъзможно е инсталацията да се провали!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] е инсталиран",
        "config-apc": "[http://www.php.net/apc APC] е инсталиран",
+       "config-apcu": "[http://www.php.net/apc APC] е инсталиран",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] е инсталиран",
        "config-mod-security": "<strong>Предупреждение:</strong> [http://modsecurity.org/ mod_security]/mod_security2 е включено на вашия уеб сървър. Много от обичайните му конфигурации пораждат проблеми с МедияУики и друг софтуер, който позволява публикуване на произволно съдържание.\nАко е възможно, моля изключете го. В противен случай се обърнете към [http://modsecurity.org/documentation/ документацията на mod_security] или се свържете с поддръжката на хостинга си, ако се сблъскате със случайни грешки.",
        "config-diff3-bad": "GNU diff3 не беше намерен.",
        "config-admin-help": "Въвежда се предпочитаното потребителско име, например \"Иванчо Иванчев\".\nТова ще е потребителското име, което администраторът ще използва за влизане в уикито.",
        "config-admin-name-blank": "Необходимо е да бъде въведено потребителско име на администратора.",
        "config-admin-name-invalid": "Посоченото потребителско име \"<nowiki>$1</nowiki>\" е невалидно.\nНеобходимо е да се посочи друго.",
-       "config-admin-password-blank": "Ð\9dеовÑ\85одимо Ðµ Ð´Ð° Ñ\81е Ð²Ñ\8aведе парола за администраторската сметка.",
+       "config-admin-password-blank": "Ð\92Ñ\8aведеÑ\82е парола за администраторската сметка.",
        "config-admin-password-mismatch": "Двете въведени пароли не съвпадат.",
        "config-admin-email": "Адрес за електронна поща:",
        "config-admin-email-help": "Въвеждането на адрес за е-поща позволява получаване на е-писма от другите потребители на уикито, възстановяване на изгубена или забравена парола, оповестяване при промени в страниците от списъка за наблюдение. Това поле може да бъде оставено празно.",
        "config-cache-options": "Настройки за обектното кеширане:",
        "config-cache-help": "Обектното кеширане се използва за подобряване на скоростта на МедияУики чрез кеширане на често използваните данни.\nСилно препоръчително е на средните и големите сайтове да включат тази настройка, но малките също могат да се възползват от нея.",
        "config-cache-none": "Без кеширане (не се премахва от функционалността, но това влияе на скоростта на по-големи уикита)",
-       "config-cache-accel": "PHP обектно кеширане (APC, XCache или WinCache)",
+       "config-cache-accel": "PHP обектно кеширане (APCu, XCache или WinCache)",
        "config-cache-memcached": "Използване на Memcached (изисква допълнителни настройки и конфигуриране)",
        "config-memcached-servers": "Memcached сървъри:",
        "config-memcached-help": "Списък с IP адреси за използване за Memcached.\nНеобходимо е да бъдат разделени по един на ред, както и да е посочен порта. Пример:\n127.0.0.1:11211\n192.168.1.25:1234",
        "config-install-done-path": "<strong>Поздравления!</strong>\nИнсталирането на МедияУики приключи успешно.\n\nИнсталаторът създаде файл <code>LocalSettings.php</code>.\nТой съдържа всички ваши настройки.\n\nНеобходимо е той да бъде изтеглен и поставен в <code>$4</code>. Изтеглянето би трябвало да започне автоматично.\n\nАко изтеглянето не започне автоматично или е било прекратено, файлът може да бъде изтеглен чрез щракване на препратката по-долу:\n\n$3\n\n<strong>Забележка:</strong> Ако това не бъде направено сега, генерираният конфигурационен файл няма да е достъпен на по-късен етап ако не бъде изтеглен сега или инсталацията приключи без изтеглянето му.\n\nКогато файлът вече е в основната директория, <strong>[$2 уикито ще е достъпно на този адрес]</strong>.",
        "config-download-localsettings": "Изтегляне на <code>LocalSettings.php</code>",
        "config-help": "помощ",
+       "config-help-tooltip": "Щракнете за разширяване",
        "config-nofile": "Файлът „$1“ не може да бъде открит. Да не е бил изтрит?",
        "config-extension-link": "Знаете ли, че това уики поддържа [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions разширения]?\n\nМожете да разгледате [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category разширенията по категория] или [https://www.mediawiki.org/wiki/Extension_Matrix Матрицата на разширенията] за пълен списък на разширенията.",
        "mainpagetext": "<strong>МедияУики беше успешно инсталирано.</strong>",
index fb23d01..f28e2c5 100644 (file)
@@ -6,7 +6,8 @@
                        "Aftab1995",
                        "Tauhid16",
                        "Aftabuzzaman",
-                       "Hasive"
+                       "Hasive",
+                       "আজিজ"
                ]
        },
        "config-desc": "মিডিয়াউইকির জন্য ইন্সটলার",
@@ -64,6 +65,7 @@
        "config-oracle-def-ts": "পূর্বনির্ধারিত টেবিলস্পেস",
        "config-oracle-temp-ts": "সাময়কি টেবিলস্পেস:",
        "config-type-mssql": "মাইক্রোসফট এসকিউএল সার্ভার",
+       "config-dbsupport-postgres": "* MySQL-এর বিকল্প হিসেবে [{{int:version-db-postgres-url}} PostgreSQL] হচ্ছে একটি জনপ্রিয় ওপেন সোর্স ডাটাবেস ব্যবস্থা। ([http://www.php.net/manual/en/pgsql.installation.php PostgreSQL সমর্থনসহ কিভাবে PHP সঙ্কলন করবেন])",
        "config-header-mysql": "মাইএসকিউএল সেটিংস",
        "config-header-postgres": "পোস্টগ্রেএসকিউএল সেটিংস",
        "config-header-sqlite": "এসকিউলাইট সেটিংস",
@@ -94,7 +96,9 @@
        "config-admin-name": "আপনার ব্যবহারকারী নাম:",
        "config-admin-password": "পাসওয়ার্ড:",
        "config-admin-password-confirm": "পাসওয়ার্ড আবারও প্রবেশ করান:",
+       "config-admin-help": "এখানে আপনার পছন্দের ব্যবহারকারী নাম লিখুন, উদাহরণস্বরূপ \"আজিজ\"। এই নামটি উইকিতে প্রবেশের সময় ব্যবহার করতে হবে।",
        "config-admin-name-blank": "একটি প্রশাসক ব্যবহারকারী নাম প্রবেশ করান",
+       "config-admin-name-invalid": "উল্লেখিত ব্যবহারকারী নাম \"<nowiki>$1</nowiki>\" অবৈধ। একটি ভিন্ন নাম উল্লেখ করুন।",
        "config-admin-password-blank": "প্রশাসক অ্যাকাউন্টের জন্য পাসওয়ার্ড প্রবেশ করান।",
        "config-admin-password-mismatch": "আপনি যে দুটি পাসওয়ার্ড দিয়েছেন তারা পরস্পর মেলেনি।",
        "config-admin-email": "ইমেইল ঠিকানা:",
        "config-help": "সাহায্য",
        "config-help-tooltip": "প্রসারিত করতে ক্লিক করুন",
        "mainpagetext": "<strong>মিডিয়াউইকি ইনস্টল করা হয়েছে।</strong>",
-       "mainpagedocfooter": "কীভাবে উইকি সফটওয়্যারটি ব্যবহারকার করবেন, তা জানতে [https://meta.wikimedia.org/wiki/Help:Contents ব্যবহারকারী সহায়িকা] দেখুন।\n\n== কোথা থেকে শুরু করবেন ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings কনফিগারেশন সেটিংস তালিকা]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ প্রশ্নোত্তরে মিডিয়াউইকি]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce মিডিয়াউইকি মুক্তির মেইলিং লিস্ট]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources আপনার ভাষার জন্য মিডিয়াউইকি স্থানীয়করণ করুন]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam আপনার উইকিতে স্প্যামের সাথে লড়াই করার উপায় সম্পর্কে জানুন]"
+       "mainpagedocfooter": "কীভাবে উইকি সফটওয়্যারটি ব্যবহারকার করবেন, তা জানতে [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents ব্যবহারকারী সহায়িকা] দেখুন।\n\n== কোথা থেকে শুরু করবেন ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings কনফিগারেশন সেটিংস তালিকা]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ প্রশ্নোত্তরে মিডিয়াউইকি]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce মিডিয়াউইকি মুক্তির মেইলিং লিস্ট]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources আপনার ভাষার জন্য মিডিয়াউইকি স্থানীয়করণ করুন]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam আপনার উইকিতে স্প্যামের সাথে লড়াই করার উপায় সম্পর্কে জানুন]"
 }
index 68497c5..2fee258 100644 (file)
@@ -66,6 +66,7 @@
        "config-memory-bad": "<strong>Upozornění:</strong> <code>memory_limit</code> je v PHP nastaven na $1.\nTo je pravděpodobně příliš málo.\nInstalace může selhat!",
        "config-xcache": "Je nainstalována [http://xcache.lighttpd.net/ XCache]",
        "config-apc": "Je nainstalováno [http://www.php.net/apc APC]",
+       "config-apcu": "Je nainstalováno [http://www.php.net/apcu APCu]",
        "config-wincache": "Je nainstalována [http://www.iis.net/download/WinCacheForPhp WinCache]",
        "config-no-cache-apcu": "<strong>Upozornění:</strong> Nebylo nalezeno [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache], ani [http://www.iis.net/download/WinCacheForPhp WinCache].\nKešování objektů bude vypnuto.",
        "config-mod-security": "<strong>Upozornění:</strong> váš webový server má zapnuto [http://modsecurity.org/ mod_security]/mod_security2. Mnoho běžných konfigurací bude způsobovat potíže MediaWiki a dalším programům, které umožňují ukládat libovolný obsah.\nPokud je to možné, mělo by se to vypnout. Jinak se v případě, že narazíte na náhodné chyby, podívejte do [http://modsecurity.org/documentation/ dokumentace mod_security] nebo kontaktujte technickou podporu vašeho poskytovatele.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki podporuje následující databázové systémy:\n\n$1\n\nPokud v nabídce níže nevidíte databázový systém, který chcete použít, musíte pro zapnutí podpory následovat instrukce odkázané výše.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] je pro MediaWiki hlavní platformou a je podporováno nejlépe. MediaWiki pracuje také s [{{int:version-db-mariadb-url}} MariaDB] a [{{int:version-db-percona-url}} Percona Server], které jsou s MySQL kompatibilní. ([http://www.php.net/manual/en/mysql.installation.php Jak zkompilovat PHP s podporou MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] je populární otevřený databázový systém používaný jako alternativa k MySQL. Mohou se vyskytnout ještě nějaké menší chyby, použití ve výrobním prostředí se nedoporučuje.  ([http://www.php.net/manual/en/pgsql.installation.php Jak přeložit PHP s podporou PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] je populární otevřený databázový systém používaný jako alternativa k MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Jak přeložit PHP s podporou PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] je velmi dobře podporovaný odlehčený databázový systém. ([http://www.php.net/manual/en/pdo.installation.php Jak přeložit PHP s podporou SQLite], používá PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] je komerční podniková databáze. ([http://www.php.net/manual/en/oci8.installation.php Jak přeložit PHP s podporou OCI8])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] je komerční podniková databáze pro Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Jak přeložit PHP s podporou SQLSRV])",
        "config-cache-options": "Nastavení cachování objektů:",
        "config-cache-help": "Cachování objektů se používá pro vylepšení rychlosti MediaWiki tím, že se cachují často používaná data.\nStředním až velkým serverům se jeho zapnutí důrazně doporučuje, i menší servery pocítí jeho výhody.",
        "config-cache-none": "Bez cachování (o žádnou funkcionalitu nepřijdete, na větších wiki však může dojít ke zhoršení rychlosti)",
-       "config-cache-accel": "Cachování PHP objektů (APC, XCache nebo WinCache)",
+       "config-cache-accel": "Cachování PHP objektů (APC, APCu, XCache nebo WinCache)",
        "config-cache-memcached": "Použít Memcached (vyžaduje další nastavení a konfiguraci)",
        "config-memcached-servers": "Servery Memcached:",
        "config-memcached-help": "Seznam IP adres, které se mají používat pro Memcached.\nUveďte jednu na řádek spolu s portem. Například:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-nofile": "Soubor „$1“ nelze nalézt. Byl smazán?",
        "config-extension-link": "Věděli jste, že vaše wiki podporuje [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions rozšíření]?\n\nMůžete si prohlédnout [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category seznam rozšíření po kategoriích].",
        "mainpagetext": "<strong>MediaWiki byla úspěšně nainstalována.</strong>",
-       "mainpagedocfooter": "[https://meta.wikimedia.org/wiki/Help:Contents Uživatelská příručka] vám napoví, jak používat MediaWiki.\n\n== Začínáme ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Nastavení konfigurace]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Často kladené otázky o MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce E-mailová konference oznámení MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Překlad MediaWiki do vašeho jazyka]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Naučte se bojovat se spamem na vaší wiki]"
+       "mainpagedocfooter": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Uživatelská příručka] vám napoví, jak používat MediaWiki.\n\n== Začínáme ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Nastavení konfigurace]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Často kladené otázky o MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce E-mailová konference oznámení MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Překlad MediaWiki do vašeho jazyka]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Naučte se bojovat se spamem na vaší wiki]"
 }
index e704141..c7690e2 100644 (file)
@@ -74,6 +74,7 @@
        "config-memory-bad": "'''Warnung:''' Der PHP-Parameter <code>memory_limit</code> beträgt $1.\nDieser Wert ist wahrscheinlich zu niedrig.\nDer Installationsvorgang könnte eventuell scheitern!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] ist installiert",
        "config-apc": "[http://www.php.net/apc APC] ist installiert",
+       "config-apcu": "[http://www.php.net/apcu APCu] ist installiert",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] ist installiert",
        "config-no-cache-apcu": "<strong>Warnung:</strong> [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] oder [http://www.iis.net/download/WinCacheForPhp WinCache] konnten nicht gefunden werden.\nDer Objektcache ist nicht aktiviert.",
        "config-mod-security": "'''Warnung:''' Auf dem Webserver wurde [http://modsecurity.org/ ModSecurity] aktiviert. Sofern falsch konfiguriert, kann dies zu Problemen mit MediaWiki sowie anderer Software auf dem Server führen und es Benutzern ermöglichen, beliebige Inhalte im Wiki einzustellen.\nFür weitere Informationen empfehlen wir die [http://modsecurity.org/documentation/ Dokumentation zu ModSecurity] oder den Kontakt zum Hoster, sofern Fehler auftreten.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki unterstützt die folgenden Datenbanksysteme:\n\n$1\n\nSofern unterhalb nicht das Datenbanksystem angezeigt wird, das verwendet werden soll, muss dieses noch verfügbar gemacht werden. Oben ist zu jedem unterstützten Datenbanksystem ein Link zur entsprechenden Anleitung vorhanden.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] ist das von MediaWiki primär unterstützte Datenbanksystem. MediaWiki funktioniert auch mit [{{int:version-db-mariadb-url}} MariaDB] und [{{int:version-db-percona-url}} Percona Server], die MySQL-kompatibel sind. ([https://www.php.net/manual/en/mysqli.installation.php Anleitung zur Kompilierung von PHP mit MySQL-Unterstützung])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ist ein beliebtes Open-Source-Datenbanksystem und eine Alternative zu MySQL. Es gibt allerdings einige kleinere Implementierungsfehler, so dass von der Nutzung in einer Produktivumgebung abgeraten wird. ([https://www.php.net/manual/de/pgsql.installation.php Anleitung zur Kompilierung von PHP mit PostgreSQL-Unterstützung])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ist ein beliebtes Open-Source-Datenbanksystem und eine Alternative zu MySQL. ([https://www.php.net/manual/de/pgsql.installation.php Anleitung zur Kompilierung von PHP mit PostgreSQL-Unterstützung])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] ist ein verschlanktes Datenbanksystem, das auch gut unterstützt wird ([https://www.php.net/manual/de/pdo.installation.php Anleitung zur Kompilierung von PHP mit SQLite-Unterstützung], verwendet PHP Data Objects (PDO))",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] ist eine kommerzielle Unternehmensdatenbank ([https://www.php.net/manual/en/oci8.installation.php Anleitung zur Kompilierung von PHP mit OCI8-Unterstützung])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ist eine gewerbliche Unternehmensdatenbank für Windows. ([https://www.php.net/manual/de/sqlsrv.installation.php Anleitung zur Kompilierung von PHP mit SQLSRV-Unterstützung])",
        "config-cache-options": "Einstellungen für die Zwischenspeicherung von Objekten:",
        "config-cache-help": "Das Objektcaching wird dazu genutzt, die Geschwindigkeit von MediaWiki zu verbessern, indem häufig genutzte Daten zwischengespeichert werden.\nEs wird sehr empfohlen, es für mittelgroße bis große Wikis zu nutzen, aber auch für kleine Wikis ergeben sich erkennbare Geschwindigkeitsverbesserungen.",
        "config-cache-none": "Kein Objektcaching (es wird keine Funktion entfernt, allerdings kann dies die Leistungsfähigkeit größerer Wikis negativ beeinflussen)",
-       "config-cache-accel": "Objektcaching von PHP (APC, XCache oder WinCache)",
+       "config-cache-accel": "Objektcaching von PHP (APC, APCu, XCache oder WinCache)",
        "config-cache-memcached": "Memcached Cacheserver (erfordert einen zusätzlichen Installationsvorgang mitsamt Konfiguration)",
        "config-memcached-servers": "Memcached Cacheserver",
        "config-memcached-help": "Liste der für Memcached nutzbaren IP-Adressen.\nEs sollte eine je Zeile mitsamt des vorgesehenen Ports angegeben werden. Beispiele:\n127.0.0.1:11211 oder\n192.168.1.25:1234 usw.",
        "config-nofile": "Die Datei „$1“ konnte nicht gefunden werden. Wurde sie gelöscht?",
        "config-extension-link": "Wusstest du, dass dein Wiki die Nutzung von [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions Erweiterungen] unterstützt?\n\nDu kannst die [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category Erweiterungen nach Kategorie] anzeigen oder die [https://www.mediawiki.org/wiki/Extension_Matrix Erweiterungs-Matrix] aufrufen, um eine vollständige Liste der Erweiterungen zu sehen.",
        "mainpagetext": "<strong>MediaWiki wurde installiert.</strong>",
-       "mainpagedocfooter": "Hilfe zur Benutzung und Konfiguration der Wiki-Software findest du im [https://meta.wikimedia.org/wiki/Help:Contents Benutzerhandbuch].\n\n== Starthilfen ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Liste der Konfigurationsvariablen]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki-FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Mailingliste neuer MediaWiki-Versionen]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Übersetze MediaWiki für deine Sprache]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Erfahre, wie du Spam auf deinem Wiki bekämpfen kannst]"
+       "mainpagedocfooter": "Hilfe zur Benutzung und Konfiguration der Wiki-Software findest du im [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Benutzerhandbuch].\n\n== Starthilfen ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Liste der Konfigurationsvariablen]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki-FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Mailingliste neuer MediaWiki-Versionen]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Übersetze MediaWiki für deine Sprache]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Erfahre, wie du Spam auf deinem Wiki bekämpfen kannst]"
 }
index 2890e3c..c80d54e 100644 (file)
        "config-page-complete": "Temamyayo",
        "config-page-restart": "Barkerdışi fına ser kı",
        "config-page-readme": "Mı bıwane",
+       "config-page-releasenotes": "Notë versiyoni",
        "config-page-copying": "Kopyayeno",
        "config-page-upgradedoc": "Berzkerdış",
+       "config-page-existingwiki": "Mewcud wiki",
        "config-restart": "E, fına dest pekê",
        "config-sidebar": "* [https://www.mediawiki.org MediaWiki keye]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Şınasiya Karberi]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Şınasiya İdarekaran]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Peşti]\n----\n* <doclink href=Readme>Mı buwanê</doclink>\n* <doclink href=ReleaseNotes>Notê elaqeyıni</doclink>\n* <doclink href=Copying>Kopyakerdış</doclink>\n* <doclink href=UpgradeDoc>Zêdekerdış</doclink>",
        "config-env-php": "PHP $1 i biyo saz.",
        "config-db-type": "Database tipe:",
        "config-db-host": "Database host:",
        "config-db-host-oracle": "Database TNS:",
+       "config-db-wiki-settings": "Ena wikiyer akernë",
        "config-db-name": "Database name:",
+       "config-db-name-oracle": "Şemaya hardata:",
        "config-db-username": "Database nameykarberi:",
        "config-db-password": "Database parola :",
        "config-db-port": "Portê database:",
+       "config-oracle-def-ts": "Hesıbyaye caytabloy:",
+       "config-oracle-temp-ts": "İdareten caytabloy:",
+       "config-type-mysql": "MySQL (yana hewlın)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-header-mysql": "Eyarê MySQL",
+       "config-header-sqlite": "SQLite sazi",
+       "config-header-oracle": "Orqcle sazi",
+       "config-header-mssql": "Sazë Microsoft SQL Serveri",
+       "config-missing-db-name": "\"{{int:config-db-name}}\"nrë jew erc dekerdış gerek keno.",
+       "config-missing-db-host": "\"{{int:config-db-host}}\" rë jew erc gerek keno",
+       "config-missing-db-server-oracle": "\"{{int:config-db-host-oracle}}\" rë jew erc gerek keno",
+       "config-mysql-engine": "Motorë depok kerdışi",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-binary": "Dılet",
        "config-mysql-utf8": "UTF-8",
+       "config-mssql-sqlauth": "SQL Server araştnayış",
+       "config-mssql-windowsauth": "Windows kamiye araştnayış",
        "config-site-name": "Namey wiki:",
        "config-site-name-blank": "Yew nameyê sita cıkewe.",
        "config-project-namespace": "Wareyê nameyê proceyi:",
index 3f3032b..b25ff2c 100644 (file)
@@ -57,6 +57,7 @@
        "config-memory-bad": "<strong>Warning:</strong> PHP's <code>memory_limit</code> is $1.\nThis is probably too low.\nThe installation may fail!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] is installed",
        "config-apc": "[http://www.php.net/apc APC] is installed",
+       "config-apcu": "[http://www.php.net/apcu APCu] is installed",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] is installed",
        "config-no-cache-apcu": "<strong>Warning:</strong> Could not find [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] or [http://www.iis.net/download/WinCacheForPhp WinCache].\nObject caching is not enabled.",
        "config-mod-security": "<strong>Warning:</strong> Your web server has [http://modsecurity.org/ mod_security]/mod_security2 enabled. Many common configurations of this will cause problems for MediaWiki and other software that allows users to post arbitrary content.\nIf possible, this should be disabled. Otherwise, refer to [http://modsecurity.org/documentation/ mod_security documentation] or contact your host's support if you encounter random errors.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki supports the following database systems:\n\n$1\n\nIf you do not see the database system you are trying to use listed below, then follow the instructions linked above to enable support.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] is the primary target for MediaWiki and is best supported. MediaWiki also works with [{{int:version-db-mariadb-url}} MariaDB] and [{{int:version-db-percona-url}} Percona Server], which are MySQL compatible. ([http://www.php.net/manual/en/mysqli.installation.php How to compile PHP with MySQL support])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is a popular open source database system as an alternative to MySQL. There may be some minor outstanding bugs, and it is not recommended for use in a production environment. ([http://www.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is a popular open source database system as an alternative to MySQL. ([http://www.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] is a lightweight database system that is very well supported. ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] is a commercial enterprise database. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is a commercial enterprise database for Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])",
        "config-cache-options": "Settings for object caching:",
        "config-cache-help": "Object caching is used to improve the speed of MediaWiki by caching frequently used data.\nMedium to large sites are highly encouraged to enable this, and small sites will see benefits as well.",
        "config-cache-none": "No caching (no functionality is removed, but speed may be impacted on larger wiki sites)",
-       "config-cache-accel": "PHP object caching (APC, XCache or WinCache)",
+       "config-cache-accel": "PHP object caching (APC, APCu, XCache or WinCache)",
        "config-cache-memcached": "Use Memcached (requires additional setup and configuration)",
        "config-memcached-servers": "Memcached servers:",
        "config-memcached-help": "List of IP addresses to use for Memcached.\nShould specify one per line and specify the port to be used. For example:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-nofile": "File \"$1\" could not be found. Has it been deleted?",
        "config-extension-link": "Did you know that your wiki supports [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions extensions]?\n\nYou can browse [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensions by category] or the [https://www.mediawiki.org/wiki/Extension_Matrix Extension Matrix] to see the full list of extensions.",
        "mainpagetext": "<strong>MediaWiki has been installed.</strong>",
-       "mainpagedocfooter": "Consult the [https://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.\n\n== Getting started ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki]"
+       "mainpagedocfooter": "Consult the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents] for information on using the wiki software.\n\n== Getting started ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki]"
 }
index 09f3a40..4398492 100644 (file)
@@ -31,7 +31,8 @@
                        "AlvaroMolina",
                        "Indiralena",
                        "Peter Bowman",
-                       "Dgstranz"
+                       "Dgstranz",
+                       "Irus"
                ]
        },
        "config-desc": "El instalador de MediaWiki",
@@ -89,6 +90,7 @@
        "config-memory-bad": "<strong>Advertencia:</strong> el parámetro <code>memory_limit</code> de PHP es $1.\nProbablemente sea demasiado bajo.\n¡La instalación puede fallar!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] está instalado",
        "config-apc": "[http://www.php.net/apc APC] está instalado",
+       "config-apcu": "[http://www.php.net/apcu APCu] está instalado",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] está instalado",
        "config-no-cache-apcu": "<strong>Advertencia:</strong> No se pudo encontrar [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] o [http://www.iis.net/download/WinCacheForPhp WinCache].\nEl caché de objetos no está activado.",
        "config-mod-security": "<strong>Advertencia:</strong> tu servidor web tiene activado [http://modsecurity.org/ mod_security]/mod_security2. Muchas de sus configuraciones comunes pueden causar problemas a MediaWiki u otro software que permita a los usuarios publicar contenido arbitrario. De ser posible, deberías desactivarlo. Si no, consulta la [http://modsecurity.org/documentation/ documentación de mod_security] o contacta con el administrador de tu servidor si encuentras errores aleatorios.",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong>Advertencia:</strong> has seleccionado MyISAM como motor de almacenamiento de MySQL, el cual no está recomendado para usarse con MediaWiki, porque:\n* apenas soporta concurrencia debido al bloqueo de tablas\n* es más propenso a la corrupción que otros motores\n* el código MediaWiki no siempre controla MyISAM como debiera\n\nSi tu instalación de MySQL soporta InnoDB, es muy recomendable que lo elijas en su lugar.\nSi tu instalación de MySQL no soporta InnoDB, quizás es el momento de una actualización.",
-       "config-mysql-only-myisam-dep": "<strong>Advertencia:</strong> solo se ha encontrado el motor de almacenamiento MyISAM para MySQL en esta máquina, y no se recomienda su uso con MediaWiki, porque:\n* apenas soporta concurrencia debido al bloqueo de tablas\n* es más propenso a la corrupción que otros motores\n* el código MediaWiki no siempre controla MyISAM como debiera\n\nTu instalación de MySQL no soporta InnoDB, quizás es el momento de una actualización.",
+       "config-mysql-only-myisam-dep": "<strong>Advertencia:</strong> solo se ha encontrado el motor de almacenamiento MyISAM para MySQL en esta máquina, y no se recomienda su uso con MediaWiki, porque:\n* apenas admite la concurrencia debido al bloqueo de tablas\n* es más propenso a daños que otros motores\n* el código de MediaWiki no siempre controla MyISAM como debería\n\nTu instalación de MySQL no admite InnoDB; quizás es el momento de una actualización.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> es casi siempre la mejor opción, dado que soporta bien los accesos simultáneos.\n\n<strong>MyISAM</strong> puede ser más rápido en instalaciones con usuario único o de sólo lectura.\nLas bases de datos MyISAM tienden a corromperse más a menudo que las bases de datos InnoDB.",
        "config-mysql-charset": "Conjunto de caracteres de la base de datos:",
        "config-mysql-binary": "Binario",
        "config-cache-options": "Configuración de la caché de objetos:",
        "config-cache-help": "El almacenamiento en caché de objetos se utiliza para mejorar la velocidad de MediaWiki mediante el almacenamiento en caché los datos usados más frecuentemente.\nA los sitios medianos y grandes se les recomienda que permitirlo. También es beneficioso para los sitios pequeños.",
        "config-cache-none": "Sin almacenamiento en caché (no se pierde ninguna funcionalidad, pero la velocidad puede resentirse en sitios grandes)",
-       "config-cache-accel": "Almacenamiento en caché de objetos PHP (APC, XCache o WinCache)",
+       "config-cache-accel": "Almacenamiento en caché de objetos PHP (APC, APCu, XCache o WinCache)",
        "config-cache-memcached": "Utilizar Memcached (necesita ser instalado y configurado aparte)",
        "config-memcached-servers": "Servidores Memcached:",
        "config-memcached-help": "Lista de direcciones IP que serán usadas por Memcached.\nDeben especificarse una por cada línea y especificar el puerto a utilizar. Por ejemplo:\n127.0.0.1:11211\n192.168.1.25:1234",
index dfcf1d3..46e8d90 100644 (file)
@@ -79,5 +79,5 @@
        "config-install-tables": "Tabelite loomine",
        "config-help": "abi",
        "mainpagetext": "<strong>MediaWiki tarkvara on paigaldatud.</strong>",
-       "mainpagedocfooter": "Vikitarkvara kasutamise kohta leiad lisateavet [https://meta.wikimedia.org/wiki/Help:Contents juhendist].\n\n== Alustamine ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Häälestussätete loend]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki KKK]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki versiooniuuenduste postiloend]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources MediaWiki lokaliseerimine]"
+       "mainpagedocfooter": "Vikitarkvara kasutamise kohta leiad lisateavet [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents siit].\n\n== Alustamine ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Häälestussätete loend]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki KKK]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki versiooniuuenduste postiloend]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources MediaWiki lokaliseerimine]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Loe, kuidas vikis rämpspostitusi tõrjuda]"
 }
index 7dbca51..5939291 100644 (file)
@@ -75,6 +75,7 @@
        "config-memory-bad": "'''Varoitus:''' PHP:n <code>memory_limit</code> on $1.\nTämä on luultavasti liian alhainen.\nAsennus saattaa epäonnistua!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] on asennettu",
        "config-apc": "[http://www.php.net/apc APC] on asennettu.",
+       "config-apcu": "[http://www.php.net/apcu APCu] on asennettu",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] on asennettu",
        "config-diff3-bad": "GNU diff3:a ei löytynyt.",
        "config-git": "Löydetty Git versionhallintaohjelmisto: <code>$1</code>",
index 3e7f8f3..82a2373 100644 (file)
@@ -85,8 +85,9 @@
        "config-memory-bad": "'''Attention :''' Le paramètre <code>memory_limit</code> de PHP est à $1.\nCette valeur est probablement trop faible.\nIl est possible que l’installation échoue !",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] est installé",
        "config-apc": "[http://www.php.net/apc APC] est installé",
+       "config-apcu": "[http://www.php.net/apcu APCu] est installé",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] est installé",
-       "config-no-cache-apcu": "'''Attention :''' Impossible de trouver [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] ou [http://www.iis.net/download/WinCacheForPhp WinCache].\nLa mise en cache d'objets n'est pas activée.",
+       "config-no-cache-apcu": "<strong>Attention :</strong> Impossible de trouver [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] ou [http://www.iis.net/download/WinCacheForPhp WinCache].\nLa mise en cache d'objets n'est pas activée.",
        "config-mod-security": "'''Attention''': Votre serveur web a [http://modsecurity.org/ mod_security] activé. S'il est mal configuré, cela peut poser des problèmes à MediaWiki ou à d'autres applications qui permettent aux utilisateurs de publier un contenu quelconque.\nReportez-vous à [http://modsecurity.org/documentation/ la documentation de mod_security] ou contactez le support de votre hébergeur si vous rencontrez des erreurs aléatoires.",
        "config-diff3-bad": "GNU diff3 introuvable.",
        "config-git": "Logiciel de contrôle de version Git trouvé : <code>$1</code>.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki prend en charge ces systèmes de bases de données :\n\n$1\n\nSi vous ne voyez pas le système de base de données que vous essayez d’utiliser ci-dessous, alors suivez les instructions ci-dessus (voir liens) pour activer la prise en charge.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] est le premier choix pour MediaWiki et est le mieux pris en charge. MediaWiki fonctionne aussi avec [{{int:version-db-mariadb-url}} MariaDB] et [{{int:version-db-percona-url}} Percona Server], qui sont compatibles avec MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Comment compiler PHP avec le support MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] est un système de base de données populaire et ''open source'' qui peut être une alternative à MySQL. Son support peut contenir quelques bogues mineurs et n'est pas recommandé dans un environnement de production.  ([http://www.php.net/manual/en/pgsql.installation.php Comment compiler PHP avec le support de PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] est un système de base de données populaire et ''open source'' qui peut être une alternative à MySQL ([http://www.php.net/manual/en/pgsql.installation.php Comment compiler PHP avec le support de PostgreSQL]).",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] est un système de base de données léger bien pris en charge. ([http://www.php.net/manual/fr/pdo.installation.php Comment compiler PHP avec la prise en charge de SQLite], en utilisant PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] est un système commercial de gestion de base de données d’entreprise. ([http://www.php.net/manual/en/oci8.installation.php Comment compiler PHP avec le support OCI8])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] est une base de données commerciale d’entreprise pour Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Comment compiler PHP avec le support de SQLSRV])",
        "config-mysql-engine": "Moteur de stockage :",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "''' Avertissement ''': vous avez sélectionné MyISAM comme moteur de stockage pour MySQL, ce qui n’est pas recommandé pour une utilisation avec MediaWiki, parce que :\n * il prend à peine en charge la simultanéité en raison de verrouillage de table\n * il est plus sujet à la corruption que les autres moteurs\n * le code de base MediaWiki ne gère pas toujours MyISAM comme il se doit\n\nSi votre installation MySQL prenden charge InnoDB, il est fortement recommandé que vous le choisissiez plutôt. \nSi votre installation MySQL ne prend pas en charge les tables InnoDB, il est peut-être temps de faire une mise à niveau.",
-       "config-mysql-only-myisam-dep": "'''Attention :''' MyISAM est le seul moteur de stockage disponible pour MySQL sur cette machine, et cela n’est pas recommandé pour une utilisation avec MédiaWiki, car :\n* il prend très peu en charge les accès concurrents à cause du verrouillage des tables\n* il est plus sujet à corruption que les autres moteurs\n* le code de base de MédiaWiki ne gère pas toujours MyISAM comme il faudrait\n\nVotre installation MySQL ne prend pas en charge InnoDB ; il est peut-être temps de la mettre à jour.",
-       "config-mysql-engine-help": "'''InnoDB''' est presque toujours la meilleure option, car il prend bien en charge les accès concurrents.\n\n'''MyISAM''' peut être plus rapide dans les installations monoposte ou en lecture seule.\nLes bases de données MyISAM ont tendance à se corrompre plus souvent que les bases d’InnoDB.",
+       "config-mysql-myisam-dep": "<strong> Avertissement </strong>: vous avez sélectionné MyISAM comme moteur de stockage pour MySQL, ce qui n’est pas recommandé pour une utilisation avec MediaWiki, parce que :\n * il prend à peine en charge la simultanéité en raison de verrouillage de table\n * il est plus sujet à la corruption que les autres moteurs\n * le code de base MediaWiki ne gère pas toujours MyISAM comme il se doit\n\nSi votre installation MySQL prenden charge InnoDB, il est fortement recommandé que vous le choisissiez plutôt. \nSi votre installation MySQL ne prend pas en charge les tables InnoDB, il est peut-être temps de faire une mise à niveau.",
+       "config-mysql-only-myisam-dep": "<strong>Attention :</strong> MyISAM est le seul moteur de stockage disponible pour MySQL sur cette machine, et cela n’est pas recommandé pour une utilisation avec MédiaWiki, car :\n* il prend très peu en charge les accès concurrents à cause du verrouillage des tables\n* il est plus sujet à corruption que les autres moteurs\n* le code de base de MédiaWiki ne gère pas toujours MyISAM comme il faudrait\n\nVotre installation MySQL ne prend pas en charge InnoDB ; il est peut-être temps de la mettre à jour.",
+       "config-mysql-engine-help": "<strong>InnoDB</strong> est presque toujours la meilleure option, car il prend bien en charge les accès concurrents.\n\n<strong>MyISAM</strong> peut être plus rapide dans les installations monoposte ou en lecture seule.\nLes bases de données MyISAM ont tendance à se corrompre plus souvent que les bases d’InnoDB.",
        "config-mysql-charset": "Jeu de caractères de la base de données :",
        "config-mysql-binary": "Binaire",
        "config-mysql-utf8": "UTF-8",
-       "config-mysql-charset-help": "En ''mode binaire'', MediaWiki stocke le texte au format UTF-8 dans la base de données dans des champs binaires.\nC'est plus efficace que le ''UTF-8 mode'' de MySQL, et vous permet d'utiliser toute la gamme des caractères Unicode.\n\nEn ''mode UTF-8'', MySQL reconnaîtra le jeu de caractères dans lequel sont vos données et pourra les présenter et les convertir de manière appropriée, mais il ne vous laissera pas stocker les caractères au-dessus du [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes plan multilingue de base] (en anglais).",
+       "config-mysql-charset-help": "En <strong>mode binaire</strong>, MediaWiki stocke le texte au format UTF-8 dans la base de données dans des champs binaires.\nC'est plus efficace que le ''UTF-8 mode'' de MySQL, et vous permet d'utiliser toute la gamme des caractères Unicode.\n\nEn <strong>mode UTF-8</strong>, MySQL reconnaîtra le jeu de caractères dans lequel sont vos données et pourra les présenter et les convertir de manière appropriée, mais il ne vous laissera pas stocker les caractères au-dessus du [https://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes plan multilingue de base] (en anglais).",
        "config-mssql-auth": "Type d’authentification :",
        "config-mssql-install-auth": "Sélectionner le type d’authentification qui sera utilisé pour se connecter à la base de données pendant le processus d’installation.\nSi vous sélectionnez « {{int:config-mssql-windowsauth}} », les informations d’identification de l’utilisateur faisant tourner le serveur seront utilisées.",
        "config-mssql-web-auth": "Sélectionner le type d’authentification que le serveur web utilisera pour se connecter au serveur de base de données lors des opérations habituelles du wiki.\nSi vous sélectionnez « {{int:config-mssql-windowsauth}} », les informations d’identification de l’utilisateur sous lequel tourne le serveur web seront utilisées.",
        "config-cache-options": "Paramètres pour la mise en cache des objets:",
        "config-cache-help": "La mise en cache des objets améliore la vitesse de MediaWiki en mettant en cache les données fréquemment utilisées.\nLes sites de taille moyenne à grande sont fortement encouragés à l'activer. Les petits sites y verront également des avantages.",
        "config-cache-none": "Pas de mise en cache (aucune fonctionnalité n'a été supprimée, mais la vitesse peut changer sur les wikis importants)",
-       "config-cache-accel": "Mise en cache des objets PHP (APC, XCache ou WinCache)",
+       "config-cache-accel": "Mise en cache des objets PHP (APC, APCu, XCache ou WinCache)",
        "config-cache-memcached": "Utiliser Memcached (nécessite une installation et une configuration supplémentaires)",
        "config-memcached-servers": "serveurs pour Memcached :",
        "config-memcached-help": "Liste des adresses IP à utiliser pour Memcached.\nUne par ligne, en indiquant le port à utiliser. Par exemple :\n  127.0.0.1:11211\n  192.168.1.25:1234",
index e9e757a..a2466c3 100644 (file)
@@ -64,6 +64,7 @@
        "config-memory-bad": "<strong>Atención:<strong> O parámetro <code>memory_limit</code> do PHP é $1.\nProbablemente é un valor baixo de máis.\nA instalación pode fallar!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] está instalado",
        "config-apc": "[http://www.php.net/apc APC] está instalado",
+       "config-apcu": "[http://www.php.net/apcu APCu] está instalado",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] está instalado",
        "config-no-cache-apcu": "<strong>Advertencia:</strong> Non se puido atopar [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] ou [http://www.iis.net/download/WinCacheForPhp WinCache].\nA caché de obxectos non está activada.",
        "config-mod-security": "<strong>Atención:</strong> O seu servidor web ten o [http://modsecurity.org/ mod_security] activado. Se estivese mal configurado, pode causar problemas a MediaWiki ou calquera outro software que permita aos usuarios publicar contidos arbitrarios.\nOlle a [http://modsecurity.org/documentation/ documentación do mod_security] ou póñase en contacto co soporte do seu servidor se atopa erros aleatorios.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki soporta os seguintes sistemas de bases de datos:\n\n$1\n\nSe non ve listado a continuación o sistema de base de datos que intenta usar, siga as instrucións ligadas enriba para activar o soporte.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] é o obxectivo principal para MediaWiki e está mellor soportado. MediaWiki tamén funciona con [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que son compatibles con MySQL. ([http://www.php.net/manual/en/mysqli.installation.php  Como compilar PHP con compatibilidade MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] é un sistema de base de datos popular e de código aberto como alternativa a MySQL. É posible que haxa algúns pequenos erros e non se recomenda o seu uso nunha contorna de produción. ([http://www.php.net/manual/en/pgsql.installation.php Como compilar PHP con compatibilidade PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] é un sistema de base de datos popular e de código aberto como alternativa a MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Como compilar PHP con compatibilidade PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] é un sistema de base de datos lixeiro moi ben soportado. ([http://www.php.net/manual/en/pdo.installation.php Como compilar o PHP con soporte SQLite], emprega PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] é un sistema comercial de xestión de base de datos de nivel empresarial. ([http://www.php.net/manual/en/oci8.installation.php Como compilar o PHP con compatibilidade OCI8])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] é un sistema comercial de xestión de base de datos de nivel empresarial para Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Como compilar o PHP con compatibilidade SQLSRV])",
        "config-cache-options": "Configuración da caché de obxectos:",
        "config-cache-help": "A caché de obxectos emprégase para mellorar a velocidade de MediaWiki mediante a memorización de datos usados con frecuencia.\nÉ amplamente recomendable a súa activación nos sitios de tamaño medio e grande; os sitios pequenos obterán tamén beneficios.",
        "config-cache-none": "Sen caché (non se elimina ningunha funcionalidade, pero pode afectar á velocidade en wikis grandes)",
-       "config-cache-accel": "Caché de obxectos do PHP (APC, XCache ou WinCache)",
+       "config-cache-accel": "Caché de obxectos do PHP (APC, APCu, XCache ou WinCache)",
        "config-cache-memcached": "Empregar o Memcached (necesita unha instalación e configuración adicional)",
        "config-memcached-servers": "Servidores da memoria caché:",
        "config-memcached-help": "Lista de enderezos IP para Memcached.\nDebe especificarse un por liña, así como o porto a usar. Por exemplo:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-nofile": "Non se puido atopar o ficheiro \"$1\". Se cadra, foi borrado.",
        "config-extension-link": "Sabía que o seu wiki soporta [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions extensións]?\n\nPode explorar as [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensións por categoría] ou a [https://www.mediawiki.org/wiki/Extension_Matrix matriz de extensións] para ollar a lista completa de extensións.",
        "mainpagetext": "<strong>Instalouse MediaWiki.</strong>",
-       "mainpagedocfooter": "Consulte a [https://meta.wikimedia.org/wiki/Help:Contents guía de usuario] para obter máis información sobre como usar o software wiki.\n\n== Primeiros pasos ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista das opcións de configuración]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Preguntas máis frecuentes sobre MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de correo dos lanzamentos de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localice MediaWiki á súa lingua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Aprenda como combater a publicidade na súa wiki]"
+       "mainpagedocfooter": "Consulte a [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents guía de usuario] para obter máis información sobre como usar o software wiki.\n\n== Primeiros pasos ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista das opcións de configuración]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Preguntas máis frecuentes sobre MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista de correo dos lanzamentos de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localice MediaWiki á súa lingua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Aprenda como combater a publicidade na súa wiki]"
 }
index ac67394..e98988c 100644 (file)
@@ -67,6 +67,7 @@
        "config-memory-bad": "'''אזהרה:''' ערך האפשרות <code>memory_limit</code> של PHP הוא $1.\nזה כנראה נמוך מדי.\nההתקנה עשויה להיכשל!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] מותקן",
        "config-apc": "[http://www.php.net/apc APC] מותקן",
+       "config-apcu": "[http://www.php.net/apcu APCu] מותקן",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] מותקן",
        "config-no-cache-apcu": "<strong>אזהרה:</strong> לא נמצא [http://www.php.net/apcu APCu]‏, [http://xcache.lighttpd.net/ XCache] או [http://www.iis.net/download/WinCacheForPhp WinCache].\nמטמון עצמים לא מופעל.",
        "config-mod-security": "'''אזהרה''': בשרת הווב שלך מופעל [http://modsecurity.org/ mod_security]. אם הוא לא מוגדר טוב, זה יכול לגרום לבעיות במדיה־ויקי ובתכנה אחרת שמאפשרת למשתמשים לשלוח תוכן שרירותי.\nיש לקרוא את [http://modsecurity.org/documentation/ התיעוד של mod_security] או ליצור קשר עם אנשי התמיכה של שירותי האירוח שלכם אם מופיעות לך שגיאות אקראיות.",
index cc197c8..069bf68 100644 (file)
        "config-type-mssql": "Microsoft SQL Szerver",
        "config-support-info": "A MediaWiki a következő adatbázisrendszereket támogatja:\n\n$1\n\nHa az alábbi listán nem találod azt a rendszert, melyet használni szeretnél, a fenti linken található instrukciókat követve engedélyezheted a támogatását.",
        "config-dbsupport-mysql": "* A [{{int:version-db-mysql-url}} MySQL] a MediaWiki elsődleges célpontja, így a legjobban támogatott. A MediaWiki elfut [{{int:version-db-mariadb-url}} MariaDB-n] és [{{int:version-db-percona-url}} Percona Serveren] is, mivel ezek MySQL-kompatibilisek. ([http://www.php.net/manual/en/mysql.installation.php Hogyan fordítható a PHP MySQL-támogatással])",
-       "config-dbsupport-postgres": "* A [{{int:version-db-postgres-url}} PostgreSQL] népszerű, nyílt forráskódú adatbázisrendszer, a MySQL alternatívája ([http://www.php.net/manual/en/pgsql.installation.php Hogyan fordítható a PHP PostgreSQL-támogatással]). Több apró, javítatlan hiba is előfordulhat, így nem ajánlott éles környezetben használni. ([http://www.php.net/manual/en/pgsql.installation.php Hogyan fordítható a PHP PostgreSQL-támogatással])",
+       "config-dbsupport-postgres": "* A [{{int:version-db-postgres-url}} PostgreSQL] népszerű, nyílt forráskódú adatbázisrendszer, a MySQL alternatívája. ([http://www.php.net/manual/en/pgsql.installation.php Hogyan fordítható a PHP PostgreSQL-támogatással])",
        "config-dbsupport-sqlite": "* Az [{{int:version-db-sqlite-url}} SQLite] egy könnyű, nagyon jól támogatott adatbázisrendszer. ([http://www.php.net/manual/en/pdo.installation.php Hogyan fordítható a PHP SQLite-támogatással], PDO-t használ)",
        "config-dbsupport-oracle": "* Az [{{int:version-db-oracle-url}} Oracle] kereskedelmi, vállalati adatbázisrendszer. ([http://www.php.net/manual/en/oci8.installation.php Hogyan fordítható a PHP OCI8-támogatással])",
        "config-dbsupport-mssql": "* A [{{int:version-db-mssql-url}} Microsoft SQL Server] kereskedelmi, vállalati adatbázisrendszer. ([http://www.php.net/manual/en/sqlsrv.installation.php Hogyan fordítható a PHP SQLSRV-támogatással])",
        "config-cache-options": "Objektum-gyorsítótárazás beállításai:",
        "config-cache-help": "Az objektumgyorsítótárazás célja, hogy felgyorsítsa a MediaWiki működését a gyakran használt adatok gyorsítótárazásával.\nKözepes vagy nagyobb oldalak esetén erősen ajánlott a használata, de kisebb oldalak esetén is hasznos lehet.",
        "config-cache-none": "Nincs gyorsítótárazás (minden funkció működik, de nagyobb wiki esetében lassabb működést eredményezhet)",
-       "config-cache-accel": "PHP-objektumok gyorsítótárazása (APC, XCache or WinCache)",
+       "config-cache-accel": "PHP-objektumok gyorsítótárazása (APC, APCu, XCache vagy WinCache)",
        "config-cache-memcached": "Memcached használata (további telepítés és konfigurálás szükséges)",
        "config-memcached-servers": "Memcached-szerverek:",
        "config-memcached-help": "Azon IP-címek listája, melyeket a Memcached használhat.\nVesszővel kell elválasztani őket, és meg kell adni a portot is. Például:\n 127.0.0.1:11211\n 192.168.1.25:11211",
index 4c68cf9..1d52273 100644 (file)
@@ -61,6 +61,7 @@
        "config-memory-bad": "'''Aviso:''' Le <code>memory_limit</code> de PHP es $1.\nIsto es probabilemente troppo basse.\nLe installation pote faller!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] es installate",
        "config-apc": "[http://www.php.net/apc APC] es installate",
+       "config-apcu": "[http://www.php.net/apcu APCu] es installate",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] es installate",
        "config-no-cache-apcu": "<strong>Attention:</strong> Impossibile trovar [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] o [http://www.iis.net/download/WinCacheForPhp WinCache].\nLe cache de objectos non es activate.",
        "config-mod-security": "'''Attention''': [http://modsecurity.org/ mod_security] es active in tu servitor web. Si mal configurate, isto pote causar problemas pro MediaWiki o altere software que permitte al usatores de publicar contento arbitrari.\nConsulta le [http://modsecurity.org/documentation/ documentation de mod_security] o contacta le servicio de adjuta de tu host si tu incontra estranie errores.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki supporta le sequente systemas de base de datos:\n\n$1\n\nSi tu non vide hic infra le systema de base de datos que tu tenta usar, alora seque le instructiones ligate hic supra pro activar le supporto.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] es le systema primari pro MediaWiki e le melio supportate. MediaWiki functiona anque con [{{int:version-db-mariadb-url}} MariaDB] e con [{{int:version-db-percona-url}} Percona Server], le quales es compatibile con MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Como compilar PHP con supporto de MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] es un systema de base de datos popular e open source, alternativa a MySQL. Es possibile que resta alcun minor defectos non resolvite, dunque illo non es recommendate pro uso in un ambiente de production. ([http://www.php.net/manual/en/pgsql.installation.php Como compilar PHP con supporto de PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] es un systema de base de datos popular e open source, alternativa a MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Como compilar PHP con supporto de PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] es un systema de base de datos legier que es multo ben supportate. ([http://www.php.net/manual/en/pdo.installation.php Como compilar PHP con supporto de SQLite], usa PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] es un banca de datos commercial pro interprisas. ([http://www.php.net/manual/en/oci8.installation.php Como compilar PHP con supporto de OCI8])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] es un base de datos de interprisa commercial pro Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Como compilar PHP con supporto de SQLSRV])",
        "config-cache-options": "Configuration del cache de objectos:",
        "config-cache-help": "Le cache de objectos es usate pro meliorar le rapiditate de MediaWiki per immagazinar le datos frequentemente usate.\nLe sitos medie o grande es multo incoragiate de activar isto, ma anque le sitos parve percipera le beneficios.",
        "config-cache-none": "Nulle cache (nulle functionalitate es removite, ma le rapiditate pote diminuer in grande sitos wiki)",
-       "config-cache-accel": "Cache de objectos de PHP (APC, XCache o WinCache)",
+       "config-cache-accel": "Cache de objectos PHP (APC, APCu, XCache o WinCache)",
        "config-cache-memcached": "Usar Memcached (require additional installation e configuration)",
        "config-memcached-servers": "Servitores Memcached:",
        "config-memcached-help": "Lista de adresses IP a usar pro Memcached.\nDebe specificar un per linea e specificar le porto a usar. Per exemplo:\n 127.0.0.1:11211\n 192.168.1.25:1234",
index d6ba2fe..8ad4347 100644 (file)
@@ -2,8 +2,11 @@
        "@metadata": {
                "authors": [
                        "Умар",
-                       "ElizaMag"
+                       "ElizaMag",
+                       "Adam-Yourist"
                ]
        },
+       "config-localsettings-key": "Кердадаккхара дIоагIа:",
+       "config-localsettings-badkey": "Iа белгалдаьккхад харцахь дола кердадаккхара дIоагIа.",
        "config-help": "новкъoстал"
 }
index dc24830..cedccd1 100644 (file)
@@ -19,7 +19,8 @@
                        "Macofe",
                        "Matteocng",
                        "Einreiher",
-                       "Tosky"
+                       "Tosky",
+                       "Selven"
                ]
        },
        "config-desc": "Programma di installazione per MediaWiki",
@@ -77,6 +78,7 @@
        "config-memory-bad": "''Attenzione:''' Il valore di <code>memory_limit</code> di PHP è $1.\nProbabilmente è troppo basso.\nL'installazione potrebbe non riuscire!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] è installato",
        "config-apc": "[http://www.php.net/apc APC] è installato",
+       "config-apcu": "[http://www.php.net/apc APC] è installato",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] è installato",
        "config-no-cache-apcu": "'''Attenzione:''' [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] o [http://www.iis.net/download/WinCacheForPhp WinCache] non sono stati trovati.\nLa caching degli oggetti non è attivata.",
        "config-mod-security": "<strong>Attenzione:</strong> Il tuo server web ha il [http://modsecurity.org/ mod_security] abilitato. Se non correttamente configurato, può creare problemi a MediaWiki o ad altro software che permette agli utenti di pubblicare contenuto.\nFai riferimento alla [http://modsecurity.org/documentation/ documentazione sul mod_security] o contatta il supporto tecnico del tuo provider di hosting se si verificano errori.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki supporta i seguenti sistemi di database:\n\n$1\n\nSe fra quelli elencati qui sotto non vedi il sistema di database che vorresti utilizzare, seguire le istruzioni linkate sopra per abilitare il supporto.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] è la configurazione preferibile per MediaWiki ed è quella meglio supportata. MediaWiki funziona anche con [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], che sono compatibili con MySQL.([http://www.php.net/manual/en/mysqli.installation.php Come compilare PHP con supporto MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] è un popolare sistema di database open source come alternativa a MySQL. Ci possono essere alcuni bug minori in sospeso, e non è raccomandato per l'uso in un ambiente di produzione. ([http://www.php.net/manual/en/pgsql.installation.php Come compilare PHP con supporto PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] è un popolare sistema di database open source come alternativa a MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Come compilare PHP con supporto PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]  è un sistema di database leggero, che è supportato molto bene. ([http://www.php.net/manual/en/pdo.installation.php Come compilare PHP con supporto SQLite], utilizza PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] è un database di un'impresa commerciale. ([http://www.php.net/manual/en/oci8.installation.php Come compilare PHP con supporto OCI8])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] è un database di un'impresa commerciale per Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Come compilare PHP con supporto SQLSRV])",
        "config-subscribe-help": "Si tratta di una mailing list a basso traffico dedicata agli annunci di nuove versioni, compresi importanti segnalazioni riguardanti la sicurezza.\nÈ consigliato iscriversi e aggiornare la propria installazione di MediaWiki quando una nuova versione viene resa pubblica.",
        "config-subscribe-noemail": "Hai provato ad iscriverti alla mailing list dedicata agli annunci delle nuove versioni senza fornire un indirizzo email.\nInserire un indirizzo email se si desidera effettuare l'iscrizione alla mailing list.",
        "config-pingback": "Condividi i dati su questa installazione con gli sviluppatori di MediaWiki.",
+       "config-pingback-help": "Se si seleziona questa opzione, MediaWiki contatterà periodicamente https://www.mediawiki.org con i dati base su questa istanza MediaWiki. In questa categoria di dati rientrano, per esempio, il tipo di sistema, la versione di PHP e database di backend scelto. La Wikimedia Foundation condivide questi dati con gli sviluppatori Mediawiki per aiutarla a guidare i futuri sforzi di sviluppo. Per il tuo sistema saranno inviati i seguenti dati:\n<pre>$1</pre>",
        "config-almost-done": "Hai quasi finito!\nAdesso puoi saltare la rimanente parte della configurazione e semplicemente installare il wiki.",
        "config-optional-continue": "Fammi altre domande.",
        "config-optional-skip": "Sono già stanco, installa solo il wiki.",
        "config-cache-options": "Impostazioni per la cache di oggetti:",
        "config-cache-help": "La memorizzazione di oggetti nella cache è utilizzata per migliorare la velocità di MediaWiki attraverso l'allocazione nella cache dei dati utilizzati di frequente.\nPer siti di dimensioni medie e grandi, è caldamente consigliato attivare la cache, ma anche per piccoli siti se ne vedranno i benefici.",
        "config-cache-none": "Nessuna memorizzazione in cache (nessuna funzionalità viene impedita, ma sui siti wiki più grandi la velocità potrebbe risentirne)",
-       "config-cache-accel": "Mettere in cache oggetti PHP (APC, XCache o WinCache)",
+       "config-cache-accel": "Mettere in cache oggetti PHP (APC, APCu, XCache o WinCache)",
        "config-cache-memcached": "Usa Memcached (richiede ulteriori attività di installazione e configurazione)",
        "config-memcached-servers": "Server di memcached:",
        "config-memcached-help": "Elenco di indirizzi IP da utilizzare per Memcached.\nDovresti specificarne uno per riga e indicare la porta da utilizzare. Per esempio:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-install-extension-tables": "Creazione delle tabelle per le estensioni attivate",
        "config-install-mainpage-failed": "Impossibile inserire la pagina principale: $1",
        "config-install-done": "<strong>Complimenti!</strong>\nHai installato MediaWiki.\n\nIl programma di installazione ha generato un file <code>LocalSettings.php</code> che contiene tutte le impostazioni.\n\nDevi scaricarlo ed inserirlo nella directory base del tuo wiki (la stessa dove è presente index.php). Il download dovrebbe partire automaticamente.\n\nSe il download non si avvia, o se è stato annullato, puoi riavviarlo cliccando sul collegamento di seguito:\n\n$3\n\n<strong>Nota:</strong> se esci ora dall'installazione senza scaricare il file di configurazione che è stato generato, questo poi non sarà più disponibile in seguito.\n\nQuando hai fatto, puoi <strong>[$2 entrare nel tuo wiki]</strong>.",
+       "config-install-done-path": "<strong>Complimenti!</strong>\nHai installato MediaWiki.\n\nIl programma di installazione ha generato un file <code>LocalSettings.php</code> che contiene tutte le impostazioni.\n\nDevi scaricarlo ed inserirlo in <code>$4</code>. Il download dovrebbe partire automaticamente.\n\nSe il download non si avvia, o se è stato annullato, puoi riavviarlo cliccando sul collegamento seguente:\n\n$3\n\n<strong>Nota:</strong> se esci ora dall'installazione senza scaricare il file di configurazione che è stato generato, questo poi non sarà più disponibile in seguito.\n\nQuando hai fatto, puoi <strong>[$2 entrare nel tuo wiki]</strong>.",
        "config-download-localsettings": "Scarica <code>LocalSettings.php</code>",
        "config-help": "aiuto",
        "config-help-tooltip": "fai clic per espandere",
        "config-nofile": "Il file \"$1\" non può essere trovato. È stato eliminato?",
        "config-extension-link": "Sapevi che il tuo wiki supporta le  [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions estensioni]?\n\nPuoi navigare tra le [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category estensioni per categoria].",
        "mainpagetext": "<strong>MediaWiki è stato installato.</strong>",
-       "mainpagedocfooter": "Consulta la [https://meta.wikimedia.org/wiki/Special:MyLanguage/Help:Contents Guida utente] per maggiori informazioni sull'uso di questo software wiki.\n\n== Per iniziare ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Impostazioni di configurazione]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Domande frequenti su MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Mailing list annunci MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Trova MediaWiki nella tua lingua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Imparare a combattere lo spam sul tuo wiki]"
+       "mainpagedocfooter": "Consulta la [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents guida utente] per maggiori informazioni sull'uso di questo software wiki.\n\n== Per iniziare ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Impostazioni di configurazione]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Domande frequenti su MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Mailing list annunci MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Trova MediaWiki nella tua lingua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Imparare a combattere lo spam sul tuo wiki]"
 }
index 5406be1..2a09893 100644 (file)
@@ -18,7 +18,9 @@
                        "Macofe",
                        "2nd-player",
                        "Otokoume",
-                       "Rxy"
+                       "Rxy",
+                       "Foresttttttt",
+                       "ネイ"
                ]
        },
        "config-desc": "MediaWiki のインストーラー",
@@ -76,6 +78,7 @@
        "config-memory-bad": "<strong>警告:</strong> PHPの<code>memory_limit</code>に$1に設定されています。\nこの値はおそらく小さすぎます。\nインストールが失敗するおそれがあります!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] がインストール済み",
        "config-apc": "[http://www.php.net/apc APC] がインストール済み",
+       "config-apcu": "[http://www.php.net/apc APC] がインストール済みです。",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] がインストール済み",
        "config-no-cache-apcu": "<strong>警告:</strong> [http://www.php.net/apcu APCu]、 [http://xcache.lighttpd.net/ XCache]、 [http://www.iis.net/download/WinCacheForPhp WinCache] のいずれも見つかりませんでした。\nオブジェクトのキャッシュは有効化されません。",
        "config-mod-security": "<strong>警告:</strong> あなたのウェブサーバーでは [http://modsecurity.org/ mod_security] が有効になっています。正しく構成されていない場合は、MediaWiki や利用者にコンテンツの投稿を許可するその他のソフトウェアに問題が発生する場合があります。\n[http://modsecurity.org/documentation/ mod_security の説明文書]を確認するか、ランダムなエラーが発生した場合はあなたのホストのサポートにお問い合わせください。",
        "config-type-mssql": "マイクロソフト SQL Server",
        "config-support-info": "MediaWiki は以下のデータベース システムに対応しています:\n\n$1\n\n使用しようとしているデータベース システムが下記の一覧にない場合は、上記リンク先の手順に従ってインストールしてください。",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]はMediaWikiの主要な対象であり、最もよくサポートされています。MediaWikiはMySQLと互換性のある[{{int:version-db-mariadb-url}} MariaDB]、[{{int:version-db-percona-url}} Percona Server]でも動きます。 ([http://www.php.net/manual/ja/mysqli.installation.php PHPをMySQLサポート付きでコンパイルする方法])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] は、MySQLの代替として人気があるオープンソースのデータベースシステムです。細部の未解消バグがある場合があるため、プロダクション環境での使用は推奨されません。 ([http://www.php.net/manual/en/pgsql.installation.php PHPをPostgreSQLサポート付きでコンパイルする方法])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] は、MySQLの代替として人気がある公開のデータベースシステムです。([http://www.php.net/manual/en/pgsql.installation.php PHPをPostgreSQLサポート付きでコンパイルする方法])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]は、良くサポートされている、軽量データベースシステムです。([http://www.php.net/manual/ja/pdo.installation.php SQLiteに対応したPHPをコンパイルする方法]、PDOを使用)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle]は商業企業のデータベースです。([http://www.php.net/manual/en/oci8.installation.php OCI8サポートなPHPをコンパイルする方法])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]は商業企業のWindows用データベースです。([http://www.php.net/manual/en/sqlsrv.installation.php SQLSRVサポートなPHPをコンパイルする方法])",
        "config-subscribe": "[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce リリース告知のメーリングリスト]を購読する。",
        "config-subscribe-help": "これは、リリースの告知 (重要なセキュリティに関する案内を含む) に使用される、流量が少ないメーリングリストです。\nこのメーリングリストを購読して、新しいバージョンが出た場合にMediaWikiを更新してください。",
        "config-subscribe-noemail": "メールアドレスなしでリリースアナウンスのメーリングリストを購読しようとしています。\nメーリングリストを購読する場合にはメールアドレスを入力してください。",
+       "config-pingback": "このインストールに関するデータをMediaWikiの開発者と共有する。",
+       "config-pingback-help": "もし君がこのオプションを選択したら、メデイアウィキは定期的にhttps://www.mediawiki.orgとメデイアウィキのインスタンスに関する基本的のデータをピンします。このデータはシステムのタイプ、PHPのバージョンと選択されたデータベースのバックエンドなどを含んでいます。メデイアウィキファンデーションは将来の",
        "config-almost-done": "これでほぼ終わりました!\n残りの設定を飛ばして、ウィキを今すぐインストールできます。",
        "config-optional-continue": "私にもっと質問してください。",
        "config-optional-skip": "もう飽きてしまったので、とにかくウィキをインストールしてください。",
        "config-nofile": "ファイル「$1」が見つかりませんでした。削除された可能性があります。",
        "config-extension-link": "あなたのウィキは[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions 拡張機能]をサポートしていることをご存知ですか?\n\n[https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category カテゴリ別で拡張機能を見る]か[https://www.mediawiki.org/wiki/Extension_Matrix 拡張機能のマトリックス]で拡張機能すべてのリストをご覧になれます。",
        "mainpagetext": "<strong>MediaWiki はインストール済みです。</strong>",
-       "mainpagedocfooter": "ウィキソフトウェアの使い方に関する情報は[https://meta.wikimedia.org/wiki/Help:Contents 利用者案内]を参照してください。\n\n== はじめましょう ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings/ja 設定の一覧]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/ja MediaWiki よくある質問と回答]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki リリース情報メーリングリスト]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation/ja MediaWiki のあなたの言語へのローカライズ]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki]"
+       "mainpagedocfooter": "ウィキソフトウェアの使い方に関する情報は[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents 利用者案内]を参照してください。\n\n== はじめましょう ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings/ja 設定の一覧]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/ja MediaWiki よくある質問と回答]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki リリース情報メーリングリスト]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation/ja MediaWiki のあなたの言語へのローカライズ]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam あなたのウィキでスパムと戦う方法を学ぶ]"
 }
index c9ae2c8..ce3ae88 100644 (file)
@@ -69,6 +69,7 @@
        "config-memory-bad": "<strong>경고:</strong> PHP의 <code>memory_limit</code>는 $1입니다.\n아마도 너무 낮은 것 같습니다.\n설치가 실패할 수 있습니다!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache]가 설치되었습니다",
        "config-apc": "[http://www.php.net/apc APC]가 설치되었습니다",
+       "config-apcu": "[http://www.php.net/apcu APCu]가 설치되었습니다",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache]가 설치되었습니다",
        "config-no-cache-apcu": "<strong>경고:</strong> [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] 또는 [http://www.iis.net/download/WinCacheForPhp WinCache]를 찾을 수 없습니다.\n개체 캐싱을 활성화할 수 없습니다.",
        "config-mod-security": "<strong>경고:</strong> 웹 서버에 [http://modsecurity.org/ mod_security]가 허용되었습니다. 잘못 설정된 경우 미디어위키나 사용자가 임의의 내용을 게시할 수 있는 다른 소프트웨어에 대한 문제를 일으킬 수 있습니다.\n[http://modsecurity.org/documentation/ mod_security] 문서를 참고하거나 임의의 오류가 발생할 경우 호스트의 지원 요청에 문의하십시오.",
        "config-type-mssql": "Microsoft SQL 서버",
        "config-support-info": "미디어위키는 다음의 데이터베이스 시스템을 지원합니다:\n\n$1\n\n데이터베이스 시스템이 표시되지 않을 때 아래에 나열된 다음 지원을 활성화하려면 위의 링크된 지시에 따라 설치해볼 수 있습니다.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]은 미디어위키의 기본 대상이며 가장 잘 지원됩니다. 미디어위키는 또한 MySQL와 호환되는 [{{int:version-db-mariadb-url}} MariaDB]와 [{{int:version-db-percona-url}} Percona 서버]에서도 작동합니다. ([http://www.php.net/manual/en/mysql.installation.php MySQL 지원으로 PHP를 컴파일하는 방법])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]은 MySQL의 대안으로서 인기 있는 오픈 소스 데이터베이스 시스템입니다. ([http://www.php.net/manual/en/pgsql.installation.php PostgreSQL 지원으로 PHP를 컴파일하는 방법]) 몇 가지 해결하지 못한 사소한 버그가 있을 수 있으며, 이를 제작 환경에서 사용하지 않는 것이 좋습니다.",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]은 MySQL의 대안으로서 인기 있는 오픈 소스 데이터베이스 시스템입니다. ([http://www.php.net/manual/en/pgsql.installation.php PostgreSQL 지원으로 PHP를 컴파일하는 방법])",
        "config-dbsupport-sqlite": "*  [{{int:version-db-sqlite-url}} SQLite]는 매우 잘 지원되고 가벼운 데이터베이스 시스템입니다. ([http://www.php.net/manual/en/pdo.installation.php SQLite 지원으로 PHP를 컴파일하는 방법], PDO 사용)",
        "config-dbsupport-oracle": "*  [{{int:version-db-oracle-url}} Oracle]은 상용 기업 데이터베이스입니다. ([http://www.php.net/manual/en/oci8.installation.php OCI8 지원으로 PHP를 컴파일하는 방법])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL 서버]는 Windows용 상용 기업 데이터베이스입니다. ([http://www.php.net/manual/en/sqlsrv.installation.php SQLSRV 지원으로 PHP를 컴파일하는 방법])",
        "config-cache-options": "개체 캐싱을 위한 설정:",
        "config-cache-help": "개체 캐싱은 자주 사용하는 데이터를 캐싱하여 미디어위키의 속도를 개선하는 데 사용합니다.\n큰 규모의 사이트는 이를 많이 사용하도록 권장하고 있으며, 소규모 사이트들도 물론 혜택을 볼 수 있습니다.",
        "config-cache-none": "캐시하지 않음 (기능이 삭제되지는 않지만 큰 위키 사이트에 속도가 영향을 받을 수 있습니다)",
-       "config-cache-accel": "PHP 개체 캐싱 (APC, XCache 또는 WinCache)",
+       "config-cache-accel": "PHP 개체 캐싱 (APC, APCu, XCache 또는 WinCache)",
        "config-cache-memcached": "Memcached 사용 (추가적인 설치와 설정이 필요합니다)",
        "config-memcached-servers": "Memcached 서버:",
        "config-memcached-help": "Memcached의 사용하기 위한 IP 주소 목록입니다.\n한 줄에 하나씩 사용할 포트를 지정해야 합니다. 예를 들어:\n 127.0.0.1:11211\n 192.168.1.25:1234",
index 91df060..d1b1a9b 100644 (file)
@@ -50,6 +50,7 @@
        "config-memory-bad": "'''Opgepasst:''' De Parameter <code>memory_limit</code> vu PHP ass $1.\nDat ass wahrscheinlech ze niddreg.\nD'Installatioun kéint net funktionéieren.",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] ass installéiert",
        "config-apc": "[http://www.php.net/apc APC] ass installéiert",
+       "config-apcu": "[http://www.php.net/apcu APCu] ass installéiert.",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] ass installéiert",
        "config-diff3-bad": "GNU diff3 gouf net fonnt.",
        "config-git": "D'Software Git fir d'Kontroll vu Versioune gouf fonnt: <code>$1</code>.",
@@ -83,7 +84,7 @@
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ass e beléiften Open-Source-Datebanksystem an eng Alternativ zu MySQL. Et gëtt awer e puer kleng Implementatiounsfeeler, dofir gëtt vun der Notzung an engem Produktivsystem ofgeroden. ([http://www.php.net/manual/de/pgsql.installation.php Uleedung fir d'Kompilatoun vu PHP mat PostgreSQL-Ënnerstëtzung])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] ass e beléiften Open-Source-Datebanksystem an eng Alternativ zu MySQL. ([http://www.php.net/manual/de/pgsql.installation.php Uleedung fir d'Kompilatoun vu PHP mat PostgreSQL-Ënnerstëtzung])",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] ass eng kommerziell Datebank-Software. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP mat OCI8 Ënnerstëtzung])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ass eng kommerziell Datebank-Software fir Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Wéi PHP mat SQLSRV Ënnerstëtzung kompiléieren])",
        "config-header-mysql": "MySQL-Astellungen",
        "config-help-tooltip": "klickt fir opzeklappen",
        "config-nofile": "De Fichier \"$1\" gouf net fonnt. Gouf e geläscht?",
        "mainpagetext": "<strong>MediaWiki gouf installéiert.</strong>",
-       "mainpagedocfooter": "Kuckt w.e.g. [https://meta.wikimedia.org/wiki/Help:Contents d'Benotzerhandbuch] fir Informatiounen iwwer de Gebruach vun der Wiki Software.\n\n== Fir  unzefänken ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Hëllef bei der Konfiguratioun]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki-FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Mailinglëscht vun neie MediaWiki-Versiounen]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Lokaliséiert MediaWiki fir Är Sprooch]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Léiert wéi Spam op Ärer Wiki reduzéiert gi kann]"
+       "mainpagedocfooter": "Kuckt w.e.g. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents d'Benotzerhandbuch] fir Informatiounen iwwer de Gebruach vun der Wiki Software.\n\n== Fir  unzefänken ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Hëllef bei der Konfiguratioun]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki-FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Mailinglëscht vun neie MediaWiki-Versiounen]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Lokaliséiert MediaWiki fir Är Sprooch]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Léiert wéi Spam op Ärer Wiki reduzéiert gi kann]"
 }
index 22cceb4..07e4c90 100644 (file)
@@ -4,7 +4,8 @@
                        "Eitvys200",
                        "Mantak111",
                        "Zygimantus",
-                       "Hugo.arg"
+                       "Hugo.arg",
+                       "Homo"
                ]
        },
        "config-desc": "MediaWiki diegimas",
@@ -53,6 +54,7 @@
        "config-memory-raised": "PHP <code>memory_limit</code> yra $1, padidintas iki $2.",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] yra įdiegtas",
        "config-apc": "[http://www.php.net/apc APC] yra įdiegtas",
+       "config-apcu": "[http://www.php.net/apcu APCu] yra įdiegtas",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] yra įdiegtas",
        "config-no-cache-apcu": "<strong>Įspėjimas:</strong> Nepavyko rasti [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] or [http://www.iis.net/download/WinCacheForPhp WinCache].\nObjekto spartinimas neįjungtas.",
        "config-diff3-bad": "GNU diff3 nerastas.",
@@ -69,7 +71,7 @@
        "config-db-install-account": "Vartotojo paskyra diegimui",
        "config-db-username": "Duomenų bazės vartotojo vardas:",
        "config-db-password": "Duomenų bazės slaptažodis:",
-       "config-db-wiki-account": "Vartotojo paskyra normaliai operacijai",
+       "config-db-wiki-account": "Naudotojo paskyra įprastai operacijai",
        "config-db-prefix": "Duomenų bazės lentelės priešdėlis:",
        "config-mysql-old": "MySQL $1 ar vėlesnė yra reikalinga. Jūs turite $2.",
        "config-db-port": "Duomenų bazės prievadas:",
@@ -92,6 +94,7 @@
        "config-postgres-old": "PostgreSQL $1 ar vėlesnė yra reikalinga. Jūs turite $2.",
        "config-sqlite-cant-create-db": "Nepavyko sukurti duomenų bazės failo <code>$1</code>.",
        "config-regenerate": "Pergeneruoti LocalSettings.php →",
+       "config-db-web-account": "Duomenų bazės paskyra dėl internetinės prieigos",
        "config-db-web-account-same": "Naudoti tą pačią paskyrą kaip ir įdiegimui",
        "config-db-web-create": "Sukurti paskyrą, jeigu jos nėra",
        "config-mysql-engine": "Saugojimo variklis:",
        "config-license": "Autorinės teisės ir licencija:",
        "config-license-pd": "Viešas domenas",
        "config-email-settings": "El. pašto nustatymai",
-       "config-email-watchlist": "Įjungti stebimų pranešimą",
+       "config-email-watchlist": "Įjungti stebimų pranešimą",
        "config-email-auth": "Įjungti el. pašto autentifikavimą",
        "config-upload-settings": "Vaizdų ir failų įkėlimai",
        "config-upload-enable": "Įgalinti failų įkėlimus",
        "config-help-tooltip": "spustelėkite išplėtimui",
        "config-nofile": "Failas \"$1\" nerastas. Ar jis buvo ištrintas?",
        "mainpagetext": "<strong>MediaWiki sėkmingai įdiegta.</strong>",
-       "mainpagedocfooter": "Informacijos apie wiki programinės įrangos naudojimą, ieškokite [https://meta.wikimedia.org/wiki/Help:Contents žinyne].\n\n== Pradžiai ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Konfigūracijos nustatymų sąrašas]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki DUK]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki pranešimai paštu apie naujas versijas]"
+       "mainpagedocfooter": "Informacijos apie viki programinės įrangos naudojimą, ieškokite [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents].\n\n== Pradžia ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Konfigūracijos nustatymų sąrašas]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MedijaViki DUK]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MedijaViki pranešimai el. paštu apie naujas versijas]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Lokalizuoti MedijaViki savo kalbai]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Sužinokite kaip kovoti su šlamštu savo viki]"
 }
index 7fe3a64..23f3de1 100644 (file)
@@ -26,6 +26,8 @@
        "config-page-copying": "Kopē",
        "config-restart": "Jā, restartēt",
        "config-env-php": "PHP $1 ir uzstādīts.",
+       "config-env-hhvm": "HHVM $1 ir uzstādīts.",
+       "config-apcu": "[http://www.php.net/apcu APCu] ir uzstādīts",
        "config-diff3-bad": "GNU diff3 nav atrasts.",
        "config-db-name": "Datubāzes nosaukums:",
        "config-db-username": "Datubāzes lietotājvārds:",
        "config-email-settings": "E-pasta iestatījumi",
        "config-logo": "Logo URL:",
        "config-cc-again": "Izvēlies vēlreiz...",
+       "config-memcached-servers": "Memcached serveri:",
        "config-extensions": "Paplašinājumi",
        "config-install-step-done": "Gatavs",
+       "config-install-user": "Veido datu bāzes lietotāju",
        "config-help": "palīdzība",
        "config-help-tooltip": "uzspiediet, lai izvērstu",
        "mainpagetext": "<strong>MediaWiki veiksmīgi instalēts.</strong>",
index 8b8e0fb..5e3fc0d 100644 (file)
@@ -21,9 +21,9 @@
        "config-page-dbsettings": "डाटाबेस कुंजी",
        "config-page-name": "नाम",
        "config-page-options": "विकल्प",
-       "config-page-install": "सà¥\8dथापित à¤\95रà¥\81",
+       "config-page-install": "सà¥\8dथापित à¤\95रà¥\80",
        "config-page-complete": "पूर्ण!",
-       "config-page-restart": "स्थापनाके पुनारम्भ करु",
+       "config-page-restart": "स्थापनाक पुनारम्भ करी",
        "config-page-readme": "पढू",
        "config-page-releasenotes": "रिलीज नोट्स",
        "config-page-copying": "अनुकरण",
index f8b66c1..649d9ce 100644 (file)
@@ -61,6 +61,7 @@
        "config-memory-bad": "'''Предупредување:''' <code>memory_limit</code> за PHP изнесува $1.\nОва е веројатно премалку.\nВоспоставката може да не успее!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] е воспоставен",
        "config-apc": "[http://www.php.net/apc APC] е воспоставен",
+       "config-apcu": "[http://www.php.net/apcu APCu] е воспоставен",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] е воспоставен",
        "config-no-cache-apcu": "<strong>Предупредување:</strong> Не можев да го најдам [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] или [http://www.iis.net/download/WinCacheForPhp WinCache].\nМеѓускладирањето на објекти не е овозможено",
        "config-mod-security": "'''Предупредување''': на вашиот опслужувач има овозможено [http://modsecurity.org/ mod_security]. Ако не е поставено како што треба, ова може да предизвика проблеми кај МедијаВики и други програми што им овозможуваат на корисниците да објавуваат произволни содржини.\nПогледнете ја [http://modsecurity.org/documentation/ mod_security документацијата] или обратете се кај домаќинот ако наидете на случајни грешки.",
        "config-cache-options": "Нагодувања за меѓускладирање на објекти:",
        "config-cache-help": "Меѓускладирањето на објекти се користи за зголемување на брзината на МедијаВики со меѓускладирање на често употребуваните податоци.\nОва многу се препорачува на средни до големи викија, но од тоа ќе имаат полза и малите викија.",
        "config-cache-none": "Без меѓускладирање (не се остранува ниедна функција, но може да влијае на брзината кај поголеми викија)",
-       "config-cache-accel": "Меѓускладирање на PHP-објекти (APC, XCache или WinCache)",
+       "config-cache-accel": "Меѓускладирање на PHP-објекти (APC, APCu, XCache или WinCache)",
        "config-cache-memcached": "Користи Memcached (бара дополнително поставување и нагодување)",
        "config-memcached-servers": "Memcached-опслужувачи:",
        "config-memcached-help": "Список на IP-адреси за употреба во Memcached.\nТреба да се наведе по една во секој ред, како и портата што ќе се користи. На пример:\n 127.0.0.1:11211\n 192.168.1.25:1234",
index a8bc219..a6b1508 100644 (file)
@@ -52,7 +52,7 @@
        "config-sidebar": "* [https://www.mediawiki.org MediaWiki hjem]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Brukerguide]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Administratorguide]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ OSS]\n----\n* <doclink href=Readme>Les meg</doclink>\n* <doclink href=ReleaseNotes>Utgivelsesnotater</doclink>\n* <doclink href=Copying>Kopiering</doclink>\n* <doclink href=UpgradeDoc>Oppgradering</doclink>",
        "config-env-good": "Miljøet har blitt sjekket.\nDu kan installere MediaWiki.",
        "config-env-bad": "Miljøet har blitt sjekket.\nDu kan installere MediaWiki.",
-       "config-env-php": "PHP $1 er innstallert.",
+       "config-env-php": "PHP $1 er installert.",
        "config-env-hhvm": "HHVM $1 er installert.",
        "config-unicode-using-intl": "Bruker [http://pecl.php.net/intl intl PECL-utvidelsen] for Unicode-normalisering.",
        "config-unicode-pure-php-warning": "'''Advarsel''': [http://pecl.php.net/intl intl PECL-utvidelsen] er ikke tilgjengelig for å håndtere Unicode-normaliseringen, faller tilbake til en langsommere ren-PHP-implementasjon.\nOm du kjører et nettsted med høy trafikk bør du lese litt om [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode-normalisering].",
@@ -64,8 +64,9 @@
        "config-pcre-no-utf8": "'''Fatal''': PHPs PCRE modul ser ut til å være kompilert uten PCRE_UTF8-støtte.\nMediaWiki krever UTF-8-støtte for å fungere riktig.",
        "config-memory-raised": "PHPs <code>memory_limit</code> er $1, økt til $2.",
        "config-memory-bad": "'''Advarsel:''' PHPs <code>memory_limit</code> er $1.\nDette er sannsynligvis for lavt.\nInstallasjonen kan mislykkes!",
-       "config-xcache": "[http://xcache.lighttpd.net/ XCache] er innstallert",
-       "config-apc": "[http://www.php.net/apc APC] er innstallert",
+       "config-xcache": "[http://xcache.lighttpd.net/ XCache] er installert",
+       "config-apc": "[http://www.php.net/apc APC] er installert",
+       "config-apcu": "[http://www.php.net/apcu APCu] er installert",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] er installert",
        "config-no-cache-apcu": "<strong>Advarsel:</strong> Kunne ikke finne [http://www.php.net/apc APC], [http://xcache.lighttpd.net/ XCache] eller [http://www.iis.net/download/WinCacheForPhp WinCache].\nObjekthurtiglagring er ikke aktivert.",
        "config-mod-security": "'''Advarsel''': Din web-tjener har [http://modsecurity.org/ mod_security] påslått. Hvis denne er feilinnstilt, kan det gi problemer for MediaWiki eller annen programvare som tillater brukere å poste vilkårlig innhold.\nSjekk [http://modsecurity.org/documentation/ mod_security-dokumentasjonen] eller ta kontakt med din nettleverandør hvis du opplever tilfeldige feil.",
        "config-cache-options": "Innstillinger for objekt-mellomlagring:",
        "config-cache-help": "Objekt-mellomlagring brukes for å forbedre hastigheten for MediaWiki. Ofte forekommende data lagres for gjenbruk.\nMiddels til store nettsteder bør absolutt aktivisere mellomlagring, med også små nettsteder kan ha nytte av dette.",
        "config-cache-none": "Ingen mellomlagring (ingen funksjonalitet mistes, men hastigheten kan bli dårlig for store wikier-nettsteder)",
-       "config-cache-accel": "Mellomlagring av PHP-objekter (APC, XCache or WinCache)",
+       "config-cache-accel": "Mellomlagring av PHP-objekter (APC, APCu, XCache eller WinCache)",
        "config-cache-memcached": "Bruk Memcached (krever tilleggsoppsett og -konfigurering)",
        "config-memcached-servers": "Memcached-servere:",
        "config-memcached-help": "Liste av IP-adresser for bruk fra Memcached.\nDet bør angis en per linje sammen med porten som brukes. For eksempel:\n 127.0.0.1:11211\n 192.168.1.25:1234",
index 7c50e82..3ee33c1 100644 (file)
@@ -24,7 +24,7 @@
        "config-page-dbconnect": "डेटाबेससँग सम्बन्ध बनाउने",
        "config-page-dbsettings": "डेटावेस सेटिङ",
        "config-page-name": "नाम",
-       "config-page-options": "विà¤\95लà¥\8dपहरà¥\81",
+       "config-page-options": "विà¤\95लà¥\8dपहरà¥\82",
        "config-page-install": "स्थापना गर्ने",
        "config-page-complete": "पूरा भयो !",
        "config-page-restart": "स्थापना फेरि सुरु गर्ने",
@@ -57,7 +57,7 @@
        "config-ns-other": "अन्य(खुलाउनुहोस)",
        "config-ns-other-default": "MyWiki",
        "config-admin-box": "प्रवन्धक खाता",
-       "config-admin-name": "तपाà¤\88à¤\81को प्रयोगकर्ता नाम:",
+       "config-admin-name": "तपाà¤\88à¤\82को प्रयोगकर्ता नाम:",
        "config-admin-password": "पासवर्ड:",
        "config-admin-email": "इमेल ठेगाना:",
        "config-optional-continue": "मलाई थप प्रश्नहरू सोध्नुहोस् ।",
@@ -82,5 +82,5 @@
        "config-help": "सहायता",
        "config-help-tooltip": "विस्तार गर्न क्लीक गर्नुहोस्",
        "mainpagetext": "'''मीडिया सफलतापूर्वक कम्प्यूटरमा स्थापित भयो ।'''",
-       "mainpagedocfooter": " विकी अनुप्रयोग कसरी प्रयोग गर्ने भन्ने जानकारीको लागि  [https://meta.wikimedia.org/wiki/Help:Contents प्रयोगकर्ता सहायता] हेर्नुहोस्\n\n== सुरू गर्नको लागि  ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings विन्यास सेटिङ्ग सूची]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ मेडियाविकि सामान्य प्रश्नका उत्तरहरु]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce मेडियाविकि सुचना मेलिङ्ग सूची]"
+       "mainpagedocfooter": " विकी अनुप्रयोग कसरी प्रयोग गर्ने भन्ने जानकारीको लागि  [https://meta.wikimedia.org/wiki/Help:Contents प्रयोगकर्ता सहायता] हेर्नुहोस्\n\n विकी अनुप्रयोग कसरी प्रयोग गर्ने भन्ने जानकारीको लागि  [https://meta.wikimedia.org/wiki/Help:Contents प्रयोगकर्ता सहायता] हेर्नुहोस्\n\n== सुरू गर्नको लागि  ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings विन्यास सेटिङ्ग सूची]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ मेडियाविकि सामान्य प्रश्नका उत्तरहरू]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce मेडियाविकि सूचना मेलिङ्ग सूची]"
 }
index 78649ce..87a176c 100644 (file)
@@ -16,7 +16,8 @@
                        "Sjoerddebruin",
                        "Esketti",
                        "JaapDeKleine",
-                       "Macofe"
+                       "Macofe",
+                       "Hex"
                ]
        },
        "config-desc": "Het installatieprogramma voor MediaWiki",
@@ -57,7 +58,7 @@
        "config-restart": "Ja, opnieuw starten",
        "config-welcome": "=== Controle omgeving ===\nEr worden een aantal basiscontroles uitgevoerd met als doel vast te stellen of deze omgeving geschikt is voor een installatie van MediaWiki.\nLever deze gegevens aan als u ondersteuning vraagt bij de installatie.",
        "config-copyright": "=== Auteursrechten en voorwaarden ===\n\n$1\n\nDit programma is vrije software. U mag het verder verspreiden en/of aanpassen in overeenstemming met de voorwaarden van de GNU General Public License zoals uitgegeven door de Free Software Foundation; ofwel versie 2 van de Licentie of - naar uw keuze - enige latere versie.\n\nDit programma wordt verspreid in de hoop dat het nuttig is, maar '''zonder enige garantie''', zelfs zonder de impliciete garantie van '''verkoopbaarheid''' of '''geschiktheid voor een bepaald doel'''.\nZie de GNU General Public License voor meer informatie.\n\nSamen met dit programma hoort u een <doclink href=Copying>exemplaar van de GNU General Public License</doclink> ontvangen te hebben; zo niet, schrijf dan aan de Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, Verenigde Staten. Of [http://www.gnu.org/copyleft/gpl.html lees de licentie online].",
-       "config-sidebar": "* [https://www.mediawiki.org MediaWiki thuispagina]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Gebruikershandleiding] (Engelstalig)\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Beheerdershandleiding] (Engelstalig)\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Veelgestelde vragen] (Engelstalig)\n----\n* <doclink href=Readme>Leesmij</doclink> (Engelstalig)\n* <doclink href=ReleaseNotes>Release notes</doclink> (Engelstalig)\n* <doclink href=Copying>Kopiëren</doclink> (Engelstalig)\n* <doclink href=UpgradeDoc>Versie bijwerken</doclink> (Engelstalig)",
+       "config-sidebar": "* [https://www.mediawiki.org MediaWiki-thuispagina]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Gebruikershandleiding] (Engelstalig)\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Beheerdershandleiding] (Engelstalig)\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Veelgestelde vragen] (Engelstalig)\n----\n* <doclink href=Readme>Leesmij</doclink> (Engelstalig)\n* <doclink href=ReleaseNotes>Release notes</doclink> (Engelstalig)\n* <doclink href=Copying>Kopiëren</doclink> (Engelstalig)\n* <doclink href=UpgradeDoc>Versie bijwerken</doclink> (Engelstalig)",
        "config-env-good": "De omgeving is gecontroleerd.\nU kunt MediaWiki installeren.",
        "config-env-bad": "De omgeving is gecontroleerd.\nU kunt MediaWiki niet installeren.",
        "config-env-php": "PHP $1 is op dit moment geïnstalleerd.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki ondersteunt de volgende databasesystemen:\n\n$1\n\nAls u het databasesysteem dat u wilt gebruiken niet in de lijst terugvindt, volg dan de handleiding waarnaar hierboven wordt verwezen om ondersteuning toe te voegen.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] is de primaire database voor MediaWiki en wordt het best ondersteund. MediaWiki werkt ook met [{{int:version-db-mariadb-url}} MariaDB] en [{{int:version-db-percona-url}} Percona Server], die MySQL compatibel zijn ([http://www.php.net/manual/en/mysqli.installation.php hoe PHP te compileren met MySQL-ondersteuning]).",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is een populair open source databasesysteem als alternatief voor MySQL. Het is mogelijk dat er een aantal bekende kleinere problemen zijn met MediaWiki in combinatie met deze database en daarom wordt PostgreSQL niet aanbevolen voor een productieomgeving ([http://www.php.net/manual/en/pgsql.installation.php hoe PHP gecompileerd moet zijn met ondersteuning voor PostgreSQL]).",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] is een populair open source databasesysteem als alternatief voor MySQL.([http://www.php.net/manual/en/pgsql.installation.php Hoe u PHP kunt compileren met ondersteuning voor PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] is een zeer goed ondersteund lichtgewicht databasesysteem ([http://www.php.net/manual/en/pdo.installation.php hoe PHP gecompileerd moet zijn met ondersteuning voor SQLite]; gebruikt PDO).",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] is een commerciële database voor grote bedrijven ([http://www.php.net/manual/en/oci8.installation.php PHP compileren met ondersteuning voor OCI8]).",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] is een commerciële enterprisedatabase voor Windows ([http://www.php.net/manual/en/sqlsrv.installation.php PHP compileren met ondersteuning voor SQLSRV]).",
        "config-ns-site-name": "Zelfde als de wiki: $1",
        "config-ns-other": "Andere (geef aan welke)",
        "config-ns-other-default": "MijnWiki",
-       "config-project-namespace-help": "In het kielzog van Wikipedia beheren veel wiki's hun beleidspagina's apart van hun inhoudelijke pagina's in een \"'''projectnaamruimte'''\".\nAlle paginanamen in deze naamruimte beginnen met een bepaald voorvoegsel dat u hier kunt opgeven.\nDit voorvoegsel wordt meestal afgeleid van de naam van de wiki, maar het kan geen bijzondere tekens bevatten als \"#\" of \":\".",
+       "config-project-namespace-help": "In het kielzog van Wikipedia beheren veel wiki's hun beleidspagina's apart van hun inhoudelijke pagina's in een '''projectnaamruimte'''.\nAlle paginanamen in deze naamruimte beginnen met een bepaald voorvoegsel dat u hier kunt opgeven.\nDit voorvoegsel wordt meestal afgeleid van de naam van de wiki, maar het kan geen bijzondere tekens bevatten als \"#\" of \":\".",
        "config-ns-invalid": "De opgegeven naamruimte \"<nowiki>$1</nowiki>\" is ongeldig.\nGeef een andere naamruimte op.",
        "config-ns-conflict": "De opgegeven naamruimte \"<nowiki>$1</nowiki>\" conflicteert met een standaard naamruimte in MediaWiki.\nGeef een andere naam op voor de projectnaamruimte.",
        "config-admin-box": "Beheerdersgebruiker",
        "config-subscribe": "Abonneren op de [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce mailinglijst releaseaankondigen].",
        "config-subscribe-help": "Dit is een mailinglijst met een laag volume voor aankondigingen van nieuwe versies, inclusief belangrijke aankondigingen met betrekking tot beveiliging.\nAbonneer uzelf erop en werk uw MediaWiki-installatie bij als er nieuwe versies uitkomen.",
        "config-subscribe-noemail": "U hebt geprobeerd zich te abonneren op de mailinglijst voor release-aankondigingen zonder een e-mailadres op te geven.\nGeef een e-mailadres op als u zich wilt abonneren op de mailinglijst.",
+       "config-pingback": "Gegevens over deze installatie delen met MediaWiki-ontwikkelaars.",
        "config-almost-done": "U bent bijna klaar!\nAls u wilt kunt u de overige instellingen overslaan en de wiki nu installeren.",
        "config-optional-continue": "Stel me meer vragen.",
        "config-optional-skip": "Laat maar zitten, installeer gewoon de wiki.",
        "config-logo": "URL voor logo:",
        "config-logo-help": "Het standaarduiterlijk van MediaWiki bevat ruimte voor een logo van 135x160 pixels boven het menu.\nUpload een afbeelding met de juiste afmetingen en voer de URL hier in.\n\nU kunt <code>$wgStylePath</code> of <code>$wgScriptPath</code> gebruiken als uw logo relatief is aan een van deze paden.\n\nAls u geen logo wilt gebruiken, kunt u dit veld leeg laten.",
        "config-instantcommons": "Instant Commons inschakelen",
-       "config-instantcommons-help": "[https://www.mediawiki.org/wiki/InstantCommons Instant Commons] is functie die het mogelijk maakt om afbeeldingen, geluidsbestanden en andere mediabestanden te gebruiken van de website [https://commons.wikimedia.org/ Wikimedia Commons].\nHiervoor heeft MediaWiki toegang nodig tot Internet.\n\nMeer informatie over deze functie en hoe deze in te stellen voor andere wiki's dan Wikimedia Commons is te vinden in de [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos handleiding].",
+       "config-instantcommons-help": "[https://www.mediawiki.org/wiki/InstantCommons Instant Commons] is functie die het mogelijk maakt om afbeeldingen, geluidsbestanden en andere mediabestanden te gebruiken van de website [https://commons.wikimedia.org/ Wikimedia Commons].\nHiervoor heeft MediaWiki toegang nodig tot internet.\n\nMeer informatie over deze functie en hoe deze in te stellen voor andere wiki's dan Wikimedia Commons is te vinden in de [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos handleiding].",
        "config-cc-error": "De licentiekiezer van Creative Commons heeft geen resultaat opgeleverd.\nVoer de licentie handmatig in.",
        "config-cc-again": "Opnieuw kiezen...",
        "config-cc-not-chosen": "Kies de Creative Commonslicentie die u wilt gebruiken en klik op \"proceed\".",
        "config-cache-options": "Instellingen voor het cachen van objecten:",
        "config-cache-help": "Het cachen van objecten wordt gebruikt om de snelheid van MediaWiki te verbeteren door vaak gebruikte gegevens te bewaren.\nMiddelgrote tot grote websites wordt geadviseerd dit in te schakelen en ook kleine sites merken de voordelen.",
        "config-cache-none": "Niets cachen.\nEr gaat geen functionaliteit verloren, maar dit kan invloed hebben op de prestaties.",
-       "config-cache-accel": "Cachen van objecten via PHP (APC, XCache of WinCache)",
+       "config-cache-accel": "Cachen van objecten via PHP (APC, APCu, XCache of WinCache)",
        "config-cache-memcached": "Memcached gebruiken (dit vereist aanvullende instellingen)",
        "config-memcached-servers": "Memcachedservers:",
        "config-memcached-help": "Lijst met IP-adressen te gebruiken voor Memcached.\nEén IP-adres per regel met een poortnummer.\nBijvoorbeeld:\n 127.0.0.1:11211\n 192.168.1.25:1234",
index e04944f..6cd4d38 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "Harald Khan",
                        "Nghtwlkr",
-                       "Njardarlogar"
+                       "Njardarlogar",
+                       "Jon Harald Søby"
                ]
        },
        "config-your-language": "Språket ditt:",
@@ -13,8 +14,8 @@
        "config-page-language": "Språk",
        "config-memory-raised": "PHPs <code>memory_limit</code> er $1, auka til $2.",
        "config-memory-bad": "'''Advarsel:''' PHPs <code>memory_limit</code> er $1.\nDette er sannsynlegvis for lågt.\nInstallasjonen kan mislukkast!",
-       "config-xcache": "[http://xcache.lighttpd.net/ XCache] er innstallert",
-       "config-apc": "[http://www.php.net/apc APC] er innstallert",
+       "config-xcache": "[http://xcache.lighttpd.net/ XCache] er installert",
+       "config-apc": "[http://www.php.net/apc APC] er installert",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] er installert",
        "config-db-name": "Databasenamn:",
        "config-db-username": "Databasebrukarnamn:",
index 8d54c98..f224b5d 100644 (file)
@@ -71,7 +71,7 @@
        "config-unicode-using-intl": "Korzystanie z [http://pecl.php.net/intl rozszerzenia intl PECL] do normalizacji Unicode.",
        "config-unicode-pure-php-warning": "<strong>Uwaga:<strong> [http://pecl.php.net/intl Rozszerzenie intl PECL] do obsługi normalizacji Unicode nie jest dostępne. Użyta zostanie mało wydajna zwykła implementacja w PHP.\nJeśli prowadzisz stronę o dużym natężeniu ruchu, powinieneś zapoznać się z informacjami o [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalizacji Unicode].",
        "config-unicode-update-warning": "<strong>Uwaga:</strong> zainstalowana wersja normalizacji Unicode korzysta z nieaktualnej biblioteki [http://site.icu-project.org/ projektu ICU].\nPowinieneś [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations wykonać aktualizację], jeśli chcesz korzystać w pełni z Unicode.",
-       "config-no-db": "Nie można odnaleźć właściwego sterownika bazy danych! Musisz zainstalować sterownik bazy danych dla PHP.\nMożna użyć {{PLURAL:$2|następującego typu bazy|następujących typów baz} danych: $1.\n\nJeśli skompilowałeś PHP samodzielnie, skonfiguruj je ponownie z włączonym klientem bazy danych, na przykład za pomocą polecenia <code>./configure --with-mysqli</code>.\nJeśli zainstalowałeś PHP jako pakiet Debiana lub Ubuntu, musisz również zainstalować np. moduł <code>php5-mysql</code>.",
+       "config-no-db": "Nie można odnaleźć właściwego sterownika bazy danych! Musisz zainstalować sterownik bazy danych dla PHP.\nMożna użyć {{PLURAL:$2|następującego typu bazy|następujących typów baz}} danych: $1.\n\nJeśli skompilowałeś PHP samodzielnie, skonfiguruj go ponownie z włączonym klientem bazy danych, na przykład za pomocą polecenia <code>./configure --with-mysqli</code>.\nJeśli zainstalowałeś PHP jako pakiet Debiana lub Ubuntu, musisz również zainstalować np. moduł <code>php5-mysql</code>.",
        "config-outdated-sqlite": "'''Ostrzeżenie''': masz SQLite  $1, która jest niższa od minimalnej wymaganej wersji  $2 . SQLite będzie niedostępne.",
        "config-no-fts3": "'''Uwaga''' – SQLite został skompilowany bez [//sqlite.org/fts3.html modułu FTS3] – funkcje wyszukiwania nie będą dostępne.",
        "config-pcre-old": "<strong>Błąd krytyczny:</strong> Wymagany jest PCRE w wersji $1 lub nowszej.\nTwój plik wykonywalny PHP jest powiązany z wersją PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Więcej informacji].",
@@ -80,6 +80,7 @@
        "config-memory-bad": "'''Uwaga:''' PHP <code>memory_limit</code> jest ustawione na $1.\nTo jest prawdopodobnie zbyt mało.\nInstalacja może się nie udać!",
        "config-xcache": "[Http://trac.lighttpd.net/xcache/ XCache] jest zainstalowany",
        "config-apc": "[Http://www.php.net/apc APC] jest zainstalowany",
+       "config-apcu": "[http://www.php.net/apcu APCu] jest zainstalowany",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] jest zainstalowany",
        "config-no-cache-apcu": "<strong>Ostrzeżenie:</strong> Nie można znaleźć [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] lub [http://www.iis.net/download/WinCacheForPhp WinCache].\nPamięć podręczna obiektów nie zostanie włączona.",
        "config-mod-security": "''' Ostrzeżenie ''': Serwer sieci web ma włączone [http://modsecurity.org/ mod_security]. Jeśli jest niepoprawnie skonfigurowane, może być przyczyną problemów MediaWiki lub innego oprogramowania, które pozwala użytkownikom na wysyłanie dowolnej zawartości.\nSprawdź w [http://modsecurity.org/documentation/ dokumentacji mod_security] lub skontaktuj się z obsługa hosta, jeśli wystąpią losowe błędy.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki może współpracować z następującymi systemami baz danych:\n\n$1\n\nPoniżej wyświetlone są systemy baz danych gotowe do użycia. Jeżeli poniżej brakuje bazy danych, z której chcesz skorzystać, oznacza to, że brakuje odpowiedniego oprogramowania lub zostało ono niepoprawnie skonfigurowane. Powyżej znajdziesz odnośniki do dokumentacji, która pomoże w konfiguracji odpowiednich komponentów.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] jest bazą danych, na której rozwijane jest oprogramowanie MediaWiki. MediaWiki działa również z [{{int:version-db-mariadb-url}} MariaDB] i [{{int:version-db-percona-url}} Percona Server], które są zgodne z MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Zobacz, jak skompilować PHP ze wsparciem dla MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] jest popularnym systemem baz danych, często stosowanym zamiast MySQL. Z powodu możliwości wystąpienia drobnych błędów, nie jest zalecana do wymagających wdrożeń. ([http://www.php.net/manual/en/pgsql.installation.php Zobacz, jak skompilować PHP ze wsparciem dla PostgreSQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] jest popularnym systemem baz danych, często stosowanym zamiast MySQL. ([http://www.php.net/manual/pl/pgsql.installation.php Zobacz, jak skompilować PHP z obsługą PostgreSQL])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] jest niewielkim systemem bazy danych, z którym MediaWiki bardzo dobrze współpracuje. ([http://www.php.net/manual/en/pdo.installation.php Zobacz, jak skompilować PHP ze wsparciem dla SQLite], korzystając z PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] jest komercyjną profesjonalną bazą danych. ([http://www.php.net/manual/en/oci8.installation.php Jak skompilować PHP ze wsparciem dla OCI8])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] jest komercyjną profesjonalną bazą danych. ([http://www.php.net/manual/pl/sqlsrv.installation.php Jak skompilować PHP ze wsparciem dla SQLSRV])",
        "config-cc-not-chosen": "Wybierz, którą chcesz licencję Creative Commons i kliknij „proceed”.",
        "config-advanced-settings": "Konfiguracja zaawansowana",
        "config-cache-options": "Ustawienia buforowania obiektów:",
-       "config-cache-help": "Buforowanie obiekto jest używane aby przyspieszyć MediaWiki przez trzymanie w pamięci podręcznej często używanych danych.\nŚrednie oraz duże witryny są wysoce zachęcane by je włączyć, a małe witryny także dostrzegą korzyści.",
+       "config-cache-help": "Buforowanie obiektów jest używane do przyspieszenia MediaWiki przez trzymanie w pamięci podręcznej często używanych danych.\nŚrednie oraz duże witryny są wysoce zachęcane by je włączyć, ale małe witryny również dostrzegą korzyści.",
        "config-cache-none": "Brak buforowania (wszystkie funkcje będą działać, ale mogą wystąpić kłopoty z wydajnością na dużych witrynach wiki)",
-       "config-cache-accel": "Buforowania obiektów PHP (APC, XCache lub WinCache)",
+       "config-cache-accel": "Buforowania obiektów PHP (APC, APCu, XCache lub WinCache)",
        "config-cache-memcached": "Użyj Memcached (wymaga dodatkowej instalacji i konfiguracji)",
        "config-memcached-servers": "Serwery Memcached:",
        "config-memcached-help": "Lista adresów IP do wykorzystania przez Memcached.\nAdresy powinny być umieszczane po jednym w linii i określać również wykorzystywany port. Na przykład:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-install-begin": "Po naciśnięciu \"{{int:config-continue}}\", rozpocznie się instalacja MediaWiki.\nJeśli nadal chcesz dokonać zmian, naciśnij \"{{int:config-back}}\".",
        "config-install-step-done": "gotowe",
        "config-install-step-failed": "nieudane",
-       "config-install-extensions": "Włącznie z rozszerzeniami",
+       "config-install-extensions": "Dołączanie rozszerzeń",
        "config-install-database": "Konfigurowanie bazy danych",
        "config-install-schema": "Tworzenie schematu",
        "config-install-pg-schema-not-exist": "Schemat PostgreSQL nie istnieje.",
        "config-help": "pomoc",
        "config-help-tooltip": "kliknij, aby rozwinąć",
        "config-nofile": "Nie udało się odnaleźć pliku \"$1\". Czy nie został usunięty?",
-       "config-extension-link": "Czy wiesz, że twoja wiki obsługuje [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions/pl rozszerzenia]?\n\nMożesz przejrzeć [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category rozszerzenia według kategorii] lub [https://www.mediawiki.org/wiki/Extension_Matrix Extension Matrix] aby zobaczyć pełną listę rozszerzeń.",
+       "config-extension-link": "Czy wiesz, że twoja wiki obsługuje [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions rozszerzenia]?\n\nMożesz przejrzeć [https://www.mediawiki.org/wiki/Category:Extensions_by_category rozszerzenia według kategorii] lub [https://www.mediawiki.org/wiki/Extension_Matrix Extension Matrix], aby zobaczyć pełną listę rozszerzeń.",
        "mainpagetext": "<strong>Instalacja MediaWiki powiodła się.</strong>",
-       "mainpagedocfooter": "Zobacz [https://meta.wikimedia.org/wiki/Help:Contents przewodnik użytkownika], aby uzyskać informacje o działaniu oprogramowania wiki.\n\n== Na początek ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings/pl Lista ustawień konfiguracyjnych]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/pl MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Komunikaty o nowych wersjach MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Przetłumacz MediaWiki na swój język]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam \nDowiedz się, jak walczyć ze spamem na swojej wiki]"
+       "mainpagedocfooter": "Zapoznaj się z [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents informacjami o działaniu oprogramowania wiki].\n\n== Na początek ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista ustawień konfiguracyjnych]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Komunikaty o nowych wersjach MediaWiki (lista dyskusyjna)]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Przetłumacz MediaWiki na swój język]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Dowiedz się, jak walczyć ze spamem na swojej wiki]"
 }
index 49f242a..18d77e3 100644 (file)
@@ -16,7 +16,8 @@
                        "Cainamarques",
                        "Vitorvicentevalente",
                        "Macofe",
-                       "Diniscoelho"
+                       "Diniscoelho",
+                       "Ruila"
                ]
        },
        "config-desc": "O instalador do MediaWiki",
        "config-session-error": "Erro ao iniciar a sessão: $1",
        "config-session-expired": "Os seus dados de sessão parecem ter expirado.\nAs sessões estão configuradas para uma duração de $1.\nPode aumentar esta duração configurando <code>session.gc_maxlifetime</code> no php.ini.\nReinicie o processo de instalação.",
        "config-no-session": "Os seus dados de sessão foram perdidos!\nVerifique o seu php.ini e certifique-se de que em <code>session.save_path</code> está definido um diretório apropriado.",
-       "config-your-language": "O seu idioma:",
+       "config-your-language": "A sua língua:",
        "config-your-language-help": "Selecione o idioma que será usado durante o processo de instalação.",
-       "config-wiki-language": "Idioma da wiki:",
+       "config-wiki-language": "Língua da wiki:",
        "config-wiki-language-help": "Selecione o idioma que será predominante na wiki.",
        "config-back": "← Voltar",
        "config-continue": "Continuar →",
-       "config-page-language": "Idioma",
+       "config-page-language": "Língua",
        "config-page-welcome": "Bem-vindo(a) ao MediaWiki!",
        "config-page-dbconnect": "Ligar à base de dados",
        "config-page-upgrade": "Atualizar a instalação existente",
@@ -55,7 +56,7 @@
        "config-page-existingwiki": "Wiki existente",
        "config-help-restart": "Deseja limpar todos os dados gravados que introduziu e reiniciar o processo de instalação?",
        "config-restart": "Sim, reiniciar",
-       "config-welcome": "=== Verificações do ambiente ===\nSão realizadas verificações básicas para determinar se este ambiente é apropriado para instalação do MediaWiki.\nSe necessitar de pedir ajuda durante a instalação, deve fornecer os resultados destas verificações.",
+       "config-welcome": "=== Verificações do ambiente ===\nSerão agora realizadas verificações básicas para determinar se este ambiente é apropriado para instalação do MediaWiki.\nLembre-se de fornecer esta informação se necessitar de pedir ajuda para concluir a instalação.",
        "config-copyright": "=== Direitos de autor e Condições de uso ===\n\n$1\n\nEste programa é software livre; pode redistribuí-lo e/ou modificá-lo nos termos da licença GNU General Public License, tal como publicada pela Free Software Foundation; tanto a versão 2 da Licença, como (por opção sua) qualquer versão posterior.\n\nEste programa é distribuído na esperança de que seja útil, mas '''sem qualquer garantia'''; inclusive, sem a garantia implícita da '''possibilidade de ser comercializado''' ou de '''adequação para qualquer finalidade específica'''.\nConsulte a licença GNU General Public License para mais detalhes.\n\nEm conjunto com este programa deve ter recebido <doclink href=Copying>uma cópia da licença GNU General Public License</doclink>; se não a recebeu, peça-a por escrito a Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ou [http://www.gnu.org/copyleft/gpl.html leia-a na internet].",
        "config-sidebar": "* [https://www.mediawiki.org/wiki/MediaWiki/pt Página principal do MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents/pt Ajuda]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents/pt Manual técnico]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ FAQ]\n----\n* <doclink href=Readme>Leia-me</doclink>\n* <doclink href=ReleaseNotes>Notas de lançamento</doclink>\n* <doclink href=Copying>Cópia</doclink>\n* <doclink href=UpgradeDoc>Atualização</doclink>",
        "config-env-good": "O ambiente foi verificado.\nPode instalar o MediaWiki.",
@@ -74,7 +75,9 @@
        "config-memory-bad": "'''Aviso:''' A configuração <code>memory_limit</code> do PHP é $1.\nIsto é provavelmente demasiado baixo.\nA instalação poderá falhar!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] instalada",
        "config-apc": "[http://www.php.net/apc APC] instalada",
+       "config-apcu": "[http://www.php.net/apcu APCu] está instalado",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] instalada",
+       "config-no-cache-apcu": "<strong>Aviso:</strong> Não foram encontrados o [http://www.php.net/apcu APCu], o [http://xcache.lighttpd.net/ XCache] ou o [http://www.iis.net/download/WinCacheForPhp WinCache].\nA cache de objetos não está ativa.",
        "config-mod-security": "'''Aviso''': O seu servidor de internet tem o [http://modsecurity.org/ mod_security] ativado. Se este estiver mal configurado, pode causar problemas ao MediaWiki ou a outros programas, permitindo que os utilizadores publiquem conteúdos arbitrários.\nConsulte a [http://modsecurity.org/documentation/ mod_security documentação] ou peça apoio ao fornecedor do alojamento do seu servidor se encontrar erros aleatórios.",
        "config-diff3-bad": "O GNU diff3 não foi encontrado.",
        "config-git": "Foi encontrado o software de controlo de versões Git: <code>$1</code>.",
        "config-imagemagick": "Foi encontrado o ImageMagick: <code>$1</code>.\nSe possibilitar uploads, a miniaturização de imagens será ativada.",
        "config-gd": "Foi encontrada a biblioteca gráfica GD.\nSe possibilitar uploads, a miniaturização de imagens será ativada.",
        "config-no-scaling": "Não foi encontrada a biblioteca gráfica GD nem o ImageMagick.\nA miniaturização de imagens será desativada.",
-       "config-no-uri": "'''Erro:''' Não foi possível determinar a URI atual.\nA instalação foi abortada.",
+       "config-no-uri": "<strong>Erro:</strong> Não foi possível determinar o URI atual.\nA instalação foi abortada.",
        "config-no-cli-uri": "'''Aviso''':  Não foi especificado um <code>--scriptpath</code>; por omissão, será usado: <code>$1</code>.",
        "config-using-server": "Será usado o nome do servidor \"<nowiki>$1</nowiki>\".",
-       "config-using-uri": "Será usada a URL do servidor \"<nowiki>$1$2</nowiki>\".",
+       "config-using-uri": "Será usado o URL do servidor \"<nowiki>$1$2</nowiki>\".",
        "config-uploads-not-safe": "'''Aviso:''' O diretório por omissão para carregamentos <code>$1</code>, está vulnerável à execução arbitrária de scripts.\nEmbora o MediaWiki verifique a existência de ameaças de segurança em todos os ficheiros enviados, é altamente recomendado que [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security vede esta vulnerabilidade de segurança] antes de possibilitar uploads.",
        "config-no-cli-uploads-check": "'''Aviso:''' O diretório por omissão para carregamentos, <code>$1</code>, não é verificado para determinar se é vulnerável à execução de código arbitrário durante a instalação por CLI (\"Command-line Interface\").",
        "config-brokenlibxml": "O seu sistema tem uma combinação de versões do PHP e do libxml2 conhecida por ser problemática, podendo causar corrupção de dados no MediaWiki e noutras aplicações da internet.\nAtualize para a versão 2.7.3 ou posterior do libxml2 ([https://bugs.php.net/bug.php?id=45996 incidência reportada no PHP]).\nInstalação cancelada.",
        "config-db-account-oracle-warn": "Há três cenários suportados na instalação do servidor de base de dados Oracle:\n\nSe pretende criar a conta de acesso pela internet na base de dados durante o processo de instalação, forneça como conta para a instalação uma conta com o papel de SYSDBA na base de dados e especifique as credenciais desejadas para a conta de acesso pela internet. Se não pretende criar a conta de acesso pela internet durante a instalação, pode criá-la manualmente e fornecer só essa conta para a instalação (se ela tiver as permissões necessárias para criar os objetos do esquema ''(schema)''). A terceira alternativa é fornecer duas contas diferentes; uma com privilégios de criação e outra com privilégios limitados para o acesso pela internet.\n\nExiste um script para criação de uma conta com os privilégios necessários no diretório \"maintenance/oracle/\" desta instalação. Mantenha em mente que usar uma conta com privilégios limitados impossibilita todas as operações de manutenção com a conta padrão.",
        "config-db-install-account": "Conta do utilizador para a instalação",
        "config-db-username": "Nome do utilizador da base de dados:",
-       "config-db-password": "Palavra-chave do utilizador da base de dados:",
+       "config-db-password": "Palavra-passe do utilizador da base de dados:",
        "config-db-install-username": "Introduza o nome de utilizador que será usado para aceder à base de dados durante o processo de instalação. Este utilizador não é o do MediaWiki; é o utilizador da base de dados.",
-       "config-db-install-password": "Introduza a palavra-chave do utilizador que será usado para aceder à base de dados durante o processo de instalação. Esta palavra-chave não é a do utilizador do MediaWiki; é a palavra-chave do utilizador da base de dados.",
-       "config-db-install-help": "Introduza o nome de utilizador e a palavra-chave que serão usados para aceder à base de dados durante o processo de instalação.",
-       "config-db-account-lock": "Usar o mesmo nome de utilizador e palavra-chave durante a operação normal",
+       "config-db-install-password": "Introduza a palavra-passe do utilizador que será usado para aceder à base de dados durante o processo de instalação.\nEsta palavra-passe não é a do utilizador do MediaWiki; é a palavra-passe do utilizador da base de dados.",
+       "config-db-install-help": "Introduza o nome de utilizador e a palavra-passe que serão usados para aceder à base de dados durante o processo de instalação.",
+       "config-db-account-lock": "Usar o mesmo nome de utilizador e palavra-passe durante a operação normal",
        "config-db-wiki-account": "Conta de utilizador para a operação normal",
-       "config-db-wiki-help": "Introduza o nome de utilizador e a palavra-chave que serão usados para aceder à base de dados durante a operação normal da wiki.\nSe o utilizador não existir na base de dados, mas a conta de instalação tiver privilégios suficientes, o utilizador que introduzir será criado na base de dados com os privilégios mínimos necessários para a operação normal da wiki.",
+       "config-db-wiki-help": "Introduza o nome de utilizador e a palavra-passe que serão usados para aceder à base de dados durante a operação normal da wiki.\nSe o utilizador não existir na base de dados, mas a conta de instalação tiver privilégios suficientes, o utilizador que introduzir será criado na base de dados com os privilégios mínimos necessários para a operação normal da wiki.",
        "config-db-prefix": "Prefixo para as tabelas da base de dados:",
        "config-db-prefix-help": "Se necessitar de partilhar uma só base de dados entre várias wikis, ou entre o MediaWiki e outra aplicação, pode escolher adicionar um prefixo ao nome de todas as tabelas desta instalação, para evitar conflitos.\nNão use espaços.\n\nNormalmente, este campo deve ficar vazio.",
        "config-mysql-old": "É necessário o MySQL $1 ou posterior; tem a versão $2.",
        "config-db-schema-help": "Normalmente, este esquema estará correto.\nAltere-o só se souber que precisa de o fazer.",
        "config-pg-test-error": "Não foi possível criar uma ligação à base de dados '''$1''': $2",
        "config-sqlite-dir": "Diretório de dados do SQLite:",
-       "config-sqlite-dir-help": "O SQLite armazena todos os dados num único ficheiro.\n\nDurante a instalação, o servidor de internet precisa de ter permissão de escrita no diretório que especificar.\n\nEste diretório '''não''' deve poder ser acedido diretamente da internet, por isso está a ser colocado onde estão os seus ficheiros PHP.\n\nJuntamente com o diretório, o instalador irá criar um ficheiro <code>.htaccess</code>, mas se esta operação falhar é possível que alguém venha a ter acesso direto à base de dados.\nIsto inclui acesso aos dados dos utilizadores (endereços de correio eletrónico, palavras-chave encriptadas), às revisões eliminadas e a outros dados de acesso restrito na wiki.\n\nConsidere colocar a base de dados num local completamente diferente, como, por exemplo, em <code>/var/lib/mediawiki/asuawiki</code>.",
+       "config-sqlite-dir-help": "O SQLite armazena todos os dados num único ficheiro.\n\nDurante a instalação, o servidor de Internet precisa de ter permissão de escrita no diretório que especificar.\n\nEste diretório '''não''' deve poder ser acedido diretamente da Internet, por isso está a ser colocado onde estão os seus ficheiros PHP.\n\nJuntamente com o diretório, o instalador irá criar um ficheiro <code>.htaccess</code>, mas se esta operação falhar é possível que alguém venha a ter acesso direto à base de dados.\nIsto inclui acesso aos dados dos utilizadores (endereços de correio eletrónico, palavras-passe encriptadas), às revisões eliminadas e a outros dados de acesso restrito na wiki.\n\nConsidere colocar a base de dados num local completamente diferente, como, por exemplo, em <code>/var/lib/mediawiki/asuawiki</code>.",
        "config-oracle-def-ts": "Tablespace padrão:",
        "config-oracle-temp-ts": "Tablespace temporário:",
        "config-type-mysql": "MySQL (ou compatível)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "O MediaWiki suporta as seguintes plataformas de base de dados:\n\n$1\n\nSe a plataforma que pretende usar não está listada abaixo, siga as instruções nos links acima para ativar o suporte.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] é a plataforma primária do MediaWiki e é a melhor suportada. O MediaWiki também trabalha com [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], que são compatíveis com MySQL. ([http://www.php.net/manual/en/mysql.installation.php Como compilar PHP com suporte a MySQL])",
-       "config-dbsupport-postgres": "* O [{{int:version-db-postgres-url}} PostgreSQL] é uma plataforma popular de base de dados de fonte aberta, alternativa ao MySQL. Poderá conter pequenos defeitos e o seu uso em ambientes de exploração/produção não é recomendado. ([http://www.php.net/manual/en/pgsql.installation.php Como compilar o PHP com suporte PostgreSQL])",
+       "config-dbsupport-postgres": "* O [{{int:version-db-postgres-url}} PostgreSQL] é uma plataforma popular de base de dados de código aberto, alternativa ao MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Como compilar o PHP com suporte PostgreSQL])",
        "config-dbsupport-sqlite": "* O [{{int:version-db-sqlite-url}} SQLite] é uma plataforma de base de dados ligeira muito bem suportada. ([http://www.php.net/manual/en/pdo.installation.php Como compilar o PHP com suporte SQLite], usa PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] é uma base de dados comercial para empresas. ([http://www.php.net/manual/en/oci8.installation.php Como compilar o PHP com suporte OCI8])",
        "config-dbsupport-mssql": "* O [{{int:version-db-mssql-url}} Microsoft SQL Server] é uma base de dados comercial do Windows para empresas. ([http://www.php.net/manual/en/sqlsrv.installation.php Como compilar o PHP com suporte SQLSRV])",
        "config-invalid-db-server-oracle": "O TNS da base de dados, \"$1\", é inválido.\nUse \"TNS Name\" ou o método \"Easy Connect\" ([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Métodos de Configuração da Conectividade em Oracle])",
        "config-invalid-db-name": "O nome da base de dados, \"$1\",  é inválido.\nUse só letras (a-z, A-Z), algarismos (0-9), sublinhados (_) e hífens (-) dos caracteres ASCII.",
        "config-invalid-db-prefix": "O prefixo da base de dados, \"$1\",  é inválido.\nUse só letras (a-z, A-Z), algarismos (0-9), sublinhados (_) e hífens (-) dos caracteres ASCII.",
-       "config-connection-error": "$1.\n\nVerifique o servidor, o nome do utilizador e a palavra-chave abaixo e tente novamente.",
+       "config-connection-error": "$1.\n\nVerifique o servidor, o nome do utilizador e a palavra-passe e tente novamente.",
        "config-invalid-schema": "O esquema ''(schema)'' do MediaWiki, \"$1\", é inválido.\nUse só letras (a-z, A-Z), algarismos (0-9) e sublinhados (_) dos caracteres ASCII.",
        "config-db-sys-create-oracle": "O instalador só permite criar uma conta nova usando uma conta SYSDBA.",
        "config-db-sys-user-exists-oracle": "A conta \"$1\" já existe. A conta SYSDBA só pode criar uma conta nova!",
        "config-show-table-status": "A consulta <code>SHOW TABLE STATUS</code> falhou!",
        "config-unknown-collation": "'''Aviso:''' A base de dados está a utilizar uma colação ''(collation)'' desconhecida.",
        "config-db-web-account": "Conta na base de dados para acesso pela internet",
-       "config-db-web-help": "Selecione o nome de utilizador e a palavra-chave que o servidor de internet irá utilizar para aceder ao servidor da base de dados, durante a operação normal da wiki.",
+       "config-db-web-help": "Selecione o nome de utilizador e a palavra-passe que o servidor de Internet irá utilizar para aceder ao servidor da base de dados, durante a operação normal da wiki.",
        "config-db-web-account-same": "Usar a mesma conta usada na instalação",
        "config-db-web-create": "Criar a conta se ainda não existir",
        "config-db-web-no-create-privs": "A conta que especificou para a instalação não tem privilégios suficientes para criar uma conta.\nA conta que especificar aqui já tem de existir.",
        "config-ns-conflict": "O espaço nominal que especificou, \"<nowiki>$1</nowiki>\", cria um conflito com um dos espaços nominais padrão do MediaWiki.\nEspecifique um espaço nominal do projeto diferente.",
        "config-admin-box": "Conta de administrador",
        "config-admin-name": "Seu nome de utilizador:",
-       "config-admin-password": "Palavra-chave:",
-       "config-admin-password-confirm": "Repita a palavra-chave:",
+       "config-admin-password": "Palavra-passe:",
+       "config-admin-password-confirm": "Repita a palavra-passe:",
        "config-admin-help": "Introduza aqui o seu nome de utilizador preferido, por exemplo, \"João Beltrão\".\nEste é o nome que irá utilizar para entrar na wiki.",
        "config-admin-name-blank": "Introduza um nome de utilizador para administrador.",
        "config-admin-name-invalid": "O nome de utilizador especificado \"<nowiki>$1</nowiki>\" é inválido.\nIntroduza um nome de utilizador diferente.",
-       "config-admin-password-blank": "Introduza uma palavra-chave para a conta de administrador.",
-       "config-admin-password-mismatch": "As duas palavras-chave que introduziu não coincidem.",
+       "config-admin-password-blank": "Introduza uma palavra-passe para a conta de administrador.",
+       "config-admin-password-mismatch": "As duas palavras-passe que introduziu não coincidem.",
        "config-admin-email": "Correio electrónico:",
-       "config-admin-email-help": "Introduza aqui um correio electrónico que lhe permita receber mensagens de outros utilizadores da wiki, reiniciar a sua palavra-chave e receber notificações de alterações às suas páginas vigiadas. Pode deixar o campo vazio.",
+       "config-admin-email-help": "Introduza aqui um correio eletrónico que lhe permita receber mensagens de outros utilizadores da wiki, reiniciar a sua palavra-passe e receber notificações de alterações às suas páginas vigiadas. Pode deixar o campo vazio.",
        "config-admin-error-user": "Ocorreu um erro interno ao criar um administrador com o nome \"<nowiki>$1</nowiki>\".",
-       "config-admin-error-password": "Ocorreu um erro interno ao definir uma palavra-chave para o administrador \"<nowiki>$1</nowiki>\": <pre>$2</pre>",
+       "config-admin-error-password": "Ocorreu um erro interno ao definir uma palavra-passe para o administrador \"<nowiki>$1</nowiki>\": <pre>$2</pre>",
        "config-admin-error-bademail": "Introduziu um correio electrónico inválido",
-       "config-subscribe": "Subscreva a [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce lista de divulgação de anúncios de lançamento].",
+       "config-subscribe": "Subscrever a [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce lista de divulgação de anúncios de lançamento].",
        "config-subscribe-help": "Esta é uma lista de divulgação de baixo volume para anúncios de lançamento de versões novas, incluindo anúncios de segurança importantes.\nDeve subscrevê-la e atualizar a sua instalação MediaWiki quando são lançadas versões novas.",
        "config-subscribe-noemail": "Tentou subscrever a lista de divulgação dos anúncios de novas versões, sem fornecer um endereço de correio electrónico.\nPara subscrever esta lista de divulgação tem de fornecer um endereço de correio electrónico.",
-       "config-almost-done": "Está quase a terminar!\nAgora pode saltar as configurações restantes e instalar já a wiki.",
+       "config-pingback": "Partilhar dados sobre esta instalação com os programadores do MediaWiki.",
+       "config-pingback-help": "Se selecionar esta opção, o MediaWiki fará periodicamente um <i>ping</i> a https://www.mediawiki.org com dados básicos acerca desta instância do MediaWiki. Estes dados incluem, por exemplo, o tipo de sistema, a versão do PHP e a base de dados que escolheu. A Wikimedia Foundation partilha estes dados com os programadores do MediaWiki, para ajudar a guiar o esforço de desenvolvimento futuro. Para o seu sistema, serão enviados os seguintes dados:\n<pre>$1</pre>",
+       "config-almost-done": "Está quase a terminar!\nAgora pode ignorar as restantes configurações e instalar já a wiki.",
        "config-optional-continue": "Faz-me mais perguntas.",
        "config-optional-skip": "Já estou aborrecido, instala lá a wiki.",
        "config-profile": "Perfil de permissões:",
        "config-upload-deleted": "Diretório para os ficheiros apagados:",
        "config-upload-deleted-help": "Escolha um diretório onde serão arquivados os ficheiros apagados.\nO ideal é que este diretório não possa ser diretamente acedido a partir da internet.",
        "config-logo": "URL do logótipo:",
-       "config-logo-help": "O tema padrão do MediaWiki inclui espaço para um logótipo de 135x160 pixels acima do menu da barra lateral.\nColoque na wiki uma imagem com estas dimensões e introduza aqui a URL dessa imagem.\n\nSe não pretende usar um logótipo, deixe este campo em branco.",
+       "config-logo-help": "O tema padrão do MediaWiki inclui espaço para um logótipo de 135x160 píxeis acima do menu da barra lateral.\nColoque na wiki uma imagem com estas dimensões e introduza aqui o URL dessa imagem.\n\nSe não pretende usar um logótipo, deixe este campo em branco.",
        "config-instantcommons": "Ativar Instant Commons",
        "config-instantcommons-help": "O [https://www.mediawiki.org/wiki/InstantCommons Instant Commons] é uma funcionalidade que permite que as wikis usem imagens, áudio e outros ficheiros multimédia disponíveis no sítio [https://commons.wikimedia.org/ Wikimedia Commons].\nPara poder usá-los, o MediaWiki necessita de acesso à Internet.\n\nPara mais informações sobre esta funcionalidade, incluindo instruções sobre como configurá-la para usar outras wikis em vez da Wikimedia Commons, consulte o [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos Manual Técnico].",
        "config-cc-error": "O auxiliar de escolha de licenças da Creative Commons não produziu resultados.\nIntroduza o nome da licença manualmente.",
        "config-cache-options": "Configuração da cache de objetos:",
        "config-cache-help": "A cache de objetos é usada para melhorar o desempenho do MediaWiki. Armazena dados usados com frequência.\nSites de tamanho médio ou grande são altamente encorajados a ativar esta funcionalidade e os sites pequenos também terão alguns benefícios em fazê-lo.",
        "config-cache-none": "Sem cache (não é removida nenhuma funcionalidade, mas a velocidade de operação pode ser afectada nas wikis grandes)",
-       "config-cache-accel": "Cache de objetos do PHP (APC, XCache ou WinCache)",
+       "config-cache-accel": "Cache de objetos do PHP (APC, APCu, XCache ou WinCache)",
        "config-cache-memcached": "Usar Memcached (requer instalação e configurações adicionais)",
        "config-memcached-servers": "Servidores Memcached:",
        "config-memcached-help": "Lista de endereços IP que serão usados para o Memcached.\nDeve-se colocar um por linha e indicar a porta a utilizar. Por exemplo:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-skins": "Temas",
        "config-skins-help": "Os temas listados abaixo foram detetados no seu diretório <code>./skins</code>. Deverá ativar pelo menos um e escolher qual o escolhido por padrão.",
        "config-skins-use-as-default": "Usar este tema como padrão",
+       "config-skins-missing": "Não foi encontrado nenhum tema; o MediaWiki usará um tema de recurso até instalar temas adequados.",
        "config-skins-must-enable-some": "Deve escolher pelo menos um tema para ativar.",
        "config-skins-must-enable-default": "O tema escolhido como padrão deve ser ativado.",
        "config-install-alreadydone": "'''Aviso:''' Parece que já instalou o MediaWiki e está a tentar instalá-lo novamente.\nPasse para a próxima página, por favor.",
        "config-install-tables": "A criar as tabelas",
        "config-install-tables-exist": "'''Aviso''': As tabelas do MediaWiki parecem já existir.\nA criação das tabelas será saltada.",
        "config-install-tables-failed": "'''Erro''': A criação das tabelas falhou com o seguinte erro: $1",
-       "config-install-interwiki": "A preencher a tabela padrão de interlínguas",
+       "config-install-interwiki": "A preencher a tabela padrão de interwikis",
        "config-install-interwiki-list": "Não foi possível encontrar o ficheiro <code>interwiki.list</code>.",
        "config-install-interwiki-exists": "'''Aviso''': A tabela de interwikis parece já conter entradas.\nO preenchimento padrão desta tabela será saltado.",
        "config-install-stats": "A inicializar as estatísticas",
        "config-install-keys": "A gerar as chaves secretas",
        "config-insecure-keys": "'''Aviso:''' {{PLURAL:$2|A chave segura|As chaves seguras}} ($1) {{PLURAL:$2|gerada durante a instalação não é completamente segura|geradas durante a instalação não são completamente seguras}}. Considere a possibilidade de {{PLURAL:$2|alterá-la|alterá-las}} manualmente.",
+       "config-install-updates": "Evitar executar atualizações desnecessárias",
+       "config-install-updates-failed": "<strong>Erro:</strong> A inserção de chaves de atualização nas tabelas falhou com o seguinte erro: $1",
        "config-install-sysop": "A criar a conta de administrador",
        "config-install-subscribe-fail": "Não foi possível subscrever a lista mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "cURL não está instalado e <code>allow_url_fopen</code> não está disponível.",
        "config-install-mainpage": "A criar a página principal com o conteúdo padrão.",
        "config-install-extension-tables": "A criar as tabelas das extensões ativadas",
        "config-install-mainpage-failed": "Não foi possível inserir a página principal: $1",
-       "config-install-done": "<strong>Parabéns!</strong>\nTerminou a instalação do MediaWiki.\n\nO instalador gerou um ficheiro <code>LocalSettings.php</code>.\nEste ficheiro contém todas as configurações.\n\nPrecisa de fazer a descarga do ficheiro e colocá-lo no diretório de raiz da sua instalação (o mesmo diretório onde está o ficheiro index.php). Esta descarga deverá ter sido iniciada automaticamente.\n\nSe a descarga não foi iniciada, ou se o cancelou, pode recomeçá-la ao clicar na ligação abaixo:\n\n$3\n\n<strong>Nota</strong>: Se não fizer isto agora, o ficheiro que foi gerado deixará de estar disponível quando sair do processo de instalação.\n\nDepois de terminar o passo anterior, pode <strong>[$2 entrar na wiki]</strong>.",
-       "config-install-done-path": "<strong>Parabéns!</strong>\nTerminou a instalação do MediaWiki.\n\nO instalador gerou um ficheiro <code>LocalSettings.php</code>.\nEste ficheiro contém todas as configurações.\n\nPrecisa de fazer a descarga do ficheiro e colocá-lo no diretório <code>$4</code>. Esta descarga deverá ter sido iniciada automaticamente.\n\nSe a descarga não foi iniciada, ou se o cancelou, pode recomeçá-la ao clicar na ligação abaixo:\n\n$3\n\n<strong>Nota</strong>: Se não fizer isto agora, o ficheiro que foi gerado deixará de estar disponível quando sair do processo de instalação.\n\nDepois de terminar o passo anterior, pode <strong>[$2 entrar na wiki]</strong>.",
-       "config-download-localsettings": "Descarga do <code>LocalSettings.php</code>",
+       "config-install-done": "<strong>Parabéns!</strong>\nTerminou a instalação do MediaWiki.\n\nO instalador gerou um ficheiro <code>LocalSettings.php</code>.\nEste ficheiro contém todas as configurações.\n\nPrecisa de descarregar o ficheiro e colocá-lo no diretório de raiz da sua instalação (o mesmo diretório onde está o ficheiro index.php). Este descarregamento deverá ter sido iniciado automaticamente.\n\nSe o descarregamento não foi iniciado, ou se o cancelou, pode recomeçá-lo clicando na ligação abaixo:\n\n$3\n\n<strong>Nota</strong>: Se não o descarregar agora, o ficheiro que foi gerado deixará de estar disponível quando sair do processo de instalação.\n\nDepois de terminar o passo anterior, pode <strong>[$2 entrar na wiki]</strong>.",
+       "config-install-done-path": "<strong>Parabéns!</strong>\nTerminou a instalação do MediaWiki.\n\nO instalador gerou um ficheiro <code>LocalSettings.php</code>.\nEste ficheiro contém todas as configurações.\n\nPrecisa de descarregar o ficheiro e colocá-lo no diretório <code>$4</code>. Este descarregamento deverá ter sido iniciado automaticamente.\n\nSe o descarregamento não foi iniciado, ou se o cancelou, pode recomeçá-lo clicando na ligação abaixo:\n\n$3\n\n<strong>Nota</strong>: Se não fizer o descarregamento agora, o ficheiro que foi gerado deixará de estar disponível quando sair do processo de instalação.\n\nDepois de terminar o passo anterior, pode <strong>[$2 entrar na wiki]</strong>.",
+       "config-download-localsettings": "Descarregar <code>LocalSettings.php</code>",
        "config-help": "ajuda",
        "config-help-tooltip": "clique para expandir",
        "config-nofile": "Não foi possível encontrar o ficheiro \"$1\". Terá sido apagado?",
        "config-extension-link": "Sabia que a sua wiki suporta [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions extensões]?\n\nPode procurar [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensões por categoria].",
        "mainpagetext": "<strong>MediaWiki instalado.</strong>",
-       "mainpagedocfooter": "Consulte o [https://meta.wikimedia.org/wiki/Help:Contents Guia de Utilizadores] para informações sobre o uso do software wiki.\n\n== Onde começar ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista de opções de configuração]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Perguntas e respostas frequentes sobre o MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Subscreva a lista de divulgação de novas versões do MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Regionalize o MediaWiki para seu idioma]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Aprenda a combater spam na sua wiki]"
+       "mainpagedocfooter": "Consulte a [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Ajuda do MediaWiki] para informações sobre o uso do software wiki.\n\n== Onde começar ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista de opções de configuração]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Perguntas e respostas frequentes sobre o MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Subscreva a lista de divulgação de novas versões do MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Regionalize o MediaWiki para a sua língua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Aprenda a combater <i>spam</i> na sua wiki]"
 }
index 833e7d6..d7e86be 100644 (file)
@@ -75,6 +75,7 @@
        "config-memory-bad": "Parameters:\n* $1 is the configured <code>memory_limit</code>.",
        "config-xcache": "Message indicates if this program is available",
        "config-apc": "Message indicates if this program is available",
+       "config-apcu": "Message indicates if this program is available",
        "config-wincache": "Message indicates if this program is available",
        "config-no-cache-apcu": "Status message in the MediaWiki installer environment checks.",
        "config-mod-security": "Status message in the MediaWiki installer environment checks.",
index 53b4c9e..c285e73 100644 (file)
@@ -21,7 +21,8 @@
                        "Striking Blue",
                        "Ильнар",
                        "Macofe",
-                       "StasR"
+                       "StasR",
+                       "Irus"
                ]
        },
        "config-desc": "Инсталлятор MediaWiki",
@@ -79,6 +80,7 @@
        "config-memory-bad": "'''Внимание:''' размер PHP <code>memory_limit</code> составляет $1.\nВероятно, этого слишком мало.\nУстановка может потерпеть неудачу!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] установлен",
        "config-apc": "[http://www.php.net/apc APC] установлен",
+       "config-apcu": "[http://www.php.net/apcu APCu] установлен",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] установлен",
        "config-no-cache-apcu": "'''Внимание:''' Не найдены [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] или [http://www.iis.net/download/WinCacheForPhp WinCache].\nКэширование объектов будет отключено.",
        "config-mod-security": "<strong>Внимание</strong>: На вашем веб-сервере включен [http://modsecurity.org/ mod_security]/mod_security2. Многие его стандартные настройки могут вызывать проблемы для MediaWiki или другого ПО, позволяющего пользователям отправлять на сервер произвольный контент.\nОбратитесь к [http://modsecurity.org/documentation/ документации mod_security] или в службу поддержки вашего хостинг-провайдера, если вы сталкиваетесь со случайными ошибками.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki поддерживает следующие СУБД:\n\n$1\n\nЕсли вы не видите своей системы хранения данных в этом списке, следуйте инструкциям, на которые есть ссылка выше, чтобы получить поддержку.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] — основная база данных для MediaWiki, которая поддерживается лучше всего. MediaWiki также работает с [{{int:version-db-mariadb-url}} MariaDB] и [{{int:version-db-percona-url}} Percona Server], которые являются MySQL-совместимым. ([http://www.php.net/manual/ru/mysql.installation.php инструкция, как собрать PHP с поддержкой MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] — популярная открытая СУБД, альтернатива MySQL\nМогут встречаться небольшие неисправленные ошибки, не рекомендуется для использования в рабочей системе. ([http://www.php.net/manual/ru/pgsql.installation.php инструкция, как собрать PHP с поддержкой PostgreSQL]).",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] — популярная открытая СУБД, альтернатива MySQL. ([http://www.php.net/manual/ru/pgsql.installation.php инструкция, как собрать PHP с поддержкой PostgreSQL]).",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] — это легковесная система баз данных, имеющая очень хорошую поддержку. ([http://www.php.net/manual/ru/pdo.installation.php инструкция, как собрать PHP с поддержкой SQLite], работающей посредством PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] — это коммерческая база данных масштаба предприятия. ([http://www.php.net/manual/ru/oci8.installation.php Как собрать PHP с поддержкой OCI8])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — это коммерческое база данных база данных для Windows масштаба предприятия. ([http://www.php.net/manual/ru/sqlsrv.installation.php Как собрать PHP с поддержкой SQLSRV])",
        "config-cache-options": "Параметры кэширования объектов:",
        "config-cache-help": "Кэширование объектов используется для повышения скорости MediaWiki путем кэширования часто используемых данных.\nДля средних и больших сайтов кеширование настоятельно рекомендуется включать, а для небольших сайтов кеширование может показать преимущество.",
        "config-cache-none": "Без кэширования (никакой функционал не теряется, но крупные вики-сайты могут работать медленнее)",
-       "config-cache-accel": "PHP кэширование объектов (APC, XCache или WinCache)",
+       "config-cache-accel": "Кэширование PHP-объектов (APC, APCu, XCache или WinCache)",
        "config-cache-memcached": "Использовать Memcached (требует дополнительной настройки)",
        "config-memcached-servers": "Сервера Memcached:",
        "config-memcached-help": "Список IP-адресов, используемых Memcached.\nПеречислите по одному адресу на строку с указанием портов. Например:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-nofile": "Файл \"$1\" не удается найти. Он был удален?",
        "config-extension-link": "Знаете ли вы, что ваш вики-проект поддерживает [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions расширения]?\n\nВы можете просмотреть [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category расширения по категориям] или [https://www.mediawiki.org/wiki/Extension_Matrix матрицу расширений], чтобы увидеть их полный список.",
        "mainpagetext": "<strong>MediaWiki успешно установлена.</strong>",
-       "mainpagedocfooter": "Информацию по работе с этой вики можно найти в [https://meta.wikimedia.org/wiki/Help:Contents/ru справочном руководстве].\n\n== Некоторые полезные ресурсы ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Список возможных настроек];\n* [https://www.mediawiki.org/wiki/Manual:FAQ/ru Часто задаваемые вопросы и ответы по MediaWiki];\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Рассылка уведомлений о выходе новых версий MediaWiki].\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Перевод MediaWiki на свой язык]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Узнайте, как бороться со спамом в вашей вики]"
+       "mainpagedocfooter": "Информацию по работе с этой вики можно найти в [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents справочном руководстве].\n\n== Некоторые полезные ресурсы ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Список возможных настроек];\n* [https://www.mediawiki.org/wiki/Manual:FAQ/ru Часто задаваемые вопросы и ответы по MediaWiki];\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Рассылка уведомлений о выходе новых версий MediaWiki].\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Перевод MediaWiki на свой язык]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Узнайте, как бороться со спамом в вашей вики]"
 }
index 33fa590..21a3297 100644 (file)
@@ -2,11 +2,12 @@
        "@metadata": {
                "authors": [
                        "Sindhu",
-                       "Aursani"
+                       "Aursani",
+                       "Mehtab ahmed"
                ]
        },
        "config-information": "معلومات",
-       "config-localsettings-badkey": "توهان جي ڏنل ڪنجي غيردرست آهي.",
+       "config-localsettings-badkey": "توهان جي سنواري ڏنل ڪنجي غيردرست آهي.",
        "config-your-language": "توهان جي ٻولي:",
        "config-wiki-language": "وڪِي ٻولي:",
        "config-back": "پوئتي ←",
@@ -26,6 +27,5 @@
        "config-page-existingwiki": "موجوده وڪِي",
        "config-restart": "ها، وري کان شروع ڪريو",
        "config-env-php": "PHP $1 تنصيب ٿي چڪو",
-       "config-env-hhvm": "HHVM $1 تنصيب ٿي چڪو.",
-       "config-xml-bad": "PHP جو XML ماڊيول کٽل آهي. ذريعات‌وڪيءَ کي ان ماڊيول ۾  فنڪشنس گھربل آهن ۽ اها موجوده ترتيب يا ڪنفيگيوريشن ۾ ڪم نہ ڪندي. \nتوهان کي گھرجي تہ php-xml RPM پيڪيج تنصيب ڪريو."
+       "config-env-hhvm": "HHVM $1 تنصيب ٿي چڪو."
 }
index 41be1ac..86d88a3 100644 (file)
        "config-cc-again": "Izberi ponovno ...",
        "config-cc-not-chosen": "Izberite licenco Creative Commons, ki jo želite uporabiti, in kliknite »proceed«.",
        "config-advanced-settings": "Napredna konfiguracija",
-       "config-cache-accel": "Predpomnjenje predmetov PHP (APC, XCache ali WinCache)",
+       "config-cache-accel": "Predpomnjenje predmetov PHP (APC, APCu, XCache ali WinCache)",
        "config-cache-memcached": "Uporabi Memcached (zahteva dodatno namestitev in konfiguracijo)",
        "config-memcached-servers": "Strežniki Memcached:",
        "config-memcache-badip": "Vnesli ste neveljaven IP-naslov za Memcached: $1",
        "config-download-localsettings": "Prenesi <code>LocalSettings.php</code>",
        "config-help": "pomoč",
        "mainpagetext": "<strong>Programje MediaWiki je bilo nameščeno.</strong>",
-       "mainpagedocfooter": "Oglejte si [https://meta.wikimedia.org/wiki/Help:Contents Uporabniški priročnik] za informacije o uporabi programja wiki.\n\n== Kako začeti ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Seznam konfiguracijskih nastavitev]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Poogsto zastavljena vprašanja MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Poštni seznam izdaj MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Prevedite MediaWiki v svoj jezik]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Izvedite, kako se boriti proti smetju na svojem wikiju]"
+       "mainpagedocfooter": "Oglejte si [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Uporabniški priročnik] za informacije o uporabi programja wiki.\n\n== Kako začeti ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Seznam konfiguracijskih nastavitev]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Poogsto zastavljena vprašanja MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Poštni seznam izdaj MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Prevedite MediaWiki v svoj jezik]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Izvedite, kako se boriti proti smetju na svojem wikiju]"
 }
index 2c5b8ce..f434356 100644 (file)
@@ -52,7 +52,7 @@
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
        "config-header-mysql": "MySQL подешавања",
-       "config-header-mssql": "Поставке Microsoft SQL Server-а",
+       "config-header-mssql": "Подешавања Microsoft SQL Server-а",
        "config-invalid-db-type": "Неважећи тип базе података.",
        "config-mssql-old": "Потребан је Microsoft SQL Server $1 или новији. Ви имате $2.",
        "config-mysql-innodb": "InnoDB",
index 20c2877..e0c5408 100644 (file)
@@ -1,7 +1,8 @@
 {
        "@metadata": {
                "authors": [
-                       "Milicevic01"
+                       "Milicevic01",
+                       "Сербијана"
                ]
        },
        "config-session-error": "Greška pri započinjanju sesije: $1",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
+       "config-header-mssql": "Podešavanja Microsoft SQL Server-a",
        "config-site-name": "Ime vikija:",
+       "config-admin-email": "Imejl adresa:",
        "config-license-cc-0": "Creative Commons Zero (javno vlasništvo)",
+       "config-email-settings": "Podešavanja imejla",
        "config-skins": "Teme",
        "mainpagetext": "<strong>Medijaviki je uspešno instaliran.</strong>",
        "mainpagedocfooter": "Molimo vidite [https://meta.wikimedia.org/wiki/Help:Contents korisnički vodič] za informacije o upotrebi viki softvera.\n\n== Za početak ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Pomoć u vezi sa podešavanjima]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Najčešće postavljena pitanja]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Mejling lista o izdanjima MedijaVikija]"
index 20ebf9b..45c5a7d 100644 (file)
@@ -67,6 +67,7 @@
        "config-memory-bad": "''' Varning:''' PHP:s <code>memory_limit</code> är $1.\nDetta är förmodligen för lågt.\nInstallationen kan misslyckas!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] är installerat",
        "config-apc": "[http://www.php.net/apc APC] är installerat",
+       "config-apcu": "[http://www.php.net/apcu APCu] är installerat",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] är installerat",
        "config-no-cache-apcu": "'''Varning:''' Kunde inte hitta [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] eller [http://www.iis.net/download/WinCacheForPhp WinCache].\nCachelagring av objekt är inte aktiverat.",
        "config-mod-security": "'''Varning:''' Din webbserver har [http://modsecurity.org/ mod_security] aktiverat. Om felaktigt konfigurerat kan den skapa problem för MediaWiki eller annan programvara som tillåter användaren att posta godtyckligt innehåll.\nTitta på [http://modsecurity.org/documentation/ mod_security-dokumentationen] eller kontakta din värd om du påträffar slumpmässiga fel.",
        "config-cache-options": "Inställningar för cachelagring av objekt:",
        "config-cache-help": "Cachelagring av objekt används för att förbättra hastigheten på MediaWiki genom att cachelagra data som används ofta.\nMedelstora till stora webbplatser är starkt uppmuntrade att aktivera detta, och små webbplatser kommer även att se fördelar.",
        "config-cache-none": "Ingen cachelagring (ingen funktionalitet tas bort, men hastighet kan påverkas på större wiki-webbplatser)",
-       "config-cache-accel": "Cachelagring av PHP-objekt (APC, XCache eller WinCache)",
+       "config-cache-accel": "Cachelagring av PHP-objekt (APC, APCu, XCache eller WinCache)",
        "config-cache-memcached": "Använda Memcached (kräver ytterligare inställningar och konfiguration)",
        "config-memcached-servers": "Memcached-servrar:",
        "config-memcached-help": "Lista över IP-adresser som ska användas för Memcached.\nBör ange en per rad och specificera den port som ska användas. Till exempel:\n 127.0.0.1:11211\n 192.168.1.25:1234",
index 5240f13..7644f41 100644 (file)
@@ -70,6 +70,7 @@
        "config-memory-bad": "'''Увага:''' Розмір пам'яті PHP (<code>memory_limit</code>) становить $1.\nІмовірно, це замало.\nВстановлення може не вдатись!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] встановлено",
        "config-apc": "[http://www.php.net/apc APC] встановлено",
+       "config-apcu": "[http://www.php.net/apcu APCu] встановлено",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] встановлено",
        "config-no-cache-apcu": "<strong>Увага:</strong> Не вдалося знайти [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache] чи [http://www.iis.net/download/WinCacheForPhp WinCache].\nКешування об'єктів не ввімкнено.",
        "config-mod-security": "'''Увага''': на Вашому веб-сервері увімкнено [http://modsecurity.org/ mod_security]. У разі неправильних налаштувать, він може викликати проблеми MediaWiki або іншого ПЗ, яке дозволяє користувачам надсилати довільний вміст.\nЗверніться до [http://modsecurity.org/documentation/ документації mod_security] або підтримки Вашого хостера, якщо під час роботи виникають незрозумілі помилки.",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki підтримує такі системи баз даних:\n\n$1\n\nЯкщо Ви не бачите серед перерахованих систему баз даних, яку використовуєте, виконайте вказівки, вказані вище, щоб увімкнути підтримку.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] є основною для MediaWiki і найкраще підтримується.  MediaWiki також працює із [{{int:version-db-mariadb-url}} MariaDB] та [{{int:version-db-percona-url}} Percona Server], які сумісні з MySQL.  ([http://www.php.net/manual/en/mysqli.installation.php як зібрати PHP з допомогою MySQL])",
-       "config-dbsupport-postgres": "*  [{{int:version-db-postgres-url}} PostgreSQL] — популярна відкрита СУБД, альтернатива MySQL. Можуть зустрічатись деякі невеликі невиправлені помилки, не рекомендується використовувати у робочій системі.([http://www.php.net/manual/en/pgsql.installation.php як зібрати PHP з допомогою PostgreSQL]).",
+       "config-dbsupport-postgres": "*  [{{int:version-db-postgres-url}} PostgreSQL] — популярна відкрита СУБД, альтернатива MySQL. ([http://www.php.net/manual/en/pgsql.installation.php як зібрати PHP з допомогою PostgreSQL]).",
        "config-dbsupport-sqlite": "*  [{{int:version-db-sqlite-url}} SQLite] — легка система баз даних, яка дуже добре підтримується. ([http://www.php.net/manual/en/pdo.installation.php Як зібрати PHP з допомогою SQLite], що використовує PDO)",
        "config-dbsupport-oracle": "*  [{{int:version-db-oracle-url}} Oracle] — комерційна база даних масштабу підприємства. ([http://www.php.net/manual/en/oci8.installation.php Як зібрати PHP з підтримкою OCI8])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] — це комерційна база даних для Windows масштабу підприємства. ([http://www.php.net/manual/ru/sqlsrv.installation.php Як зібрати PHP з підтримкою SQLSRV])",
        "config-cache-options": "Налаштування кешування об'єктів:",
        "config-cache-help": "Кешування об'єктів використовується для покращення швидкодії MediaWiki методом кешування часто використовуваних даних.\nЗаохочується увімкнення цієї можливості для середніх і великих сайтів, малі сайти також можуть відчути її перевагу.",
        "config-cache-none": "Без кешування (жодні функції не втрачаються, але впливає на швидкодію великих вікі-сайтів)",
-       "config-cache-accel": "PHP кешування об'єктів (APC, XCache чи WinCache)",
+       "config-cache-accel": "PHP кешування об'єктів (APC, APCu, XCache чи WinCache)",
        "config-cache-memcached": "Використовувати Memcached (вимагає додаткової установки і налаштування)",
        "config-memcached-servers": "Сервери Memcached:",
        "config-memcached-help": "Список IP-адрес, що викоритовує Memcached.\nВкажіть по одному в рядку, разом з портами. Наприклад:\n 127.0.0.1:11211\n 192.168.1.25:1234",
        "config-nofile": "Файл \"$1\" не знайдено. Його видалено?",
        "config-extension-link": "Чи знаєте ви, що ваше вікі підтримує [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions розширення]?\n\nВи можете переглядати [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category розширення по категорії] або в [https://www.mediawiki.org/wiki/Extension_Matrix матрицю розширень] щоб побачити повний список розширень.",
        "mainpagetext": "<strong>Програмне забезпечення «MediaWiki» встановлено.</strong>",
-       "mainpagedocfooter": "Ð\86нÑ\84оÑ\80маÑ\86Ñ\96Ñ\8e Ð¿Ñ\80о Ñ\80обоÑ\82Ñ\83 Ð· Ñ\86Ñ\96Ñ\94Ñ\8e Ð²Ñ\96кÑ\96 Ð¼Ð¾Ð¶Ð½Ð° Ð·Ð½Ð°Ð¹Ñ\82и Ð² [https://meta.wikimedia.org/wiki/Help:Contents Ð¿Ð¾Ñ\81Ñ\96бникÑ\83 ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87а].\n\n== Деякі корисні ресурси ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Список налаштувань];\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Часті питання з приводу MediaWiki];\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Розсилка повідомлень про появу нових версій MediaWiki];\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Локалізувати MediaWiki своєю мовою]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Дізнатися, як боротися зі спамом у своїй вікі]"
+       "mainpagedocfooter": "Ð\86нÑ\84оÑ\80маÑ\86Ñ\96Ñ\8e Ð¿Ñ\80о Ñ\80обоÑ\82Ñ\83 Ð· Ñ\86Ñ\96Ñ\94Ñ\8e Ð²Ñ\96кÑ\96 Ð¼Ð¾Ð¶Ð½Ð° Ð·Ð½Ð°Ð¹Ñ\82и Ð½Ð° Ñ\81Ñ\82оÑ\80Ñ\96нÑ\86Ñ\96 [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Ð\94овÑ\96дка:Ð\92мÑ\96Ñ\81Ñ\82].\n\n== Деякі корисні ресурси ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Список налаштувань];\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Часті питання з приводу MediaWiki];\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Розсилка повідомлень про появу нових версій MediaWiki];\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Локалізувати MediaWiki своєю мовою]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Дізнатися, як боротися зі спамом у своїй вікі]"
 }
index 365231c..0820ff5 100644 (file)
@@ -64,6 +64,7 @@
        "config-memory-bad": "<strong>Cảnh báo:</strong> <code>memory_limit</code> của PHP là $1.\nGiá trị này có lẽ quá thấp.\nCài đặt có thể bị thất bại!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] đã được cài đặt",
        "config-apc": "[http://www.php.net/apc APC] đã được cài đặt",
+       "config-apcu": "[http://www.php.net/apcu APCu] đã được cài đặt",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache] đã được cài đặt",
        "config-no-cache-apcu": "<strong>Cảnh báo:</strong> Không tìm thấy [http://www.php.net/apcu APCu], [http://xcache.lighttpd.net/ XCache], hoặc [http://www.iis.net/download/WinCacheForPhp WinCache].\nVùng nhớ đệm đối tượng không được kích hoạt.",
        "config-mod-security": "<strong>Cảnh báo:</strong> [http://modsecurity.org/ mod_security]/mod_security2 đã được kích hoạt trên máy chủ Web của bạn. Nhiều cấu hình phổ biến của phần mềm này sẽ gây vấn đề cho MediaWiki và những phần mềm khác cho phép người dùng đăng các nội dung tùy tiện.\nNếu có thể, bạn nên vô hiệu nó. Còn không, tra cứu [http://modsecurity.org/documentation/ tài liệu mod_security] hoặc liên hệ với nhà cung cấp hỗ trợ cho máy chủ nếu bạn gặp những lỗi ngẫu nhiên nào đó.",
        "config-cache-options": "Thiết lập bộ nhớ đệm đối tượng:",
        "config-cache-help": "Lưu vào bộ nhớ đệm đối tượng được sử dụng để cải thiện tốc độ của MediaWiki bằng cách lưu vào bộ nhớ đệm những dữ liệu thường xuyên sử dụng.\nCác trang web từ trung bình cho đến các trang web lớn rất được khuyến khích kích hoạt tính năng này, và các trang web nhỏ cũng sẽ nhìn thấy lợi ích tương tự.",
        "config-cache-none": "Không lưu vào bộ nhớ đệm (không có chức năng nhiệm vụ sẽ được loại bỏ, nhưng tốc độ có thể bị ảnh hưởng trên các trang web wiki lớn hơn)",
-       "config-cache-accel": "Bộ nhớ đệm đối tượng PHP (APC, XCache, hoặc WinCache)",
+       "config-cache-accel": "Bộ nhớ đệm đối tượng PHP (APC, APCu, XCache, hoặc WinCache)",
        "config-cache-memcached": "Sử dụng Memcached (cần thiết lập và cấu hình thêm)",
        "config-memcached-servers": "Máy chủ Memcached:",
        "config-memcached-help": "Danh sách các địa chỉ IP để sử dụng cho Memcached .\nNên xác định trên một dòng và chỉ định các cổng được sử dụng. Ví dụ:\n 127.0.0.1:11211\n 192.168.1.25:1234",
index d541696..55654bc 100644 (file)
@@ -80,6 +80,7 @@
        "config-memory-bad": "<strong>警告:</strong>PHP的内存使用上限<code>memory_limit</code>为$1。\n该设定可能过低,并导致安装失败!",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache]已安装",
        "config-apc": "[http://www.php.net/apc APC]已安装",
+       "config-apcu": "[http://www.php.net/apcu APCu]已安装",
        "config-wincache": "[http://www.iis.net/download/WinCacheForPhp WinCache]已安装",
        "config-no-cache-apcu": "<strong>警告:</strong>找不到[http://www.php.net/apcu APCu]、[http://xcache.lighttpd.net/ XCache]或[http://www.iis.net/download/WinCacheForPhp WinCache]。\n对象缓存未启用。",
        "config-mod-security": "<strong>警告:</strong>您的web服务器已启用[http://modsecurity.org/ mod_security]/mod_security2。它的很多常见配置可能导致MediaWiki及其他软件允许用户发布任意内容的问题。如果可能,这应当被禁用。否则,当您遭遇随机错误时,请参考[http://modsecurity.org/documentation/ mod_security 文档]或联络您的主机支持。",
        "config-type-mssql": "微软SQL服务器",
        "config-support-info": "MediaWiki支持以下数据库系统:\n\n$1\n\n如果您在下面列出的数据库系统中没有找到您希望使用的系统,请根据上方链向的指引启用支持。",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL]是MediaWiki的首选数据库,对它的支持最为完备。MediaWiki也可以在[{{int:version-db-mariadb-url}} MariaDB]和[{{int:version-db-percona-url}} Percona Server]下工作,它们与MySQL兼容。([http://www.php.net/manual/en/mysql.installation.php 如何将对MySQL的支持编译进PHP中])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]是一种流行的开源数据库系统,可作为MySQL的替代([http://www.php.net/manual/en/pgsql.installation.php 如何将对PostgreSQL的支持编译进PHP中])。本程序中可能依然存在一些小而明显的错误,因此并不建议在生产环境中使用该数据库系统。",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL]是一种流行的开源数据库系统,可作为MySQL的替代([http://www.php.net/manual/en/pgsql.installation.php 如何将对PostgreSQL的支持编译进PHP中])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite]是一种轻量级的数据库系统,能被良好地支持。([http://www.php.net/manual/en/pdo.installation.php 如何将对SQLite的支持编译进PHP中],须使用PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle]是一种商用企业级的数据库。([http://www.php.net/manual/en/oci8.installation.php 如何将对OCI8的支持编译进PHP中])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server]是一个适用于Windows的商业性企业数据库。([http://www.php.net/manual/en/sqlsrv.installation.php 如何编译带有SQLSRV支持的PHP])",
        "config-header-oracle": "Oracle设置",
        "config-header-mssql": "Microsoft SQL Server设置",
        "config-invalid-db-type": "无效的数据库类型",
-       "config-missing-db-name": "您必须为“{{int:config-db-name}}”输入内容。",
-       "config-missing-db-host": "您必须为“{{int:config-db-host}}”输入内容。",
-       "config-missing-db-server-oracle": "您必须为“{{int:config-db-host-oracle}}”输入内容。",
+       "config-missing-db-name": "您必须为“{{int:config-db-name}}”输入一个值。",
+       "config-missing-db-host": "您必须为“{{int:config-db-host}}”输入一个值。",
+       "config-missing-db-server-oracle": "您必须为“{{int:config-db-host-oracle}}”输入一个值。",
        "config-invalid-db-server-oracle": "无效的数据库TNS“$1”。请使用“TNS 名称”或者一个“轻松连接”字符串([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Oracle 命名方法])",
        "config-invalid-db-name": "无效的数据库名称“$1”。请只使用ASCII字母(a-z、A-Z)、数字(0-9)、下划线(_)和连字号(-)。",
        "config-invalid-db-prefix": "无效的数据库前缀“$1”。请只使用ASCII字母(a-z、A-Z)、数字(0-9)、下划线(_)和连字号(-)。",
        "config-mysql-utf8": "UTF-8",
        "config-mysql-charset-help": "在<strong>二进制模式</strong>下,MediaWiki会将UTF-8编码的文本存于数据库的二进制字段中。相对于MySQL的UTF-8模式,这种方法效率更高,并允许您使用全范围的Unicode字符。\n\n在<strong>UTF-8模式</strong>下,MySQL将知道您数据使用的字符集,并能适当地提供和转换内容。但这样做您将无法在数据库中存储[https://zh.wikipedia.org/wiki/基本多文种平面 基本多文种平面]以外的字符。",
        "config-mssql-auth": "身份验证类型:",
-       "config-mssql-install-auth": "选择安装过程中链接数据库时将采用的身份验证方式。\n如果您选择“{{int:config-mssql-windowsauth}}”,将使用运行服务器的用户的身份凭据。",
-       "config-mssql-web-auth": "选择Web服务器在通常wiki操作期间用来连接数据库服务器的身份验证方式。\n如果您选择“{{int:config-mssql-windowsauth}}”,将使用运行Web服务器的用户的凭据。",
+       "config-mssql-install-auth": "选择安装过程中链接数据库时将采用的身份验证方式。如果您选择“{{int:config-mssql-windowsauth}}”,将使用运行服务器的用户的身份凭据。",
+       "config-mssql-web-auth": "选择Web服务器在通常wiki操作期间用来连接数据库服务器的身份验证方式。如果您选择“{{int:config-mssql-windowsauth}}”,将使用运行Web服务器的用户的凭据。",
        "config-mssql-sqlauth": "SQL Server 身份验证",
        "config-mssql-windowsauth": "Windows 身份验证",
        "config-site-name": "wiki的名称:",
        "config-license-gfdl": "GNU自由文档许可证1.3或更高版本",
        "config-license-pd": "公有领域",
        "config-license-cc-choose": "选择自定义的知识共享许可证",
-       "config-license-help": "许多公共wiki将所有用户贡献置于[http://freedomdefined.org/Definition 自由许可证]之下。这有助于构建社区的主人翁意识,并鼓励长期贡献。对于非公共wiki或公司wiki,这并非必要条件。\n\n如果您希望使用来自维基百科的内容,并希望维基百科能接受复制自您的wiki的内容,您应当选择<strong>{{int:config-license-cc-by-sa}}</strong>\n\nGNU自由文档许可证是维基百科曾经使用过的许可证,并迄今有效。然而,该许可证难以理解,并会增加重用内容的难度。",
+       "config-license-help": "许多公共wiki将所有用户贡献置于[http://freedomdefined.org/Definition 自由许可证]之下。这有助于构建社区的主人翁意识,并鼓励长期贡献。对于非公共wiki或公司wiki,这并非必要条件。\n\n如果您希望使用来自维基百科的内容,并希望维基百科能接受复制自您的wiki的内容,您应当选择<strong>{{int:config-license-cc-by-sa}}</strong>\n\nGNU自由文档许可证是维基百科曾经使用过的许可证,并迄今有效。然而,该许可证难以理解,并会增加重用内容的难度。",
        "config-email-settings": "电子邮件设置",
        "config-enable-email": "启用出站电子邮件",
        "config-enable-email-help": "如果您希望使用电子邮件功能,请正确配置[http://www.php.net/manual/en/mail.configuration.php PHP的邮件设定]。如果您不需要任何电子邮件功能,请在此处禁用它。",
        "config-cache-options": "对象缓存设置:",
        "config-cache-help": "对象缓存可通过缓存频繁使用的数据来提高MediaWiki的速度。高度推荐中到大型的网站启用该功能,小型网站亦能从其中受益。",
        "config-cache-none": "无缓存(不影响功能,但对较大型的wiki网站会有速度影响)",
-       "config-cache-accel": "PHP对象缓存(APC、XCache或WinCache)",
+       "config-cache-accel": "PHP对象缓存(APC、APCu、XCache或WinCache)",
        "config-cache-memcached": "使用Memcached(需要另外安装并配置)",
        "config-memcached-servers": "Memcached服务器:",
        "config-memcached-help": "用于Memcached的IP地址列表。请保持每行一条,并指定要使用的端口。例如:\n127.0.0.1:11211\n192.168.1.25:1234",
        "config-nofile": "找不到文件“$1”。它是否已被删除?",
        "config-extension-link": "您是否知道您的wiki支持[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions 扩展]?\n\n您可以浏览[https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category 扩展分类]或[https://www.mediawiki.org/wiki/Extension_Matrix 扩展矩阵]以查看完整的扩展列表。",
        "mainpagetext": "<strong>已安装MediaWiki。</strong>",
-       "mainpagedocfooter": "请查阅[https://meta.wikimedia.org/wiki/Help:Contents 用户指南]以获取使用本wiki软件的信息!\n\n== 入门 ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings MediaWiki配置设置列表]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/zh-hans MediaWiki常见问题]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources 本地化MediaWiki到您的语言]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam 了解如何在您的wiki上打击破坏]"
+       "mainpagedocfooter": "请查阅[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents]以获取使用本wiki软件的信息!\n\n== 入门 ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings MediaWiki配置设置列表]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/zh-hans MediaWiki常见问题]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki发布邮件列表]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources 本地化MediaWiki到您的语言]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam 了解如何在您的wiki上打击破坏]"
 }
index ab21779..2f2e934 100644 (file)
        "config-cache-options": "物件快取設定:",
        "config-cache-help": "物件快取是用來增進 MediaWiki 速度的一項功能,透過快取經常使用的資料。\n中型到大型的網站我們會建議開啟這個選項,對小型的網站也有一定程度的效果。",
        "config-cache-none": "不快取 (不會影響功能,但在大型 Wiki 網站可能會有處理速度的問題)",
-       "config-cache-accel": "使用 PHP 物件快取 (APC、XCache 或 WinCache)",
+       "config-cache-accel": "使用 PHP 物件快取 (APC、APCu、XCache 或 WinCache)",
        "config-cache-memcached": "使用 Memcached (需要額外安裝與設定)",
        "config-memcached-servers": "Memcached 伺服器:",
        "config-memcached-help": "請列出 Memcached 伺服器的 IP 位址。\n每一行只指定一個位置並且要註明使用的埠號,例如:\n 127.0.0.1:11211\n 192.168.1.25:1234",
diff --git a/includes/interwiki/InterwikiLookupAdapter.php b/includes/interwiki/InterwikiLookupAdapter.php
new file mode 100644 (file)
index 0000000..60d6f43
--- /dev/null
@@ -0,0 +1,175 @@
+<?php
+namespace MediaWiki\Interwiki;
+
+/**
+ * InterwikiLookupAdapter on top of SiteLookup
+ *
+ * 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.29
+ * @ingroup InterwikiLookup
+ *
+ * @license GNU GPL v2+
+ */
+
+use Interwiki;
+use Site;
+use SiteLookup;
+use MediaWikiSite;
+
+class InterwikiLookupAdapter implements InterwikiLookup {
+
+       /**
+        * @var SiteLookup
+        */
+       private $siteLookup;
+
+       /**
+        * @var Interwiki[]|null associative array mapping interwiki prefixes to Interwiki objects
+        */
+       private $interwikiMap;
+
+       function __construct(
+               SiteLookup $siteLookup,
+               array $interwikiMap = null
+       ) {
+               $this->siteLookup = $siteLookup;
+               $this->interwikiMap = $interwikiMap;
+       }
+
+       /**
+        * See InterwikiLookup::isValidInterwiki
+        * It loads the whole interwiki map.
+        *
+        * @param string $prefix Interwiki prefix to use
+        * @return bool Whether it exists
+        */
+       public function isValidInterwiki( $prefix ) {
+
+               return array_key_exists( $prefix, $this->getInterwikiMap() );
+       }
+
+       /**
+        * See InterwikiLookup::fetch
+        * It loads the whole interwiki map.
+        *
+        * @param string $prefix Interwiki prefix to use
+        * @return Interwiki|null|bool
+        */
+       public function fetch( $prefix ) {
+               if ( $prefix == '' ) {
+                       return null;
+               }
+
+               if ( !$this->isValidInterwiki( $prefix ) ) {
+                       return false;
+               }
+
+               return $this->interwikiMap[$prefix];
+       }
+
+       /**
+        * See InterwikiLookup::getAllPrefixes
+        *
+        * @param string|null $local If set, limits output to local/non-local interwikis
+        * @return string[] List of prefixes
+        */
+       public function getAllPrefixes( $local = null ) {
+               if ( $local === null ) {
+                       return array_keys( $this->getInterwikiMap() );
+               }
+               $res = [];
+               foreach ( $this->getInterwikiMap() as $interwikiId => $interwiki ) {
+                       if ( $interwiki->isLocal() === $local ) {
+                               $res[] = $interwikiId;
+                       }
+               }
+               return $res;
+       }
+
+       /**
+        * See InterwikiLookup::invalidateCache
+        *
+        * @param string $prefix
+        */
+       public function invalidateCache( $prefix ) {
+               if ( !isset( $this->interwikiMap[$prefix] ) ) {
+                       return;
+               }
+               $globalId = $this->interwikiMap[$prefix]->getWikiID();
+               unset( $this->interwikiMap[$prefix] );
+
+               // Reload the interwiki
+               $site = $this->siteLookup->getSites()->getSite( $globalId );
+               $interwikis = $this->getSiteInterwikis( $site );
+               $this->interwikiMap = array_merge( $this->interwikiMap, [ $interwikis[$prefix] ] );
+       }
+
+       /**
+        * Load interwiki map to use as cache
+        */
+       private function loadInterwikiMap() {
+               $interwikiMap = [];
+               $siteList = $this->siteLookup->getSites();
+               foreach ( $siteList as $site ) {
+                       $interwikis = $this->getSiteInterwikis( $site );
+                       $interwikiMap = array_merge( $interwikiMap, $interwikis );
+               }
+               $this->interwikiMap = $interwikiMap;
+       }
+
+       /**
+        * Get interwikiMap attribute, load if needed.
+        *
+        * @return Interwiki[]
+        */
+       private function getInterwikiMap() {
+               if ( $this->interwikiMap === null ) {
+                       $this->loadInterwikiMap();
+               }
+               return $this->interwikiMap;
+       }
+
+       /**
+        * Load interwikis for the given site
+        *
+        * @param Site $site
+        * @return Interwiki[]
+        */
+       private function getSiteInterwikis( Site $site ) {
+               $interwikis = [];
+               foreach ( $site->getInterwikiIds() as $interwiki ) {
+                       $url = $site->getPageUrl();
+                       if ( $site instanceof MediaWikiSite ) {
+                               $path = $site->getFileUrl( 'api.php' );
+                       } else {
+                               $path = '';
+                       }
+                       $local = $site->getSource() === 'local';
+                       // TODO: How to adapt trans?
+                       $interwikis[$interwiki] = new Interwiki(
+                               $interwiki,
+                               $url,
+                               $path,
+                               $site->getGlobalId(),
+                               $local
+                       );
+               }
+               return $interwikis;
+       }
+}
index bbd0ddb..f814cee 100644 (file)
@@ -301,7 +301,9 @@ abstract class Job implements IJobSpecification {
        }
 
        /**
-        * @param callable $callback
+        * @param callable $callback A function with one parameter, the success status, which will be
+        *   false if the job failed or it succeeded but the DB changes could not be committed or
+        *   any deferred updates threw an exception. (This parameter was added in 1.28.)
         * @since 1.27
         */
        protected function addTeardownCallback( $callback ) {
@@ -310,12 +312,12 @@ abstract class Job implements IJobSpecification {
 
        /**
         * Do any final cleanup after run(), deferred updates, and all DB commits happen
-        *
+        * @param bool $status Whether the job, its deferred updates, and DB commit all succeeded
         * @since 1.27
         */
-       public function teardown() {
+       public function teardown( $status ) {
                foreach ( $this->teardownCallbacks as $callback ) {
-                       call_user_func( $callback );
+                       call_user_func( $callback, $status );
                }
        }
 
index 856cdfd..0a8ae7f 100644 (file)
@@ -21,6 +21,7 @@
  * @author Aaron Schulz
  */
 use MediaWiki\MediaWikiServices;
+use Wikimedia\ScopedCallback;
 
 /**
  * Class to handle job queues stored in the DB
@@ -68,7 +69,7 @@ class JobQueueDB extends JobQueue {
         * @return bool
         */
        protected function doIsEmpty() {
-               $dbr = $this->getSlaveDB();
+               $dbr = $this->getReplicaDB();
                try {
                        $found = $dbr->selectField( // unclaimed job
                                'job', '1', [ 'job_cmd' => $this->type, 'job_token' => '' ], __METHOD__
@@ -93,7 +94,7 @@ class JobQueueDB extends JobQueue {
                }
 
                try {
-                       $dbr = $this->getSlaveDB();
+                       $dbr = $this->getReplicaDB();
                        $size = (int)$dbr->selectField( 'job', 'COUNT(*)',
                                [ 'job_cmd' => $this->type, 'job_token' => '' ],
                                __METHOD__
@@ -122,7 +123,7 @@ class JobQueueDB extends JobQueue {
                        return $count;
                }
 
-               $dbr = $this->getSlaveDB();
+               $dbr = $this->getReplicaDB();
                try {
                        $count = (int)$dbr->selectField( 'job', 'COUNT(*)',
                                [ 'job_cmd' => $this->type, "job_token != {$dbr->addQuotes( '' )}" ],
@@ -153,7 +154,7 @@ class JobQueueDB extends JobQueue {
                        return $count;
                }
 
-               $dbr = $this->getSlaveDB();
+               $dbr = $this->getReplicaDB();
                try {
                        $count = (int)$dbr->selectField( 'job', 'COUNT(*)',
                                [
@@ -323,7 +324,7 @@ class JobQueueDB extends JobQueue {
                $invertedDirection = false; // whether one job_random direction was already scanned
                // This uses a replication safe method for acquiring jobs. One could use UPDATE+LIMIT
                // instead, but that either uses ORDER BY (in which case it deadlocks in MySQL) or is
-               // not replication safe. Due to http://bugs.mysql.com/bug.php?id=6980, subqueries cannot
+               // not replication safe. Due to https://bugs.mysql.com/bug.php?id=6980, subqueries cannot
                // be used here with MySQL.
                do {
                        if ( $tinyQueue ) { // queue has <= MAX_OFFSET rows
@@ -397,7 +398,7 @@ class JobQueueDB extends JobQueue {
                $row = false; // the row acquired
                do {
                        if ( $dbw->getType() === 'mysql' ) {
-                               // Per http://bugs.mysql.com/bug.php?id=6980, we can't use subqueries on the
+                               // Per https://bugs.mysql.com/bug.php?id=6980, we can't use subqueries on the
                                // same table being changed in an UPDATE query in MySQL (gives Error: 1093).
                                // Oracle and Postgre have no such limitation. However, MySQL offers an
                                // alternative here by supporting ORDER BY + LIMIT for UPDATE queries.
@@ -565,7 +566,7 @@ class JobQueueDB extends JobQueue {
         * @return Iterator
         */
        protected function getJobIterator( array $conds ) {
-               $dbr = $this->getSlaveDB();
+               $dbr = $this->getReplicaDB();
                try {
                        return new MappedIterator(
                                $dbr->select( 'job', self::selectFields(), $conds ),
@@ -593,7 +594,7 @@ class JobQueueDB extends JobQueue {
        }
 
        protected function doGetSiblingQueuesWithJobs( array $types ) {
-               $dbr = $this->getSlaveDB();
+               $dbr = $this->getReplicaDB();
                // @note: this does not check whether the jobs are claimed or not.
                // This is useful so JobQueueGroup::pop() also sees queues that only
                // have stale jobs. This lets recycleAndDeleteStaleJobs() re-enqueue
@@ -610,7 +611,7 @@ class JobQueueDB extends JobQueue {
        }
 
        protected function doGetSiblingQueueSizes( array $types ) {
-               $dbr = $this->getSlaveDB();
+               $dbr = $this->getReplicaDB();
                $res = $dbr->select( 'job', [ 'job_cmd', 'COUNT(*) AS count' ],
                        [ 'job_cmd' => $types ], __METHOD__, [ 'GROUP BY' => 'job_cmd' ] );
 
@@ -736,7 +737,7 @@ class JobQueueDB extends JobQueue {
         * @throws JobQueueConnectionError
         * @return DBConnRef
         */
-       protected function getSlaveDB() {
+       protected function getReplicaDB() {
                try {
                        return $this->getDB( DB_REPLICA );
                } catch ( DBConnectionError $e ) {
index ed3aa9a..990f112 100644 (file)
@@ -26,6 +26,7 @@ use MediaWiki\Logger\LoggerFactory;
 use Liuggio\StatsdClient\Factory\StatsdDataFactory;
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerInterface;
+use Wikimedia\ScopedCallback;
 
 /**
  * Job queue runner utility methods
@@ -283,7 +284,7 @@ class JobRunner implements LoggerAwareInterface {
                }
                // Always attempt to call teardown() even if Job throws exception.
                try {
-                       $job->teardown();
+                       $job->teardown( $status );
                } catch ( Exception $e ) {
                        MWExceptionHandler::logException( $e );
                }
@@ -335,7 +336,7 @@ class JobRunner implements LoggerAwareInterface {
         */
        private function getMaxRssKb() {
                $info = wfGetRusage() ?: [];
-               // see http://linux.die.net/man/2/getrusage
+               // see https://linux.die.net/man/2/getrusage
                return isset( $info['ru_maxrss'] ) ? (int)$info['ru_maxrss'] : null;
        }
 
index 060cabb..e2914be 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup Upload
  */
+use Wikimedia\ScopedCallback;
 
 /**
  * Assemble the segments of a chunked upload.
index 78531dc..37e80c2 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Upload
  * @ingroup JobQueue
  */
+use Wikimedia\ScopedCallback;
 
 /**
  * Upload a file from the upload stash into the local file repo.
index 775ab43..41541ef 100644 (file)
@@ -271,7 +271,7 @@ class FormatJson {
         */
        public static function stripComments( $json ) {
                // Ensure we have a string
-               $str = (string) $json;
+               $str = (string)$json;
                $buffer = '';
                $maxLen = strlen( $str );
                $mark = 0;
index 6e40f4c..bc99672 100644 (file)
@@ -319,7 +319,7 @@ class CSSMin {
                                                        );
 
                                                        $url = $match['file'] . $match['query'];
-                                                       $file = $local . $match['file'];
+                                                       $file = "{$local}/{$match['file']}";
                                                        if (
                                                                !self::isRemoteUrl( $url ) && !self::isLocalUrl( $url )
                                                                && file_exists( $file )
@@ -357,7 +357,6 @@ class CSSMin {
                }, $source );
 
                return $source;
-
        }
 
        /**
diff --git a/includes/libs/CryptHKDF.php b/includes/libs/CryptHKDF.php
new file mode 100644 (file)
index 0000000..4c86757
--- /dev/null
@@ -0,0 +1,282 @@
+<?php
+/**
+ * Extract-and-Expand Key Derivation Function (HKDF). A cryptographicly
+ * secure key expansion function based on RFC 5869.
+ *
+ * This relies on the secrecy of $wgSecretKey (by default), or $wgHKDFSecret.
+ * By default, sha256 is used as the underlying hashing algorithm, but any other
+ * algorithm can be used. Finding the secret key from the output would require
+ * an attacker to discover the input key (the PRK) to the hmac that generated
+ * the output, and discover the particular data, hmac'ed with an evolving key
+ * (salt), to produce the PRK. Even with md5, no publicly known attacks make
+ * this currently feasible.
+ *
+ * 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
+ *
+ * @author Chris Steipp
+ * @file
+ */
+
+class CryptHKDF {
+
+       /**
+        * @var BagOStuff The persistent cache
+        */
+       protected $cache = null;
+
+       /**
+        * @var string Cache key we'll use for our salt
+        */
+       protected $cacheKey = null;
+
+       /**
+        * @var string The hash algorithm being used
+        */
+       protected $algorithm = null;
+
+       /**
+        * @var string binary string, the salt for the HKDF
+        * @see getSaltUsingCache
+        */
+       protected $salt = '';
+
+       /**
+        * @var string The pseudorandom key
+        */
+       private $prk = '';
+
+       /**
+        * The secret key material. This must be kept secret to preserve
+        * the security properties of this RNG.
+        *
+        * @var string
+        */
+       private $skm;
+
+       /**
+        * @var string The last block (K(i)) of the most recent expanded key
+        */
+       protected $lastK;
+
+       /**
+        * a "context information" string CTXinfo (which may be null)
+        * See http://eprint.iacr.org/2010/264.pdf Section 4.1
+        *
+        * @var array
+        */
+       protected $context = [];
+
+       /**
+        * Round count is computed based on the hash'es output length,
+        * which neither php nor openssl seem to provide easily.
+        *
+        * @var int[]
+        */
+       public static $hashLength = [
+               'md5' => 16,
+               'sha1' => 20,
+               'sha224' => 28,
+               'sha256' => 32,
+               'sha384' => 48,
+               'sha512' => 64,
+               'ripemd128' => 16,
+               'ripemd160' => 20,
+               'ripemd256' => 32,
+               'ripemd320' => 40,
+               'whirlpool' => 64,
+       ];
+
+       /**
+        * @var CryptRand
+        */
+       private $cryptRand;
+
+       /**
+        * @param string $secretKeyMaterial
+        * @param string $algorithm Name of hashing algorithm
+        * @param BagOStuff $cache
+        * @param string|array $context Context to mix into HKDF context
+        * @param CryptRand $cryptRand
+        * @throws InvalidArgumentException if secret key material is too short
+        */
+       public function __construct( $secretKeyMaterial, $algorithm, BagOStuff $cache, $context,
+               CryptRand $cryptRand
+       ) {
+               if ( strlen( $secretKeyMaterial ) < 16 ) {
+                       throw new InvalidArgumentException( "secret was too short." );
+               }
+               $this->skm = $secretKeyMaterial;
+               $this->algorithm = $algorithm;
+               $this->cache = $cache;
+               $this->context = is_array( $context ) ? $context : [ $context ];
+               $this->cryptRand = $cryptRand;
+
+               // To prevent every call from hitting the same memcache server, pick
+               // from a set of keys to use. mt_rand is only use to pick a random
+               // server, and does not affect the security of the process.
+               $this->cacheKey = $cache->makeKey( 'HKDF', mt_rand( 0, 16 ) );
+       }
+
+       /**
+        * Save the last block generated, so the next user will compute a different PRK
+        * from the same SKM. This should keep things unpredictable even if an attacker
+        * is able to influence CTXinfo.
+        */
+       function __destruct() {
+               if ( $this->lastK ) {
+                       $this->cache->set( $this->cacheKey, $this->lastK );
+               }
+       }
+
+       /**
+        * MW specific salt, cached from last run
+        * @return string Binary string
+        */
+       protected function getSaltUsingCache() {
+               if ( $this->salt == '' ) {
+                       $lastSalt = $this->cache->get( $this->cacheKey );
+                       if ( $lastSalt === false ) {
+                               // If we don't have a previous value to use as our salt, we use
+                               // 16 bytes from CryptRand, which will use a small amount of
+                               // entropy from our pool. Note, "XTR may be deterministic or keyed
+                               // via an optional “salt value”  (i.e., a non-secret random
+                               // value)..." - http://eprint.iacr.org/2010/264.pdf. However, we
+                               // use a strongly random value since we can.
+                               $lastSalt = $this->cryptRand->generate( 16 );
+                       }
+                       // Get a binary string that is hashLen long
+                       $this->salt = hash( $this->algorithm, $lastSalt, true );
+               }
+               return $this->salt;
+       }
+
+       /**
+        * Produce $bytes of secure random data. As a side-effect,
+        * $this->lastK is set to the last hashLen block of key material.
+        *
+        * @param int $bytes Number of bytes of data
+        * @param string $context Context to mix into CTXinfo
+        * @return string Binary string of length $bytes
+        */
+       public function generate( $bytes, $context = '' ) {
+               if ( $this->prk === '' ) {
+                       $salt = $this->getSaltUsingCache();
+                       $this->prk = self::HKDFExtract(
+                               $this->algorithm,
+                               $salt,
+                               $this->skm
+                       );
+               }
+
+               $CTXinfo = implode( ':', array_merge( $this->context, [ $context ] ) );
+
+               return self::HKDFExpand(
+                       $this->algorithm,
+                       $this->prk,
+                       $CTXinfo,
+                       $bytes,
+                       $this->lastK
+               );
+       }
+
+       /**
+        * RFC5869 defines HKDF in 2 steps, extraction and expansion.
+        * From http://eprint.iacr.org/2010/264.pdf:
+        *
+        * The scheme HKDF is specifed as:
+        *      HKDF(XTS, SKM, CTXinfo, L) = K(1) || K(2) || ... || K(t)
+        * where the values K(i) are defined as follows:
+        *      PRK = HMAC(XTS, SKM)
+        *      K(1) = HMAC(PRK, CTXinfo || 0);
+        *      K(i+1) = HMAC(PRK, K(i) || CTXinfo || i), 1 <= i < t;
+        * where t = [L/k] and the value K(t) is truncated to its first d = L mod k bits;
+        * the counter i is non-wrapping and of a given fixed size, e.g., a single byte.
+        * Note that the length of the HMAC output is the same as its key length and therefore
+        * the scheme is well defined.
+        *
+        * XTS is the "extractor salt"
+        * SKM is the "secret keying material"
+        *
+        * N.B. http://eprint.iacr.org/2010/264.pdf seems to differ from RFC 5869 in that the test
+        * vectors from RFC 5869 only work if K(0) = '' and K(1) = HMAC(PRK, K(0) || CTXinfo || 1)
+        *
+        * @param string $hash The hashing function to use (e.g., sha256)
+        * @param string $ikm The input keying material
+        * @param string $salt The salt to add to the ikm, to get the prk
+        * @param string $info Optional context (change the output without affecting
+        *      the randomness properties of the output)
+        * @param int $L Number of bytes to return
+        * @return string Cryptographically secure pseudorandom binary string
+        */
+       public static function HKDF( $hash, $ikm, $salt, $info, $L ) {
+               $prk = self::HKDFExtract( $hash, $salt, $ikm );
+               $okm = self::HKDFExpand( $hash, $prk, $info, $L );
+               return $okm;
+       }
+
+       /**
+        * Extract the PRK, PRK = HMAC(XTS, SKM)
+        * Note that the hmac is keyed with XTS (the salt),
+        * and the SKM (source key material) is the "data".
+        *
+        * @param string $hash The hashing function to use (e.g., sha256)
+        * @param string $salt The salt to add to the ikm, to get the prk
+        * @param string $ikm The input keying material
+        * @return string Binary string (pseudorandm key) used as input to HKDFExpand
+        */
+       private static function HKDFExtract( $hash, $salt, $ikm ) {
+               return hash_hmac( $hash, $ikm, $salt, true );
+       }
+
+       /**
+        * Expand the key with the given context
+        *
+        * @param string $hash Hashing Algorithm
+        * @param string $prk A pseudorandom key of at least HashLen octets
+        *    (usually, the output from the extract step)
+        * @param string $info Optional context and application specific information
+        *    (can be a zero-length string)
+        * @param int $bytes Length of output keying material in bytes
+        *    (<= 255*HashLen)
+        * @param string &$lastK Set by this function to the last block of the expansion.
+        *    In MediaWiki, this is used to seed future Extractions.
+        * @return string Cryptographically secure random string $bytes long
+        * @throws InvalidArgumentException
+        */
+       private static function HKDFExpand( $hash, $prk, $info, $bytes, &$lastK = '' ) {
+               $hashLen = self::$hashLength[$hash];
+               $rounds = ceil( $bytes / $hashLen );
+               $output = '';
+
+               if ( $bytes > 255 * $hashLen ) {
+                       throw new InvalidArgumentException( 'Too many bytes requested from HDKFExpand' );
+               }
+
+               // K(1) = HMAC(PRK, CTXinfo || 1);
+               // K(i) = HMAC(PRK, K(i-1) || CTXinfo || i); 1 < i <= t;
+               for ( $counter = 1; $counter <= $rounds; ++$counter ) {
+                       $lastK = hash_hmac(
+                               $hash,
+                               $lastK . $info . chr( $counter ),
+                               $prk,
+                               true
+                       );
+                       $output .= $lastK;
+               }
+
+               return substr( $output, 0, $bytes );
+       }
+}
diff --git a/includes/libs/CryptRand.php b/includes/libs/CryptRand.php
new file mode 100644 (file)
index 0000000..10088f2
--- /dev/null
@@ -0,0 +1,387 @@
+<?php
+/**
+ * A cryptographic random generator class used for generating secret keys
+ *
+ * This is based in part on Drupal code as well as what we used in our own code
+ * prior to introduction of this class.
+ *
+ * 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
+ *
+ * @author Daniel Friesen
+ * @file
+ */
+use Psr\Log\LoggerInterface;
+
+class CryptRand {
+       /**
+        * Minimum number of iterations we want to make in our drift calculations.
+        */
+       const MIN_ITERATIONS = 1000;
+
+       /**
+        * Number of milliseconds we want to spend generating each separate byte
+        * of the final generated bytes.
+        * This is used in combination with the hash length to determine the duration
+        * we should spend doing drift calculations.
+        */
+       const MSEC_PER_BYTE = 0.5;
+
+       /**
+        * A boolean indicating whether the previous random generation was done using
+        * cryptographically strong random number generator or not.
+        */
+       protected $strong = null;
+
+       /**
+        * List of functions to call to generate some random state
+        *
+        * @var callable[]
+        */
+       protected $randomFuncs = [];
+
+       /**
+        * List of files to generate some random state from
+        *
+        * @var string[]
+        */
+       protected $randomFiles = [];
+
+       /**
+        * @var LoggerInterface
+        */
+       protected $logger;
+
+       public function __construct( array $randomFuncs, array $randomFiles, LoggerInterface $logger ) {
+               $this->randomFuncs = $randomFuncs;
+               $this->randomFiles = $randomFiles;
+               $this->logger = $logger;
+       }
+
+       /**
+        * Initialize an initial random state based off of whatever we can find
+        * @return string
+        */
+       protected function initialRandomState() {
+               // $_SERVER contains a variety of unstable user and system specific information
+               // It'll vary a little with each page, and vary even more with separate users
+               // It'll also vary slightly across different machines
+               $state = serialize( $_SERVER );
+
+               // Try to gather a little entropy from the different php rand sources
+               $state .= rand() . uniqid( mt_rand(), true );
+
+               // Include some information about the filesystem's current state in the random state
+               $files = $this->randomFiles;
+
+               // We know this file is here so grab some info about ourselves
+               $files[] = __FILE__;
+
+               // We must also have a parent folder, and with the usual file structure, a grandparent
+               $files[] = __DIR__;
+               $files[] = dirname( __DIR__ );
+
+               foreach ( $files as $file ) {
+                       MediaWiki\suppressWarnings();
+                       $stat = stat( $file );
+                       MediaWiki\restoreWarnings();
+                       if ( $stat ) {
+                               // stat() duplicates data into numeric and string keys so kill off all the numeric ones
+                               foreach ( $stat as $k => $v ) {
+                                       if ( is_numeric( $k ) ) {
+                                               unset( $k );
+                                       }
+                               }
+                               // The absolute filename itself will differ from install to install so don't leave it out
+                               $path = realpath( $file );
+                               if ( $path !== false ) {
+                                       $state .= $path;
+                               } else {
+                                       $state .= $file;
+                               }
+                               $state .= implode( '', $stat );
+                       } else {
+                               // The fact that the file isn't there is worth at least a
+                               // minuscule amount of entropy.
+                               $state .= '0';
+                       }
+               }
+
+               // Try and make this a little more unstable by including the varying process
+               // id of the php process we are running inside of if we are able to access it
+               if ( function_exists( 'getmypid' ) ) {
+                       $state .= getmypid();
+               }
+
+               // If available try to increase the instability of the data by throwing in
+               // the precise amount of memory that we happen to be using at the moment.
+               if ( function_exists( 'memory_get_usage' ) ) {
+                       $state .= memory_get_usage( true );
+               }
+
+               foreach ( $this->randomFuncs as $randomFunc ) {
+                       $state .= call_user_func( $randomFunc );
+               }
+
+               return $state;
+       }
+
+       /**
+        * Randomly hash data while mixing in clock drift data for randomness
+        *
+        * @param string $data The data to randomly hash.
+        * @return string The hashed bytes
+        * @author Tim Starling
+        */
+       protected function driftHash( $data ) {
+               // Minimum number of iterations (to avoid slow operations causing the
+               // loop to gather little entropy)
+               $minIterations = self::MIN_ITERATIONS;
+               // Duration of time to spend doing calculations (in seconds)
+               $duration = ( self::MSEC_PER_BYTE / 1000 ) * MWCryptHash::hashLength();
+               // Create a buffer to use to trigger memory operations
+               $bufLength = 10000000;
+               $buffer = str_repeat( ' ', $bufLength );
+               $bufPos = 0;
+
+               // Iterate for $duration seconds or at least $minIterations number of iterations
+               $iterations = 0;
+               $startTime = microtime( true );
+               $currentTime = $startTime;
+               while ( $iterations < $minIterations || $currentTime - $startTime < $duration ) {
+                       // Trigger some memory writing to trigger some bus activity
+                       // This may create variance in the time between iterations
+                       $bufPos = ( $bufPos + 13 ) % $bufLength;
+                       $buffer[$bufPos] = ' ';
+                       // Add the drift between this iteration and the last in as entropy
+                       $nextTime = microtime( true );
+                       $delta = (int)( ( $nextTime - $currentTime ) * 1000000 );
+                       $data .= $delta;
+                       // Every 100 iterations hash the data and entropy
+                       if ( $iterations % 100 === 0 ) {
+                               $data = sha1( $data );
+                       }
+                       $currentTime = $nextTime;
+                       $iterations++;
+               }
+               $timeTaken = $currentTime - $startTime;
+               $data = MWCryptHash::hash( $data );
+
+               $this->logger->debug( "Clock drift calculation " .
+                       "(time-taken=" . ( $timeTaken * 1000 ) . "ms, " .
+                       "iterations=$iterations, " .
+                       "time-per-iteration=" . ( $timeTaken / $iterations * 1e6 ) . "us)" );
+
+               return $data;
+       }
+
+       /**
+        * Return a rolling random state initially build using data from unstable sources
+        * @return string A new weak random state
+        */
+       protected function randomState() {
+               static $state = null;
+               if ( is_null( $state ) ) {
+                       // Initialize the state with whatever unstable data we can find
+                       // It's important that this data is hashed right afterwards to prevent
+                       // it from being leaked into the output stream
+                       $state = MWCryptHash::hash( $this->initialRandomState() );
+               }
+               // Generate a new random state based on the initial random state or previous
+               // random state by combining it with clock drift
+               $state = $this->driftHash( $state );
+
+               return $state;
+       }
+
+       /**
+        * Return a boolean indicating whether or not the source used for cryptographic
+        * random bytes generation in the previously run generate* call
+        * was cryptographically strong.
+        *
+        * @return bool Returns true if the source was strong, false if not.
+        */
+       public function wasStrong() {
+               if ( is_null( $this->strong ) ) {
+                       throw new RuntimeException( __METHOD__ . ' called before generation of random data' );
+               }
+
+               return $this->strong;
+       }
+
+       /**
+        * Generate a run of (ideally) cryptographically random data and return
+        * it in raw binary form.
+        * You can use CryptRand::wasStrong() if you wish to know if the source used
+        * was cryptographically strong.
+        *
+        * @param int $bytes The number of bytes of random data to generate
+        * @param bool $forceStrong Pass true if you want generate to prefer cryptographically
+        *                          strong sources of entropy even if reading from them may steal
+        *                          more entropy from the system than optimal.
+        * @return string Raw binary random data
+        */
+       public function generate( $bytes, $forceStrong = false ) {
+
+               $bytes = floor( $bytes );
+               static $buffer = '';
+               if ( is_null( $this->strong ) ) {
+                       // Set strength to false initially until we know what source data is coming from
+                       $this->strong = true;
+               }
+
+               if ( strlen( $buffer ) < $bytes ) {
+                       // If available make use of mcrypt_create_iv URANDOM source to generate randomness
+                       // On unix-like systems this reads from /dev/urandom but does it without any buffering
+                       // and bypasses openbasedir restrictions, so it's preferable to reading directly
+                       // On Windows starting in PHP 5.3.0 Windows' native CryptGenRandom is used to generate
+                       // entropy so this is also preferable to just trying to read urandom because it may work
+                       // on Windows systems as well.
+                       if ( function_exists( 'mcrypt_create_iv' ) ) {
+                               $rem = $bytes - strlen( $buffer );
+                               $iv = mcrypt_create_iv( $rem, MCRYPT_DEV_URANDOM );
+                               if ( $iv === false ) {
+                                       $this->logger->debug( "mcrypt_create_iv returned false." );
+                               } else {
+                                       $buffer .= $iv;
+                                       $this->logger->debug( "mcrypt_create_iv generated " . strlen( $iv ) .
+                                               " bytes of randomness." );
+                               }
+                       }
+               }
+
+               if ( strlen( $buffer ) < $bytes ) {
+                       if ( function_exists( 'openssl_random_pseudo_bytes' ) ) {
+                               $rem = $bytes - strlen( $buffer );
+                               $openssl_bytes = openssl_random_pseudo_bytes( $rem, $openssl_strong );
+                               if ( $openssl_bytes === false ) {
+                                       $this->logger->debug( "openssl_random_pseudo_bytes returned false." );
+                               } else {
+                                       $buffer .= $openssl_bytes;
+                                       $this->logger->debug( "openssl_random_pseudo_bytes generated " .
+                                               strlen( $openssl_bytes ) . " bytes of " .
+                                               ( $openssl_strong ? "strong" : "weak" ) . " randomness." );
+                               }
+                               if ( strlen( $buffer ) >= $bytes ) {
+                                       // openssl tells us if the random source was strong, if some of our data was generated
+                                       // using it use it's say on whether the randomness is strong
+                                       $this->strong = !!$openssl_strong;
+                               }
+                       }
+               }
+
+               // Only read from urandom if we can control the buffer size or were passed forceStrong
+               if ( strlen( $buffer ) < $bytes &&
+                       ( function_exists( 'stream_set_read_buffer' ) || $forceStrong )
+               ) {
+                       $rem = $bytes - strlen( $buffer );
+                       if ( !function_exists( 'stream_set_read_buffer' ) && $forceStrong ) {
+                               $this->logger->debug( "Was forced to read from /dev/urandom " .
+                                       "without control over the buffer size." );
+                       }
+                       // /dev/urandom is generally considered the best possible commonly
+                       // available random source, and is available on most *nix systems.
+                       MediaWiki\suppressWarnings();
+                       $urandom = fopen( "/dev/urandom", "rb" );
+                       MediaWiki\restoreWarnings();
+
+                       // Attempt to read all our random data from urandom
+                       // php's fread always does buffered reads based on the stream's chunk_size
+                       // so in reality it will usually read more than the amount of data we're
+                       // asked for and not storing that risks depleting the system's random pool.
+                       // If stream_set_read_buffer is available set the chunk_size to the amount
+                       // of data we need. Otherwise read 8k, php's default chunk_size.
+                       if ( $urandom ) {
+                               // php's default chunk_size is 8k
+                               $chunk_size = 1024 * 8;
+                               if ( function_exists( 'stream_set_read_buffer' ) ) {
+                                       // If possible set the chunk_size to the amount of data we need
+                                       stream_set_read_buffer( $urandom, $rem );
+                                       $chunk_size = $rem;
+                               }
+                               $random_bytes = fread( $urandom, max( $chunk_size, $rem ) );
+                               $buffer .= $random_bytes;
+                               fclose( $urandom );
+                               $this->logger->debug( "/dev/urandom generated " . strlen( $random_bytes ) .
+                                       " bytes of randomness." );
+
+                               if ( strlen( $buffer ) >= $bytes ) {
+                                       // urandom is always strong, set to true if all our data was generated using it
+                                       $this->strong = true;
+                               }
+                       } else {
+                               $this->logger->debug( "/dev/urandom could not be opened." );
+                       }
+               }
+
+               // If we cannot use or generate enough data from a secure source
+               // use this loop to generate a good set of pseudo random data.
+               // This works by initializing a random state using a pile of unstable data
+               // and continually shoving it through a hash along with a variable salt.
+               // We hash the random state with more salt to avoid the state from leaking
+               // out and being used to predict the /randomness/ that follows.
+               if ( strlen( $buffer ) < $bytes ) {
+                       $this->logger->debug( __METHOD__ .
+                               ": Falling back to using a pseudo random state to generate randomness." );
+               }
+               while ( strlen( $buffer ) < $bytes ) {
+                       $buffer .= MWCryptHash::hmac( $this->randomState(), strval( mt_rand() ) );
+                       // This code is never really cryptographically strong, if we use it
+                       // at all, then set strong to false.
+                       $this->strong = false;
+               }
+
+               // Once the buffer has been filled up with enough random data to fulfill
+               // the request shift off enough data to handle the request and leave the
+               // unused portion left inside the buffer for the next request for random data
+               $generated = substr( $buffer, 0, $bytes );
+               $buffer = substr( $buffer, $bytes );
+
+               $this->logger->debug( strlen( $buffer ) .
+                       " bytes of randomness leftover in the buffer." );
+
+               return $generated;
+       }
+
+       /**
+        * Generate a run of (ideally) cryptographically random data and return
+        * it in hexadecimal string format.
+        * You can use CryptRand::wasStrong() if you wish to know if the source used
+        * was cryptographically strong.
+        *
+        * @param int $chars The number of hex chars of random data to generate
+        * @param bool $forceStrong Pass true if you want generate to prefer cryptographically
+        *                          strong sources of entropy even if reading from them may steal
+        *                          more entropy from the system than optimal.
+        * @return string Hexadecimal random data
+        */
+       public function generateHex( $chars, $forceStrong = false ) {
+               // hex strings are 2x the length of raw binary so we divide the length in half
+               // odd numbers will result in a .5 that leads the generate() being 1 character
+               // short, so we use ceil() to ensure that we always have enough bytes
+               $bytes = ceil( $chars / 2 );
+               // Generate the data and then convert it to a hex string
+               $hex = bin2hex( $this->generate( $bytes, $forceStrong ) );
+
+               // A bit of paranoia here, the caller asked for a specific length of string
+               // here, and it's possible (eg when given an odd number) that we may actually
+               // have at least 1 char more than they asked for. Just in case they made this
+               // call intending to insert it into a database that does truncation we don't
+               // want to give them too much and end up with their database and their live
+               // code having two different values because part of what we gave them is truncated
+               // hence, we strip out any run of characters longer than what we were asked for.
+               return substr( $hex, 0, $chars );
+       }
+}
diff --git a/includes/libs/IEContentAnalyzer.php b/includes/libs/IEContentAnalyzer.php
deleted file mode 100644 (file)
index 0d1e527..0000000
+++ /dev/null
@@ -1,851 +0,0 @@
-<?php
-/**
- * Simulation of Microsoft Internet Explorer's MIME type detection algorithm.
- *
- * @file
- * @todo Define the exact license of this file.
- */
-
-/**
- * This class simulates Microsoft Internet Explorer's terribly broken and
- * insecure MIME type detection algorithm. It can be used to check web uploads
- * with an apparently safe type, to see if IE will reinterpret them to produce
- * something dangerous.
- *
- * It is full of bugs and strange design choices should not under any
- * circumstances be used to determine a MIME type to present to a user or
- * client. (Apple Safari developers, this means you too.)
- *
- * This class is based on a disassembly of IE 5.0, 6.0 and 7.0. Although I have
- * attempted to ensure that this code works in exactly the same way as Internet
- * Explorer, it does not share any source code, or creative choices such as
- * variable names, thus I (Tim Starling) claim copyright on it.
- *
- * It may be redistributed without restriction. To aid reuse, this class does
- * not depend on any MediaWiki module.
- */
-class IEContentAnalyzer {
-       /**
-        * Relevant data taken from the type table in IE 5
-        */
-       protected $baseTypeTable = [
-               'ambiguous' /*1*/ => [
-                       'text/plain',
-                       'application/octet-stream',
-                       'application/x-netcdf', // [sic]
-               ],
-               'text' /*3*/ => [
-                       'text/richtext', 'image/x-bitmap', 'application/postscript', 'application/base64',
-                       'application/macbinhex40', 'application/x-cdf', 'text/scriptlet'
-               ],
-               'binary' /*4*/ => [
-                       'application/pdf', 'audio/x-aiff', 'audio/basic', 'audio/wav', 'image/gif',
-                       'image/pjpeg', 'image/jpeg', 'image/tiff', 'image/x-png', 'image/png', 'image/bmp',
-                       'image/x-jg', 'image/x-art', 'image/x-emf', 'image/x-wmf', 'video/avi',
-                       'video/x-msvideo', 'video/mpeg', 'application/x-compressed',
-                       'application/x-zip-compressed', 'application/x-gzip-compressed', 'application/java',
-                       'application/x-msdownload'
-               ],
-               'html' /*5*/ => [ 'text/html' ],
-       ];
-
-       /**
-        * Changes to the type table in later versions of IE
-        */
-       protected $addedTypes = [
-               'ie07' => [
-                       'text' => [ 'text/xml', 'application/xml' ]
-               ],
-       ];
-
-       /**
-        * An approximation of the "Content Type" values in HKEY_CLASSES_ROOT in a
-        * typical Windows installation.
-        *
-        * Used for extension to MIME type mapping if detection fails.
-        */
-       protected $registry = [
-               '.323' => 'text/h323',
-               '.3g2' => 'video/3gpp2',
-               '.3gp' => 'video/3gpp',
-               '.3gp2' => 'video/3gpp2',
-               '.3gpp' => 'video/3gpp',
-               '.aac' => 'audio/aac',
-               '.ac3' => 'audio/ac3',
-               '.accda' => 'application/msaccess',
-               '.accdb' => 'application/msaccess',
-               '.accdc' => 'application/msaccess',
-               '.accde' => 'application/msaccess',
-               '.accdr' => 'application/msaccess',
-               '.accdt' => 'application/msaccess',
-               '.ade' => 'application/msaccess',
-               '.adp' => 'application/msaccess',
-               '.adts' => 'audio/aac',
-               '.ai' => 'application/postscript',
-               '.aif' => 'audio/aiff',
-               '.aifc' => 'audio/aiff',
-               '.aiff' => 'audio/aiff',
-               '.amc' => 'application/x-mpeg',
-               '.application' => 'application/x-ms-application',
-               '.asf' => 'video/x-ms-asf',
-               '.asx' => 'video/x-ms-asf',
-               '.au' => 'audio/basic',
-               '.avi' => 'video/avi',
-               '.bmp' => 'image/bmp',
-               '.caf' => 'audio/x-caf',
-               '.cat' => 'application/vnd.ms-pki.seccat',
-               '.cbo' => 'application/sha',
-               '.cdda' => 'audio/aiff',
-               '.cer' => 'application/x-x509-ca-cert',
-               '.conf' => 'text/plain',
-               '.crl' => 'application/pkix-crl',
-               '.crt' => 'application/x-x509-ca-cert',
-               '.css' => 'text/css',
-               '.csv' => 'application/vnd.ms-excel',
-               '.der' => 'application/x-x509-ca-cert',
-               '.dib' => 'image/bmp',
-               '.dif' => 'video/x-dv',
-               '.dll' => 'application/x-msdownload',
-               '.doc' => 'application/msword',
-               '.docm' => 'application/vnd.ms-word.document.macroEnabled.12',
-               '.docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
-               '.dot' => 'application/msword',
-               '.dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
-               '.dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
-               '.dv' => 'video/x-dv',
-               '.dwfx' => 'model/vnd.dwfx+xps',
-               '.edn' => 'application/vnd.adobe.edn',
-               '.eml' => 'message/rfc822',
-               '.eps' => 'application/postscript',
-               '.etd' => 'application/x-ebx',
-               '.exe' => 'application/x-msdownload',
-               '.fdf' => 'application/vnd.fdf',
-               '.fif' => 'application/fractals',
-               '.gif' => 'image/gif',
-               '.gsm' => 'audio/x-gsm',
-               '.hqx' => 'application/mac-binhex40',
-               '.hta' => 'application/hta',
-               '.htc' => 'text/x-component',
-               '.htm' => 'text/html',
-               '.html' => 'text/html',
-               '.htt' => 'text/webviewhtml',
-               '.hxa' => 'application/xml',
-               '.hxc' => 'application/xml',
-               '.hxd' => 'application/octet-stream',
-               '.hxe' => 'application/xml',
-               '.hxf' => 'application/xml',
-               '.hxh' => 'application/octet-stream',
-               '.hxi' => 'application/octet-stream',
-               '.hxk' => 'application/xml',
-               '.hxq' => 'application/octet-stream',
-               '.hxr' => 'application/octet-stream',
-               '.hxs' => 'application/octet-stream',
-               '.hxt' => 'application/xml',
-               '.hxv' => 'application/xml',
-               '.hxw' => 'application/octet-stream',
-               '.ico' => 'image/x-icon',
-               '.iii' => 'application/x-iphone',
-               '.ins' => 'application/x-internet-signup',
-               '.iqy' => 'text/x-ms-iqy',
-               '.isp' => 'application/x-internet-signup',
-               '.jfif' => 'image/jpeg',
-               '.jnlp' => 'application/x-java-jnlp-file',
-               '.jpe' => 'image/jpeg',
-               '.jpeg' => 'image/jpeg',
-               '.jpg' => 'image/jpeg',
-               '.jtx' => 'application/x-jtx+xps',
-               '.latex' => 'application/x-latex',
-               '.log' => 'text/plain',
-               '.m1v' => 'video/mpeg',
-               '.m2v' => 'video/mpeg',
-               '.m3u' => 'audio/x-mpegurl',
-               '.mac' => 'image/x-macpaint',
-               '.man' => 'application/x-troff-man',
-               '.mda' => 'application/msaccess',
-               '.mdb' => 'application/msaccess',
-               '.mde' => 'application/msaccess',
-               '.mfp' => 'application/x-shockwave-flash',
-               '.mht' => 'message/rfc822',
-               '.mhtml' => 'message/rfc822',
-               '.mid' => 'audio/mid',
-               '.midi' => 'audio/mid',
-               '.mod' => 'video/mpeg',
-               '.mov' => 'video/quicktime',
-               '.mp2' => 'video/mpeg',
-               '.mp2v' => 'video/mpeg',
-               '.mp3' => 'audio/mpeg',
-               '.mp4' => 'video/mp4',
-               '.mpa' => 'video/mpeg',
-               '.mpe' => 'video/mpeg',
-               '.mpeg' => 'video/mpeg',
-               '.mpf' => 'application/vnd.ms-mediapackage',
-               '.mpg' => 'video/mpeg',
-               '.mpv2' => 'video/mpeg',
-               '.mqv' => 'video/quicktime',
-               '.NMW' => 'application/nmwb',
-               '.nws' => 'message/rfc822',
-               '.odc' => 'text/x-ms-odc',
-               '.ols' => 'application/vnd.ms-publisher',
-               '.p10' => 'application/pkcs10',
-               '.p12' => 'application/x-pkcs12',
-               '.p7b' => 'application/x-pkcs7-certificates',
-               '.p7c' => 'application/pkcs7-mime',
-               '.p7m' => 'application/pkcs7-mime',
-               '.p7r' => 'application/x-pkcs7-certreqresp',
-               '.p7s' => 'application/pkcs7-signature',
-               '.pct' => 'image/pict',
-               '.pdf' => 'application/pdf',
-               '.pdx' => 'application/vnd.adobe.pdx',
-               '.pfx' => 'application/x-pkcs12',
-               '.pic' => 'image/pict',
-               '.pict' => 'image/pict',
-               '.pinstall' => 'application/x-picasa-detect',
-               '.pko' => 'application/vnd.ms-pki.pko',
-               '.png' => 'image/png',
-               '.pnt' => 'image/x-macpaint',
-               '.pntg' => 'image/x-macpaint',
-               '.pot' => 'application/vnd.ms-powerpoint',
-               '.potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
-               '.potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
-               '.ppa' => 'application/vnd.ms-powerpoint',
-               '.ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
-               '.pps' => 'application/vnd.ms-powerpoint',
-               '.ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
-               '.ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
-               '.ppt' => 'application/vnd.ms-powerpoint',
-               '.pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
-               '.pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
-               '.prf' => 'application/pics-rules',
-               '.ps' => 'application/postscript',
-               '.pub' => 'application/vnd.ms-publisher',
-               '.pwz' => 'application/vnd.ms-powerpoint',
-               '.py' => 'text/plain',
-               '.pyw' => 'text/plain',
-               '.qht' => 'text/x-html-insertion',
-               '.qhtm' => 'text/x-html-insertion',
-               '.qt' => 'video/quicktime',
-               '.qti' => 'image/x-quicktime',
-               '.qtif' => 'image/x-quicktime',
-               '.qtl' => 'application/x-quicktimeplayer',
-               '.rat' => 'application/rat-file',
-               '.rmf' => 'application/vnd.adobe.rmf',
-               '.rmi' => 'audio/mid',
-               '.rqy' => 'text/x-ms-rqy',
-               '.rtf' => 'application/msword',
-               '.sct' => 'text/scriptlet',
-               '.sd2' => 'audio/x-sd2',
-               '.sdp' => 'application/sdp',
-               '.shtml' => 'text/html',
-               '.sit' => 'application/x-stuffit',
-               '.sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12',
-               '.sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
-               '.slk' => 'application/vnd.ms-excel',
-               '.snd' => 'audio/basic',
-               '.so' => 'application/x-apachemodule',
-               '.sol' => 'text/plain',
-               '.sor' => 'text/plain',
-               '.spc' => 'application/x-pkcs7-certificates',
-               '.spl' => 'application/futuresplash',
-               '.sst' => 'application/vnd.ms-pki.certstore',
-               '.stl' => 'application/vnd.ms-pki.stl',
-               '.swf' => 'application/x-shockwave-flash',
-               '.thmx' => 'application/vnd.ms-officetheme',
-               '.tif' => 'image/tiff',
-               '.tiff' => 'image/tiff',
-               '.txt' => 'text/plain',
-               '.uls' => 'text/iuls',
-               '.vcf' => 'text/x-vcard',
-               '.vdx' => 'application/vnd.ms-visio.viewer',
-               '.vsd' => 'application/vnd.ms-visio.viewer',
-               '.vss' => 'application/vnd.ms-visio.viewer',
-               '.vst' => 'application/vnd.ms-visio.viewer',
-               '.vsx' => 'application/vnd.ms-visio.viewer',
-               '.vtx' => 'application/vnd.ms-visio.viewer',
-               '.wav' => 'audio/wav',
-               '.wax' => 'audio/x-ms-wax',
-               '.wbk' => 'application/msword',
-               '.wdp' => 'image/vnd.ms-photo',
-               '.wiz' => 'application/msword',
-               '.wm' => 'video/x-ms-wm',
-               '.wma' => 'audio/x-ms-wma',
-               '.wmd' => 'application/x-ms-wmd',
-               '.wmv' => 'video/x-ms-wmv',
-               '.wmx' => 'video/x-ms-wmx',
-               '.wmz' => 'application/x-ms-wmz',
-               '.wpl' => 'application/vnd.ms-wpl',
-               '.wsc' => 'text/scriptlet',
-               '.wvx' => 'video/x-ms-wvx',
-               '.xaml' => 'application/xaml+xml',
-               '.xbap' => 'application/x-ms-xbap',
-               '.xdp' => 'application/vnd.adobe.xdp+xml',
-               '.xfdf' => 'application/vnd.adobe.xfdf',
-               '.xht' => 'application/xhtml+xml',
-               '.xhtml' => 'application/xhtml+xml',
-               '.xla' => 'application/vnd.ms-excel',
-               '.xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
-               '.xlk' => 'application/vnd.ms-excel',
-               '.xll' => 'application/vnd.ms-excel',
-               '.xlm' => 'application/vnd.ms-excel',
-               '.xls' => 'application/vnd.ms-excel',
-               '.xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
-               '.xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
-               '.xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
-               '.xlt' => 'application/vnd.ms-excel',
-               '.xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
-               '.xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
-               '.xlw' => 'application/vnd.ms-excel',
-               '.xml' => 'text/xml',
-               '.xps' => 'application/vnd.ms-xpsdocument',
-               '.xsl' => 'text/xml',
-       ];
-
-       /**
-        * IE versions which have been analysed to bring you this class, and for
-        * which some substantive difference exists. These will appear as keys
-        * in the return value of getRealMimesFromData(). The names are chosen to sort correctly.
-        */
-       protected $versions = [ 'ie05', 'ie06', 'ie07', 'ie07.strict', 'ie07.nohtml' ];
-
-       /**
-        * Type table with versions expanded
-        */
-       protected $typeTable = [];
-
-       /** constructor */
-       function __construct() {
-               // Construct versioned type arrays from the base type array plus additions
-               $types = $this->baseTypeTable;
-               foreach ( $this->versions as $version ) {
-                       if ( isset( $this->addedTypes[$version] ) ) {
-                               foreach ( $this->addedTypes[$version] as $format => $addedTypes ) {
-                                       $types[$format] = array_merge( $types[$format], $addedTypes );
-                               }
-                       }
-                       $this->typeTable[$version] = $types;
-               }
-       }
-
-       /**
-        * Get the MIME types from getMimesFromData(), but convert the result from IE's
-        * idiosyncratic private types into something other apps will understand.
-        *
-        * @param string $fileName the file name (unused at present)
-        * @param string $chunk the first 256 bytes of the file
-        * @param string $proposed the MIME type proposed by the server
-        *
-        * @return Array: map of IE version to detected MIME type
-        */
-       public function getRealMimesFromData( $fileName, $chunk, $proposed ) {
-               $types = $this->getMimesFromData( $fileName, $chunk, $proposed );
-               $types = array_map( [ $this, 'translateMimeType' ], $types );
-               return $types;
-       }
-
-       /**
-        * Translate a MIME type from IE's idiosyncratic private types into
-        * more commonly understood type strings
-        * @param $type
-        * @return string
-        */
-       public function translateMimeType( $type ) {
-               static $table = [
-                       'image/pjpeg' => 'image/jpeg',
-                       'image/x-png' => 'image/png',
-                       'image/x-wmf' => 'application/x-msmetafile',
-                       'image/bmp' => 'image/x-bmp',
-                       'application/x-zip-compressed' => 'application/zip',
-                       'application/x-compressed' => 'application/x-compress',
-                       'application/x-gzip-compressed' => 'application/x-gzip',
-                       'audio/mid' => 'audio/midi',
-               ];
-               if ( isset( $table[$type] ) ) {
-                       $type = $table[$type];
-               }
-               return $type;
-       }
-
-       /**
-        * Get the untranslated MIME types for all known versions
-        *
-        * @param string $fileName the file name (unused at present)
-        * @param string $chunk the first 256 bytes of the file
-        * @param string $proposed the MIME type proposed by the server
-        *
-        * @return Array: map of IE version to detected MIME type
-        */
-       public function getMimesFromData( $fileName, $chunk, $proposed ) {
-               $types = [];
-               foreach ( $this->versions as $version ) {
-                       $types[$version] = $this->getMimeTypeForVersion( $version, $fileName, $chunk, $proposed );
-               }
-               return $types;
-       }
-
-       /**
-        * Get the MIME type for a given named version
-        * @param $version
-        * @param $fileName
-        * @param $chunk
-        * @param $proposed
-        * @return bool|string
-        */
-       protected function getMimeTypeForVersion( $version, $fileName, $chunk, $proposed ) {
-               // Strip text after a semicolon
-               $semiPos = strpos( $proposed, ';' );
-               if ( $semiPos !== false ) {
-                       $proposed = substr( $proposed, 0, $semiPos );
-               }
-
-               $proposedFormat = $this->getDataFormat( $version, $proposed );
-               if ( $proposedFormat == 'unknown'
-                       && $proposed != 'multipart/mixed'
-                       && $proposed != 'multipart/x-mixed-replace' )
-               {
-                       return $proposed;
-               }
-               if ( strval( $chunk ) === '' ) {
-                       return $proposed;
-               }
-
-               // Truncate chunk at 255 bytes
-               $chunk = substr( $chunk, 0, 255 );
-
-               // IE does the Check*Headers() calls last, and instead does the following image
-               // type checks by directly looking for the magic numbers. What I do here should
-               // have the same effect since the magic number checks are identical in both cases.
-               $result = $this->sampleData( $version, $chunk );
-               $sampleFound = $result['found'];
-               $counters = $result['counters'];
-               $binaryType = $this->checkBinaryHeaders( $version, $chunk );
-               $textType = $this->checkTextHeaders( $version, $chunk );
-
-               if ( $proposed == 'text/html' && isset( $sampleFound['html'] ) ) {
-                       return 'text/html';
-               }
-               if ( $proposed == 'image/gif' && $binaryType == 'image/gif' ) {
-                       return 'image/gif';
-               }
-               if ( ( $proposed == 'image/pjpeg' || $proposed == 'image/jpeg' )
-                       && $binaryType == 'image/pjpeg' )
-               {
-                       return $proposed;
-               }
-               // PNG check added in IE 7
-               if ( $version >= 'ie07'
-                       && ( $proposed == 'image/x-png' || $proposed == 'image/png' )
-                       && $binaryType == 'image/x-png' )
-               {
-                       return $proposed;
-               }
-
-               // CDF was removed in IE 7 so it won't be in $sampleFound for later versions
-               if ( isset( $sampleFound['cdf'] ) ) {
-                       return 'application/x-cdf';
-               }
-
-               // RSS and Atom were added in IE 7 so they won't be in $sampleFound for
-               // previous versions
-               if ( isset( $sampleFound['rss'] ) ) {
-                       return 'application/rss+xml';
-               }
-               if ( isset( $sampleFound['rdf-tag'] )
-                       && isset( $sampleFound['rdf-url'] )
-                       && isset( $sampleFound['rdf-purl'] ) )
-               {
-                       return 'application/rss+xml';
-               }
-               if ( isset( $sampleFound['atom'] ) ) {
-                       return 'application/atom+xml';
-               }
-
-               if ( isset( $sampleFound['xml'] ) ) {
-                       // TODO: I'm not sure under what circumstances this flag is enabled
-                       if ( strpos( $version, 'strict' ) !== false ) {
-                               if ( $proposed == 'text/html' || $proposed == 'text/xml' ) {
-                                       return 'text/xml';
-                               }
-                       } else {
-                               return 'text/xml';
-                       }
-               }
-               if ( isset( $sampleFound['html'] ) ) {
-                       // TODO: I'm not sure under what circumstances this flag is enabled
-                       if ( strpos( $version, 'nohtml' ) !== false ) {
-                               if ( $proposed == 'text/plain' ) {
-                                       return 'text/html';
-                               }
-                       } else {
-                               return 'text/html';
-                       }
-               }
-               if ( isset( $sampleFound['xbm'] ) ) {
-                       return 'image/x-bitmap';
-               }
-               if ( isset( $sampleFound['binhex'] ) ) {
-                       return 'application/macbinhex40';
-               }
-               if ( isset( $sampleFound['scriptlet'] ) ) {
-                       if ( strpos( $version, 'strict' ) !== false ) {
-                               if ( $proposed == 'text/plain' || $proposed == 'text/scriptlet' ) {
-                                       return 'text/scriptlet';
-                               }
-                       } else {
-                               return 'text/scriptlet';
-                       }
-               }
-
-               // Freaky heuristics to determine if the data is text or binary
-               // The heuristic is of course broken for non-ASCII text
-               if ( $counters['ctrl'] != 0 && ( $counters['ff'] + $counters['low'] )
-                       < ( $counters['ctrl'] + $counters['high'] ) * 16 )
-               {
-                       $kindOfBinary = true;
-                       $type = $binaryType ? $binaryType : $textType;
-                       if ( $type === false ) {
-                               $type = 'application/octet-stream';
-                       }
-               } else {
-                       $kindOfBinary = false;
-                       $type = $textType ? $textType : $binaryType;
-                       if ( $type === false ) {
-                               $type = 'text/plain';
-                       }
-               }
-
-               // Check if the output format is ambiguous
-               // This generally means that detection failed, real types aren't ambiguous
-               $detectedFormat = $this->getDataFormat( $version, $type );
-               if ( $detectedFormat != 'ambiguous' ) {
-                       return $type;
-               }
-
-               if ( $proposedFormat != 'ambiguous' ) {
-                       // FormatAgreesWithData()
-                       if ( $proposedFormat == 'text' && !$kindOfBinary ) {
-                               return $proposed;
-                       }
-                       if ( $proposedFormat == 'binary' && $kindOfBinary ) {
-                               return $proposed;
-                       }
-                       if ( $proposedFormat == 'html' ) {
-                               return $proposed;
-                       }
-               }
-
-               // Find a MIME type by searching the registry for the file extension.
-               $dotPos = strrpos( $fileName, '.' );
-               if ( $dotPos === false ) {
-                       return $type;
-               }
-               $ext = substr( $fileName, $dotPos );
-               if ( isset( $this->registry[$ext] ) ) {
-                       return $this->registry[$ext];
-               }
-
-               // TODO: If the extension has an application registered to it, IE will return
-               // application/octet-stream. We'll skip that, so we could erroneously
-               // return text/plain or application/x-netcdf where application/octet-stream
-               // would be correct.
-
-               return $type;
-       }
-
-       /**
-        * Check for text headers at the start of the chunk
-        * Confirmed same in 5 and 7.
-        * @param $version
-        * @param $chunk
-        * @return bool|string
-        */
-       private function checkTextHeaders( $version, $chunk ) {
-               $chunk2 = substr( $chunk, 0, 2 );
-               $chunk4 = substr( $chunk, 0, 4 );
-               $chunk5 = substr( $chunk, 0, 5 );
-               if ( $chunk4 == '%PDF' ) {
-                       return 'application/pdf';
-               }
-               if ( $chunk2 == '%!' ) {
-                       return 'application/postscript';
-               }
-               if ( $chunk5 == '{\\rtf' ) {
-                       return 'text/richtext';
-               }
-               if ( $chunk5 == 'begin' ) {
-                       return 'application/base64';
-               }
-               return false;
-       }
-
-       /**
-        * Check for binary headers at the start of the chunk
-        * Confirmed same in 5 and 7.
-        * @param $version
-        * @param $chunk
-        * @return bool|string
-        */
-       private function checkBinaryHeaders( $version, $chunk ) {
-               $chunk2 = substr( $chunk, 0, 2 );
-               $chunk3 = substr( $chunk, 0, 3 );
-               $chunk4 = substr( $chunk, 0, 4 );
-               $chunk5 = substr( $chunk, 0, 5 );
-               $chunk5uc = strtoupper( $chunk5 );
-               $chunk8 = substr( $chunk, 0, 8 );
-               if ( $chunk5uc == 'GIF87' || $chunk5uc == 'GIF89' ) {
-                       return 'image/gif';
-               }
-               if ( $chunk2 == "\xff\xd8" ) {
-                       return 'image/pjpeg'; // actually plain JPEG but this is what IE returns
-               }
-
-               if ( $chunk2 == 'BM'
-                       && substr( $chunk, 6, 2 ) == "\000\000"
-                       && substr( $chunk, 8, 2 ) == "\000\000" )
-               {
-                       return 'image/bmp'; // another non-standard MIME
-               }
-               if ( $chunk4 == 'RIFF'
-                       && substr( $chunk, 8, 4 ) == 'WAVE' )
-               {
-                       return 'audio/wav';
-               }
-               // These were integer literals in IE
-               // Perhaps the author was not sure what the target endianness was
-               if ( $chunk4 == ".sd\000"
-                       || $chunk4 == ".snd"
-                       || $chunk4 == "\000ds."
-                       || $chunk4 == "dns." )
-               {
-                       return 'audio/basic';
-               }
-               if ( $chunk3 == "MM\000" ) {
-                       return 'image/tiff';
-               }
-               if ( $chunk2 == 'MZ' ) {
-                       return 'application/x-msdownload';
-               }
-               if ( $chunk8 == "\x89PNG\x0d\x0a\x1a\x0a" ) {
-                       return 'image/x-png'; // [sic]
-               }
-               if ( strlen( $chunk ) >= 5 ) {
-                       $byte2 = ord( $chunk[2] );
-                       $byte4 = ord( $chunk[4] );
-                       if ( $byte2 >= 3 && $byte2 <= 31 && $byte4 == 0 && $chunk2 == 'JG' ) {
-                               return 'image/x-jg';
-                       }
-               }
-               // More endian confusion?
-               if ( $chunk4 == 'MROF' ) {
-                       return 'audio/x-aiff';
-               }
-               $chunk4_8 = substr( $chunk, 8, 4 );
-               if ( $chunk4 == 'FORM' && ( $chunk4_8 == 'AIFF' || $chunk4_8 == 'AIFC' ) ) {
-                       return 'audio/x-aiff';
-               }
-               if ( $chunk4 == 'RIFF' && $chunk4_8 == 'AVI ' ) {
-                       return 'video/avi';
-               }
-               if ( $chunk4 == "\x00\x00\x01\xb3" || $chunk4 == "\x00\x00\x01\xba" ) {
-                       return 'video/mpeg';
-               }
-               if ( $chunk4 == "\001\000\000\000"
-                       && substr( $chunk, 40, 4 ) == ' EMF' )
-               {
-                       return 'image/x-emf';
-               }
-               if ( $chunk4 == "\xd7\xcd\xc6\x9a" ) {
-                       return 'image/x-wmf';
-               }
-               if ( $chunk4 == "\xca\xfe\xba\xbe" ) {
-                       return 'application/java';
-               }
-               if ( $chunk2 == 'PK' ) {
-                       return 'application/x-zip-compressed';
-               }
-               if ( $chunk2 == "\x1f\x9d" ) {
-                       return 'application/x-compressed';
-               }
-               if ( $chunk2 == "\x1f\x8b" ) {
-                       return 'application/x-gzip-compressed';
-               }
-               // Skip redundant check for ZIP
-               if ( $chunk5 == "MThd\000" ) {
-                       return 'audio/mid';
-               }
-               if ( $chunk4 == '%PDF' ) {
-                       return 'application/pdf';
-               }
-               return false;
-       }
-
-       /**
-        * Do heuristic checks on the bulk of the data sample.
-        * Search for HTML tags.
-        * @param $version
-        * @param $chunk
-        * @return array
-        */
-       protected function sampleData( $version, $chunk ) {
-               $found = [];
-               $counters = [
-                       'ctrl' => 0,
-                       'high' => 0,
-                       'low' => 0,
-                       'lf' => 0,
-                       'cr' => 0,
-                       'ff' => 0
-               ];
-               $htmlTags = [
-                       'html',
-                       'head',
-                       'title',
-                       'body',
-                       'script',
-                       'a href',
-                       'pre',
-                       'img',
-                       'plaintext',
-                       'table'
-               ];
-               $rdfUrl = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
-               $rdfPurl = 'http://purl.org/rss/1.0/';
-               $xbmMagic1 = '#define';
-               $xbmMagic2 = '_width';
-               $xbmMagic3 = '_bits';
-               $binhexMagic = 'converted with BinHex';
-               $chunkLength = strlen( $chunk );
-
-               for ( $offset = 0; $offset < $chunkLength; $offset++ ) {
-                       $curChar = $chunk[$offset];
-                       if ( $curChar == "\x0a" ) {
-                               $counters['lf']++;
-                               continue;
-                       } elseif ( $curChar == "\x0d" ) {
-                               $counters['cr']++;
-                               continue;
-                       } elseif ( $curChar == "\x0c" ) {
-                               $counters['ff']++;
-                               continue;
-                       } elseif ( $curChar == "\t" ) {
-                               $counters['low']++;
-                               continue;
-                       } elseif ( ord( $curChar ) < 32 ) {
-                               $counters['ctrl']++;
-                               continue;
-                       } elseif ( ord( $curChar ) >= 128 ) {
-                               $counters['high']++;
-                               continue;
-                       }
-
-                       $counters['low']++;
-                       if ( $curChar == '<' ) {
-                               // XML
-                               $remainder = substr( $chunk, $offset + 1 );
-                               if ( !strncasecmp( $remainder, '?XML', 4 ) ) {
-                                       $nextChar = substr( $chunk, $offset + 5, 1 );
-                                       if ( $nextChar == ':' || $nextChar == ' ' || $nextChar == "\t" ) {
-                                               $found['xml'] = true;
-                                       }
-                               }
-                               // Scriptlet (JSP)
-                               if ( !strncasecmp( $remainder, 'SCRIPTLET', 9 ) ) {
-                                       $found['scriptlet'] = true;
-                                       break;
-                               }
-                               // HTML
-                               foreach ( $htmlTags as $tag ) {
-                                       if ( !strncasecmp( $remainder, $tag, strlen( $tag ) ) ) {
-                                               $found['html'] = true;
-                                       }
-                               }
-                               // Skip broken check for additional tags (HR etc.)
-
-                               // CHANNEL replaced by RSS, RDF and FEED in IE 7
-                               if ( $version < 'ie07' ) {
-                                       if ( !strncasecmp( $remainder, 'CHANNEL', 7 ) ) {
-                                               $found['cdf'] = true;
-                                       }
-                               } else {
-                                       // RSS
-                                       if ( !strncasecmp( $remainder, 'RSS', 3 ) ) {
-                                               $found['rss'] = true;
-                                               break; // return from SampleData
-                                       }
-                                       if ( !strncasecmp( $remainder, 'rdf:RDF', 7 ) ) {
-                                               $found['rdf-tag'] = true;
-                                               // no break
-                                       }
-                                       if ( !strncasecmp( $remainder, 'FEED', 4 ) ) {
-                                               $found['atom'] = true;
-                                               break;
-                                       }
-                               }
-                               continue;
-                       }
-                       // Skip broken check for -->
-
-                       // RSS URL checks
-                       // For some reason both URLs must appear before it is recognised
-                       $remainder = substr( $chunk, $offset );
-                       if ( !strncasecmp( $remainder, $rdfUrl, strlen( $rdfUrl ) ) ) {
-                               $found['rdf-url'] = true;
-                               if ( isset( $found['rdf-tag'] )
-                                       && isset( $found['rdf-purl'] ) ) // [sic]
-                               {
-                                       break;
-                               }
-                               continue;
-                       }
-
-                       if ( !strncasecmp( $remainder, $rdfPurl, strlen( $rdfPurl ) ) ) {
-                               if ( isset( $found['rdf-tag'] )
-                                       && isset( $found['rdf-url'] ) ) // [sic]
-                               {
-                                       break;
-                               }
-                               continue;
-                       }
-
-                       // XBM checks
-                       if ( !strncasecmp( $remainder, $xbmMagic1, strlen( $xbmMagic1 ) ) ) {
-                               $found['xbm1'] = true;
-                               continue;
-                       }
-                       if ( $curChar == '_' ) {
-                               if ( isset( $found['xbm2'] ) ) {
-                                       if ( !strncasecmp( $remainder, $xbmMagic3, strlen( $xbmMagic3 ) ) ) {
-                                               $found['xbm'] = true;
-                                               break;
-                                       }
-                               } elseif ( isset( $found['xbm1'] ) ) {
-                                       if ( !strncasecmp( $remainder, $xbmMagic2, strlen( $xbmMagic2 ) ) ) {
-                                               $found['xbm2'] = true;
-                                       }
-                               }
-                       }
-
-                       // BinHex
-                       if ( !strncmp( $remainder, $binhexMagic, strlen( $binhexMagic ) ) ) {
-                               $found['binhex'] = true;
-                       }
-               }
-               return [ 'found' => $found, 'counters' => $counters ];
-       }
-
-       /**
-        * @param $version
-        * @param $type
-        * @return int|string
-        */
-       protected function getDataFormat( $version, $type ) {
-               $types = $this->typeTable[$version];
-               if ( $type == '(null)' || strval( $type ) === '' ) {
-                       return 'ambiguous';
-               }
-               foreach ( $types as $format => $list ) {
-                       if ( in_array( $type, $list ) ) {
-                               return $format;
-                       }
-               }
-               return 'unknown';
-       }
-}
diff --git a/includes/libs/MWCryptHash.php b/includes/libs/MWCryptHash.php
new file mode 100644 (file)
index 0000000..f9b7172
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+/**
+ * Utility functions for generating hashes
+ *
+ * This is based in part on Drupal code as well as what we used in our own code
+ * prior to introduction of this class, by way of MWCryptRand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+class MWCryptHash {
+       /**
+        * The hash algorithm being used
+        */
+       protected static $algo = null;
+
+       /**
+        * The number of bytes outputted by the hash algorithm
+        */
+       protected static $hashLength = [
+               true => null,
+               false => null,
+       ];
+
+       /**
+        * Decide on the best acceptable hash algorithm we have available for hash()
+        * @return string A hash algorithm
+        */
+       public static function hashAlgo() {
+               if ( !is_null( self::$algo ) ) {
+                       return self::$algo;
+               }
+
+               $algos = hash_algos();
+               $preference = [ 'whirlpool', 'sha256', 'sha1', 'md5' ];
+
+               foreach ( $preference as $algorithm ) {
+                       if ( in_array( $algorithm, $algos ) ) {
+                               self::$algo = $algorithm;
+
+                               return self::$algo;
+                       }
+               }
+
+               // We only reach here if no acceptable hash is found in the list, this should
+               // be a technical impossibility since most of php's hash list is fixed and
+               // some of the ones we list are available as their own native functions
+               // But since we already require at least 5.2 and hash() was default in
+               // 5.1.2 we don't bother falling back to methods like sha1 and md5.
+               throw new DomainException( "Could not find an acceptable hashing function in hash_algos()" );
+       }
+
+       /**
+        * Return the byte-length output of the hash algorithm we are
+        * using in self::hash and self::hmac.
+        *
+        * @param bool $raw True to return the length for binary data, false to
+        *   return for hex-encoded
+        * @return int Number of bytes the hash outputs
+        */
+       public static function hashLength( $raw = true ) {
+               $raw = (bool)$raw;
+               if ( is_null( self::$hashLength[$raw] ) ) {
+                       self::$hashLength[$raw] = strlen( self::hash( '', $raw ) );
+               }
+
+               return self::$hashLength[$raw];
+       }
+
+       /**
+        * Generate an acceptably unstable one-way-hash of some text
+        * making use of the best hash algorithm that we have available.
+        *
+        * @param string $data
+        * @param bool $raw True to return binary data, false to return it hex-encoded
+        * @return string A hash of the data
+        */
+       public static function hash( $data, $raw = true ) {
+               return hash( self::hashAlgo(), $data, $raw );
+       }
+
+       /**
+        * Generate an acceptably unstable one-way-hmac of some text
+        * making use of the best hash algorithm that we have available.
+        *
+        * @param string $data
+        * @param string $key
+        * @param bool $raw True to return binary data, false to return it hex-encoded
+        * @return string An hmac hash of the data + key
+        */
+       public static function hmac( $data, $key, $raw = true ) {
+               if ( !is_string( $key ) ) {
+                       // a fatal error in HHVM; an exception will at least give us a stack trace
+                       throw new InvalidArgumentException( 'Invalid key type: ' . gettype( $key ) );
+               }
+               return hash_hmac( self::hashAlgo(), $data, $key, $raw );
+       }
+
+}
index 50e9732..12a5cad 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * APC-backed function memoization
+ * APC-backed and APCu-backed function memoization
  *
  * This class provides memoization for pure functions. A function is pure
  * if its result value depends on nothing other than its input parameters
@@ -8,7 +8,7 @@
  *
  * The first invocation of the memoized callable with a particular set of
  * arguments will be delegated to the underlying callable. Repeat invocations
- * with the same input parameters will be served from APC.
+ * with the same input parameters will be served from APC or APCu.
  *
  * @par Example:
  * @code
@@ -70,7 +70,7 @@ class MemoizedCallable {
        }
 
        /**
-        * Fetch the result of a previous invocation from APC.
+        * Fetch the result of a previous invocation from APC or APCu.
         *
         * @param string $key
         * @param bool &$success
@@ -79,12 +79,14 @@ class MemoizedCallable {
                $success = false;
                if ( function_exists( 'apc_fetch' ) ) {
                        return apc_fetch( $key, $success );
+               } elseif ( function_exists( 'apcu_fetch' ) ) {
+                       return apcu_fetch( $key, $success );
                }
                return false;
        }
 
        /**
-        * Store the result of an invocation in APC.
+        * Store the result of an invocation in APC or APCu.
         *
         * @param string $key
         * @param mixed $result
@@ -92,6 +94,8 @@ class MemoizedCallable {
        protected function storeResult( $key, $result ) {
                if ( function_exists( 'apc_store' ) ) {
                        apc_store( $key, $result, $this->ttl );
+               } elseif ( function_exists( 'apcu_store' ) ) {
+                       apcu_store( $key, $result, $this->ttl );
                }
        }
 
index fdcbf49..f0b44a5 100644 (file)
@@ -184,14 +184,12 @@ class MultiHttpClient {
                unset( $req ); // don't assign over this by accident
 
                $indexes = array_keys( $reqs );
-               if ( function_exists( 'curl_multi_setopt' ) ) { // PHP 5.5
-                       if ( isset( $opts['usePipelining'] ) ) {
-                               curl_multi_setopt( $chm, CURLMOPT_PIPELINING, (int)$opts['usePipelining'] );
-                       }
-                       if ( isset( $opts['maxConnsPerHost'] ) ) {
-                               // Keep these sockets around as they may be needed later in the request
-                               curl_multi_setopt( $chm, CURLMOPT_MAXCONNECTS, (int)$opts['maxConnsPerHost'] );
-                       }
+               if ( isset( $opts['usePipelining'] ) ) {
+                       curl_multi_setopt( $chm, CURLMOPT_PIPELINING, (int)$opts['usePipelining'] );
+               }
+               if ( isset( $opts['maxConnsPerHost'] ) ) {
+                       // Keep these sockets around as they may be needed later in the request
+                       curl_multi_setopt( $chm, CURLMOPT_MAXCONNECTS, (int)$opts['maxConnsPerHost'] );
                }
 
                // @TODO: use a per-host rolling handle window (e.g. CURLMOPT_MAX_HOST_CONNECTIONS)
@@ -217,7 +215,7 @@ class MultiHttpClient {
                                // Wait (if possible) for available work...
                                if ( $active > 0 && $mrc == CURLM_OK ) {
                                        if ( curl_multi_select( $chm, 10 ) == -1 ) {
-                                               // PHP bug 63411; http://curl.haxx.se/libcurl/c/curl_multi_fdset.html
+                                               // PHP bug 63411; https://curl.haxx.se/libcurl/c/curl_multi_fdset.html
                                                usleep( 5000 ); // 5ms
                                        }
                                }
@@ -258,10 +256,8 @@ class MultiHttpClient {
                unset( $req ); // don't assign over this by accident
 
                // Restore the default settings
-               if ( function_exists( 'curl_multi_setopt' ) ) { // PHP 5.5
-                       curl_multi_setopt( $chm, CURLMOPT_PIPELINING, (int)$this->usePipelining );
-                       curl_multi_setopt( $chm, CURLMOPT_MAXCONNECTS, (int)$this->maxConnsPerHost );
-               }
+               curl_multi_setopt( $chm, CURLMOPT_PIPELINING, (int)$this->usePipelining );
+               curl_multi_setopt( $chm, CURLMOPT_MAXCONNECTS, (int)$this->maxConnsPerHost );
 
                return $reqs;
        }
@@ -292,12 +288,7 @@ class MultiHttpClient {
                curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
 
                $url = $req['url'];
-               // PHP_QUERY_RFC3986 is PHP 5.4+ only
-               $query = str_replace(
-                       [ '+', '%7E' ],
-                       [ '%20', '~' ],
-                       http_build_query( $req['query'], '', '&' )
-               );
+               $query = http_build_query( $req['query'], '', '&', PHP_QUERY_RFC3986 );
                if ( $query != '' ) {
                        $url .= strpos( $req['url'], '?' ) === false ? "?$query" : "&$query";
                }
@@ -422,10 +413,8 @@ class MultiHttpClient {
        protected function getCurlMulti() {
                if ( !$this->multiHandle ) {
                        $cmh = curl_multi_init();
-                       if ( function_exists( 'curl_multi_setopt' ) ) { // PHP 5.5
-                               curl_multi_setopt( $cmh, CURLMOPT_PIPELINING, (int)$this->usePipelining );
-                               curl_multi_setopt( $cmh, CURLMOPT_MAXCONNECTS, (int)$this->maxConnsPerHost );
-                       }
+                       curl_multi_setopt( $cmh, CURLMOPT_PIPELINING, (int)$this->usePipelining );
+                       curl_multi_setopt( $cmh, CURLMOPT_MAXCONNECTS, (int)$this->maxConnsPerHost );
                        $this->multiHandle = $cmh;
                }
                return $this->multiHandle;
diff --git a/includes/libs/ScopedCallback.php b/includes/libs/ScopedCallback.php
deleted file mode 100644 (file)
index 2fd60ea..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-/**
- * This file deals with RAII style scoped callbacks.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * Class for asserting that a callback happens when a dummy object leaves scope
- *
- * @since 1.21
- */
-class ScopedCallback {
-       /** @var callable */
-       protected $callback;
-       /** @var array */
-       protected $params;
-
-       /**
-        * @param callable|null $callback
-        * @param array $params Callback arguments (since 1.25)
-        * @throws Exception
-        */
-       public function __construct( $callback, array $params = [] ) {
-               if ( $callback !== null && !is_callable( $callback ) ) {
-                       throw new InvalidArgumentException( "Provided callback is not valid." );
-               }
-               $this->callback = $callback;
-               $this->params = $params;
-       }
-
-       /**
-        * Trigger a scoped callback and destroy it.
-        * This is the same is just setting it to null.
-        *
-        * @param ScopedCallback $sc
-        */
-       public static function consume( ScopedCallback &$sc = null ) {
-               $sc = null;
-       }
-
-       /**
-        * Destroy a scoped callback without triggering it
-        *
-        * @param ScopedCallback $sc
-        */
-       public static function cancel( ScopedCallback &$sc = null ) {
-               if ( $sc ) {
-                       $sc->callback = null;
-               }
-               $sc = null;
-       }
-
-       /**
-        * Trigger the callback when this leaves scope
-        */
-       function __destruct() {
-               if ( $this->callback !== null ) {
-                       call_user_func_array( $this->callback, $this->params );
-               }
-       }
-}
index bff9abd..db085da 100644 (file)
@@ -88,7 +88,7 @@ class StatusValue {
         *         1 => object(StatusValue) # The StatusValue with warning messages, only
         * ]
         *
-        * @return array
+        * @return StatusValue[]
         */
        public function splitByErrorType() {
                $errorsOnlyStatusValue = clone $this;
@@ -160,7 +160,7 @@ class StatusValue {
         * @param mixed $value
         */
        public function setResult( $ok, $value = null ) {
-               $this->ok = $ok;
+               $this->ok = (bool)$ok;
                $this->value = $value;
        }
 
index 62baaf1..57c253d 100644 (file)
@@ -36,9 +36,9 @@ use Psr\Log\NullLogger;
  *   getEntryByName().
  *
  * The in-line documentation incorporates content from the User Timing Specification
- * http://www.w3.org/TR/user-timing/
+ * https://www.w3.org/TR/user-timing/
  * Copyright © 2013 World Wide Web Consortium, (MIT, ERCIM, Keio, Beihang).
- * http://www.w3.org/Consortium/Legal/2015/doc-license
+ * https://www.w3.org/Consortium/Legal/2015/doc-license
  *
  * @since 1.27
  */
diff --git a/includes/libs/WaitConditionLoop.php b/includes/libs/WaitConditionLoop.php
deleted file mode 100644 (file)
index 969e86e..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-<?php
-/**
- * Wait loop that reaches a condition or times out.
- *
- * 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
- * @author Aaron Schulz
- */
-
-/**
- * Wait loop that reaches a condition or times out
- * @since 1.28
- */
-class WaitConditionLoop {
-       /** @var callable */
-       private $condition;
-       /** @var callable[] */
-       private $busyCallbacks = [];
-       /** @var float Seconds */
-       private $timeout;
-       /** @var float Seconds */
-       private $lastWaitTime;
-       /** @var integer|null */
-       private $rusageMode;
-
-       const CONDITION_REACHED = 1;
-       const CONDITION_CONTINUE = 0; // evaluates as falsey
-       const CONDITION_FAILED = -1;
-       const CONDITION_TIMED_OUT = -2;
-       const CONDITION_ABORTED = -3;
-
-       /**
-        * @param callable $condition Callback that returns a WaitConditionLoop::CONDITION_ constant
-        * @param float $timeout Timeout in seconds
-        * @param array &$busyCallbacks List of callbacks to do useful work (by reference)
-        */
-       public function __construct( callable $condition, $timeout = 5.0, &$busyCallbacks = [] ) {
-               $this->condition = $condition;
-               $this->timeout = $timeout;
-               $this->busyCallbacks =& $busyCallbacks;
-
-               if ( defined( 'HHVM_VERSION' ) && PHP_OS === 'Linux' ) {
-                       $this->rusageMode = 2; // RUSAGE_THREAD
-               } elseif ( function_exists( 'getrusage' ) ) {
-                       $this->rusageMode = 0; // RUSAGE_SELF
-               }
-       }
-
-       /**
-        * Invoke the loop and continue until either:
-        *   - a) The condition callback returns neither CONDITION_CONTINUE nor false
-        *   - b) The timeout is reached
-        * This a condition callback can return true (stop) or false (continue) for convenience.
-        * In such cases, the halting result of "true" will be converted to CONDITION_REACHED.
-        *
-        * If $timeout is 0, then only the condition callback will be called (no busy callbacks),
-        * and this will immediately return CONDITION_FAILED if the condition was not met.
-        *
-        * Exceptions in callbacks will be caught and the callback will be swapped with
-        * one that simply rethrows that exception back to the caller when invoked.
-        *
-        * @return integer WaitConditionLoop::CONDITION_* constant
-        * @throws Exception Any error from the condition callback
-        */
-       public function invoke() {
-               $elapsed = 0.0; // seconds
-               $sleepUs = 0; // microseconds to sleep each time
-               $lastCheck = false;
-               $finalResult = self::CONDITION_TIMED_OUT;
-               do {
-                       $checkStartTime = $this->getWallTime();
-                       // Check if the condition is met yet
-                       $realStart = $this->getWallTime();
-                       $cpuStart = $this->getCpuTime();
-                       $checkResult = call_user_func( $this->condition );
-                       $cpu = $this->getCpuTime() - $cpuStart;
-                       $real = $this->getWallTime() - $realStart;
-                       // Exit if the condition is reached, and error occurs, or this is non-blocking
-                       if ( $this->timeout <= 0 ) {
-                               $finalResult = $checkResult ? self::CONDITION_REACHED : self::CONDITION_FAILED;
-                               break;
-                       } elseif ( (int)$checkResult !== self::CONDITION_CONTINUE ) {
-                               if ( is_int( $checkResult ) ) {
-                                       $finalResult = $checkResult;
-                               } else {
-                                       $finalResult = self::CONDITION_REACHED;
-                               }
-                               break;
-                       } elseif ( $lastCheck ) {
-                               break; // timeout reached
-                       }
-                       // Detect if condition callback seems to block or if justs burns CPU
-                       $conditionUsesInterrupts = ( $real > 0.100 && $cpu <= $real * .03 );
-                       if ( !$this->popAndRunBusyCallback() && !$conditionUsesInterrupts ) {
-                               // 10 queries = 10(10+100)/2 ms = 550ms, 14 queries = 1050ms
-                               $sleepUs = min( $sleepUs + 10 * 1e3, 1e6 ); // stop incrementing at ~1s
-                               $this->usleep( $sleepUs );
-                       }
-                       $checkEndTime = $this->getWallTime();
-                       // The max() protects against the clock getting set back
-                       $elapsed += max( $checkEndTime - $checkStartTime, 0.010 );
-                       // Do not let slow callbacks timeout without checking the condition one more time
-                       $lastCheck = ( $elapsed >= $this->timeout );
-               } while ( true );
-
-               $this->lastWaitTime = $elapsed;
-
-               return $finalResult;
-       }
-
-       /**
-        * @return float Seconds
-        */
-       public function getLastWaitTime() {
-               return $this->lastWaitTime;
-       }
-
-       /**
-        * @param integer $microseconds
-        */
-       protected function usleep( $microseconds ) {
-               usleep( $microseconds );
-       }
-
-       /**
-        * @return float
-        */
-       protected function getWallTime() {
-               return microtime( true );
-       }
-
-       /**
-        * @return float Returns 0.0 if not supported (Windows on PHP < 7)
-        */
-       protected function getCpuTime() {
-               if ( $this->rusageMode === null ) {
-                       return microtime( true ); // assume worst case (all time is CPU)
-               }
-
-               $ru = getrusage( $this->rusageMode );
-               $time = $ru['ru_utime.tv_sec'] + $ru['ru_utime.tv_usec'] / 1e6;
-               $time += $ru['ru_stime.tv_sec'] + $ru['ru_stime.tv_usec'] / 1e6;
-
-               return $time;
-       }
-
-       /**
-        * Run one of the callbacks that does work ahead of time for another caller
-        *
-        * @return bool Whether a callback was executed
-        */
-       private function popAndRunBusyCallback() {
-               if ( $this->busyCallbacks ) {
-                       reset( $this->busyCallbacks );
-                       $key = key( $this->busyCallbacks );
-                       /** @var callable $workCallback */
-                       $workCallback =& $this->busyCallbacks[$key];
-                       try {
-                               $workCallback();
-                       } catch ( Exception $e ) {
-                               $workCallback = function () use ( $e ) {
-                                       throw $e;
-                               };
-                       }
-                       unset( $this->busyCallbacks[$key] ); // consume
-
-                       return true;
-               }
-
-               return false;
-       }
-}
diff --git a/includes/libs/XmlTypeCheck.php b/includes/libs/XmlTypeCheck.php
deleted file mode 100644 (file)
index f057140..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-<?php
-/**
- * XML syntax and type checker.
- *
- * Since 1.24.2, it uses XMLReader instead of xml_parse, which gives us
- * more control over the expansion of XML entities. When passed to the
- * callback, entities will be fully expanded, but may report the XML is
- * invalid if expanding the entities are likely to cause a DoS.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-class XmlTypeCheck {
-       /**
-        * Will be set to true or false to indicate whether the file is
-        * well-formed XML. Note that this doesn't check schema validity.
-        */
-       public $wellFormed = null;
-
-       /**
-        * Will be set to true if the optional element filter returned
-        * a match at some point.
-        */
-       public $filterMatch = false;
-
-       /**
-        * Will contain the type of filter hit if the optional element filter returned
-        * a match at some point.
-        * @var mixed
-        */
-       public $filterMatchType = false;
-
-       /**
-        * Name of the document's root element, including any namespace
-        * as an expanded URL.
-        */
-       public $rootElement = '';
-
-       /**
-        * A stack of strings containing the data of each xml element as it's processed. Append
-        * data to the top string of the stack, then pop off the string and process it when the
-        * element is closed.
-        */
-       protected $elementData = [];
-
-       /**
-        * A stack of element names and attributes, as we process them.
-        */
-       protected $elementDataContext = [];
-
-       /**
-        * Current depth of the data stack.
-        */
-       protected $stackDepth = 0;
-
-       /**
-        * Additional parsing options
-        */
-       private $parserOptions = [
-               'processing_instruction_handler' => '',
-       ];
-
-       /**
-        * @param string $input a filename or string containing the XML element
-        * @param callable $filterCallback (optional)
-        *        Function to call to do additional custom validity checks from the
-        *        SAX element handler event. This gives you access to the element
-        *        namespace, name, attributes, and text contents.
-        *        Filter should return 'true' to toggle on $this->filterMatch
-        * @param bool $isFile (optional) indicates if the first parameter is a
-        *        filename (default, true) or if it is a string (false)
-        * @param array $options list of additional parsing options:
-        *        processing_instruction_handler: Callback for xml_set_processing_instruction_handler
-        */
-       function __construct( $input, $filterCallback = null, $isFile = true, $options = [] ) {
-               $this->filterCallback = $filterCallback;
-               $this->parserOptions = array_merge( $this->parserOptions, $options );
-               $this->validateFromInput( $input, $isFile );
-       }
-
-       /**
-        * Alternative constructor: from filename
-        *
-        * @param string $fname the filename of an XML document
-        * @param callable $filterCallback (optional)
-        *        Function to call to do additional custom validity checks from the
-        *        SAX element handler event. This gives you access to the element
-        *        namespace, name, and attributes, but not to text contents.
-        *        Filter should return 'true' to toggle on $this->filterMatch
-        * @return XmlTypeCheck
-        */
-       public static function newFromFilename( $fname, $filterCallback = null ) {
-               return new self( $fname, $filterCallback, true );
-       }
-
-       /**
-        * Alternative constructor: from string
-        *
-        * @param string $string a string containing an XML element
-        * @param callable $filterCallback (optional)
-        *        Function to call to do additional custom validity checks from the
-        *        SAX element handler event. This gives you access to the element
-        *        namespace, name, and attributes, but not to text contents.
-        *        Filter should return 'true' to toggle on $this->filterMatch
-        * @return XmlTypeCheck
-        */
-       public static function newFromString( $string, $filterCallback = null ) {
-               return new self( $string, $filterCallback, false );
-       }
-
-       /**
-        * Get the root element. Simple accessor to $rootElement
-        *
-        * @return string
-        */
-       public function getRootElement() {
-               return $this->rootElement;
-       }
-
-       /**
-        * @param string $fname the filename
-        */
-       private function validateFromInput( $xml, $isFile ) {
-               $reader = new XMLReader();
-               if ( $isFile ) {
-                       $s = $reader->open( $xml, null, LIBXML_NOERROR | LIBXML_NOWARNING );
-               } else {
-                       $s = $reader->XML( $xml, null, LIBXML_NOERROR | LIBXML_NOWARNING );
-               }
-               if ( $s !== true ) {
-                       // Couldn't open the XML
-                       $this->wellFormed = false;
-               } else {
-                       $oldDisable = libxml_disable_entity_loader( true );
-                       $reader->setParserProperty( XMLReader::SUBST_ENTITIES, true );
-                       try {
-                               $this->validate( $reader );
-                       } catch ( Exception $e ) {
-                               // Calling this malformed, because we didn't parse the whole
-                               // thing. Maybe just an external entity refernce.
-                               $this->wellFormed = false;
-                               $reader->close();
-                               libxml_disable_entity_loader( $oldDisable );
-                               throw $e;
-                       }
-                       $reader->close();
-                       libxml_disable_entity_loader( $oldDisable );
-               }
-       }
-
-       private function readNext( XMLReader $reader ) {
-               set_error_handler( [ $this, 'XmlErrorHandler' ] );
-               $ret = $reader->read();
-               restore_error_handler();
-               return $ret;
-       }
-
-       public function XmlErrorHandler( $errno, $errstr ) {
-               $this->wellFormed = false;
-       }
-
-       private function validate( $reader ) {
-
-               // First, move through anything that isn't an element, and
-               // handle any processing instructions with the callback
-               do {
-                       if ( !$this->readNext( $reader ) ) {
-                               // Hit the end of the document before any elements
-                               $this->wellFormed = false;
-                               return;
-                       }
-                       if ( $reader->nodeType === XMLReader::PI ) {
-                               $this->processingInstructionHandler( $reader->name, $reader->value );
-                       }
-               } while ( $reader->nodeType != XMLReader::ELEMENT );
-
-               // Process the rest of the document
-               do {
-                       switch ( $reader->nodeType ) {
-                               case XMLReader::ELEMENT:
-                                       $name = $this->expandNS(
-                                               $reader->name,
-                                               $reader->namespaceURI
-                                       );
-                                       if ( $this->rootElement === '' ) {
-                                               $this->rootElement = $name;
-                                       }
-                                       $empty = $reader->isEmptyElement;
-                                       $attrs = $this->getAttributesArray( $reader );
-                                       $this->elementOpen( $name, $attrs );
-                                       if ( $empty ) {
-                                               $this->elementClose();
-                                       }
-                                       break;
-
-                               case XMLReader::END_ELEMENT:
-                                       $this->elementClose();
-                                       break;
-
-                               case XMLReader::WHITESPACE:
-                               case XMLReader::SIGNIFICANT_WHITESPACE:
-                               case XMLReader::CDATA:
-                               case XMLReader::TEXT:
-                                       $this->elementData( $reader->value );
-                                       break;
-
-                               case XMLReader::ENTITY_REF:
-                                       // Unexpanded entity (maybe external?),
-                                       // don't send to the filter (xml_parse didn't)
-                                       break;
-
-                               case XMLReader::COMMENT:
-                                       // Don't send to the filter (xml_parse didn't)
-                                       break;
-
-                               case XMLReader::PI:
-                                       // Processing instructions can happen after the header too
-                                       $this->processingInstructionHandler(
-                                               $reader->name,
-                                               $reader->value
-                                       );
-                                       break;
-                               default:
-                                       // One of DOC, DOC_TYPE, ENTITY, END_ENTITY,
-                                       // NOTATION, or XML_DECLARATION
-                                       // xml_parse didn't send these to the filter, so we won't.
-                       }
-
-               } while ( $this->readNext( $reader ) );
-
-               if ( $this->stackDepth !== 0 ) {
-                       $this->wellFormed = false;
-               } elseif ( $this->wellFormed === null ) {
-                       $this->wellFormed = true;
-               }
-
-       }
-
-       /**
-        * Get all of the attributes for an XMLReader's current node
-        * @param $r XMLReader
-        * @return array of attributes
-        */
-       private function getAttributesArray( XMLReader $r ) {
-               $attrs = [];
-               while ( $r->moveToNextAttribute() ) {
-                       if ( $r->namespaceURI === 'http://www.w3.org/2000/xmlns/' ) {
-                               // XMLReader treats xmlns attributes as normal
-                               // attributes, while xml_parse doesn't
-                               continue;
-                       }
-                       $name = $this->expandNS( $r->name, $r->namespaceURI );
-                       $attrs[$name] = $r->value;
-               }
-               return $attrs;
-       }
-
-       /**
-        * @param $name element or attribute name, maybe with a full or short prefix
-        * @param $namespaceURI the namespaceURI
-        * @return string the name prefixed with namespaceURI
-        */
-       private function expandNS( $name, $namespaceURI ) {
-               if ( $namespaceURI ) {
-                       $parts = explode( ':', $name );
-                       $localname = array_pop( $parts );
-                       return "$namespaceURI:$localname";
-               }
-               return $name;
-       }
-
-       /**
-        * @param $name
-        * @param $attribs
-        */
-       private function elementOpen( $name, $attribs ) {
-               $this->elementDataContext[] = [ $name, $attribs ];
-               $this->elementData[] = '';
-               $this->stackDepth++;
-       }
-
-       /**
-        */
-       private function elementClose() {
-               list( $name, $attribs ) = array_pop( $this->elementDataContext );
-               $data = array_pop( $this->elementData );
-               $this->stackDepth--;
-               $callbackReturn = false;
-
-               if ( is_callable( $this->filterCallback ) ) {
-                       $callbackReturn = call_user_func(
-                               $this->filterCallback,
-                               $name,
-                               $attribs,
-                               $data
-                       );
-               }
-               if ( $callbackReturn ) {
-                       // Filter hit!
-                       $this->filterMatch = true;
-                       $this->filterMatchType = $callbackReturn;
-               }
-       }
-
-       /**
-        * @param $data
-        */
-       private function elementData( $data ) {
-               // Collect any data here, and we'll run the callback in elementClose
-               $this->elementData[ $this->stackDepth - 1 ] .= trim( $data );
-       }
-
-       /**
-        * @param $target
-        * @param $data
-        */
-       private function processingInstructionHandler( $target, $data ) {
-               $callbackReturn = false;
-               if ( $this->parserOptions['processing_instruction_handler'] ) {
-                       $callbackReturn = call_user_func(
-                               $this->parserOptions['processing_instruction_handler'],
-                               $target,
-                               $data
-                       );
-               }
-               if ( $callbackReturn ) {
-                       // Filter hit!
-                       $this->filterMatch = true;
-                       $this->filterMatchType = $callbackReturn;
-               }
-       }
-}
index 311508f..62231a8 100644 (file)
@@ -12,14 +12,9 @@ class ComposerJson {
         * @param string $location
         */
        public function __construct( $location ) {
-               $this->hash = md5_file( $location );
                $this->contents = json_decode( file_get_contents( $location ), true );
        }
 
-       public function getHash() {
-               return $this->hash;
-       }
-
        /**
         * Dependencies as specified by composer.json
         *
index e93127c..818ccdf 100644 (file)
@@ -15,10 +15,6 @@ class ComposerLock {
                $this->contents = json_decode( file_get_contents( $location ), true );
        }
 
-       public function getHash() {
-               return $this->contents['hash'];
-       }
-
        /**
         * Dependencies currently installed according to composer.lock
         *
diff --git a/includes/libs/filebackend/FSFile.php b/includes/libs/filebackend/FSFile.php
deleted file mode 100644 (file)
index dacad1c..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-<?php
-/**
- * Non-directory file on the file system.
- *
- * 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 FileBackend
- */
-
-/**
- * Class representing a non-directory file on the file system
- *
- * @ingroup FileBackend
- */
-class FSFile {
-       /** @var string Path to file */
-       protected $path;
-
-       /** @var string File SHA-1 in base 36 */
-       protected $sha1Base36;
-
-       /**
-        * Sets up the file object
-        *
-        * @param string $path Path to temporary file on local disk
-        */
-       public function __construct( $path ) {
-               $this->path = $path;
-       }
-
-       /**
-        * Returns the file system path
-        *
-        * @return string
-        */
-       public function getPath() {
-               return $this->path;
-       }
-
-       /**
-        * Checks if the file exists
-        *
-        * @return bool
-        */
-       public function exists() {
-               return is_file( $this->path );
-       }
-
-       /**
-        * Get the file size in bytes
-        *
-        * @return int|bool
-        */
-       public function getSize() {
-               return filesize( $this->path );
-       }
-
-       /**
-        * Get the file's last-modified timestamp
-        *
-        * @return string|bool TS_MW timestamp or false on failure
-        */
-       public function getTimestamp() {
-               MediaWiki\suppressWarnings();
-               $timestamp = filemtime( $this->path );
-               MediaWiki\restoreWarnings();
-               if ( $timestamp !== false ) {
-                       $timestamp = wfTimestamp( TS_MW, $timestamp );
-               }
-
-               return $timestamp;
-       }
-
-       /**
-        * Get an associative array containing information about
-        * a file with the given storage path.
-        *
-        * Resulting array fields include:
-        *   - fileExists
-        *   - size (filesize in bytes)
-        *   - mime (as major/minor)
-        *   - file-mime (as major/minor)
-        *   - sha1 (in base 36)
-        *   - major_mime
-        *   - minor_mime
-        *
-        * @param string|bool $ext The file extension, or true to extract it from the filename.
-        *             Set it to false to ignore the extension. Currently unused.
-        * @return array
-        */
-       public function getProps( $ext = true ) {
-               $info = self::placeholderProps();
-               $info['fileExists'] = $this->exists();
-
-               if ( $info['fileExists'] ) {
-                       $info['size'] = $this->getSize(); // bytes
-                       $info['sha1'] = $this->getSha1Base36();
-
-                       $mime = mime_content_type( $this->path );
-                       # MIME type according to file contents
-                       $info['file-mime'] = ( $mime === false ) ? 'unknown/unknown' : $mime;
-                       # logical MIME type
-                       $info['mime'] = $mime;
-
-                       if ( strpos( $mime, '/' ) !== false ) {
-                               list( $info['major_mime'], $info['minor_mime'] ) = explode( '/', $mime, 2 );
-                       } else {
-                               list( $info['major_mime'], $info['minor_mime'] ) = [ $mime, 'unknown' ];
-                       }
-               }
-
-               return $info;
-       }
-
-       /**
-        * Placeholder file properties to use for files that don't exist
-        *
-        * Resulting array fields include:
-        *   - fileExists
-        *   - size (filesize in bytes)
-        *   - mime (as major/minor)
-        *   - file-mime (as major/minor)
-        *   - sha1 (in base 36)
-        *   - major_mime
-        *   - minor_mime
-        *
-        * @return array
-        */
-       public static function placeholderProps() {
-               $info = [];
-               $info['fileExists'] = false;
-               $info['size'] = 0;
-               $info['file-mime'] = null;
-               $info['major_mime'] = null;
-               $info['minor_mime'] = null;
-               $info['mime'] = null;
-               $info['sha1'] = '';
-
-               return $info;
-       }
-
-       /**
-        * Get a SHA-1 hash of a file in the local filesystem, in base-36 lower case
-        * encoding, zero padded to 31 digits.
-        *
-        * 160 log 2 / log 36 = 30.95, so the 160-bit hash fills 31 digits in base 36
-        * fairly neatly.
-        *
-        * @param bool $recache
-        * @return bool|string False on failure
-        */
-       public function getSha1Base36( $recache = false ) {
-               if ( $this->sha1Base36 !== null && !$recache ) {
-                       return $this->sha1Base36;
-               }
-
-               MediaWiki\suppressWarnings();
-               $this->sha1Base36 = sha1_file( $this->path );
-               MediaWiki\restoreWarnings();
-
-               if ( $this->sha1Base36 !== false ) {
-                       $this->sha1Base36 = Wikimedia\base_convert( $this->sha1Base36, 16, 36, 31 );
-               }
-
-               return $this->sha1Base36;
-       }
-
-       /**
-        * Get the final file extension from a file system path
-        *
-        * @param string $path
-        * @return string
-        */
-       public static function extensionFromPath( $path ) {
-               $i = strrpos( $path, '.' );
-
-               return strtolower( $i ? substr( $path, $i + 1 ) : '' );
-       }
-
-       /**
-        * Get an associative array containing information about a file in the local filesystem.
-        *
-        * @param string $path Absolute local filesystem path
-        * @param string|bool $ext The file extension, or true to extract it from the filename.
-        *   Set it to false to ignore the extension.
-        * @return array
-        */
-       public static function getPropsFromPath( $path, $ext = true ) {
-               $fsFile = new self( $path );
-
-               return $fsFile->getProps( $ext );
-       }
-
-       /**
-        * Get a SHA-1 hash of a file in the local filesystem, in base-36 lower case
-        * encoding, zero padded to 31 digits.
-        *
-        * 160 log 2 / log 36 = 30.95, so the 160-bit hash fills 31 digits in base 36
-        * fairly neatly.
-        *
-        * @param string $path
-        * @return bool|string False on failure
-        */
-       public static function getSha1Base36FromPath( $path ) {
-               $fsFile = new self( $path );
-
-               return $fsFile->getSha1Base36();
-       }
-}
index 0ef9f63..15f13b9 100644 (file)
@@ -30,6 +30,7 @@
  */
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerInterface;
+use Wikimedia\ScopedCallback;
 
 /**
  * @brief Base class for all file backend classes (including multi-write backends).
@@ -185,15 +186,15 @@ abstract class FileBackend implements LoggerAwareInterface {
                $this->concurrency = isset( $config['concurrency'] )
                        ? (int)$config['concurrency']
                        : 50;
-               $this->obResetFunc = isset( $params['obResetFunc'] )
-                       ? $params['obResetFunc']
+               $this->obResetFunc = isset( $config['obResetFunc'] )
+                       ? $config['obResetFunc']
                        : [ $this, 'resetOutputBuffer' ];
-               $this->streamMimeFunc = isset( $params['streamMimeFunc'] )
-                       ? $params['streamMimeFunc']
+               $this->streamMimeFunc = isset( $config['streamMimeFunc'] )
+                       ? $config['streamMimeFunc']
                        : null;
                $this->statusWrapper = isset( $config['statusWrapper'] ) ? $config['statusWrapper'] : null;
 
-               $this->profiler = isset( $params['profiler'] ) ? $params['profiler'] : null;
+               $this->profiler = isset( $config['profiler'] ) ? $config['profiler'] : null;
                $this->logger = isset( $config['logger'] ) ? $config['logger'] : new \Psr\Log\NullLogger();
                $this->statusWrapper = isset( $config['statusWrapper'] ) ? $config['statusWrapper'] : null;
                $this->tmpDirectory = isset( $config['tmpDirectory'] ) ? $config['tmpDirectory'] : null;
@@ -927,7 +928,7 @@ abstract class FileBackend implements LoggerAwareInterface {
         * @return ScopedCallback|null
         */
        final protected function getScopedPHPBehaviorForOps() {
-               if ( PHP_SAPI != 'cli' ) { // http://bugs.php.net/bug.php?id=47540
+               if ( PHP_SAPI != 'cli' ) { // https://bugs.php.net/bug.php?id=47540
                        $old = ignore_user_abort( true ); // avoid half-finished operations
                        return new ScopedCallback( function () use ( $old ) {
                                ignore_user_abort( $old );
@@ -1620,7 +1621,7 @@ abstract class FileBackend implements LoggerAwareInterface {
        protected function scopedProfileSection( $section ) {
                if ( $this->profiler ) {
                        call_user_func( [ $this->profiler, 'profileIn' ], $section );
-                       return new ScopedCallback( [ $this->profiler, 'profileOut' ] );
+                       return new ScopedCallback( [ $this->profiler, 'profileOut' ], [ $section ] );
                }
 
                return null;
index 7c32d02..212e84f 100644 (file)
@@ -575,11 +575,14 @@ class FileBackendMultiWrite extends FileBackend {
        }
 
        public function concatenate( array $params ) {
+               $status = $this->newStatus();
                // We are writing to an FS file, so we don't need to do this per-backend
                $index = $this->getReadIndexFromParams( $params );
                $realParams = $this->substOpPaths( $params, $this->backends[$index] );
 
-               return $this->backends[$index]->concatenate( $realParams );
+               $status->merge( $this->backends[$index]->concatenate( $realParams ) );
+
+               return $status;
        }
 
        public function fileExists( array $params ) {
index b1b7652..bd2ce5d 100644 (file)
@@ -1098,9 +1098,9 @@ abstract class FileBackendStore extends FileBackend {
 
                // Build the list of paths involved
                $paths = [];
-               foreach ( $performOps as $op ) {
-                       $paths = array_merge( $paths, $op->storagePathsRead() );
-                       $paths = array_merge( $paths, $op->storagePathsChanged() );
+               foreach ( $performOps as $performOp ) {
+                       $paths = array_merge( $paths, $performOp->storagePathsRead() );
+                       $paths = array_merge( $paths, $performOp->storagePathsChanged() );
                }
 
                // Enlarge the cache to fit the stat entries of these files
index 4bc0ce6..08cb388 100644 (file)
@@ -176,7 +176,6 @@ class SwiftFileBackend extends FileBackendStore {
                return isset( $params['headers'] )
                        ? $this->getCustomHeaders( $params['headers'] )
                        : [];
-
        }
 
        /**
@@ -1209,7 +1208,7 @@ class SwiftFileBackend extends FileBackendStore {
                                        $this->rgwS3SecretKey,
                                        true // raw
                                ) );
-                               // See http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html.
+                               // See https://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html.
                                // Note: adding a newline for empty CanonicalizedAmzHeaders does not work.
                                // Note: S3 API is the rgw default; remove the /swift/ URL bit.
                                return str_replace( '/swift/v1', '', $this->storageUrl( $auth ) . $spath ) .
@@ -1305,7 +1304,7 @@ class SwiftFileBackend extends FileBackendStore {
        /**
         * Set read/write permissions for a Swift container.
         *
-        * @see http://swift.openstack.org/misc.html#acls
+        * @see http://docs.openstack.org/developer/swift/misc.html#acls
         *
         * In general, we don't allow listings to end-users. It's not useful, isn't well-defined
         * (lists are truncated to 10000 item with no way to page), and is just a performance risk.
diff --git a/includes/libs/filebackend/TempFSFile.php b/includes/libs/filebackend/TempFSFile.php
deleted file mode 100644 (file)
index fed6812..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-<?php
-/**
- * Location holder of files stored temporarily
- *
- * 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 FileBackend
- */
-
-/**
- * This class is used to hold the location and do limited manipulation
- * of files stored temporarily (this will be whatever wfTempDir() returns)
- *
- * @ingroup FileBackend
- */
-class TempFSFile extends FSFile {
-       /** @var bool Garbage collect the temp file */
-       protected $canDelete = false;
-
-       /** @var array Map of (path => 1) for paths to delete on shutdown */
-       protected static $pathsCollect = null;
-
-       public function __construct( $path ) {
-               parent::__construct( $path );
-
-               if ( self::$pathsCollect === null ) {
-                       self::$pathsCollect = [];
-                       register_shutdown_function( [ __CLASS__, 'purgeAllOnShutdown' ] );
-               }
-       }
-
-       /**
-        * Make a new temporary file on the file system.
-        * Temporary files may be purged when the file object falls out of scope.
-        *
-        * @param string $prefix
-        * @param string $extension Optional file extension
-        * @param string|null $tmpDirectory Optional parent directory
-        * @return TempFSFile|null
-        */
-       public static function factory( $prefix, $extension = '', $tmpDirectory = null ) {
-               $ext = ( $extension != '' ) ? ".{$extension}" : '';
-
-               $attempts = 5;
-               while ( $attempts-- ) {
-                       $hex = sprintf( '%06x%06x', mt_rand( 0, 0xffffff ), mt_rand( 0, 0xffffff ) );
-                       if ( !is_string( $tmpDirectory ) ) {
-                               $tmpDirectory = self::getUsableTempDirectory();
-                       }
-                       $path = wfTempDir() . '/' . $prefix . $hex . $ext;
-                       MediaWiki\suppressWarnings();
-                       $newFileHandle = fopen( $path, 'x' );
-                       MediaWiki\restoreWarnings();
-                       if ( $newFileHandle ) {
-                               fclose( $newFileHandle );
-                               $tmpFile = new self( $path );
-                               $tmpFile->autocollect();
-                               // Safely instantiated, end loop.
-                               return $tmpFile;
-                       }
-               }
-
-               // Give up
-               return null;
-       }
-
-       /**
-        * @return string Filesystem path to a temporary directory
-        * @throws RuntimeException
-        */
-       public static function getUsableTempDirectory() {
-               $tmpDir = array_map( 'getenv', [ 'TMPDIR', 'TMP', 'TEMP' ] );
-               $tmpDir[] = sys_get_temp_dir();
-               $tmpDir[] = ini_get( 'upload_tmp_dir' );
-               foreach ( $tmpDir as $tmp ) {
-                       if ( $tmp != '' && is_dir( $tmp ) && is_writable( $tmp ) ) {
-                               return $tmp;
-                       }
-               }
-
-               // PHP on Windows will detect C:\Windows\Temp as not writable even though PHP can write to
-               // it so create a directory within that called 'mwtmp' with a suffix of the user running
-               // the current process.
-               // The user is included as if various scripts are run by different users they will likely
-               // not be able to access each others temporary files.
-               if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
-                       $tmp = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'mwtmp-' . get_current_user();
-                       if ( !file_exists( $tmp ) ) {
-                               mkdir( $tmp );
-                       }
-                       if ( is_dir( $tmp ) && is_writable( $tmp ) ) {
-                               return $tmp;
-                       }
-               }
-
-               throw new RuntimeException(
-                       'No writable temporary directory could be found. ' .
-                       'Please explicitly specify a writable directory in configuration.' );
-       }
-
-       /**
-        * Purge this file off the file system
-        *
-        * @return bool Success
-        */
-       public function purge() {
-               $this->canDelete = false; // done
-               MediaWiki\suppressWarnings();
-               $ok = unlink( $this->path );
-               MediaWiki\restoreWarnings();
-
-               unset( self::$pathsCollect[$this->path] );
-
-               return $ok;
-       }
-
-       /**
-        * Clean up the temporary file only after an object goes out of scope
-        *
-        * @param object $object
-        * @return TempFSFile This object
-        */
-       public function bind( $object ) {
-               if ( is_object( $object ) ) {
-                       if ( !isset( $object->tempFSFileReferences ) ) {
-                               // Init first since $object might use __get() and return only a copy variable
-                               $object->tempFSFileReferences = [];
-                       }
-                       $object->tempFSFileReferences[] = $this;
-               }
-
-               return $this;
-       }
-
-       /**
-        * Set flag to not clean up after the temporary file
-        *
-        * @return TempFSFile This object
-        */
-       public function preserve() {
-               $this->canDelete = false;
-
-               unset( self::$pathsCollect[$this->path] );
-
-               return $this;
-       }
-
-       /**
-        * Set flag clean up after the temporary file
-        *
-        * @return TempFSFile This object
-        */
-       public function autocollect() {
-               $this->canDelete = true;
-
-               self::$pathsCollect[$this->path] = 1;
-
-               return $this;
-       }
-
-       /**
-        * Try to make sure that all files are purged on error
-        *
-        * This method should only be called internally
-        */
-       public static function purgeAllOnShutdown() {
-               foreach ( self::$pathsCollect as $path ) {
-                       MediaWiki\suppressWarnings();
-                       unlink( $path );
-                       MediaWiki\restoreWarnings();
-               }
-       }
-
-       /**
-        * Cleans up after the temporary file by deleting it
-        */
-       function __destruct() {
-               if ( $this->canDelete ) {
-                       $this->purge();
-               }
-       }
-}
diff --git a/includes/libs/filebackend/fsfile/FSFile.php b/includes/libs/filebackend/fsfile/FSFile.php
new file mode 100644 (file)
index 0000000..dacad1c
--- /dev/null
@@ -0,0 +1,223 @@
+<?php
+/**
+ * Non-directory file on the file system.
+ *
+ * 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 FileBackend
+ */
+
+/**
+ * Class representing a non-directory file on the file system
+ *
+ * @ingroup FileBackend
+ */
+class FSFile {
+       /** @var string Path to file */
+       protected $path;
+
+       /** @var string File SHA-1 in base 36 */
+       protected $sha1Base36;
+
+       /**
+        * Sets up the file object
+        *
+        * @param string $path Path to temporary file on local disk
+        */
+       public function __construct( $path ) {
+               $this->path = $path;
+       }
+
+       /**
+        * Returns the file system path
+        *
+        * @return string
+        */
+       public function getPath() {
+               return $this->path;
+       }
+
+       /**
+        * Checks if the file exists
+        *
+        * @return bool
+        */
+       public function exists() {
+               return is_file( $this->path );
+       }
+
+       /**
+        * Get the file size in bytes
+        *
+        * @return int|bool
+        */
+       public function getSize() {
+               return filesize( $this->path );
+       }
+
+       /**
+        * Get the file's last-modified timestamp
+        *
+        * @return string|bool TS_MW timestamp or false on failure
+        */
+       public function getTimestamp() {
+               MediaWiki\suppressWarnings();
+               $timestamp = filemtime( $this->path );
+               MediaWiki\restoreWarnings();
+               if ( $timestamp !== false ) {
+                       $timestamp = wfTimestamp( TS_MW, $timestamp );
+               }
+
+               return $timestamp;
+       }
+
+       /**
+        * Get an associative array containing information about
+        * a file with the given storage path.
+        *
+        * Resulting array fields include:
+        *   - fileExists
+        *   - size (filesize in bytes)
+        *   - mime (as major/minor)
+        *   - file-mime (as major/minor)
+        *   - sha1 (in base 36)
+        *   - major_mime
+        *   - minor_mime
+        *
+        * @param string|bool $ext The file extension, or true to extract it from the filename.
+        *             Set it to false to ignore the extension. Currently unused.
+        * @return array
+        */
+       public function getProps( $ext = true ) {
+               $info = self::placeholderProps();
+               $info['fileExists'] = $this->exists();
+
+               if ( $info['fileExists'] ) {
+                       $info['size'] = $this->getSize(); // bytes
+                       $info['sha1'] = $this->getSha1Base36();
+
+                       $mime = mime_content_type( $this->path );
+                       # MIME type according to file contents
+                       $info['file-mime'] = ( $mime === false ) ? 'unknown/unknown' : $mime;
+                       # logical MIME type
+                       $info['mime'] = $mime;
+
+                       if ( strpos( $mime, '/' ) !== false ) {
+                               list( $info['major_mime'], $info['minor_mime'] ) = explode( '/', $mime, 2 );
+                       } else {
+                               list( $info['major_mime'], $info['minor_mime'] ) = [ $mime, 'unknown' ];
+                       }
+               }
+
+               return $info;
+       }
+
+       /**
+        * Placeholder file properties to use for files that don't exist
+        *
+        * Resulting array fields include:
+        *   - fileExists
+        *   - size (filesize in bytes)
+        *   - mime (as major/minor)
+        *   - file-mime (as major/minor)
+        *   - sha1 (in base 36)
+        *   - major_mime
+        *   - minor_mime
+        *
+        * @return array
+        */
+       public static function placeholderProps() {
+               $info = [];
+               $info['fileExists'] = false;
+               $info['size'] = 0;
+               $info['file-mime'] = null;
+               $info['major_mime'] = null;
+               $info['minor_mime'] = null;
+               $info['mime'] = null;
+               $info['sha1'] = '';
+
+               return $info;
+       }
+
+       /**
+        * Get a SHA-1 hash of a file in the local filesystem, in base-36 lower case
+        * encoding, zero padded to 31 digits.
+        *
+        * 160 log 2 / log 36 = 30.95, so the 160-bit hash fills 31 digits in base 36
+        * fairly neatly.
+        *
+        * @param bool $recache
+        * @return bool|string False on failure
+        */
+       public function getSha1Base36( $recache = false ) {
+               if ( $this->sha1Base36 !== null && !$recache ) {
+                       return $this->sha1Base36;
+               }
+
+               MediaWiki\suppressWarnings();
+               $this->sha1Base36 = sha1_file( $this->path );
+               MediaWiki\restoreWarnings();
+
+               if ( $this->sha1Base36 !== false ) {
+                       $this->sha1Base36 = Wikimedia\base_convert( $this->sha1Base36, 16, 36, 31 );
+               }
+
+               return $this->sha1Base36;
+       }
+
+       /**
+        * Get the final file extension from a file system path
+        *
+        * @param string $path
+        * @return string
+        */
+       public static function extensionFromPath( $path ) {
+               $i = strrpos( $path, '.' );
+
+               return strtolower( $i ? substr( $path, $i + 1 ) : '' );
+       }
+
+       /**
+        * Get an associative array containing information about a file in the local filesystem.
+        *
+        * @param string $path Absolute local filesystem path
+        * @param string|bool $ext The file extension, or true to extract it from the filename.
+        *   Set it to false to ignore the extension.
+        * @return array
+        */
+       public static function getPropsFromPath( $path, $ext = true ) {
+               $fsFile = new self( $path );
+
+               return $fsFile->getProps( $ext );
+       }
+
+       /**
+        * Get a SHA-1 hash of a file in the local filesystem, in base-36 lower case
+        * encoding, zero padded to 31 digits.
+        *
+        * 160 log 2 / log 36 = 30.95, so the 160-bit hash fills 31 digits in base 36
+        * fairly neatly.
+        *
+        * @param string $path
+        * @return bool|string False on failure
+        */
+       public static function getSha1Base36FromPath( $path ) {
+               $fsFile = new self( $path );
+
+               return $fsFile->getSha1Base36();
+       }
+}
diff --git a/includes/libs/filebackend/fsfile/TempFSFile.php b/includes/libs/filebackend/fsfile/TempFSFile.php
new file mode 100644 (file)
index 0000000..fed6812
--- /dev/null
@@ -0,0 +1,196 @@
+<?php
+/**
+ * Location holder of files stored temporarily
+ *
+ * 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 FileBackend
+ */
+
+/**
+ * This class is used to hold the location and do limited manipulation
+ * of files stored temporarily (this will be whatever wfTempDir() returns)
+ *
+ * @ingroup FileBackend
+ */
+class TempFSFile extends FSFile {
+       /** @var bool Garbage collect the temp file */
+       protected $canDelete = false;
+
+       /** @var array Map of (path => 1) for paths to delete on shutdown */
+       protected static $pathsCollect = null;
+
+       public function __construct( $path ) {
+               parent::__construct( $path );
+
+               if ( self::$pathsCollect === null ) {
+                       self::$pathsCollect = [];
+                       register_shutdown_function( [ __CLASS__, 'purgeAllOnShutdown' ] );
+               }
+       }
+
+       /**
+        * Make a new temporary file on the file system.
+        * Temporary files may be purged when the file object falls out of scope.
+        *
+        * @param string $prefix
+        * @param string $extension Optional file extension
+        * @param string|null $tmpDirectory Optional parent directory
+        * @return TempFSFile|null
+        */
+       public static function factory( $prefix, $extension = '', $tmpDirectory = null ) {
+               $ext = ( $extension != '' ) ? ".{$extension}" : '';
+
+               $attempts = 5;
+               while ( $attempts-- ) {
+                       $hex = sprintf( '%06x%06x', mt_rand( 0, 0xffffff ), mt_rand( 0, 0xffffff ) );
+                       if ( !is_string( $tmpDirectory ) ) {
+                               $tmpDirectory = self::getUsableTempDirectory();
+                       }
+                       $path = wfTempDir() . '/' . $prefix . $hex . $ext;
+                       MediaWiki\suppressWarnings();
+                       $newFileHandle = fopen( $path, 'x' );
+                       MediaWiki\restoreWarnings();
+                       if ( $newFileHandle ) {
+                               fclose( $newFileHandle );
+                               $tmpFile = new self( $path );
+                               $tmpFile->autocollect();
+                               // Safely instantiated, end loop.
+                               return $tmpFile;
+                       }
+               }
+
+               // Give up
+               return null;
+       }
+
+       /**
+        * @return string Filesystem path to a temporary directory
+        * @throws RuntimeException
+        */
+       public static function getUsableTempDirectory() {
+               $tmpDir = array_map( 'getenv', [ 'TMPDIR', 'TMP', 'TEMP' ] );
+               $tmpDir[] = sys_get_temp_dir();
+               $tmpDir[] = ini_get( 'upload_tmp_dir' );
+               foreach ( $tmpDir as $tmp ) {
+                       if ( $tmp != '' && is_dir( $tmp ) && is_writable( $tmp ) ) {
+                               return $tmp;
+                       }
+               }
+
+               // PHP on Windows will detect C:\Windows\Temp as not writable even though PHP can write to
+               // it so create a directory within that called 'mwtmp' with a suffix of the user running
+               // the current process.
+               // The user is included as if various scripts are run by different users they will likely
+               // not be able to access each others temporary files.
+               if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
+                       $tmp = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'mwtmp-' . get_current_user();
+                       if ( !file_exists( $tmp ) ) {
+                               mkdir( $tmp );
+                       }
+                       if ( is_dir( $tmp ) && is_writable( $tmp ) ) {
+                               return $tmp;
+                       }
+               }
+
+               throw new RuntimeException(
+                       'No writable temporary directory could be found. ' .
+                       'Please explicitly specify a writable directory in configuration.' );
+       }
+
+       /**
+        * Purge this file off the file system
+        *
+        * @return bool Success
+        */
+       public function purge() {
+               $this->canDelete = false; // done
+               MediaWiki\suppressWarnings();
+               $ok = unlink( $this->path );
+               MediaWiki\restoreWarnings();
+
+               unset( self::$pathsCollect[$this->path] );
+
+               return $ok;
+       }
+
+       /**
+        * Clean up the temporary file only after an object goes out of scope
+        *
+        * @param object $object
+        * @return TempFSFile This object
+        */
+       public function bind( $object ) {
+               if ( is_object( $object ) ) {
+                       if ( !isset( $object->tempFSFileReferences ) ) {
+                               // Init first since $object might use __get() and return only a copy variable
+                               $object->tempFSFileReferences = [];
+                       }
+                       $object->tempFSFileReferences[] = $this;
+               }
+
+               return $this;
+       }
+
+       /**
+        * Set flag to not clean up after the temporary file
+        *
+        * @return TempFSFile This object
+        */
+       public function preserve() {
+               $this->canDelete = false;
+
+               unset( self::$pathsCollect[$this->path] );
+
+               return $this;
+       }
+
+       /**
+        * Set flag clean up after the temporary file
+        *
+        * @return TempFSFile This object
+        */
+       public function autocollect() {
+               $this->canDelete = true;
+
+               self::$pathsCollect[$this->path] = 1;
+
+               return $this;
+       }
+
+       /**
+        * Try to make sure that all files are purged on error
+        *
+        * This method should only be called internally
+        */
+       public static function purgeAllOnShutdown() {
+               foreach ( self::$pathsCollect as $path ) {
+                       MediaWiki\suppressWarnings();
+                       unlink( $path );
+                       MediaWiki\restoreWarnings();
+               }
+       }
+
+       /**
+        * Cleans up after the temporary file by deleting it
+        */
+       function __destruct() {
+               if ( $this->canDelete ) {
+                       $this->purge();
+               }
+       }
+}
diff --git a/includes/libs/iterators/IteratorDecorator.php b/includes/libs/iterators/IteratorDecorator.php
new file mode 100644 (file)
index 0000000..c1b5020
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Allows extending classes to decorate an Iterator with
+ * reduced boilerplate.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Maintenance
+ */
+abstract class IteratorDecorator implements Iterator {
+       protected $iterator;
+
+       public function __construct( Iterator $iterator ) {
+               $this->iterator = $iterator;
+       }
+
+       public function current() {
+               return $this->iterator->current();
+       }
+
+       public function key() {
+               return $this->iterator->key();
+       }
+
+       public function next() {
+               $this->iterator->next();
+       }
+
+       public function rewind() {
+               $this->iterator->rewind();
+       }
+
+       public function valid() {
+               return $this->iterator->valid();
+       }
+}
diff --git a/includes/libs/iterators/NotRecursiveIterator.php b/includes/libs/iterators/NotRecursiveIterator.php
new file mode 100644 (file)
index 0000000..52ca61b
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Wraps a non-recursive iterator with methods to be recursive
+ * without children.
+ *
+ * Alternatively wraps a recursive iterator to prevent recursing deeper
+ * than the wrapped iterator.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Maintenance
+ */
+class NotRecursiveIterator extends IteratorDecorator implements RecursiveIterator {
+       public function hasChildren() {
+               return false;
+       }
+
+       public function getChildren() {
+               return null;
+       }
+}
index 99cf399..40f22c5 100644 (file)
@@ -6,9 +6,9 @@
  * Minifies a javascript file using a javascript parser
  *
  * This implements a PHP port of Brendan Eich's Narcissus open source javascript engine (in javascript)
- * References: http://en.wikipedia.org/wiki/Narcissus_(JavaScript_engine)
- * Narcissus sourcecode: http://mxr.mozilla.org/mozilla/source/js/narcissus/
- * JSMinPlus weblog: http://crisp.tweakblogs.net/blog/cat/716
+ * References: https://en.wikipedia.org/wiki/Narcissus_(JavaScript_engine)
+ * Narcissus sourcecode: https://mxr.mozilla.org/mozilla/source/js/narcissus/
+ * JSMinPlus weblog: https://crisp.tweakblogs.net/blog/cat/716
  *
  * Tino Zijdel <crisp@tweakers.net>
  *
@@ -936,7 +936,7 @@ class JSParser
                                {
                                        // <script language="JavaScript"> (without version hints) may need
                                        // automatic semicolon insertion without a newline after do-while.
-                                       // See http://bugzilla.mozilla.org/show_bug.cgi?id=238945.
+                                       // See https://bugzilla.mozilla.org/show_bug.cgi?id=238945.
                                        $this->t->match(OP_SEMICOLON);
                                        return $n;
                                }
index 64a2916..b17b1a0 100644 (file)
@@ -58,7 +58,7 @@ abstract class DBLockManager extends QuorumLockManager {
         *                     - user        : DB user
         *                     - password    : DB user password
         *                     - tablePrefix : DB table prefix
-        *                     - flags       : DB flags (see DatabaseBase)
+        *                     - flags       : DB flags; bitfield of IDatabase::DBO_* constants
         *   - dbsByBucket : Array of 1-16 consecutive integer keys, starting from 0,
         *                   each having an odd-numbered list of DB names (peers) as values.
         *   - lockExpiry  : Lock timeout (seconds) for dropped connections. [optional]
index 42391a0..bee34dc 100644 (file)
@@ -4,6 +4,7 @@
  * @ingroup FileBackend
  */
 use Psr\Log\LoggerInterface;
+use Wikimedia\WaitConditionLoop;
 
 /**
  * Resource locking handling.
@@ -68,6 +69,9 @@ abstract class LockManager {
        const LOCK_UW = 2; // shared lock (for reads used to write elsewhere)
        const LOCK_EX = 3; // exclusive lock (for writes)
 
+       /** @var int Max expected lock expiry in any context */
+       const MAX_LOCK_TTL = 7200; // 2 hours
+
        /**
         * Construct a new instance from configuration
         *
@@ -87,6 +91,11 @@ abstract class LockManager {
                        $this->lockTTL = max( 5 * 60, 2 * (int)$met );
                }
 
+               // Upper bound on how long to keep lock structures around. This is useful when setting
+               // TTLs, as the "lockTTL" value may vary based on CLI mode and app server group. This is
+               // a "safe" value that can be used to avoid clobbering other locks that use high TTLs.
+               $this->lockTTL = min( $this->lockTTL, self::MAX_LOCK_TTL );
+
                $random = [];
                for ( $i = 1; $i <= 5; ++$i ) {
                        $random[] = mt_rand( 0, 0xFFFFFFF );
diff --git a/includes/libs/lockmanager/MemcLockManager.php b/includes/libs/lockmanager/MemcLockManager.php
new file mode 100644 (file)
index 0000000..aecdf60
--- /dev/null
@@ -0,0 +1,356 @@
+<?php
+/**
+ * Version of LockManager based on using memcached servers.
+ *
+ * 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 LockManager
+ */
+use Wikimedia\WaitConditionLoop;
+
+/**
+ * Manage locks using memcached servers.
+ *
+ * Version of LockManager based on using memcached servers.
+ * This is meant for multi-wiki systems that may share files.
+ * All locks are non-blocking, which avoids deadlocks.
+ *
+ * All lock requests for a resource, identified by a hash string, will map to one
+ * bucket. Each bucket maps to one or several peer servers, each running memcached.
+ * A majority of peers must agree for a lock to be acquired.
+ *
+ * @ingroup LockManager
+ * @since 1.20
+ */
+class MemcLockManager extends QuorumLockManager {
+       /** @var array Mapping of lock types to the type actually used */
+       protected $lockTypeMap = [
+               self::LOCK_SH => self::LOCK_SH,
+               self::LOCK_UW => self::LOCK_SH,
+               self::LOCK_EX => self::LOCK_EX
+       ];
+
+       /** @var MemcachedBagOStuff[] Map of (server name => MemcachedBagOStuff) */
+       protected $cacheServers = [];
+       /** @var HashBagOStuff Server status cache */
+       protected $statusCache;
+
+       /**
+        * Construct a new instance from configuration.
+        *
+        * @param array $config Parameters include:
+        *   - lockServers  : Associative array of server names to "<IP>:<port>" strings.
+        *   - srvsByBucket : Array of 1-16 consecutive integer keys, starting from 0,
+        *                    each having an odd-numbered list of server names (peers) as values.
+        *   - memcConfig   : Configuration array for MemcachedBagOStuff::construct() with an
+        *                    additional 'class' parameter specifying which MemcachedBagOStuff
+        *                    subclass to use. The server names will be injected. [optional]
+        * @throws Exception
+        */
+       public function __construct( array $config ) {
+               parent::__construct( $config );
+
+               // Sanitize srvsByBucket config to prevent PHP errors
+               $this->srvsByBucket = array_filter( $config['srvsByBucket'], 'is_array' );
+               $this->srvsByBucket = array_values( $this->srvsByBucket ); // consecutive
+
+               $memcConfig = isset( $config['memcConfig'] ) ? $config['memcConfig'] : [];
+               $memcConfig += [ 'class' => 'MemcachedPhpBagOStuff' ]; // default
+
+               $class = $memcConfig['class'];
+               if ( !is_subclass_of( $class, 'MemcachedBagOStuff' ) ) {
+                       throw new InvalidArgumentException( "$class is not of type MemcachedBagOStuff." );
+               }
+
+               foreach ( $config['lockServers'] as $name => $address ) {
+                       $params = [ 'servers' => [ $address ] ] + $memcConfig;
+                       $this->cacheServers[$name] = new $class( $params );
+               }
+
+               $this->statusCache = new HashBagOStuff();
+       }
+
+       protected function getLocksOnServer( $lockSrv, array $pathsByType ) {
+               $status = StatusValue::newGood();
+
+               $memc = $this->getCache( $lockSrv );
+               // List of affected paths
+               $paths = call_user_func_array( 'array_merge', array_values( $pathsByType ) );
+               $paths = array_unique( $paths );
+               // List of affected lock record keys
+               $keys = array_map( [ $this, 'recordKeyForPath' ], $paths );
+
+               // Lock all of the active lock record keys...
+               if ( !$this->acquireMutexes( $memc, $keys ) ) {
+                       foreach ( $paths as $path ) {
+                               $status->fatal( 'lockmanager-fail-acquirelock', $path );
+                       }
+
+                       return $status;
+               }
+
+               // Fetch all the existing lock records...
+               $lockRecords = $memc->getMulti( $keys );
+
+               $now = time();
+               // Check if the requested locks conflict with existing ones...
+               foreach ( $pathsByType as $type => $paths ) {
+                       foreach ( $paths as $path ) {
+                               $locksKey = $this->recordKeyForPath( $path );
+                               $locksHeld = isset( $lockRecords[$locksKey] )
+                                       ? self::sanitizeLockArray( $lockRecords[$locksKey] )
+                                       : self::newLockArray(); // init
+                               foreach ( $locksHeld[self::LOCK_EX] as $session => $expiry ) {
+                                       if ( $expiry < $now ) { // stale?
+                                               unset( $locksHeld[self::LOCK_EX][$session] );
+                                       } elseif ( $session !== $this->session ) {
+                                               $status->fatal( 'lockmanager-fail-acquirelock', $path );
+                                       }
+                               }
+                               if ( $type === self::LOCK_EX ) {
+                                       foreach ( $locksHeld[self::LOCK_SH] as $session => $expiry ) {
+                                               if ( $expiry < $now ) { // stale?
+                                                       unset( $locksHeld[self::LOCK_SH][$session] );
+                                               } elseif ( $session !== $this->session ) {
+                                                       $status->fatal( 'lockmanager-fail-acquirelock', $path );
+                                               }
+                                       }
+                               }
+                               if ( $status->isOK() ) {
+                                       // Register the session in the lock record array
+                                       $locksHeld[$type][$this->session] = $now + $this->lockTTL;
+                                       // We will update this record if none of the other locks conflict
+                                       $lockRecords[$locksKey] = $locksHeld;
+                               }
+                       }
+               }
+
+               // If there were no lock conflicts, update all the lock records...
+               if ( $status->isOK() ) {
+                       foreach ( $paths as $path ) {
+                               $locksKey = $this->recordKeyForPath( $path );
+                               $locksHeld = $lockRecords[$locksKey];
+                               $ok = $memc->set( $locksKey, $locksHeld, self::MAX_LOCK_TTL );
+                               if ( !$ok ) {
+                                       $status->fatal( 'lockmanager-fail-acquirelock', $path );
+                               } else {
+                                       $this->logger->debug( __METHOD__ . ": acquired lock on key $locksKey.\n" );
+                               }
+                       }
+               }
+
+               // Unlock all of the active lock record keys...
+               $this->releaseMutexes( $memc, $keys );
+
+               return $status;
+       }
+
+       protected function freeLocksOnServer( $lockSrv, array $pathsByType ) {
+               $status = StatusValue::newGood();
+
+               $memc = $this->getCache( $lockSrv );
+               // List of affected paths
+               $paths = call_user_func_array( 'array_merge', array_values( $pathsByType ) );
+               $paths = array_unique( $paths );
+               // List of affected lock record keys
+               $keys = array_map( [ $this, 'recordKeyForPath' ], $paths );
+
+               // Lock all of the active lock record keys...
+               if ( !$this->acquireMutexes( $memc, $keys ) ) {
+                       foreach ( $paths as $path ) {
+                               $status->fatal( 'lockmanager-fail-releaselock', $path );
+                       }
+
+                       return $status;
+               }
+
+               // Fetch all the existing lock records...
+               $lockRecords = $memc->getMulti( $keys );
+
+               // Remove the requested locks from all records...
+               foreach ( $pathsByType as $type => $paths ) {
+                       foreach ( $paths as $path ) {
+                               $locksKey = $this->recordKeyForPath( $path ); // lock record
+                               if ( !isset( $lockRecords[$locksKey] ) ) {
+                                       $status->warning( 'lockmanager-fail-releaselock', $path );
+                                       continue; // nothing to do
+                               }
+                               $locksHeld = $this->sanitizeLockArray( $lockRecords[$locksKey] );
+                               if ( isset( $locksHeld[$type][$this->session] ) ) {
+                                       unset( $locksHeld[$type][$this->session] ); // unregister this session
+                                       $lockRecords[$locksKey] = $locksHeld;
+                               } else {
+                                       $status->warning( 'lockmanager-fail-releaselock', $path );
+                               }
+                       }
+               }
+
+               // Persist the new lock record values...
+               foreach ( $paths as $path ) {
+                       $locksKey = $this->recordKeyForPath( $path );
+                       if ( !isset( $lockRecords[$locksKey] ) ) {
+                               continue; // nothing to do
+                       }
+                       $locksHeld = $lockRecords[$locksKey];
+                       if ( $locksHeld === $this->newLockArray() ) {
+                               $ok = $memc->delete( $locksKey );
+                       } else {
+                               $ok = $memc->set( $locksKey, $locksHeld, self::MAX_LOCK_TTL );
+                       }
+                       if ( $ok ) {
+                               $this->logger->debug( __METHOD__ . ": released lock on key $locksKey.\n" );
+                       } else {
+                               $status->fatal( 'lockmanager-fail-releaselock', $path );
+                       }
+               }
+
+               // Unlock all of the active lock record keys...
+               $this->releaseMutexes( $memc, $keys );
+
+               return $status;
+       }
+
+       /**
+        * @see QuorumLockManager::releaseAllLocks()
+        * @return StatusValue
+        */
+       protected function releaseAllLocks() {
+               return StatusValue::newGood(); // not supported
+       }
+
+       /**
+        * @see QuorumLockManager::isServerUp()
+        * @param string $lockSrv
+        * @return bool
+        */
+       protected function isServerUp( $lockSrv ) {
+               return (bool)$this->getCache( $lockSrv );
+       }
+
+       /**
+        * Get the MemcachedBagOStuff object for a $lockSrv
+        *
+        * @param string $lockSrv Server name
+        * @return MemcachedBagOStuff|null
+        */
+       protected function getCache( $lockSrv ) {
+               if ( !isset( $this->cacheServers[$lockSrv] ) ) {
+                       throw new InvalidArgumentException( "Invalid cache server '$lockSrv'." );
+               }
+
+               $online = $this->statusCache->get( "online:$lockSrv" );
+               if ( $online === false ) {
+                       $online = $this->cacheServers[$lockSrv]->set( __CLASS__ . ':ping', 1, 1 );
+                       if ( !$online ) { // server down?
+                               $this->logger->warning( __METHOD__ . ": Could not contact $lockSrv." );
+                       }
+                       $this->statusCache->set( "online:$lockSrv", (int)$online, 30 );
+               }
+
+               return $online ? $this->cacheServers[$lockSrv] : null;
+       }
+
+       /**
+        * @param string $path
+        * @return string
+        */
+       protected function recordKeyForPath( $path ) {
+               return implode( ':', [ __CLASS__, 'locks', $this->sha1Base36Absolute( $path ) ] );
+       }
+
+       /**
+        * @return array An empty lock structure for a key
+        */
+       protected function newLockArray() {
+               return [ self::LOCK_SH => [], self::LOCK_EX => [] ];
+       }
+
+       /**
+        * @param array $a
+        * @return array An empty lock structure for a key
+        */
+       protected function sanitizeLockArray( $a ) {
+               if ( is_array( $a ) && isset( $a[self::LOCK_EX] ) && isset( $a[self::LOCK_SH] ) ) {
+                       return $a;
+               }
+
+               $this->logger->error( __METHOD__ . ": reset invalid lock array." );
+
+               return $this->newLockArray();
+       }
+
+       /**
+        * @param MemcachedBagOStuff $memc
+        * @param array $keys List of keys to acquire
+        * @return bool
+        */
+       protected function acquireMutexes( MemcachedBagOStuff $memc, array $keys ) {
+               $lockedKeys = [];
+
+               // Acquire the keys in lexicographical order, to avoid deadlock problems.
+               // If P1 is waiting to acquire a key P2 has, P2 can't also be waiting for a key P1 has.
+               sort( $keys );
+
+               // Try to quickly loop to acquire the keys, but back off after a few rounds.
+               // This reduces memcached spam, especially in the rare case where a server acquires
+               // some lock keys and dies without releasing them. Lock keys expire after a few minutes.
+               $loop = new WaitConditionLoop(
+                       function () use ( $memc, $keys, &$lockedKeys ) {
+                               foreach ( array_diff( $keys, $lockedKeys ) as $key ) {
+                                       if ( $memc->add( "$key:mutex", 1, 180 ) ) { // lock record
+                                               $lockedKeys[] = $key;
+                                       }
+                               }
+
+                               return array_diff( $keys, $lockedKeys )
+                                       ? WaitConditionLoop::CONDITION_CONTINUE
+                                       : true;
+                       },
+                       3.0 // timeout
+               );
+               $loop->invoke();
+
+               if ( count( $lockedKeys ) != count( $keys ) ) {
+                       $this->releaseMutexes( $memc, $lockedKeys ); // failed; release what was locked
+                       return false;
+               }
+
+               return true;
+       }
+
+       /**
+        * @param MemcachedBagOStuff $memc
+        * @param array $keys List of acquired keys
+        */
+       protected function releaseMutexes( MemcachedBagOStuff $memc, array $keys ) {
+               foreach ( $keys as $key ) {
+                       $memc->delete( "$key:mutex" );
+               }
+       }
+
+       /**
+        * Make sure remaining locks get cleared for sanity
+        */
+       function __destruct() {
+               while ( count( $this->locksHeld ) ) {
+                       foreach ( $this->locksHeld as $path => $locks ) {
+                               $this->doUnlock( [ $path ], self::LOCK_EX );
+                               $this->doUnlock( [ $path ], self::LOCK_SH );
+                       }
+               }
+       }
+}
index 8b5e7fd..a89d864 100644 (file)
@@ -33,7 +33,7 @@ abstract class QuorumLockManager extends LockManager {
        protected $srvsByBucket = []; // (bucket index => (lsrv1, lsrv2, ...))
 
        /** @var array Map of degraded buckets */
-       protected $degradedBuckets = []; // (buckey index => UNIX timestamp)
+       protected $degradedBuckets = []; // (bucket index => UNIX timestamp)
 
        final protected function doLock( array $paths, $type ) {
                return $this->doLockByType( [ $type => $paths ] );
index 6001705..ea9dde7 100644 (file)
@@ -102,7 +102,7 @@ class RedisLockManager extends QuorumLockManager {
 <<<LUA
                        local failed = {}
                        -- Load input params (e.g. session, ttl, time of request)
-                       local rSession, rTTL, rTime = unpack(ARGV)
+                       local rSession, rTTL, rMaxTTL, rTime = unpack(ARGV)
                        -- Check that all the locks can be acquired
                        for i,requestKey in ipairs(KEYS) do
                                local _, _, rType, resourceKey = string.find(requestKey,"(%w+):(%w+)$")
@@ -133,7 +133,7 @@ class RedisLockManager extends QuorumLockManager {
                                        local _, _, rType, resourceKey = string.find(requestKey,"(%w+):(%w+)$")
                                        redis.call('hSet',resourceKey,rType .. ':' .. rSession,rTime + rTTL)
                                        -- In addition to invalidation logic, be sure to garbage collect
-                                       redis.call('expire',resourceKey,rTTL)
+                                       redis.call('expire',resourceKey,rMaxTTL)
                                end
                        end
                        return failed
@@ -144,7 +144,8 @@ LUA;
                                        [
                                                $this->session, // ARGV[1]
                                                $this->lockTTL, // ARGV[2]
-                                               time() // ARGV[3]
+                                               self::MAX_LOCK_TTL, // ARGV[3]
+                                               time() // ARGV[4]
                                        ]
                                ),
                                count( $pathsByKey ) # number of first argument(s) that are keys
diff --git a/includes/libs/mime/IEContentAnalyzer.php b/includes/libs/mime/IEContentAnalyzer.php
new file mode 100644 (file)
index 0000000..0d1e527
--- /dev/null
@@ -0,0 +1,851 @@
+<?php
+/**
+ * Simulation of Microsoft Internet Explorer's MIME type detection algorithm.
+ *
+ * @file
+ * @todo Define the exact license of this file.
+ */
+
+/**
+ * This class simulates Microsoft Internet Explorer's terribly broken and
+ * insecure MIME type detection algorithm. It can be used to check web uploads
+ * with an apparently safe type, to see if IE will reinterpret them to produce
+ * something dangerous.
+ *
+ * It is full of bugs and strange design choices should not under any
+ * circumstances be used to determine a MIME type to present to a user or
+ * client. (Apple Safari developers, this means you too.)
+ *
+ * This class is based on a disassembly of IE 5.0, 6.0 and 7.0. Although I have
+ * attempted to ensure that this code works in exactly the same way as Internet
+ * Explorer, it does not share any source code, or creative choices such as
+ * variable names, thus I (Tim Starling) claim copyright on it.
+ *
+ * It may be redistributed without restriction. To aid reuse, this class does
+ * not depend on any MediaWiki module.
+ */
+class IEContentAnalyzer {
+       /**
+        * Relevant data taken from the type table in IE 5
+        */
+       protected $baseTypeTable = [
+               'ambiguous' /*1*/ => [
+                       'text/plain',
+                       'application/octet-stream',
+                       'application/x-netcdf', // [sic]
+               ],
+               'text' /*3*/ => [
+                       'text/richtext', 'image/x-bitmap', 'application/postscript', 'application/base64',
+                       'application/macbinhex40', 'application/x-cdf', 'text/scriptlet'
+               ],
+               'binary' /*4*/ => [
+                       'application/pdf', 'audio/x-aiff', 'audio/basic', 'audio/wav', 'image/gif',
+                       'image/pjpeg', 'image/jpeg', 'image/tiff', 'image/x-png', 'image/png', 'image/bmp',
+                       'image/x-jg', 'image/x-art', 'image/x-emf', 'image/x-wmf', 'video/avi',
+                       'video/x-msvideo', 'video/mpeg', 'application/x-compressed',
+                       'application/x-zip-compressed', 'application/x-gzip-compressed', 'application/java',
+                       'application/x-msdownload'
+               ],
+               'html' /*5*/ => [ 'text/html' ],
+       ];
+
+       /**
+        * Changes to the type table in later versions of IE
+        */
+       protected $addedTypes = [
+               'ie07' => [
+                       'text' => [ 'text/xml', 'application/xml' ]
+               ],
+       ];
+
+       /**
+        * An approximation of the "Content Type" values in HKEY_CLASSES_ROOT in a
+        * typical Windows installation.
+        *
+        * Used for extension to MIME type mapping if detection fails.
+        */
+       protected $registry = [
+               '.323' => 'text/h323',
+               '.3g2' => 'video/3gpp2',
+               '.3gp' => 'video/3gpp',
+               '.3gp2' => 'video/3gpp2',
+               '.3gpp' => 'video/3gpp',
+               '.aac' => 'audio/aac',
+               '.ac3' => 'audio/ac3',
+               '.accda' => 'application/msaccess',
+               '.accdb' => 'application/msaccess',
+               '.accdc' => 'application/msaccess',
+               '.accde' => 'application/msaccess',
+               '.accdr' => 'application/msaccess',
+               '.accdt' => 'application/msaccess',
+               '.ade' => 'application/msaccess',
+               '.adp' => 'application/msaccess',
+               '.adts' => 'audio/aac',
+               '.ai' => 'application/postscript',
+               '.aif' => 'audio/aiff',
+               '.aifc' => 'audio/aiff',
+               '.aiff' => 'audio/aiff',
+               '.amc' => 'application/x-mpeg',
+               '.application' => 'application/x-ms-application',
+               '.asf' => 'video/x-ms-asf',
+               '.asx' => 'video/x-ms-asf',
+               '.au' => 'audio/basic',
+               '.avi' => 'video/avi',
+               '.bmp' => 'image/bmp',
+               '.caf' => 'audio/x-caf',
+               '.cat' => 'application/vnd.ms-pki.seccat',
+               '.cbo' => 'application/sha',
+               '.cdda' => 'audio/aiff',
+               '.cer' => 'application/x-x509-ca-cert',
+               '.conf' => 'text/plain',
+               '.crl' => 'application/pkix-crl',
+               '.crt' => 'application/x-x509-ca-cert',
+               '.css' => 'text/css',
+               '.csv' => 'application/vnd.ms-excel',
+               '.der' => 'application/x-x509-ca-cert',
+               '.dib' => 'image/bmp',
+               '.dif' => 'video/x-dv',
+               '.dll' => 'application/x-msdownload',
+               '.doc' => 'application/msword',
+               '.docm' => 'application/vnd.ms-word.document.macroEnabled.12',
+               '.docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+               '.dot' => 'application/msword',
+               '.dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
+               '.dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
+               '.dv' => 'video/x-dv',
+               '.dwfx' => 'model/vnd.dwfx+xps',
+               '.edn' => 'application/vnd.adobe.edn',
+               '.eml' => 'message/rfc822',
+               '.eps' => 'application/postscript',
+               '.etd' => 'application/x-ebx',
+               '.exe' => 'application/x-msdownload',
+               '.fdf' => 'application/vnd.fdf',
+               '.fif' => 'application/fractals',
+               '.gif' => 'image/gif',
+               '.gsm' => 'audio/x-gsm',
+               '.hqx' => 'application/mac-binhex40',
+               '.hta' => 'application/hta',
+               '.htc' => 'text/x-component',
+               '.htm' => 'text/html',
+               '.html' => 'text/html',
+               '.htt' => 'text/webviewhtml',
+               '.hxa' => 'application/xml',
+               '.hxc' => 'application/xml',
+               '.hxd' => 'application/octet-stream',
+               '.hxe' => 'application/xml',
+               '.hxf' => 'application/xml',
+               '.hxh' => 'application/octet-stream',
+               '.hxi' => 'application/octet-stream',
+               '.hxk' => 'application/xml',
+               '.hxq' => 'application/octet-stream',
+               '.hxr' => 'application/octet-stream',
+               '.hxs' => 'application/octet-stream',
+               '.hxt' => 'application/xml',
+               '.hxv' => 'application/xml',
+               '.hxw' => 'application/octet-stream',
+               '.ico' => 'image/x-icon',
+               '.iii' => 'application/x-iphone',
+               '.ins' => 'application/x-internet-signup',
+               '.iqy' => 'text/x-ms-iqy',
+               '.isp' => 'application/x-internet-signup',
+               '.jfif' => 'image/jpeg',
+               '.jnlp' => 'application/x-java-jnlp-file',
+               '.jpe' => 'image/jpeg',
+               '.jpeg' => 'image/jpeg',
+               '.jpg' => 'image/jpeg',
+               '.jtx' => 'application/x-jtx+xps',
+               '.latex' => 'application/x-latex',
+               '.log' => 'text/plain',
+               '.m1v' => 'video/mpeg',
+               '.m2v' => 'video/mpeg',
+               '.m3u' => 'audio/x-mpegurl',
+               '.mac' => 'image/x-macpaint',
+               '.man' => 'application/x-troff-man',
+               '.mda' => 'application/msaccess',
+               '.mdb' => 'application/msaccess',
+               '.mde' => 'application/msaccess',
+               '.mfp' => 'application/x-shockwave-flash',
+               '.mht' => 'message/rfc822',
+               '.mhtml' => 'message/rfc822',
+               '.mid' => 'audio/mid',
+               '.midi' => 'audio/mid',
+               '.mod' => 'video/mpeg',
+               '.mov' => 'video/quicktime',
+               '.mp2' => 'video/mpeg',
+               '.mp2v' => 'video/mpeg',
+               '.mp3' => 'audio/mpeg',
+               '.mp4' => 'video/mp4',
+               '.mpa' => 'video/mpeg',
+               '.mpe' => 'video/mpeg',
+               '.mpeg' => 'video/mpeg',
+               '.mpf' => 'application/vnd.ms-mediapackage',
+               '.mpg' => 'video/mpeg',
+               '.mpv2' => 'video/mpeg',
+               '.mqv' => 'video/quicktime',
+               '.NMW' => 'application/nmwb',
+               '.nws' => 'message/rfc822',
+               '.odc' => 'text/x-ms-odc',
+               '.ols' => 'application/vnd.ms-publisher',
+               '.p10' => 'application/pkcs10',
+               '.p12' => 'application/x-pkcs12',
+               '.p7b' => 'application/x-pkcs7-certificates',
+               '.p7c' => 'application/pkcs7-mime',
+               '.p7m' => 'application/pkcs7-mime',
+               '.p7r' => 'application/x-pkcs7-certreqresp',
+               '.p7s' => 'application/pkcs7-signature',
+               '.pct' => 'image/pict',
+               '.pdf' => 'application/pdf',
+               '.pdx' => 'application/vnd.adobe.pdx',
+               '.pfx' => 'application/x-pkcs12',
+               '.pic' => 'image/pict',
+               '.pict' => 'image/pict',
+               '.pinstall' => 'application/x-picasa-detect',
+               '.pko' => 'application/vnd.ms-pki.pko',
+               '.png' => 'image/png',
+               '.pnt' => 'image/x-macpaint',
+               '.pntg' => 'image/x-macpaint',
+               '.pot' => 'application/vnd.ms-powerpoint',
+               '.potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
+               '.potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
+               '.ppa' => 'application/vnd.ms-powerpoint',
+               '.ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
+               '.pps' => 'application/vnd.ms-powerpoint',
+               '.ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
+               '.ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
+               '.ppt' => 'application/vnd.ms-powerpoint',
+               '.pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
+               '.pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+               '.prf' => 'application/pics-rules',
+               '.ps' => 'application/postscript',
+               '.pub' => 'application/vnd.ms-publisher',
+               '.pwz' => 'application/vnd.ms-powerpoint',
+               '.py' => 'text/plain',
+               '.pyw' => 'text/plain',
+               '.qht' => 'text/x-html-insertion',
+               '.qhtm' => 'text/x-html-insertion',
+               '.qt' => 'video/quicktime',
+               '.qti' => 'image/x-quicktime',
+               '.qtif' => 'image/x-quicktime',
+               '.qtl' => 'application/x-quicktimeplayer',
+               '.rat' => 'application/rat-file',
+               '.rmf' => 'application/vnd.adobe.rmf',
+               '.rmi' => 'audio/mid',
+               '.rqy' => 'text/x-ms-rqy',
+               '.rtf' => 'application/msword',
+               '.sct' => 'text/scriptlet',
+               '.sd2' => 'audio/x-sd2',
+               '.sdp' => 'application/sdp',
+               '.shtml' => 'text/html',
+               '.sit' => 'application/x-stuffit',
+               '.sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12',
+               '.sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
+               '.slk' => 'application/vnd.ms-excel',
+               '.snd' => 'audio/basic',
+               '.so' => 'application/x-apachemodule',
+               '.sol' => 'text/plain',
+               '.sor' => 'text/plain',
+               '.spc' => 'application/x-pkcs7-certificates',
+               '.spl' => 'application/futuresplash',
+               '.sst' => 'application/vnd.ms-pki.certstore',
+               '.stl' => 'application/vnd.ms-pki.stl',
+               '.swf' => 'application/x-shockwave-flash',
+               '.thmx' => 'application/vnd.ms-officetheme',
+               '.tif' => 'image/tiff',
+               '.tiff' => 'image/tiff',
+               '.txt' => 'text/plain',
+               '.uls' => 'text/iuls',
+               '.vcf' => 'text/x-vcard',
+               '.vdx' => 'application/vnd.ms-visio.viewer',
+               '.vsd' => 'application/vnd.ms-visio.viewer',
+               '.vss' => 'application/vnd.ms-visio.viewer',
+               '.vst' => 'application/vnd.ms-visio.viewer',
+               '.vsx' => 'application/vnd.ms-visio.viewer',
+               '.vtx' => 'application/vnd.ms-visio.viewer',
+               '.wav' => 'audio/wav',
+               '.wax' => 'audio/x-ms-wax',
+               '.wbk' => 'application/msword',
+               '.wdp' => 'image/vnd.ms-photo',
+               '.wiz' => 'application/msword',
+               '.wm' => 'video/x-ms-wm',
+               '.wma' => 'audio/x-ms-wma',
+               '.wmd' => 'application/x-ms-wmd',
+               '.wmv' => 'video/x-ms-wmv',
+               '.wmx' => 'video/x-ms-wmx',
+               '.wmz' => 'application/x-ms-wmz',
+               '.wpl' => 'application/vnd.ms-wpl',
+               '.wsc' => 'text/scriptlet',
+               '.wvx' => 'video/x-ms-wvx',
+               '.xaml' => 'application/xaml+xml',
+               '.xbap' => 'application/x-ms-xbap',
+               '.xdp' => 'application/vnd.adobe.xdp+xml',
+               '.xfdf' => 'application/vnd.adobe.xfdf',
+               '.xht' => 'application/xhtml+xml',
+               '.xhtml' => 'application/xhtml+xml',
+               '.xla' => 'application/vnd.ms-excel',
+               '.xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
+               '.xlk' => 'application/vnd.ms-excel',
+               '.xll' => 'application/vnd.ms-excel',
+               '.xlm' => 'application/vnd.ms-excel',
+               '.xls' => 'application/vnd.ms-excel',
+               '.xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
+               '.xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
+               '.xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+               '.xlt' => 'application/vnd.ms-excel',
+               '.xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
+               '.xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
+               '.xlw' => 'application/vnd.ms-excel',
+               '.xml' => 'text/xml',
+               '.xps' => 'application/vnd.ms-xpsdocument',
+               '.xsl' => 'text/xml',
+       ];
+
+       /**
+        * IE versions which have been analysed to bring you this class, and for
+        * which some substantive difference exists. These will appear as keys
+        * in the return value of getRealMimesFromData(). The names are chosen to sort correctly.
+        */
+       protected $versions = [ 'ie05', 'ie06', 'ie07', 'ie07.strict', 'ie07.nohtml' ];
+
+       /**
+        * Type table with versions expanded
+        */
+       protected $typeTable = [];
+
+       /** constructor */
+       function __construct() {
+               // Construct versioned type arrays from the base type array plus additions
+               $types = $this->baseTypeTable;
+               foreach ( $this->versions as $version ) {
+                       if ( isset( $this->addedTypes[$version] ) ) {
+                               foreach ( $this->addedTypes[$version] as $format => $addedTypes ) {
+                                       $types[$format] = array_merge( $types[$format], $addedTypes );
+                               }
+                       }
+                       $this->typeTable[$version] = $types;
+               }
+       }
+
+       /**
+        * Get the MIME types from getMimesFromData(), but convert the result from IE's
+        * idiosyncratic private types into something other apps will understand.
+        *
+        * @param string $fileName the file name (unused at present)
+        * @param string $chunk the first 256 bytes of the file
+        * @param string $proposed the MIME type proposed by the server
+        *
+        * @return Array: map of IE version to detected MIME type
+        */
+       public function getRealMimesFromData( $fileName, $chunk, $proposed ) {
+               $types = $this->getMimesFromData( $fileName, $chunk, $proposed );
+               $types = array_map( [ $this, 'translateMimeType' ], $types );
+               return $types;
+       }
+
+       /**
+        * Translate a MIME type from IE's idiosyncratic private types into
+        * more commonly understood type strings
+        * @param $type
+        * @return string
+        */
+       public function translateMimeType( $type ) {
+               static $table = [
+                       'image/pjpeg' => 'image/jpeg',
+                       'image/x-png' => 'image/png',
+                       'image/x-wmf' => 'application/x-msmetafile',
+                       'image/bmp' => 'image/x-bmp',
+                       'application/x-zip-compressed' => 'application/zip',
+                       'application/x-compressed' => 'application/x-compress',
+                       'application/x-gzip-compressed' => 'application/x-gzip',
+                       'audio/mid' => 'audio/midi',
+               ];
+               if ( isset( $table[$type] ) ) {
+                       $type = $table[$type];
+               }
+               return $type;
+       }
+
+       /**
+        * Get the untranslated MIME types for all known versions
+        *
+        * @param string $fileName the file name (unused at present)
+        * @param string $chunk the first 256 bytes of the file
+        * @param string $proposed the MIME type proposed by the server
+        *
+        * @return Array: map of IE version to detected MIME type
+        */
+       public function getMimesFromData( $fileName, $chunk, $proposed ) {
+               $types = [];
+               foreach ( $this->versions as $version ) {
+                       $types[$version] = $this->getMimeTypeForVersion( $version, $fileName, $chunk, $proposed );
+               }
+               return $types;
+       }
+
+       /**
+        * Get the MIME type for a given named version
+        * @param $version
+        * @param $fileName
+        * @param $chunk
+        * @param $proposed
+        * @return bool|string
+        */
+       protected function getMimeTypeForVersion( $version, $fileName, $chunk, $proposed ) {
+               // Strip text after a semicolon
+               $semiPos = strpos( $proposed, ';' );
+               if ( $semiPos !== false ) {
+                       $proposed = substr( $proposed, 0, $semiPos );
+               }
+
+               $proposedFormat = $this->getDataFormat( $version, $proposed );
+               if ( $proposedFormat == 'unknown'
+                       && $proposed != 'multipart/mixed'
+                       && $proposed != 'multipart/x-mixed-replace' )
+               {
+                       return $proposed;
+               }
+               if ( strval( $chunk ) === '' ) {
+                       return $proposed;
+               }
+
+               // Truncate chunk at 255 bytes
+               $chunk = substr( $chunk, 0, 255 );
+
+               // IE does the Check*Headers() calls last, and instead does the following image
+               // type checks by directly looking for the magic numbers. What I do here should
+               // have the same effect since the magic number checks are identical in both cases.
+               $result = $this->sampleData( $version, $chunk );
+               $sampleFound = $result['found'];
+               $counters = $result['counters'];
+               $binaryType = $this->checkBinaryHeaders( $version, $chunk );
+               $textType = $this->checkTextHeaders( $version, $chunk );
+
+               if ( $proposed == 'text/html' && isset( $sampleFound['html'] ) ) {
+                       return 'text/html';
+               }
+               if ( $proposed == 'image/gif' && $binaryType == 'image/gif' ) {
+                       return 'image/gif';
+               }
+               if ( ( $proposed == 'image/pjpeg' || $proposed == 'image/jpeg' )
+                       && $binaryType == 'image/pjpeg' )
+               {
+                       return $proposed;
+               }
+               // PNG check added in IE 7
+               if ( $version >= 'ie07'
+                       && ( $proposed == 'image/x-png' || $proposed == 'image/png' )
+                       && $binaryType == 'image/x-png' )
+               {
+                       return $proposed;
+               }
+
+               // CDF was removed in IE 7 so it won't be in $sampleFound for later versions
+               if ( isset( $sampleFound['cdf'] ) ) {
+                       return 'application/x-cdf';
+               }
+
+               // RSS and Atom were added in IE 7 so they won't be in $sampleFound for
+               // previous versions
+               if ( isset( $sampleFound['rss'] ) ) {
+                       return 'application/rss+xml';
+               }
+               if ( isset( $sampleFound['rdf-tag'] )
+                       && isset( $sampleFound['rdf-url'] )
+                       && isset( $sampleFound['rdf-purl'] ) )
+               {
+                       return 'application/rss+xml';
+               }
+               if ( isset( $sampleFound['atom'] ) ) {
+                       return 'application/atom+xml';
+               }
+
+               if ( isset( $sampleFound['xml'] ) ) {
+                       // TODO: I'm not sure under what circumstances this flag is enabled
+                       if ( strpos( $version, 'strict' ) !== false ) {
+                               if ( $proposed == 'text/html' || $proposed == 'text/xml' ) {
+                                       return 'text/xml';
+                               }
+                       } else {
+                               return 'text/xml';
+                       }
+               }
+               if ( isset( $sampleFound['html'] ) ) {
+                       // TODO: I'm not sure under what circumstances this flag is enabled
+                       if ( strpos( $version, 'nohtml' ) !== false ) {
+                               if ( $proposed == 'text/plain' ) {
+                                       return 'text/html';
+                               }
+                       } else {
+                               return 'text/html';
+                       }
+               }
+               if ( isset( $sampleFound['xbm'] ) ) {
+                       return 'image/x-bitmap';
+               }
+               if ( isset( $sampleFound['binhex'] ) ) {
+                       return 'application/macbinhex40';
+               }
+               if ( isset( $sampleFound['scriptlet'] ) ) {
+                       if ( strpos( $version, 'strict' ) !== false ) {
+                               if ( $proposed == 'text/plain' || $proposed == 'text/scriptlet' ) {
+                                       return 'text/scriptlet';
+                               }
+                       } else {
+                               return 'text/scriptlet';
+                       }
+               }
+
+               // Freaky heuristics to determine if the data is text or binary
+               // The heuristic is of course broken for non-ASCII text
+               if ( $counters['ctrl'] != 0 && ( $counters['ff'] + $counters['low'] )
+                       < ( $counters['ctrl'] + $counters['high'] ) * 16 )
+               {
+                       $kindOfBinary = true;
+                       $type = $binaryType ? $binaryType : $textType;
+                       if ( $type === false ) {
+                               $type = 'application/octet-stream';
+                       }
+               } else {
+                       $kindOfBinary = false;
+                       $type = $textType ? $textType : $binaryType;
+                       if ( $type === false ) {
+                               $type = 'text/plain';
+                       }
+               }
+
+               // Check if the output format is ambiguous
+               // This generally means that detection failed, real types aren't ambiguous
+               $detectedFormat = $this->getDataFormat( $version, $type );
+               if ( $detectedFormat != 'ambiguous' ) {
+                       return $type;
+               }
+
+               if ( $proposedFormat != 'ambiguous' ) {
+                       // FormatAgreesWithData()
+                       if ( $proposedFormat == 'text' && !$kindOfBinary ) {
+                               return $proposed;
+                       }
+                       if ( $proposedFormat == 'binary' && $kindOfBinary ) {
+                               return $proposed;
+                       }
+                       if ( $proposedFormat == 'html' ) {
+                               return $proposed;
+                       }
+               }
+
+               // Find a MIME type by searching the registry for the file extension.
+               $dotPos = strrpos( $fileName, '.' );
+               if ( $dotPos === false ) {
+                       return $type;
+               }
+               $ext = substr( $fileName, $dotPos );
+               if ( isset( $this->registry[$ext] ) ) {
+                       return $this->registry[$ext];
+               }
+
+               // TODO: If the extension has an application registered to it, IE will return
+               // application/octet-stream. We'll skip that, so we could erroneously
+               // return text/plain or application/x-netcdf where application/octet-stream
+               // would be correct.
+
+               return $type;
+       }
+
+       /**
+        * Check for text headers at the start of the chunk
+        * Confirmed same in 5 and 7.
+        * @param $version
+        * @param $chunk
+        * @return bool|string
+        */
+       private function checkTextHeaders( $version, $chunk ) {
+               $chunk2 = substr( $chunk, 0, 2 );
+               $chunk4 = substr( $chunk, 0, 4 );
+               $chunk5 = substr( $chunk, 0, 5 );
+               if ( $chunk4 == '%PDF' ) {
+                       return 'application/pdf';
+               }
+               if ( $chunk2 == '%!' ) {
+                       return 'application/postscript';
+               }
+               if ( $chunk5 == '{\\rtf' ) {
+                       return 'text/richtext';
+               }
+               if ( $chunk5 == 'begin' ) {
+                       return 'application/base64';
+               }
+               return false;
+       }
+
+       /**
+        * Check for binary headers at the start of the chunk
+        * Confirmed same in 5 and 7.
+        * @param $version
+        * @param $chunk
+        * @return bool|string
+        */
+       private function checkBinaryHeaders( $version, $chunk ) {
+               $chunk2 = substr( $chunk, 0, 2 );
+               $chunk3 = substr( $chunk, 0, 3 );
+               $chunk4 = substr( $chunk, 0, 4 );
+               $chunk5 = substr( $chunk, 0, 5 );
+               $chunk5uc = strtoupper( $chunk5 );
+               $chunk8 = substr( $chunk, 0, 8 );
+               if ( $chunk5uc == 'GIF87' || $chunk5uc == 'GIF89' ) {
+                       return 'image/gif';
+               }
+               if ( $chunk2 == "\xff\xd8" ) {
+                       return 'image/pjpeg'; // actually plain JPEG but this is what IE returns
+               }
+
+               if ( $chunk2 == 'BM'
+                       && substr( $chunk, 6, 2 ) == "\000\000"
+                       && substr( $chunk, 8, 2 ) == "\000\000" )
+               {
+                       return 'image/bmp'; // another non-standard MIME
+               }
+               if ( $chunk4 == 'RIFF'
+                       && substr( $chunk, 8, 4 ) == 'WAVE' )
+               {
+                       return 'audio/wav';
+               }
+               // These were integer literals in IE
+               // Perhaps the author was not sure what the target endianness was
+               if ( $chunk4 == ".sd\000"
+                       || $chunk4 == ".snd"
+                       || $chunk4 == "\000ds."
+                       || $chunk4 == "dns." )
+               {
+                       return 'audio/basic';
+               }
+               if ( $chunk3 == "MM\000" ) {
+                       return 'image/tiff';
+               }
+               if ( $chunk2 == 'MZ' ) {
+                       return 'application/x-msdownload';
+               }
+               if ( $chunk8 == "\x89PNG\x0d\x0a\x1a\x0a" ) {
+                       return 'image/x-png'; // [sic]
+               }
+               if ( strlen( $chunk ) >= 5 ) {
+                       $byte2 = ord( $chunk[2] );
+                       $byte4 = ord( $chunk[4] );
+                       if ( $byte2 >= 3 && $byte2 <= 31 && $byte4 == 0 && $chunk2 == 'JG' ) {
+                               return 'image/x-jg';
+                       }
+               }
+               // More endian confusion?
+               if ( $chunk4 == 'MROF' ) {
+                       return 'audio/x-aiff';
+               }
+               $chunk4_8 = substr( $chunk, 8, 4 );
+               if ( $chunk4 == 'FORM' && ( $chunk4_8 == 'AIFF' || $chunk4_8 == 'AIFC' ) ) {
+                       return 'audio/x-aiff';
+               }
+               if ( $chunk4 == 'RIFF' && $chunk4_8 == 'AVI ' ) {
+                       return 'video/avi';
+               }
+               if ( $chunk4 == "\x00\x00\x01\xb3" || $chunk4 == "\x00\x00\x01\xba" ) {
+                       return 'video/mpeg';
+               }
+               if ( $chunk4 == "\001\000\000\000"
+                       && substr( $chunk, 40, 4 ) == ' EMF' )
+               {
+                       return 'image/x-emf';
+               }
+               if ( $chunk4 == "\xd7\xcd\xc6\x9a" ) {
+                       return 'image/x-wmf';
+               }
+               if ( $chunk4 == "\xca\xfe\xba\xbe" ) {
+                       return 'application/java';
+               }
+               if ( $chunk2 == 'PK' ) {
+                       return 'application/x-zip-compressed';
+               }
+               if ( $chunk2 == "\x1f\x9d" ) {
+                       return 'application/x-compressed';
+               }
+               if ( $chunk2 == "\x1f\x8b" ) {
+                       return 'application/x-gzip-compressed';
+               }
+               // Skip redundant check for ZIP
+               if ( $chunk5 == "MThd\000" ) {
+                       return 'audio/mid';
+               }
+               if ( $chunk4 == '%PDF' ) {
+                       return 'application/pdf';
+               }
+               return false;
+       }
+
+       /**
+        * Do heuristic checks on the bulk of the data sample.
+        * Search for HTML tags.
+        * @param $version
+        * @param $chunk
+        * @return array
+        */
+       protected function sampleData( $version, $chunk ) {
+               $found = [];
+               $counters = [
+                       'ctrl' => 0,
+                       'high' => 0,
+                       'low' => 0,
+                       'lf' => 0,
+                       'cr' => 0,
+                       'ff' => 0
+               ];
+               $htmlTags = [
+                       'html',
+                       'head',
+                       'title',
+                       'body',
+                       'script',
+                       'a href',
+                       'pre',
+                       'img',
+                       'plaintext',
+                       'table'
+               ];
+               $rdfUrl = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
+               $rdfPurl = 'http://purl.org/rss/1.0/';
+               $xbmMagic1 = '#define';
+               $xbmMagic2 = '_width';
+               $xbmMagic3 = '_bits';
+               $binhexMagic = 'converted with BinHex';
+               $chunkLength = strlen( $chunk );
+
+               for ( $offset = 0; $offset < $chunkLength; $offset++ ) {
+                       $curChar = $chunk[$offset];
+                       if ( $curChar == "\x0a" ) {
+                               $counters['lf']++;
+                               continue;
+                       } elseif ( $curChar == "\x0d" ) {
+                               $counters['cr']++;
+                               continue;
+                       } elseif ( $curChar == "\x0c" ) {
+                               $counters['ff']++;
+                               continue;
+                       } elseif ( $curChar == "\t" ) {
+                               $counters['low']++;
+                               continue;
+                       } elseif ( ord( $curChar ) < 32 ) {
+                               $counters['ctrl']++;
+                               continue;
+                       } elseif ( ord( $curChar ) >= 128 ) {
+                               $counters['high']++;
+                               continue;
+                       }
+
+                       $counters['low']++;
+                       if ( $curChar == '<' ) {
+                               // XML
+                               $remainder = substr( $chunk, $offset + 1 );
+                               if ( !strncasecmp( $remainder, '?XML', 4 ) ) {
+                                       $nextChar = substr( $chunk, $offset + 5, 1 );
+                                       if ( $nextChar == ':' || $nextChar == ' ' || $nextChar == "\t" ) {
+                                               $found['xml'] = true;
+                                       }
+                               }
+                               // Scriptlet (JSP)
+                               if ( !strncasecmp( $remainder, 'SCRIPTLET', 9 ) ) {
+                                       $found['scriptlet'] = true;
+                                       break;
+                               }
+                               // HTML
+                               foreach ( $htmlTags as $tag ) {
+                                       if ( !strncasecmp( $remainder, $tag, strlen( $tag ) ) ) {
+                                               $found['html'] = true;
+                                       }
+                               }
+                               // Skip broken check for additional tags (HR etc.)
+
+                               // CHANNEL replaced by RSS, RDF and FEED in IE 7
+                               if ( $version < 'ie07' ) {
+                                       if ( !strncasecmp( $remainder, 'CHANNEL', 7 ) ) {
+                                               $found['cdf'] = true;
+                                       }
+                               } else {
+                                       // RSS
+                                       if ( !strncasecmp( $remainder, 'RSS', 3 ) ) {
+                                               $found['rss'] = true;
+                                               break; // return from SampleData
+                                       }
+                                       if ( !strncasecmp( $remainder, 'rdf:RDF', 7 ) ) {
+                                               $found['rdf-tag'] = true;
+                                               // no break
+                                       }
+                                       if ( !strncasecmp( $remainder, 'FEED', 4 ) ) {
+                                               $found['atom'] = true;
+                                               break;
+                                       }
+                               }
+                               continue;
+                       }
+                       // Skip broken check for -->
+
+                       // RSS URL checks
+                       // For some reason both URLs must appear before it is recognised
+                       $remainder = substr( $chunk, $offset );
+                       if ( !strncasecmp( $remainder, $rdfUrl, strlen( $rdfUrl ) ) ) {
+                               $found['rdf-url'] = true;
+                               if ( isset( $found['rdf-tag'] )
+                                       && isset( $found['rdf-purl'] ) ) // [sic]
+                               {
+                                       break;
+                               }
+                               continue;
+                       }
+
+                       if ( !strncasecmp( $remainder, $rdfPurl, strlen( $rdfPurl ) ) ) {
+                               if ( isset( $found['rdf-tag'] )
+                                       && isset( $found['rdf-url'] ) ) // [sic]
+                               {
+                                       break;
+                               }
+                               continue;
+                       }
+
+                       // XBM checks
+                       if ( !strncasecmp( $remainder, $xbmMagic1, strlen( $xbmMagic1 ) ) ) {
+                               $found['xbm1'] = true;
+                               continue;
+                       }
+                       if ( $curChar == '_' ) {
+                               if ( isset( $found['xbm2'] ) ) {
+                                       if ( !strncasecmp( $remainder, $xbmMagic3, strlen( $xbmMagic3 ) ) ) {
+                                               $found['xbm'] = true;
+                                               break;
+                                       }
+                               } elseif ( isset( $found['xbm1'] ) ) {
+                                       if ( !strncasecmp( $remainder, $xbmMagic2, strlen( $xbmMagic2 ) ) ) {
+                                               $found['xbm2'] = true;
+                                       }
+                               }
+                       }
+
+                       // BinHex
+                       if ( !strncmp( $remainder, $binhexMagic, strlen( $binhexMagic ) ) ) {
+                               $found['binhex'] = true;
+                       }
+               }
+               return [ 'found' => $found, 'counters' => $counters ];
+       }
+
+       /**
+        * @param $version
+        * @param $type
+        * @return int|string
+        */
+       protected function getDataFormat( $version, $type ) {
+               $types = $this->typeTable[$version];
+               if ( $type == '(null)' || strval( $type ) === '' ) {
+                       return 'ambiguous';
+               }
+               foreach ( $types as $format => $list ) {
+                       if ( in_array( $type, $list ) ) {
+                               return $format;
+                       }
+               }
+               return 'unknown';
+       }
+}
diff --git a/includes/libs/mime/MimeAnalyzer.php b/includes/libs/mime/MimeAnalyzer.php
new file mode 100644 (file)
index 0000000..e42d1a9
--- /dev/null
@@ -0,0 +1,1166 @@
+<?php
+/**
+ * Module defining helper functions for detecting and dealing with MIME types.
+ *
+ * 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
+ */
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Implements functions related to MIME types such as detection and mapping to file extension
+ *
+ * @since 1.28
+ */
+class MimeAnalyzer implements LoggerAwareInterface {
+       /** @var string */
+       protected $typeFile;
+       /** @var string */
+       protected $infoFile;
+       /** @var string */
+       protected $xmlTypes;
+       /** @var callable */
+       protected $initCallback;
+       /** @var callable */
+       protected $detectCallback;
+       /** @var callable */
+       protected $guessCallback;
+       /** @var callable */
+       protected $extCallback;
+       /** @var array Mapping of media types to arrays of MIME types */
+       protected $mediaTypes = null;
+       /** @var array Map of MIME type aliases */
+       protected $mimeTypeAliases = null;
+       /** @var array Map of MIME types to file extensions (as a space separated list) */
+       protected $mimetoExt = null;
+
+       /** @var array Map of file extensions types to MIME types (as a space separated list) */
+       public $mExtToMime = null; // legacy name; field accessed by hooks
+
+       /** @var IEContentAnalyzer */
+       protected $IEAnalyzer;
+
+       /** @var string Extra MIME types, set for example by media handling extensions */
+       private $extraTypes = '';
+       /** @var string Extra MIME info, set for example by media handling extensions */
+       private $extraInfo = '';
+
+       /** @var LoggerInterface */
+       private $logger;
+
+       /**
+        * Defines a set of well known MIME types
+        * This is used as a fallback to mime.types files.
+        * An extensive list of well known MIME types is provided by
+        * the file mime.types in the includes directory.
+        *
+        * This list concatenated with mime.types is used to create a MIME <-> ext
+        * map. Each line contains a MIME type followed by a space separated list of
+        * extensions. If multiple extensions for a single MIME type exist or if
+        * multiple MIME types exist for a single extension then in most cases
+        * MediaWiki assumes that the first extension following the MIME type is the
+        * canonical extension, and the first time a MIME type appears for a certain
+        * extension is considered the canonical MIME type.
+        *
+        * (Note that appending the type file list to the end of self::$wellKnownTypes
+        * sucks because you can't redefine canonical types. This could be fixed by
+        * appending self::$wellKnownTypes behind type file list, but who knows
+        * what will break? In practice this probably isn't a problem anyway -- Bryan)
+        */
+       protected static $wellKnownTypes = <<<EOT
+application/ogg ogx ogg ogm ogv oga spx
+application/pdf pdf
+application/vnd.oasis.opendocument.chart odc
+application/vnd.oasis.opendocument.chart-template otc
+application/vnd.oasis.opendocument.database odb
+application/vnd.oasis.opendocument.formula odf
+application/vnd.oasis.opendocument.formula-template otf
+application/vnd.oasis.opendocument.graphics odg
+application/vnd.oasis.opendocument.graphics-template otg
+application/vnd.oasis.opendocument.image odi
+application/vnd.oasis.opendocument.image-template oti
+application/vnd.oasis.opendocument.presentation odp
+application/vnd.oasis.opendocument.presentation-template otp
+application/vnd.oasis.opendocument.spreadsheet ods
+application/vnd.oasis.opendocument.spreadsheet-template ots
+application/vnd.oasis.opendocument.text odt
+application/vnd.oasis.opendocument.text-master otm
+application/vnd.oasis.opendocument.text-template ott
+application/vnd.oasis.opendocument.text-web oth
+application/javascript js
+application/x-shockwave-flash swf
+audio/midi mid midi kar
+audio/mpeg mpga mpa mp2 mp3
+audio/x-aiff aif aiff aifc
+audio/x-wav wav
+audio/ogg oga spx ogg
+image/x-bmp bmp
+image/gif gif
+image/jpeg jpeg jpg jpe
+image/png png
+image/svg+xml svg
+image/svg svg
+image/tiff tiff tif
+image/vnd.djvu djvu
+image/x.djvu djvu
+image/x-djvu djvu
+image/x-portable-pixmap ppm
+image/x-xcf xcf
+text/plain txt
+text/html html htm
+video/ogg ogv ogm ogg
+video/mpeg mpg mpeg
+EOT;
+
+       /**
+        * Defines a set of well known MIME info entries
+        * This is used as a fallback to mime.info files.
+        * An extensive list of well known MIME types is provided by
+        * the file mime.info in the includes directory.
+        */
+       protected static $wellKnownInfo = <<<EOT
+application/pdf [OFFICE]
+application/vnd.oasis.opendocument.chart [OFFICE]
+application/vnd.oasis.opendocument.chart-template [OFFICE]
+application/vnd.oasis.opendocument.database [OFFICE]
+application/vnd.oasis.opendocument.formula [OFFICE]
+application/vnd.oasis.opendocument.formula-template [OFFICE]
+application/vnd.oasis.opendocument.graphics [OFFICE]
+application/vnd.oasis.opendocument.graphics-template [OFFICE]
+application/vnd.oasis.opendocument.image [OFFICE]
+application/vnd.oasis.opendocument.image-template [OFFICE]
+application/vnd.oasis.opendocument.presentation [OFFICE]
+application/vnd.oasis.opendocument.presentation-template [OFFICE]
+application/vnd.oasis.opendocument.spreadsheet [OFFICE]
+application/vnd.oasis.opendocument.spreadsheet-template [OFFICE]
+application/vnd.oasis.opendocument.text [OFFICE]
+application/vnd.oasis.opendocument.text-template [OFFICE]
+application/vnd.oasis.opendocument.text-master [OFFICE]
+application/vnd.oasis.opendocument.text-web [OFFICE]
+application/javascript text/javascript application/x-javascript [EXECUTABLE]
+application/x-shockwave-flash [MULTIMEDIA]
+audio/midi [AUDIO]
+audio/x-aiff [AUDIO]
+audio/x-wav [AUDIO]
+audio/mp3 audio/mpeg [AUDIO]
+application/ogg audio/ogg video/ogg [MULTIMEDIA]
+image/x-bmp image/x-ms-bmp image/bmp [BITMAP]
+image/gif [BITMAP]
+image/jpeg [BITMAP]
+image/png [BITMAP]
+image/svg+xml [DRAWING]
+image/tiff [BITMAP]
+image/vnd.djvu [BITMAP]
+image/x-xcf [BITMAP]
+image/x-portable-pixmap [BITMAP]
+text/plain [TEXT]
+text/html [TEXT]
+video/ogg [VIDEO]
+video/mpeg [VIDEO]
+unknown/unknown application/octet-stream application/x-empty [UNKNOWN]
+EOT;
+
+       /**
+        * @param array $params Configuration map, includes:
+        *   - typeFile: path to file with the list of known MIME types
+        *   - infoFile: path to file with the MIME type info
+        *   - xmlTypes: map of root element names to XML MIME types
+        *   - initCallback: initialization callback that is passed this object [optional]
+        *   - detectCallback: alternative to finfo that returns the mime type for a file.
+        *      For example, the callback can return the output of "file -bi". [optional]
+        *   - guessCallback: callback to improve the guessed MIME type using the file data.
+        *      This is intended for fixing mistakes in fileinfo or "detectCallback". [optional]
+        *   - extCallback: callback to improve the guessed MIME type using the extension. [optional]
+        *   - logger: PSR-3 logger [optional]
+        * @note Constructing these instances is expensive due to file reads.
+        *  A service or singleton pattern should be used to avoid creating instances again and again.
+        */
+       public function __construct( array $params ) {
+               $this->typeFile = $params['typeFile'];
+               $this->infoFile = $params['infoFile'];
+               $this->xmlTypes = $params['xmlTypes'];
+               $this->initCallback = isset( $params['initCallback'] )
+                       ? $params['initCallback']
+                       : null;
+               $this->detectCallback = isset( $params['detectCallback'] )
+                       ? $params['detectCallback']
+                       : null;
+               $this->guessCallback = isset( $params['guessCallback'] )
+                       ? $params['guessCallback']
+                       : null;
+               $this->extCallback = isset( $params['extCallback'] )
+                       ? $params['extCallback']
+                       : null;
+               $this->logger = isset( $params['logger'] )
+                       ? $params['logger']
+                       : new \Psr\Log\NullLogger();
+
+               $this->loadFiles();
+       }
+
+       protected function loadFiles() {
+               /**
+                *   --- load mime.types ---
+                */
+
+               # Allow media handling extensions adding MIME-types and MIME-info
+               if ( $this->initCallback ) {
+                       call_user_func( $this->initCallback, $this );
+               }
+
+               $types = self::$wellKnownTypes;
+
+               $mimeTypeFile = $this->typeFile;
+               if ( $mimeTypeFile ) {
+                       if ( is_file( $mimeTypeFile ) && is_readable( $mimeTypeFile ) ) {
+                               $this->logger->info( __METHOD__ . ": loading mime types from $mimeTypeFile\n" );
+                               $types .= "\n";
+                               $types .= file_get_contents( $mimeTypeFile );
+                       } else {
+                               $this->logger->info( __METHOD__ . ": can't load mime types from $mimeTypeFile\n" );
+                       }
+               } else {
+                       $this->logger->info( __METHOD__ .
+                               ": no mime types file defined, using built-ins only.\n" );
+               }
+
+               $types .= "\n" . $this->extraTypes;
+
+               $types = str_replace( [ "\r\n", "\n\r", "\n\n", "\r\r", "\r" ], "\n", $types );
+               $types = str_replace( "\t", " ", $types );
+
+               $this->mimetoExt = [];
+               $this->mExtToMime = [];
+
+               $lines = explode( "\n", $types );
+               foreach ( $lines as $s ) {
+                       $s = trim( $s );
+                       if ( empty( $s ) ) {
+                               continue;
+                       }
+                       if ( strpos( $s, '#' ) === 0 ) {
+                               continue;
+                       }
+
+                       $s = strtolower( $s );
+                       $i = strpos( $s, ' ' );
+
+                       if ( $i === false ) {
+                               continue;
+                       }
+
+                       $mime = substr( $s, 0, $i );
+                       $ext = trim( substr( $s, $i + 1 ) );
+
+                       if ( empty( $ext ) ) {
+                               continue;
+                       }
+
+                       if ( !empty( $this->mimetoExt[$mime] ) ) {
+                               $this->mimetoExt[$mime] .= ' ' . $ext;
+                       } else {
+                               $this->mimetoExt[$mime] = $ext;
+                       }
+
+                       $extensions = explode( ' ', $ext );
+
+                       foreach ( $extensions as $e ) {
+                               $e = trim( $e );
+                               if ( empty( $e ) ) {
+                                       continue;
+                               }
+
+                               if ( !empty( $this->mExtToMime[$e] ) ) {
+                                       $this->mExtToMime[$e] .= ' ' . $mime;
+                               } else {
+                                       $this->mExtToMime[$e] = $mime;
+                               }
+                       }
+               }
+
+               /**
+                *   --- load mime.info ---
+                */
+
+               $mimeInfoFile = $this->infoFile;
+
+               $info = self::$wellKnownInfo;
+
+               if ( $mimeInfoFile ) {
+                       if ( is_file( $mimeInfoFile ) && is_readable( $mimeInfoFile ) ) {
+                               $this->logger->info( __METHOD__ . ": loading mime info from $mimeInfoFile\n" );
+                               $info .= "\n";
+                               $info .= file_get_contents( $mimeInfoFile );
+                       } else {
+                               $this->logger->info( __METHOD__ . ": can't load mime info from $mimeInfoFile\n" );
+                       }
+               } else {
+                       $this->logger->info( __METHOD__ .
+                               ": no mime info file defined, using built-ins only.\n" );
+               }
+
+               $info .= "\n" . $this->extraInfo;
+
+               $info = str_replace( [ "\r\n", "\n\r", "\n\n", "\r\r", "\r" ], "\n", $info );
+               $info = str_replace( "\t", " ", $info );
+
+               $this->mimeTypeAliases = [];
+               $this->mediaTypes = [];
+
+               $lines = explode( "\n", $info );
+               foreach ( $lines as $s ) {
+                       $s = trim( $s );
+                       if ( empty( $s ) ) {
+                               continue;
+                       }
+                       if ( strpos( $s, '#' ) === 0 ) {
+                               continue;
+                       }
+
+                       $s = strtolower( $s );
+                       $i = strpos( $s, ' ' );
+
+                       if ( $i === false ) {
+                               continue;
+                       }
+
+                       # print "processing MIME INFO line $s<br>";
+
+                       $match = [];
+                       if ( preg_match( '!\[\s*(\w+)\s*\]!', $s, $match ) ) {
+                               $s = preg_replace( '!\[\s*(\w+)\s*\]!', '', $s );
+                               $mtype = trim( strtoupper( $match[1] ) );
+                       } else {
+                               $mtype = MEDIATYPE_UNKNOWN;
+                       }
+
+                       $m = explode( ' ', $s );
+
+                       if ( !isset( $this->mediaTypes[$mtype] ) ) {
+                               $this->mediaTypes[$mtype] = [];
+                       }
+
+                       foreach ( $m as $mime ) {
+                               $mime = trim( $mime );
+                               if ( empty( $mime ) ) {
+                                       continue;
+                               }
+
+                               $this->mediaTypes[$mtype][] = $mime;
+                       }
+
+                       if ( count( $m ) > 1 ) {
+                               $main = $m[0];
+                               $mCount = count( $m );
+                               for ( $i = 1; $i < $mCount; $i += 1 ) {
+                                       $mime = $m[$i];
+                                       $this->mimeTypeAliases[$mime] = $main;
+                               }
+                       }
+               }
+       }
+
+       public function setLogger( LoggerInterface $logger ) {
+               $this->logger = $logger;
+       }
+
+       /**
+        * Adds to the list mapping MIME to file extensions.
+        * As an extension author, you are encouraged to submit patches to
+        * MediaWiki's core to add new MIME types to mime.types.
+        * @param string $types
+        */
+       public function addExtraTypes( $types ) {
+               $this->extraTypes .= "\n" . $types;
+       }
+
+       /**
+        * Adds to the list mapping MIME to media type.
+        * As an extension author, you are encouraged to submit patches to
+        * MediaWiki's core to add new MIME info to mime.info.
+        * @param string $info
+        */
+       public function addExtraInfo( $info ) {
+               $this->extraInfo .= "\n" . $info;
+       }
+
+       /**
+        * Returns a list of file extensions for a given MIME type as a space
+        * separated string or null if the MIME type was unrecognized. Resolves
+        * MIME type aliases.
+        *
+        * @param string $mime
+        * @return string|null
+        */
+       public function getExtensionsForType( $mime ) {
+               $mime = strtolower( $mime );
+
+               // Check the mime-to-ext map
+               if ( isset( $this->mimetoExt[$mime] ) ) {
+                       return $this->mimetoExt[$mime];
+               }
+
+               // Resolve the MIME type to the canonical type
+               if ( isset( $this->mimeTypeAliases[$mime] ) ) {
+                       $mime = $this->mimeTypeAliases[$mime];
+                       if ( isset( $this->mimetoExt[$mime] ) ) {
+                               return $this->mimetoExt[$mime];
+                       }
+               }
+
+               return null;
+       }
+
+       /**
+        * Returns a list of MIME types for a given file extension as a space
+        * separated string or null if the extension was unrecognized.
+        *
+        * @param string $ext
+        * @return string|null
+        */
+       public function getTypesForExtension( $ext ) {
+               $ext = strtolower( $ext );
+
+               $r = isset( $this->mExtToMime[$ext] ) ? $this->mExtToMime[$ext] : null;
+               return $r;
+       }
+
+       /**
+        * Returns a single MIME type for a given file extension or null if unknown.
+        * This is always the first type from the list returned by getTypesForExtension($ext).
+        *
+        * @param string $ext
+        * @return string|null
+        */
+       public function guessTypesForExtension( $ext ) {
+               $m = $this->getTypesForExtension( $ext );
+               if ( is_null( $m ) ) {
+                       return null;
+               }
+
+               // TODO: Check if this is needed; strtok( $m, ' ' ) should be sufficient
+               $m = trim( $m );
+               $m = preg_replace( '/\s.*$/', '', $m );
+
+               return $m;
+       }
+
+       /**
+        * Tests if the extension matches the given MIME type. Returns true if a
+        * match was found, null if the MIME type is unknown, and false if the
+        * MIME type is known but no matches where found.
+        *
+        * @param string $extension
+        * @param string $mime
+        * @return bool|null
+        */
+       public function isMatchingExtension( $extension, $mime ) {
+               $ext = $this->getExtensionsForType( $mime );
+
+               if ( !$ext ) {
+                       return null; // Unknown MIME type
+               }
+
+               $ext = explode( ' ', $ext );
+
+               $extension = strtolower( $extension );
+               return in_array( $extension, $ext );
+       }
+
+       /**
+        * Returns true if the MIME type is known to represent an image format
+        * supported by the PHP GD library.
+        *
+        * @param string $mime
+        *
+        * @return bool
+        */
+       public function isPHPImageType( $mime ) {
+               // As defined by imagegetsize and image_type_to_mime
+               static $types = [
+                       'image/gif', 'image/jpeg', 'image/png',
+                       'image/x-bmp', 'image/xbm', 'image/tiff',
+                       'image/jp2', 'image/jpeg2000', 'image/iff',
+                       'image/xbm', 'image/x-xbitmap',
+                       'image/vnd.wap.wbmp', 'image/vnd.xiff',
+                       'image/x-photoshop',
+                       'application/x-shockwave-flash',
+               ];
+
+               return in_array( $mime, $types );
+       }
+
+       /**
+        * Returns true if the extension represents a type which can
+        * be reliably detected from its content. Use this to determine
+        * whether strict content checks should be applied to reject
+        * invalid uploads; if we can't identify the type we won't
+        * be able to say if it's invalid.
+        *
+        * @todo Be more accurate when using fancy MIME detector plugins;
+        *       right now this is the bare minimum getimagesize() list.
+        * @param string $extension
+        * @return bool
+        */
+       function isRecognizableExtension( $extension ) {
+               static $types = [
+                       // Types recognized by getimagesize()
+                       'gif', 'jpeg', 'jpg', 'png', 'swf', 'psd',
+                       'bmp', 'tiff', 'tif', 'jpc', 'jp2',
+                       'jpx', 'jb2', 'swc', 'iff', 'wbmp',
+                       'xbm',
+
+                       // Formats we recognize magic numbers for
+                       'djvu', 'ogx', 'ogg', 'ogv', 'oga', 'spx',
+                       'mid', 'pdf', 'wmf', 'xcf', 'webm', 'mkv', 'mka',
+                       'webp',
+
+                       // XML formats we sure hope we recognize reliably
+                       'svg',
+               ];
+               return in_array( strtolower( $extension ), $types );
+       }
+
+       /**
+        * Improves a MIME type using the file extension. Some file formats are very generic,
+        * so their MIME type is not very meaningful. A more useful MIME type can be derived
+        * by looking at the file extension. Typically, this method would be called on the
+        * result of guessMimeType().
+        *
+        * @param string $mime The MIME type, typically guessed from a file's content.
+        * @param string $ext The file extension, as taken from the file name
+        *
+        * @return string The MIME type
+        */
+       public function improveTypeFromExtension( $mime, $ext ) {
+               if ( $mime === 'unknown/unknown' ) {
+                       if ( $this->isRecognizableExtension( $ext ) ) {
+                               $this->logger->info( __METHOD__ . ': refusing to guess mime type for .' .
+                                       "$ext file, we should have recognized it\n" );
+                       } else {
+                               // Not something we can detect, so simply
+                               // trust the file extension
+                               $mime = $this->guessTypesForExtension( $ext );
+                       }
+               } elseif ( $mime === 'application/x-opc+zip' ) {
+                       if ( $this->isMatchingExtension( $ext, $mime ) ) {
+                               // A known file extension for an OPC file,
+                               // find the proper MIME type for that file extension
+                               $mime = $this->guessTypesForExtension( $ext );
+                       } else {
+                               $this->logger->info( __METHOD__ .
+                                       ": refusing to guess better type for $mime file, " .
+                                       ".$ext is not a known OPC extension.\n" );
+                               $mime = 'application/zip';
+                       }
+               } elseif ( $mime === 'text/plain' && $this->findMediaType( ".$ext" ) === MEDIATYPE_TEXT ) {
+                       // Textual types are sometimes not recognized properly.
+                       // If detected as text/plain, and has an extension which is textual
+                       // improve to the extension's type. For example, csv and json are often
+                       // misdetected as text/plain.
+                       $mime = $this->guessTypesForExtension( $ext );
+               }
+
+               # Media handling extensions can improve the MIME detected
+               $callback = $this->extCallback;
+               if ( $callback ) {
+                       $callback( $this, $ext, $mime /* by reference */ );
+               }
+
+               if ( isset( $this->mimeTypeAliases[$mime] ) ) {
+                       $mime = $this->mimeTypeAliases[$mime];
+               }
+
+               $this->logger->info( __METHOD__ . ": improved mime type for .$ext: $mime\n" );
+               return $mime;
+       }
+
+       /**
+        * MIME type detection. This uses detectMimeType to detect the MIME type
+        * of the file, but applies additional checks to determine some well known
+        * file formats that may be missed or misinterpreted by the default MIME
+        * detection (namely XML based formats like XHTML or SVG, as well as ZIP
+        * based formats like OPC/ODF files).
+        *
+        * @param string $file The file to check
+        * @param string|bool $ext The file extension, or true (default) to extract
+        *   it from the filename. Set it to false to ignore the extension. DEPRECATED!
+        *   Set to false, use improveTypeFromExtension($mime, $ext) later to improve MIME type.
+        *
+        * @return string The MIME type of $file
+        */
+       public function guessMimeType( $file, $ext = true ) {
+               if ( $ext ) { // TODO: make $ext default to false. Or better, remove it.
+                       $this->logger->info( __METHOD__ .
+                               ": WARNING: use of the \$ext parameter is deprecated. " .
+                               "Use improveTypeFromExtension(\$mime, \$ext) instead.\n" );
+               }
+
+               $mime = $this->doGuessMimeType( $file, $ext );
+
+               if ( !$mime ) {
+                       $this->logger->info( __METHOD__ .
+                               ": internal type detection failed for $file (.$ext)...\n" );
+                       $mime = $this->detectMimeType( $file, $ext );
+               }
+
+               if ( isset( $this->mimeTypeAliases[$mime] ) ) {
+                       $mime = $this->mimeTypeAliases[$mime];
+               }
+
+               $this->logger->info( __METHOD__ . ": guessed mime type of $file: $mime\n" );
+               return $mime;
+       }
+
+       /**
+        * Guess the MIME type from the file contents.
+        *
+        * @todo Remove $ext param
+        *
+        * @param string $file
+        * @param mixed $ext
+        * @return bool|string
+        * @throws UnexpectedValueException
+        */
+       private function doGuessMimeType( $file, $ext ) {
+               // Read a chunk of the file
+               MediaWiki\suppressWarnings();
+               $f = fopen( $file, 'rb' );
+               MediaWiki\restoreWarnings();
+
+               if ( !$f ) {
+                       return 'unknown/unknown';
+               }
+
+               $fsize = filesize( $file );
+               if ( $fsize === false ) {
+                       return 'unknown/unknown';
+               }
+
+               $head = fread( $f, 1024 );
+               $tailLength = min( 65558, $fsize ); // 65558 = maximum size of a zip EOCDR
+               if ( fseek( $f, -1 * $tailLength, SEEK_END ) === -1 ) {
+                       throw new UnexpectedValueException(
+                               "Seeking $tailLength bytes from EOF failed in " . __METHOD__ );
+               }
+               $tail = $tailLength ? fread( $f, $tailLength ) : '';
+               fclose( $f );
+
+               $this->logger->info( __METHOD__ .
+                       ": analyzing head and tail of $file for magic numbers.\n" );
+
+               // Hardcode a few magic number checks...
+               $headers = [
+                       // Multimedia...
+                       'MThd'             => 'audio/midi',
+                       'OggS'             => 'application/ogg',
+
+                       // Image formats...
+                       // Note that WMF may have a bare header, no magic number.
+                       "\x01\x00\x09\x00" => 'application/x-msmetafile', // Possibly prone to false positives?
+                       "\xd7\xcd\xc6\x9a" => 'application/x-msmetafile',
+                       '%PDF'             => 'application/pdf',
+                       'gimp xcf'         => 'image/x-xcf',
+
+                       // Some forbidden fruit...
+                       'MZ'               => 'application/octet-stream', // DOS/Windows executable
+                       "\xca\xfe\xba\xbe" => 'application/octet-stream', // Mach-O binary
+                       "\x7fELF"          => 'application/octet-stream', // ELF binary
+               ];
+
+               foreach ( $headers as $magic => $candidate ) {
+                       if ( strncmp( $head, $magic, strlen( $magic ) ) == 0 ) {
+                               $this->logger->info( __METHOD__ .
+                                       ": magic header in $file recognized as $candidate\n" );
+                               return $candidate;
+                       }
+               }
+
+               /* Look for WebM and Matroska files */
+               if ( strncmp( $head, pack( "C4", 0x1a, 0x45, 0xdf, 0xa3 ), 4 ) == 0 ) {
+                       $doctype = strpos( $head, "\x42\x82" );
+                       if ( $doctype ) {
+                               // Next byte is datasize, then data (sizes larger than 1 byte are stupid muxers)
+                               $data = substr( $head, $doctype + 3, 8 );
+                               if ( strncmp( $data, "matroska", 8 ) == 0 ) {
+                                       $this->logger->info( __METHOD__ . ": recognized file as video/x-matroska\n" );
+                                       return "video/x-matroska";
+                               } elseif ( strncmp( $data, "webm", 4 ) == 0 ) {
+                                       $this->logger->info( __METHOD__ . ": recognized file as video/webm\n" );
+                                       return "video/webm";
+                               }
+                       }
+                       $this->logger->info( __METHOD__ . ": unknown EBML file\n" );
+                       return "unknown/unknown";
+               }
+
+               /* Look for WebP */
+               if ( strncmp( $head, "RIFF", 4 ) == 0 &&
+                       strncmp( substr( $head, 8, 7 ), "WEBPVP8", 7 ) == 0
+               ) {
+                       $this->logger->info( __METHOD__ . ": recognized file as image/webp\n" );
+                       return "image/webp";
+               }
+
+               /**
+                * Look for PHP.  Check for this before HTML/XML...  Warning: this is a
+                * heuristic, and won't match a file with a lot of non-PHP before.  It
+                * will also match text files which could be PHP. :)
+                *
+                * @todo FIXME: For this reason, the check is probably useless -- an attacker
+                * could almost certainly just pad the file with a lot of nonsense to
+                * circumvent the check in any case where it would be a security
+                * problem.  On the other hand, it causes harmful false positives (bug
+                * 16583).  The heuristic has been cut down to exclude three-character
+                * strings like "<? ", but should it be axed completely?
+                */
+               if ( ( strpos( $head, '<?php' ) !== false ) ||
+                       ( strpos( $head, "<\x00?\x00p\x00h\x00p" ) !== false ) ||
+                       ( strpos( $head, "<\x00?\x00 " ) !== false ) ||
+                       ( strpos( $head, "<\x00?\x00\n" ) !== false ) ||
+                       ( strpos( $head, "<\x00?\x00\t" ) !== false ) ||
+                       ( strpos( $head, "<\x00?\x00=" ) !== false ) ) {
+
+                       $this->logger->info( __METHOD__ . ": recognized $file as application/x-php\n" );
+                       return 'application/x-php';
+               }
+
+               /**
+                * look for XML formats (XHTML and SVG)
+                */
+               $xml = new XmlTypeCheck( $file );
+               if ( $xml->wellFormed ) {
+                       $xmlTypes = $this->xmlTypes;
+                       if ( isset( $xmlTypes[$xml->getRootElement()] ) ) {
+                               return $xmlTypes[$xml->getRootElement()];
+                       } else {
+                               return 'application/xml';
+                       }
+               }
+
+               /**
+                * look for shell scripts
+                */
+               $script_type = null;
+
+               # detect by shebang
+               if ( substr( $head, 0, 2 ) == "#!" ) {
+                       $script_type = "ASCII";
+               } elseif ( substr( $head, 0, 5 ) == "\xef\xbb\xbf#!" ) {
+                       $script_type = "UTF-8";
+               } elseif ( substr( $head, 0, 7 ) == "\xfe\xff\x00#\x00!" ) {
+                       $script_type = "UTF-16BE";
+               } elseif ( substr( $head, 0, 7 ) == "\xff\xfe#\x00!" ) {
+                       $script_type = "UTF-16LE";
+               }
+
+               if ( $script_type ) {
+                       if ( $script_type !== "UTF-8" && $script_type !== "ASCII" ) {
+                               // Quick and dirty fold down to ASCII!
+                               $pack = [ 'UTF-16BE' => 'n*', 'UTF-16LE' => 'v*' ];
+                               $chars = unpack( $pack[$script_type], substr( $head, 2 ) );
+                               $head = '';
+                               foreach ( $chars as $codepoint ) {
+                                       if ( $codepoint < 128 ) {
+                                               $head .= chr( $codepoint );
+                                       } else {
+                                               $head .= '?';
+                                       }
+                               }
+                       }
+
+                       $match = [];
+
+                       if ( preg_match( '%/?([^\s]+/)(\w+)%', $head, $match ) ) {
+                               $mime = "application/x-{$match[2]}";
+                               $this->logger->info( __METHOD__ . ": shell script recognized as $mime\n" );
+                               return $mime;
+                       }
+               }
+
+               // Check for ZIP variants (before getimagesize)
+               if ( strpos( $tail, "PK\x05\x06" ) !== false ) {
+                       $this->logger->info( __METHOD__ . ": ZIP header present in $file\n" );
+                       return $this->detectZipType( $head, $tail, $ext );
+               }
+
+               MediaWiki\suppressWarnings();
+               $gis = getimagesize( $file );
+               MediaWiki\restoreWarnings();
+
+               if ( $gis && isset( $gis['mime'] ) ) {
+                       $mime = $gis['mime'];
+                       $this->logger->info( __METHOD__ . ": getimagesize detected $file as $mime\n" );
+                       return $mime;
+               }
+
+               # Media handling extensions can guess the MIME by content
+               # It's intentionally here so that if core is wrong about a type (false positive),
+               # people will hopefully nag and submit patches :)
+               $mime = false;
+               # Some strings by reference for performance - assuming well-behaved hooks
+               $callback = $this->guessCallback;
+               if ( $callback ) {
+                       $callback( $this, $head, $tail, $file, $mime /* by reference */ );
+               };
+
+               return $mime;
+       }
+
+       /**
+        * Detect application-specific file type of a given ZIP file from its
+        * header data.  Currently works for OpenDocument and OpenXML types...
+        * If can't tell, returns 'application/zip'.
+        *
+        * @param string $header Some reasonably-sized chunk of file header
+        * @param string|null $tail The tail of the file
+        * @param string|bool $ext The file extension, or true to extract it from the filename.
+        *   Set it to false (default) to ignore the extension. DEPRECATED! Set to false,
+        *   use improveTypeFromExtension($mime, $ext) later to improve MIME type.
+        *
+        * @return string
+        */
+       function detectZipType( $header, $tail = null, $ext = false ) {
+               if ( $ext ) { # TODO: remove $ext param
+                       $this->logger->info( __METHOD__ .
+                               ": WARNING: use of the \$ext parameter is deprecated. " .
+                               "Use improveTypeFromExtension(\$mime, \$ext) instead.\n" );
+               }
+
+               $mime = 'application/zip';
+               $opendocTypes = [
+                       'chart-template',
+                       'chart',
+                       'formula-template',
+                       'formula',
+                       'graphics-template',
+                       'graphics',
+                       'image-template',
+                       'image',
+                       'presentation-template',
+                       'presentation',
+                       'spreadsheet-template',
+                       'spreadsheet',
+                       'text-template',
+                       'text-master',
+                       'text-web',
+                       'text' ];
+
+               // https://lists.oasis-open.org/archives/office/200505/msg00006.html
+               $types = '(?:' . implode( '|', $opendocTypes ) . ')';
+               $opendocRegex = "/^mimetype(application\/vnd\.oasis\.opendocument\.$types)/";
+
+               $openxmlRegex = "/^\[Content_Types\].xml/";
+
+               if ( preg_match( $opendocRegex, substr( $header, 30 ), $matches ) ) {
+                       $mime = $matches[1];
+                       $this->logger->info( __METHOD__ . ": detected $mime from ZIP archive\n" );
+               } elseif ( preg_match( $openxmlRegex, substr( $header, 30 ) ) ) {
+                       $mime = "application/x-opc+zip";
+                       # TODO: remove the block below, as soon as improveTypeFromExtension is used everywhere
+                       if ( $ext !== true && $ext !== false ) {
+                               /** This is the mode used by getPropsFromPath
+                                * These MIME's are stored in the database, where we don't really want
+                                * x-opc+zip, because we use it only for internal purposes
+                                */
+                               if ( $this->isMatchingExtension( $ext, $mime ) ) {
+                                       /* A known file extension for an OPC file,
+                                        * find the proper mime type for that file extension
+                                        */
+                                       $mime = $this->guessTypesForExtension( $ext );
+                               } else {
+                                       $mime = "application/zip";
+                               }
+                       }
+                       $this->logger->info( __METHOD__ .
+                               ": detected an Open Packaging Conventions archive: $mime\n" );
+               } elseif ( substr( $header, 0, 8 ) == "\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1" &&
+                       ( $headerpos = strpos( $tail, "PK\x03\x04" ) ) !== false &&
+                       preg_match( $openxmlRegex, substr( $tail, $headerpos + 30 ) ) ) {
+                       if ( substr( $header, 512, 4 ) == "\xEC\xA5\xC1\x00" ) {
+                               $mime = "application/msword";
+                       }
+                       switch ( substr( $header, 512, 6 ) ) {
+                               case "\xEC\xA5\xC1\x00\x0E\x00":
+                               case "\xEC\xA5\xC1\x00\x1C\x00":
+                               case "\xEC\xA5\xC1\x00\x43\x00":
+                                       $mime = "application/vnd.ms-powerpoint";
+                                       break;
+                               case "\xFD\xFF\xFF\xFF\x10\x00":
+                               case "\xFD\xFF\xFF\xFF\x1F\x00":
+                               case "\xFD\xFF\xFF\xFF\x22\x00":
+                               case "\xFD\xFF\xFF\xFF\x23\x00":
+                               case "\xFD\xFF\xFF\xFF\x28\x00":
+                               case "\xFD\xFF\xFF\xFF\x29\x00":
+                               case "\xFD\xFF\xFF\xFF\x10\x02":
+                               case "\xFD\xFF\xFF\xFF\x1F\x02":
+                               case "\xFD\xFF\xFF\xFF\x22\x02":
+                               case "\xFD\xFF\xFF\xFF\x23\x02":
+                               case "\xFD\xFF\xFF\xFF\x28\x02":
+                               case "\xFD\xFF\xFF\xFF\x29\x02":
+                                       $mime = "application/vnd.msexcel";
+                                       break;
+                       }
+
+                       $this->logger->info( __METHOD__ .
+                               ": detected a MS Office document with OPC trailer\n" );
+               } else {
+                       $this->logger->info( __METHOD__ . ": unable to identify type of ZIP archive\n" );
+               }
+               return $mime;
+       }
+
+       /**
+        * Internal MIME type detection. Detection is done using the fileinfo
+        * extension if it is available. It can be overriden by callback, which could
+        * use an external program, for example. If detection fails and $ext is not false,
+        * the MIME type is guessed from the file extension, using guessTypesForExtension.
+        *
+        * If the MIME type is still unknown, getimagesize is used to detect the
+        * MIME type if the file is an image. If no MIME type can be determined,
+        * this function returns 'unknown/unknown'.
+        *
+        * @param string $file The file to check
+        * @param string|bool $ext The file extension, or true (default) to extract it from the filename.
+        *   Set it to false to ignore the extension. DEPRECATED! Set to false, use
+        *   improveTypeFromExtension($mime, $ext) later to improve MIME type.
+        *
+        * @return string The MIME type of $file
+        */
+       private function detectMimeType( $file, $ext = true ) {
+               /** @todo Make $ext default to false. Or better, remove it. */
+               if ( $ext ) {
+                       $this->logger->info( __METHOD__ .
+                               ": WARNING: use of the \$ext parameter is deprecated. "
+                               . "Use improveTypeFromExtension(\$mime, \$ext) instead.\n" );
+               }
+
+               $callback = $this->detectCallback;
+               $m = null;
+               if ( $callback ) {
+                       $m = $callback( $file );
+               } elseif ( function_exists( "finfo_open" ) && function_exists( "finfo_file" ) ) {
+                       $mime_magic_resource = finfo_open( FILEINFO_MIME );
+
+                       if ( $mime_magic_resource ) {
+                               $m = finfo_file( $mime_magic_resource, $file );
+                               finfo_close( $mime_magic_resource );
+                       } else {
+                               $this->logger->info( __METHOD__ .
+                                       ": finfo_open failed on " . FILEINFO_MIME . "!\n" );
+                       }
+               } else {
+                       $this->logger->info( __METHOD__ . ": no magic mime detector found!\n" );
+               }
+
+               if ( $m ) {
+                       # normalize
+                       $m = preg_replace( '![;, ].*$!', '', $m ); # strip charset, etc
+                       $m = trim( $m );
+                       $m = strtolower( $m );
+
+                       if ( strpos( $m, 'unknown' ) !== false ) {
+                               $m = null;
+                       } else {
+                               $this->logger->info( __METHOD__ . ": magic mime type of $file: $m\n" );
+                               return $m;
+                       }
+               }
+
+               // If desired, look at extension as a fallback.
+               if ( $ext === true ) {
+                       $i = strrpos( $file, '.' );
+                       $ext = strtolower( $i ? substr( $file, $i + 1 ) : '' );
+               }
+               if ( $ext ) {
+                       if ( $this->isRecognizableExtension( $ext ) ) {
+                               $this->logger->info( __METHOD__ . ": refusing to guess mime type for .$ext file, "
+                                       . "we should have recognized it\n" );
+                       } else {
+                               $m = $this->guessTypesForExtension( $ext );
+                               if ( $m ) {
+                                       $this->logger->info( __METHOD__ . ": extension mime type of $file: $m\n" );
+                                       return $m;
+                               }
+                       }
+               }
+
+               // Unknown type
+               $this->logger->info( __METHOD__ . ": failed to guess mime type for $file!\n" );
+               return 'unknown/unknown';
+       }
+
+       /**
+        * Determine the media type code for a file, using its MIME type, name and
+        * possibly its contents.
+        *
+        * This function relies on the findMediaType(), mapping extensions and MIME
+        * types to media types.
+        *
+        * @todo analyse file if need be
+        * @todo look at multiple extension, separately and together.
+        *
+        * @param string $path Full path to the image file, in case we have to look at the contents
+        *        (if null, only the MIME type is used to determine the media type code).
+        * @param string $mime MIME type. If null it will be guessed using guessMimeType.
+        *
+        * @return string A value to be used with the MEDIATYPE_xxx constants.
+        */
+       function getMediaType( $path = null, $mime = null ) {
+               if ( !$mime && !$path ) {
+                       return MEDIATYPE_UNKNOWN;
+               }
+
+               // If MIME type is unknown, guess it
+               if ( !$mime ) {
+                       $mime = $this->guessMimeType( $path, false );
+               }
+
+               // Special code for ogg - detect if it's video (theora),
+               // else label it as sound.
+               if ( $mime == 'application/ogg' && file_exists( $path ) ) {
+
+                       // Read a chunk of the file
+                       $f = fopen( $path, "rt" );
+                       if ( !$f ) {
+                               return MEDIATYPE_UNKNOWN;
+                       }
+                       $head = fread( $f, 256 );
+                       fclose( $f );
+
+                       $head = str_replace( 'ffmpeg2theora', '', strtolower( $head ) );
+
+                       // This is an UGLY HACK, file should be parsed correctly
+                       if ( strpos( $head, 'theora' ) !== false ) {
+                               return MEDIATYPE_VIDEO;
+                       } elseif ( strpos( $head, 'vorbis' ) !== false ) {
+                               return MEDIATYPE_AUDIO;
+                       } elseif ( strpos( $head, 'flac' ) !== false ) {
+                               return MEDIATYPE_AUDIO;
+                       } elseif ( strpos( $head, 'speex' ) !== false ) {
+                               return MEDIATYPE_AUDIO;
+                       } else {
+                               return MEDIATYPE_MULTIMEDIA;
+                       }
+               }
+
+               $type = null;
+               // Check for entry for full MIME type
+               if ( $mime ) {
+                       $type = $this->findMediaType( $mime );
+                       if ( $type !== MEDIATYPE_UNKNOWN ) {
+                               return $type;
+                       }
+               }
+
+               // Check for entry for file extension
+               if ( $path ) {
+                       $i = strrpos( $path, '.' );
+                       $e = strtolower( $i ? substr( $path, $i + 1 ) : '' );
+
+                       // TODO: look at multi-extension if this fails, parse from full path
+                       $type = $this->findMediaType( '.' . $e );
+                       if ( $type !== MEDIATYPE_UNKNOWN ) {
+                               return $type;
+                       }
+               }
+
+               // Check major MIME type
+               if ( $mime ) {
+                       $i = strpos( $mime, '/' );
+                       if ( $i !== false ) {
+                               $major = substr( $mime, 0, $i );
+                               $type = $this->findMediaType( $major );
+                               if ( $type !== MEDIATYPE_UNKNOWN ) {
+                                       return $type;
+                               }
+                       }
+               }
+
+               if ( !$type ) {
+                       $type = MEDIATYPE_UNKNOWN;
+               }
+
+               return $type;
+       }
+
+       /**
+        * Returns a media code matching the given MIME type or file extension.
+        * File extensions are represented by a string starting with a dot (.) to
+        * distinguish them from MIME types.
+        *
+        * This function relies on the mapping defined by $this->mMediaTypes
+        * @access private
+        * @param string $extMime
+        * @return int|string
+        */
+       function findMediaType( $extMime ) {
+               if ( strpos( $extMime, '.' ) === 0 ) {
+                       // If it's an extension, look up the MIME types
+                       $m = $this->getTypesForExtension( substr( $extMime, 1 ) );
+                       if ( !$m ) {
+                               return MEDIATYPE_UNKNOWN;
+                       }
+
+                       $m = explode( ' ', $m );
+               } else {
+                       // Normalize MIME type
+                       if ( isset( $this->mimeTypeAliases[$extMime] ) ) {
+                               $extMime = $this->mimeTypeAliases[$extMime];
+                       }
+
+                       $m = [ $extMime ];
+               }
+
+               foreach ( $m as $mime ) {
+                       foreach ( $this->mediaTypes as $type => $codes ) {
+                               if ( in_array( $mime, $codes, true ) ) {
+                                       return $type;
+                               }
+                       }
+               }
+
+               return MEDIATYPE_UNKNOWN;
+       }
+
+       /**
+        * Get the MIME types that various versions of Internet Explorer would
+        * detect from a chunk of the content.
+        *
+        * @param string $fileName The file name (unused at present)
+        * @param string $chunk The first 256 bytes of the file
+        * @param string $proposed The MIME type proposed by the server
+        * @return array
+        */
+       public function getIEMimeTypes( $fileName, $chunk, $proposed ) {
+               $ca = $this->getIEContentAnalyzer();
+               return $ca->getRealMimesFromData( $fileName, $chunk, $proposed );
+       }
+
+       /**
+        * Get a cached instance of IEContentAnalyzer
+        *
+        * @return IEContentAnalyzer
+        */
+       protected function getIEContentAnalyzer() {
+               if ( is_null( $this->IEAnalyzer ) ) {
+                       $this->IEAnalyzer = new IEContentAnalyzer;
+               }
+               return $this->IEAnalyzer;
+       }
+}
diff --git a/includes/libs/mime/XmlTypeCheck.php b/includes/libs/mime/XmlTypeCheck.php
new file mode 100644 (file)
index 0000000..3958f8c
--- /dev/null
@@ -0,0 +1,344 @@
+<?php
+/**
+ * XML syntax and type checker.
+ *
+ * Since 1.24.2, it uses XMLReader instead of xml_parse, which gives us
+ * more control over the expansion of XML entities. When passed to the
+ * callback, entities will be fully expanded, but may report the XML is
+ * invalid if expanding the entities are likely to cause a DoS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+class XmlTypeCheck {
+       /**
+        * Will be set to true or false to indicate whether the file is
+        * well-formed XML. Note that this doesn't check schema validity.
+        */
+       public $wellFormed = null;
+
+       /**
+        * Will be set to true if the optional element filter returned
+        * a match at some point.
+        */
+       public $filterMatch = false;
+
+       /**
+        * Will contain the type of filter hit if the optional element filter returned
+        * a match at some point.
+        * @var mixed
+        */
+       public $filterMatchType = false;
+
+       /**
+        * Name of the document's root element, including any namespace
+        * as an expanded URL.
+        */
+       public $rootElement = '';
+
+       /**
+        * A stack of strings containing the data of each xml element as it's processed. Append
+        * data to the top string of the stack, then pop off the string and process it when the
+        * element is closed.
+        */
+       protected $elementData = [];
+
+       /**
+        * A stack of element names and attributes, as we process them.
+        */
+       protected $elementDataContext = [];
+
+       /**
+        * Current depth of the data stack.
+        */
+       protected $stackDepth = 0;
+
+       /**
+        * Additional parsing options
+        */
+       private $parserOptions = [
+               'processing_instruction_handler' => '',
+       ];
+
+       /**
+        * @param string $input a filename or string containing the XML element
+        * @param callable $filterCallback (optional)
+        *        Function to call to do additional custom validity checks from the
+        *        SAX element handler event. This gives you access to the element
+        *        namespace, name, attributes, and text contents.
+        *        Filter should return 'true' to toggle on $this->filterMatch
+        * @param bool $isFile (optional) indicates if the first parameter is a
+        *        filename (default, true) or if it is a string (false)
+        * @param array $options list of additional parsing options:
+        *        processing_instruction_handler: Callback for xml_set_processing_instruction_handler
+        */
+       function __construct( $input, $filterCallback = null, $isFile = true, $options = [] ) {
+               $this->filterCallback = $filterCallback;
+               $this->parserOptions = array_merge( $this->parserOptions, $options );
+               $this->validateFromInput( $input, $isFile );
+       }
+
+       /**
+        * Alternative constructor: from filename
+        *
+        * @param string $fname the filename of an XML document
+        * @param callable $filterCallback (optional)
+        *        Function to call to do additional custom validity checks from the
+        *        SAX element handler event. This gives you access to the element
+        *        namespace, name, and attributes, but not to text contents.
+        *        Filter should return 'true' to toggle on $this->filterMatch
+        * @return XmlTypeCheck
+        */
+       public static function newFromFilename( $fname, $filterCallback = null ) {
+               return new self( $fname, $filterCallback, true );
+       }
+
+       /**
+        * Alternative constructor: from string
+        *
+        * @param string $string a string containing an XML element
+        * @param callable $filterCallback (optional)
+        *        Function to call to do additional custom validity checks from the
+        *        SAX element handler event. This gives you access to the element
+        *        namespace, name, and attributes, but not to text contents.
+        *        Filter should return 'true' to toggle on $this->filterMatch
+        * @return XmlTypeCheck
+        */
+       public static function newFromString( $string, $filterCallback = null ) {
+               return new self( $string, $filterCallback, false );
+       }
+
+       /**
+        * Get the root element. Simple accessor to $rootElement
+        *
+        * @return string
+        */
+       public function getRootElement() {
+               return $this->rootElement;
+       }
+
+       /**
+        * @param string $fname the filename
+        */
+       private function validateFromInput( $xml, $isFile ) {
+               $reader = new XMLReader();
+               if ( $isFile ) {
+                       $s = $reader->open( $xml, null, LIBXML_NOERROR | LIBXML_NOWARNING );
+               } else {
+                       $s = $reader->XML( $xml, null, LIBXML_NOERROR | LIBXML_NOWARNING );
+               }
+               if ( $s !== true ) {
+                       // Couldn't open the XML
+                       $this->wellFormed = false;
+               } else {
+                       $oldDisable = libxml_disable_entity_loader( true );
+                       $reader->setParserProperty( XMLReader::SUBST_ENTITIES, true );
+                       try {
+                               $this->validate( $reader );
+                       } catch ( Exception $e ) {
+                               // Calling this malformed, because we didn't parse the whole
+                               // thing. Maybe just an external entity refernce.
+                               $this->wellFormed = false;
+                               $reader->close();
+                               libxml_disable_entity_loader( $oldDisable );
+                               throw $e;
+                       }
+                       $reader->close();
+                       libxml_disable_entity_loader( $oldDisable );
+               }
+       }
+
+       private function readNext( XMLReader $reader ) {
+               set_error_handler( [ $this, 'XmlErrorHandler' ] );
+               $ret = $reader->read();
+               restore_error_handler();
+               return $ret;
+       }
+
+       public function XmlErrorHandler( $errno, $errstr ) {
+               $this->wellFormed = false;
+       }
+
+       private function validate( $reader ) {
+               // First, move through anything that isn't an element, and
+               // handle any processing instructions with the callback
+               do {
+                       if ( !$this->readNext( $reader ) ) {
+                               // Hit the end of the document before any elements
+                               $this->wellFormed = false;
+                               return;
+                       }
+                       if ( $reader->nodeType === XMLReader::PI ) {
+                               $this->processingInstructionHandler( $reader->name, $reader->value );
+                       }
+               } while ( $reader->nodeType != XMLReader::ELEMENT );
+
+               // Process the rest of the document
+               do {
+                       switch ( $reader->nodeType ) {
+                               case XMLReader::ELEMENT:
+                                       $name = $this->expandNS(
+                                               $reader->name,
+                                               $reader->namespaceURI
+                                       );
+                                       if ( $this->rootElement === '' ) {
+                                               $this->rootElement = $name;
+                                       }
+                                       $empty = $reader->isEmptyElement;
+                                       $attrs = $this->getAttributesArray( $reader );
+                                       $this->elementOpen( $name, $attrs );
+                                       if ( $empty ) {
+                                               $this->elementClose();
+                                       }
+                                       break;
+
+                               case XMLReader::END_ELEMENT:
+                                       $this->elementClose();
+                                       break;
+
+                               case XMLReader::WHITESPACE:
+                               case XMLReader::SIGNIFICANT_WHITESPACE:
+                               case XMLReader::CDATA:
+                               case XMLReader::TEXT:
+                                       $this->elementData( $reader->value );
+                                       break;
+
+                               case XMLReader::ENTITY_REF:
+                                       // Unexpanded entity (maybe external?),
+                                       // don't send to the filter (xml_parse didn't)
+                                       break;
+
+                               case XMLReader::COMMENT:
+                                       // Don't send to the filter (xml_parse didn't)
+                                       break;
+
+                               case XMLReader::PI:
+                                       // Processing instructions can happen after the header too
+                                       $this->processingInstructionHandler(
+                                               $reader->name,
+                                               $reader->value
+                                       );
+                                       break;
+                               default:
+                                       // One of DOC, DOC_TYPE, ENTITY, END_ENTITY,
+                                       // NOTATION, or XML_DECLARATION
+                                       // xml_parse didn't send these to the filter, so we won't.
+                       }
+               } while ( $this->readNext( $reader ) );
+
+               if ( $this->stackDepth !== 0 ) {
+                       $this->wellFormed = false;
+               } elseif ( $this->wellFormed === null ) {
+                       $this->wellFormed = true;
+               }
+       }
+
+       /**
+        * Get all of the attributes for an XMLReader's current node
+        * @param $r XMLReader
+        * @return array of attributes
+        */
+       private function getAttributesArray( XMLReader $r ) {
+               $attrs = [];
+               while ( $r->moveToNextAttribute() ) {
+                       if ( $r->namespaceURI === 'http://www.w3.org/2000/xmlns/' ) {
+                               // XMLReader treats xmlns attributes as normal
+                               // attributes, while xml_parse doesn't
+                               continue;
+                       }
+                       $name = $this->expandNS( $r->name, $r->namespaceURI );
+                       $attrs[$name] = $r->value;
+               }
+               return $attrs;
+       }
+
+       /**
+        * @param $name element or attribute name, maybe with a full or short prefix
+        * @param $namespaceURI the namespaceURI
+        * @return string the name prefixed with namespaceURI
+        */
+       private function expandNS( $name, $namespaceURI ) {
+               if ( $namespaceURI ) {
+                       $parts = explode( ':', $name );
+                       $localname = array_pop( $parts );
+                       return "$namespaceURI:$localname";
+               }
+               return $name;
+       }
+
+       /**
+        * @param $name
+        * @param $attribs
+        */
+       private function elementOpen( $name, $attribs ) {
+               $this->elementDataContext[] = [ $name, $attribs ];
+               $this->elementData[] = '';
+               $this->stackDepth++;
+       }
+
+       /**
+        */
+       private function elementClose() {
+               list( $name, $attribs ) = array_pop( $this->elementDataContext );
+               $data = array_pop( $this->elementData );
+               $this->stackDepth--;
+               $callbackReturn = false;
+
+               if ( is_callable( $this->filterCallback ) ) {
+                       $callbackReturn = call_user_func(
+                               $this->filterCallback,
+                               $name,
+                               $attribs,
+                               $data
+                       );
+               }
+               if ( $callbackReturn ) {
+                       // Filter hit!
+                       $this->filterMatch = true;
+                       $this->filterMatchType = $callbackReturn;
+               }
+       }
+
+       /**
+        * @param $data
+        */
+       private function elementData( $data ) {
+               // Collect any data here, and we'll run the callback in elementClose
+               $this->elementData[ $this->stackDepth - 1 ] .= trim( $data );
+       }
+
+       /**
+        * @param $target
+        * @param $data
+        */
+       private function processingInstructionHandler( $target, $data ) {
+               $callbackReturn = false;
+               if ( $this->parserOptions['processing_instruction_handler'] ) {
+                       $callbackReturn = call_user_func(
+                               $this->parserOptions['processing_instruction_handler'],
+                               $target,
+                               $data
+                       );
+               }
+               if ( $callbackReturn ) {
+                       // Filter hit!
+                       $this->filterMatch = true;
+                       $this->filterMatchType = $callbackReturn;
+               }
+       }
+}
diff --git a/includes/libs/mime/defines.php b/includes/libs/mime/defines.php
new file mode 100644 (file)
index 0000000..ae0b5f8
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+/**
+ * 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
+ */
+
+/**@{
+ * Media types.
+ * This defines constants for the value returned by File::getMediaType()
+ */
+// unknown format
+define( 'MEDIATYPE_UNKNOWN', 'UNKNOWN' );
+// some bitmap image or image source (like psd, etc). Can't scale up.
+define( 'MEDIATYPE_BITMAP', 'BITMAP' );
+// some vector drawing (SVG, WMF, PS, ...) or image source (oo-draw, etc). Can scale up.
+define( 'MEDIATYPE_DRAWING', 'DRAWING' );
+// simple audio file (ogg, mp3, wav, midi, whatever)
+define( 'MEDIATYPE_AUDIO', 'AUDIO' );
+// simple video file (ogg, mpg, etc;
+// no not include formats here that may contain executable sections or scripts!)
+define( 'MEDIATYPE_VIDEO', 'VIDEO' );
+// Scriptable Multimedia (flash, advanced video container formats, etc)
+define( 'MEDIATYPE_MULTIMEDIA', 'MULTIMEDIA' );
+// Office Documents, Spreadsheets (office formats possibly containing apples, scripts, etc)
+define( 'MEDIATYPE_OFFICE', 'OFFICE' );
+// Plain text (possibly containing program code or scripts)
+define( 'MEDIATYPE_TEXT', 'TEXT' );
+// binary executable
+define( 'MEDIATYPE_EXECUTABLE', 'EXECUTABLE' );
+// archive file (zip, tar, etc)
+define( 'MEDIATYPE_ARCHIVE', 'ARCHIVE' );
+/**@}*/
diff --git a/includes/libs/mime/mime.info b/includes/libs/mime/mime.info
new file mode 100644 (file)
index 0000000..b04d3c6
--- /dev/null
@@ -0,0 +1,119 @@
+# MIME type info file.
+# the first MIME type in each line is the "main" MIME type,
+# the others are aliases for this type
+# the media type is given in upper case and square brackets,
+# like [BITMAP], and must indicate a media type as defined by
+# the MEDIATYPE_xxx constants in Defines.php
+
+
+image/gif      [BITMAP]
+image/png image/x-png  [BITMAP]
+image/ief      [BITMAP]
+image/jpeg image/pjpeg [BITMAP]
+image/jp2      [BITMAP]
+image/xbm      [BITMAP]
+image/tiff     [BITMAP]
+image/x-icon image/x-ico image/vnd.microsoft.icon      [BITMAP]
+image/x-rgb    [BITMAP]
+image/x-portable-pixmap                [BITMAP]
+image/x-portable-graymap image/x-portable-greymap      [BITMAP]
+image/x-bmp image/x-ms-bmp image/bmp application/x-bmp application/bmp [BITMAP]
+image/x-photoshop image/psd image/x-psd image/photoshop image/vnd.adobe.photoshop      [BITMAP]
+image/vnd.djvu image/x.djvu image/x-djvu [BITMAP]
+image/webp     [BITMAP]
+
+image/svg+xml application/svg+xml application/svg image/svg    [DRAWING]
+application/postscript [DRAWING]
+application/x-latex    [DRAWING]
+application/x-tex      [DRAWING]
+application/x-dia-diagram [DRAWING]
+
+
+audio/mpeg audio/mp3 audio/mpeg3       [AUDIO]
+audio/mp4                              [AUDIO]
+audio/wav audio/x-wav audio/wave       [AUDIO]
+audio/midi audio/mid   [AUDIO]
+audio/basic            [AUDIO]
+audio/ogg              [AUDIO]
+audio/x-aiff           [AUDIO]
+audio/x-pn-realaudio   [AUDIO]
+audio/x-realaudio      [AUDIO]
+audio/webm             [AUDIO]
+audio/x-matroska       [AUDIO]
+audio/x-flac           [AUDIO]
+audio/flac             [AUDIO]
+
+video/mpeg application/mpeg    [VIDEO]
+video/ogg                      [VIDEO]
+video/x-sgi-video              [VIDEO]
+video/x-flv                    [VIDEO]
+video/webm                     [VIDEO]
+video/x-matroska               [VIDEO]
+video/mp4                      [VIDEO]
+
+application/ogg application/x-ogg audio/ogg audio/x-ogg video/ogg video/x-ogg          [MULTIMEDIA]
+
+application/x-shockwave-flash  [MULTIMEDIA]
+audio/x-pn-realaudio-plugin    [MULTIMEDIA]
+model/iges     [MULTIMEDIA]
+model/mesh     [MULTIMEDIA]
+model/vrml     [MULTIMEDIA]
+video/quicktime        [MULTIMEDIA]
+video/x-msvideo        [MULTIMEDIA]
+
+text/plain     [TEXT]
+text/html application/xhtml+xml        [TEXT]
+application/xml text/xml       [TEXT]
+text   [TEXT]
+application/json       [TEXT]
+text/csv       [TEXT]
+text/tab-separated-values      [TEXT]
+
+application/zip application/x-zip      [ARCHIVE]
+application/x-gzip     [ARCHIVE]
+application/x-bzip     [ARCHIVE]
+application/x-bzip2    [ARCHIVE]
+application/x-tar      [ARCHIVE]
+application/x-stuffit  [ARCHIVE]
+application/x-opc+zip  [ARCHIVE]
+application/x-7z-compressed [ARCHIVE]
+
+application/javascript text/javascript application/x-javascript application/x-ecmascript text/ecmascript       [EXECUTABLE]
+application/x-bash     [EXECUTABLE]
+application/x-sh       [EXECUTABLE]
+application/x-csh      [EXECUTABLE]
+application/x-tcsh     [EXECUTABLE]
+application/x-tcl      [EXECUTABLE]
+application/x-perl     [EXECUTABLE]
+application/x-python   [EXECUTABLE]
+
+application/pdf application/acrobat    [OFFICE]
+application/msword             [OFFICE]
+application/vnd.ms-excel       [OFFICE]
+application/vnd.ms-powerpoint  [OFFICE]
+application/x-director         [OFFICE]
+text/rtf                       [OFFICE]
+
+application/vnd.openxmlformats-officedocument.wordprocessingml.document        [OFFICE]
+application/vnd.openxmlformats-officedocument.wordprocessingml.template                [OFFICE]
+application/vnd.ms-word.document.macroEnabled.12                               [OFFICE]
+application/vnd.ms-word.template.macroEnabled.12                               [OFFICE]
+application/vnd.openxmlformats-officedocument.presentationml.template          [OFFICE]
+application/vnd.openxmlformats-officedocument.presentationml.slideshow         [OFFICE]
+application/vnd.openxmlformats-officedocument.presentationml.presentation      [OFFICE]
+application/vnd.ms-powerpoint.addin.macroEnabled.12                            [OFFICE]
+application/vnd.ms-powerpoint.presentation.macroEnabled.12                     [OFFICE]
+application/vnd.ms-powerpoint.presentation.macroEnabled.12                     [OFFICE]
+application/vnd.ms-powerpoint.slideshow.macroEnabled.12                                [OFFICE]
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet              [OFFICE]
+application/vnd.openxmlformats-officedocument.spreadsheetml.template           [OFFICE]
+application/vnd.ms-excel.sheet.macroEnabled.12                                 [OFFICE]
+application/vnd.ms-excel.template.macroEnabled.12                              [OFFICE]
+application/vnd.ms-excel.addin.macroEnabled.12                                 [OFFICE]
+application/vnd.ms-excel.sheet.binary.macroEnabled.12                          [OFFICE]
+application/acad application/x-acad application/autocad_dwg image/x-dwg application/dwg application/x-dwg application/x-autocad image/vnd.dwg drawing/dwg [DRAWING]
+chemical/x-mdl-molfile     [DRAWING]
+chemical/x-mdl-sdfile      [DRAWING]
+chemical/x-mdl-rxnfile     [DRAWING]
+chemical/x-mdl-rdfile      [DRAWING]
+chemical/x-mdl-rgfile      [DRAWING]
diff --git a/includes/libs/mime/mime.types b/includes/libs/mime/mime.types
new file mode 100644 (file)
index 0000000..b4f515a
--- /dev/null
@@ -0,0 +1,188 @@
+application/acad dwg
+application/andrew-inset ez
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/mathml+xml mathml
+application/msword doc dot
+application/octet-stream bin dms lha lzh exe class so dll
+application/oda oda
+application/ogg ogx ogg ogm ogv oga spx opus
+application/pdf pdf
+application/postscript ai eps ps
+application/rdf+xml rdf
+application/smil smi smil
+application/srgs gram
+application/srgs+xml grxml
+application/vnd.mif mif
+application/vnd.ms-excel xls xlt xla
+application/vnd.ms-powerpoint ppt pot pps ppa
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/voicexml+xml vxml
+application/x-7z-compressed 7z
+application/x-bcpio bcpio
+application/x-bzip bz
+application/x-bzip2 bz2
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-cpio cpio
+application/x-csh csh
+application/x-dia-diagram dia
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar tar
+application/x-gzip gz
+application/x-hdf hdf
+application/x-jar jar
+application/javascript js
+application/json json
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x-xpinstall xpi
+application/xhtml+xml xhtml xht
+application/xslt+xml xslt
+application/xml xml xsl xsd kml
+application/xml-dtd dtd
+application/zip zip jar xpi sxc stc sxd std sxi sti sxm stm sxw stw
+application/x-rar rar
+application/font-woff woff
+application/font-woff2 woff2
+application/vnd.ms-fontobject eot
+application/x-font-ttf ttf
+audio/basic au snd
+audio/midi mid midi kar
+audio/mpeg mpga mp2 mp3
+audio/ogg oga ogg spx opus
+video/webm webm
+audio/webm webm
+audio/x-aiff aif aiff aifc
+audio/x-matroska mka mkv
+audio/x-mpegurl m3u
+audio/x-ogg oga ogg spx opus
+audio/x-pn-realaudio ram rm
+audio/x-pn-realaudio-plugin rpm
+audio/x-realaudio ra
+audio/x-wav wav
+audio/wav wav
+audio/x-flac flac
+audio/flac flac
+chemical/x-pdb pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm cgm
+image/gif gif
+image/ief ief
+image/jp2 j2k jp2 jpg2
+image/jpeg jpeg jpg jpe
+image/png png apng
+image/svg+xml svg
+image/tiff tiff tif
+image/vnd.djvu djvu djv
+image/vnd.microsoft.icon ico
+image/vnd.wap.wbmp wbmp
+image/webp webp
+image/x-cmu-raster ras
+image/x-icon ico
+image/x-ms-bmp bmp
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-photoshop psd
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+model/iges igs iges
+model/mesh msh mesh silo
+model/vrml wrl vrml
+text/calendar ics ifb
+text/css css
+text/csv csv
+text/html html htm
+text/plain txt
+text/richtext rtx
+text/rtf rtf
+text/sgml sgml sgm
+text/tab-separated-values tsv
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/xml xml xsl xslt rss rdf
+text/x-component htc
+text/x-setext etx
+text/x-sawfish jl
+video/mpeg mpeg mpg mpe
+video/mp4 mp4 m4a m4p m4b m4r m4v
+audio/mp4 m4a
+video/ogg ogv ogm ogg
+video/quicktime qt mov
+video/vnd.mpegurl mxu
+video/x-flv flv
+video/x-matroska mkv mka
+video/x-msvideo avi
+video/x-ogg ogv ogm ogg
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+application/vnd.oasis.opendocument.chart odc
+application/vnd.oasis.opendocument.chart-template otc
+application/vnd.oasis.opendocument.database odb
+application/vnd.oasis.opendocument.formula odf
+application/vnd.oasis.opendocument.formula-template otf
+application/vnd.oasis.opendocument.graphics odg
+application/vnd.oasis.opendocument.graphics-template otg
+application/vnd.oasis.opendocument.image odi
+application/vnd.oasis.opendocument.image-template oti
+application/vnd.oasis.opendocument.presentation odp
+application/vnd.oasis.opendocument.presentation-template otp
+application/vnd.oasis.opendocument.spreadsheet ods
+application/vnd.oasis.opendocument.spreadsheet-template ots
+application/vnd.oasis.opendocument.text odt
+application/vnd.oasis.opendocument.text-master odm
+application/vnd.oasis.opendocument.text-template ott
+application/vnd.oasis.opendocument.text-web oth
+application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
+application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
+application/vnd.ms-word.document.macroEnabled.12 docm
+application/vnd.ms-word.template.macroEnabled.12 dotm
+application/vnd.openxmlformats-officedocument.presentationml.template potx
+application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
+application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
+application/vnd.ms-powerpoint.addin.macroEnabled.12 ppam
+application/vnd.ms-powerpoint.presentation.macroEnabled.12 pptm
+application/vnd.ms-powerpoint.presentation.macroEnabled.12 potm
+application/vnd.ms-powerpoint.slideshow.macroEnabled.12 ppsm
+application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
+application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
+application/vnd.ms-excel.sheet.macroEnabled.12 xlsm
+application/vnd.ms-excel.template.macroEnabled.12 xltm
+application/vnd.ms-excel.addin.macroEnabled.12 xlam
+application/vnd.ms-excel.sheet.binary.macroEnabled.12 xlsb
+model/vnd.dwfx+xps dwfx
+application/vnd.ms-xpsdocument xps
+application/x-opc+zip docx dotx docm dotm potx ppsx pptx ppam pptm potm ppsm xlsx xltx xlsm xltm xlam xlsb dwfx xps
+chemical/x-mdl-molfile mol
+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 8f70fc7..9bfcee7 100644 (file)
@@ -75,25 +75,35 @@ class APCBagOStuff extends BagOStuff {
        }
 
        protected function doGet( $key, $flags = 0 ) {
-               $val = apc_fetch( $key . self::KEY_SUFFIX );
+               return $this->getUnserialize(
+                       apc_fetch( $key . self::KEY_SUFFIX )
+               );
+       }
 
-               if ( is_string( $val ) && !$this->nativeSerialize ) {
-                       $val = $this->isInteger( $val )
-                               ? intval( $val )
-                               : unserialize( $val );
+       protected function getUnserialize( $value ) {
+               if ( is_string( $value ) && !$this->nativeSerialize ) {
+                       $value = $this->isInteger( $value )
+                               ? intval( $value )
+                               : unserialize( $value );
                }
-
-               return $val;
+               return $value;
        }
 
        public function set( $key, $value, $exptime = 0, $flags = 0 ) {
+               apc_store(
+                       $key . self::KEY_SUFFIX,
+                       $this->setSerialize( $value ),
+                       $exptime
+               );
+
+               return true;
+       }
+
+       protected function setSerialize( $value ) {
                if ( !$this->nativeSerialize && !$this->isInteger( $value ) ) {
                        $value = serialize( $value );
                }
-
-               apc_store( $key . self::KEY_SUFFIX, $value, $exptime );
-
-               return true;
+               return $value;
        }
 
        public function delete( $key ) {
diff --git a/includes/libs/objectcache/APCUBagOStuff.php b/includes/libs/objectcache/APCUBagOStuff.php
new file mode 100644 (file)
index 0000000..02b3c92
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Object caching using PHP's APCU accelerator.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Cache
+ */
+
+/**
+ * This is a wrapper for APCU's shared memory functions
+ *
+ * @ingroup Cache
+ */
+class APCUBagOStuff extends APCBagOStuff {
+       /**
+        * Constructor
+        *
+        * Available parameters are:
+        *   - nativeSerialize:     If true, pass objects to apcu_store(), and trust it
+        *                          to serialize them correctly. If false, serialize
+        *                          all values in PHP.
+        *
+        * @param array $params
+        */
+       public function __construct( array $params = [] ) {
+               parent::__construct( $params );
+       }
+
+       protected function doGet( $key, $flags = 0 ) {
+               return $this->getUnserialize(
+                       apcu_fetch( $key . self::KEY_SUFFIX )
+               );
+       }
+
+       public function set( $key, $value, $exptime = 0, $flags = 0 ) {
+               apcu_store(
+                       $key . self::KEY_SUFFIX,
+                       $this->setSerialize( $value ),
+                       $exptime
+               );
+
+               return true;
+       }
+
+       public function delete( $key ) {
+               apcu_delete( $key . self::KEY_SUFFIX );
+
+               return true;
+       }
+
+       public function incr( $key, $value = 1 ) {
+               /**
+                * @todo When we only support php 7 or higher remove this hack
+                *
+                * https://github.com/krakjoe/apcu/issues/166
+                */
+               if ( apcu_exists( $key . self::KEY_SUFFIX ) ) {
+                       return apcu_inc( $key . self::KEY_SUFFIX, $value );
+               } else {
+                       return apcu_set( $key . self::KEY_SUFFIX, $value );
+               }
+       }
+
+       public function decr( $key, $value = 1 ) {
+               /**
+                * @todo When we only support php 7 or higher remove this hack
+                *
+                * https://github.com/krakjoe/apcu/issues/166
+                */
+               if ( apcu_exists( $key . self::KEY_SUFFIX ) ) {
+                       return apcu_dec( $key . self::KEY_SUFFIX, $value );
+               } else {
+                       return apcu_set( $key . self::KEY_SUFFIX, -$value );
+               }
+       }
+}
index cd79b67..d0b68bc 100644 (file)
@@ -29,6 +29,8 @@
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerInterface;
 use Psr\Log\NullLogger;
+use Wikimedia\ScopedCallback;
+use Wikimedia\WaitConditionLoop;
 
 /**
  * interface is intended to be more or less compatible with
index 6973392..5128d82 100644 (file)
@@ -43,13 +43,11 @@ class MemcachedBagOStuff extends BagOStuff {
         * @return array
         */
        protected function applyDefaultParams( $params ) {
-               if ( !isset( $params['compress_threshold'] ) ) {
-                       $params['compress_threshold'] = 1500;
-               }
-               if ( !isset( $params['connect_timeout'] ) ) {
-                       $params['connect_timeout'] = 0.5;
-               }
-               return $params;
+               return $params + [
+                       'compress_threshold' => 1500,
+                       'connect_timeout' => .5,
+                       'debug' => false
+               ];
        }
 
        protected function doGet( $key, $flags = 0 ) {
index 5f6e324..8d3c6d9 100644 (file)
@@ -88,6 +88,11 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        /** @var int ERR_* constant for the "last error" registry */
        protected $lastRelayError = self::ERR_NONE;
 
+       /** @var integer Callback stack depth for getWithSetCallback() */
+       private $callbackDepth = 0;
+       /** @var mixed[] Temporary warm-up cache */
+       private $warmupCache = [];
+
        /** Max time expected to pass between delete() and DB commit finishing */
        const MAX_COMMIT_DELAY = 3;
        /** Max replication+snapshot lag before applying TTL_LAGGED or disallowing set() */
@@ -284,7 +289,14 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                }
 
                // Fetch all of the raw values
-               $wrappedValues = $this->cache->getMulti( array_merge( $valueKeys, $checkKeysFlat ) );
+               $keysGet = array_merge( $valueKeys, $checkKeysFlat );
+               if ( $this->warmupCache ) {
+                       $wrappedValues = array_intersect_key( $this->warmupCache, array_flip( $keysGet ) );
+                       $keysGet = array_diff( $keysGet, array_keys( $wrappedValues ) ); // keys left to fetch
+               } else {
+                       $wrappedValues = [];
+               }
+               $wrappedValues += $this->cache->getMulti( $keysGet );
                // Time used to compare/init "check" keys (derived after getMulti() to be pessimistic)
                $now = microtime( true );
 
@@ -837,8 +849,10 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
        final public function getWithSetCallback( $key, $ttl, $callback, array $opts = [] ) {
                $pcTTL = isset( $opts['pcTTL'] ) ? $opts['pcTTL'] : self::TTL_UNCACHEABLE;
 
-               // Try the process cache if enabled
-               if ( $pcTTL >= 0 ) {
+               // Try the process cache if enabled and the cache callback is not within a cache callback.
+               // Process cache use in nested callbacks is not lag-safe with regard to HOLDOFF_TTL since
+               // the in-memory value is further lagged than the shared one since it uses a blind TTL.
+               if ( $pcTTL >= 0 && $this->callbackDepth == 0 ) {
                        $group = isset( $opts['pcGroup'] ) ? $opts['pcGroup'] : self::PC_PRIMARY;
                        $procCache = $this->getProcessCache( $group );
                        $value = $procCache->get( $key );
@@ -929,12 +943,13 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                $cValue = $this->get( $key, $curTTL, $checkKeys, $asOf ); // current value
                $value = $cValue; // return value
 
-               // Determine if a regeneration is desired
+               $preCallbackTime = microtime( true );
+               // Determine if a cached value regeneration is needed or desired
                if ( $value !== false
                        && $curTTL > 0
                        && $this->isValid( $value, $versioned, $asOf, $minTime )
                        && !$this->worthRefreshExpiring( $curTTL, $lowTTL )
-                       && !$this->worthRefreshPopular( $asOf, $ageNew, $popWindow )
+                       && !$this->worthRefreshPopular( $asOf, $ageNew, $popWindow, $preCallbackTime )
                ) {
                        return $value;
                }
@@ -984,7 +999,12 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
                // Generate the new value from the callback...
                $setOpts = [];
-               $value = call_user_func_array( $callback, [ $cValue, &$ttl, &$setOpts, $asOf ] );
+               ++$this->callbackDepth;
+               try {
+                       $value = call_user_func_array( $callback, [ $cValue, &$ttl, &$setOpts, $asOf ] );
+               } finally {
+                       --$this->callbackDepth;
+               }
                // When delete() is called, writes are write-holed by the tombstone,
                // so use a special INTERIM key to pass the new value around threads.
                if ( ( $isTombstone && $lockTSE > 0 ) && $value !== false && $ttl >= 0 ) {
@@ -1003,8 +1023,10 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                }
 
                if ( $value !== false && $ttl >= 0 ) {
-                       // Update the cache; this will fail if the key is tombstoned
                        $setOpts['lockTSE'] = $lockTSE;
+                       // Use best known "since" timestamp if not provided
+                       $setOpts += [ 'since' => $preCallbackTime ];
+                       // Update the cache; this will fail if the key is tombstoned
                        $this->set( $key, $value, $ttl, $setOpts );
                }
 
@@ -1016,6 +1038,95 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                return $value;
        }
 
+       /**
+        * Method to fetch/regenerate multiple cache keys at once
+        *
+        * This works the same as getWithSetCallback() except:
+        *   - a) The $keys argument expects the result of WANObjectCache::makeMultiKeys()
+        *   - b) The $callback argument expects a callback taking the following arguments:
+        *         - $id: ID of an entity to query
+        *         - $oldValue : the prior cache value or false if none was present
+        *         - &$ttl : a reference to the new value TTL in seconds
+        *         - &$setOpts : a reference to options for set() which can be altered
+        *         - $oldAsOf : generation UNIX timestamp of $oldValue or null if not present
+        *        Aside from the additional $id argument, the other arguments function the same
+        *        way they do in getWithSetCallback().
+        *   - c) The return value is a map of (cache key => value) in the order of $keyedIds
+        *
+        * @see WANObjectCache::getWithSetCallback()
+        *
+        * Example usage:
+        * @code
+        *     $rows = $cache->getMultiWithSetCallback(
+        *         // Map of cache keys to entity IDs
+        *         $cache->makeMultiKeys(
+        *             $this->fileVersionIds(),
+        *             function ( $id, WANObjectCache $cache ) {
+        *                 return $cache->makeKey( 'file-version', $id );
+        *             }
+        *         ),
+        *         // Time-to-live (in seconds)
+        *         $cache::TTL_DAY,
+        *         // Function that derives the new key value
+        *         return function ( $id, $oldValue, &$ttl, array &$setOpts ) {
+        *             $dbr = wfGetDB( DB_REPLICA );
+        *             // Account for any snapshot/replica DB lag
+        *             $setOpts += Database::getCacheSetOptions( $dbr );
+        *
+        *             // Load the row for this file
+        *             $row = $dbr->selectRow( 'file', '*', [ 'id' => $id ], __METHOD__ );
+        *
+        *             return $row ? (array)$row : false;
+        *         },
+        *         [
+        *             // Process cache for 30 seconds
+        *             'pcTTL' => 30,
+        *             // Use a dedicated 500 item cache (initialized on-the-fly)
+        *             'pcGroup' => 'file-versions:500'
+        *         ]
+        *     );
+        *     $files = array_map( [ __CLASS__, 'newFromRow' ], $rows );
+        * @endcode
+        *
+        * @param ArrayIterator $keyedIds Result of WANObjectCache::makeMultiKeys()
+        * @param integer $ttl Seconds to live for key updates
+        * @param callable $callback Callback the yields entity regeneration callbacks
+        * @param array $opts Options map
+        * @return array Map of (cache key => value) in the same order as $keyedIds
+        * @since 1.28
+        */
+       final public function getMultiWithSetCallback(
+               ArrayIterator $keyedIds, $ttl, callable $callback, array $opts = []
+       ) {
+               $keysWarmUp = iterator_to_array( $keyedIds, true );
+               $checkKeys = isset( $opts['checkKeys'] ) ? $opts['checkKeys'] : [];
+               foreach ( $checkKeys as $i => $checkKeyOrKeys ) {
+                       if ( is_int( $i ) ) {
+                               $keysWarmUp[] = $checkKeyOrKeys;
+                       } else {
+                               $keysWarmUp = array_merge( $keysWarmUp, $checkKeyOrKeys );
+                       }
+               }
+
+               $this->warmupCache = $this->cache->getMulti( $keysWarmUp );
+               $this->warmupCache += array_fill_keys( $keysWarmUp, false );
+
+               // Wrap $callback to match the getWithSetCallback() format while passing $id to $callback
+               $id = null;
+               $func = function ( $oldValue, &$ttl, array $setOpts, $oldAsOf ) use ( $callback, &$id ) {
+                       return $callback( $id, $oldValue, $ttl, $setOpts, $oldAsOf );
+               };
+
+               $values = [];
+               foreach ( $keyedIds as $key => $id ) {
+                       $values[$key] = $this->getWithSetCallback( $key, $ttl, $func, $opts );
+               }
+
+               $this->warmupCache = [];
+
+               return $values;
+       }
+
        /**
         * @see BagOStuff::makeKey()
         * @param string ... Key component
@@ -1036,6 +1147,21 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                return call_user_func_array( [ $this->cache, __FUNCTION__ ], func_get_args() );
        }
 
+       /**
+        * @param array $entities List of entity IDs
+        * @param callable $keyFunc Callback yielding a key from (entity ID, this WANObjectCache)
+        * @return ArrayIterator Iterator yielding (cache key => entity ID) in $entities order
+        * @since 1.28
+        */
+       public function makeMultiKeys( array $entities, callable $keyFunc ) {
+               $map = [];
+               foreach ( $entities as $entity ) {
+                       $map[$keyFunc( $entity, $this )] = $entity;
+               }
+
+               return new ArrayIterator( $map );
+       }
+
        /**
         * Get the "last error" registered; clearLastError() should be called manually
         * @return int ERR_* class constant for the "last error" registry
@@ -1222,10 +1348,11 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         * @param float $asOf UNIX timestamp of the value
         * @param integer $ageNew Age of key when this might recommend refreshing (seconds)
         * @param integer $timeTillRefresh Age of key when it should be refreshed if popular (seconds)
+        * @param float $now The current UNIX timestamp
         * @return bool
         */
-       protected function worthRefreshPopular( $asOf, $ageNew, $timeTillRefresh ) {
-               $age = microtime( true ) - $asOf;
+       protected function worthRefreshPopular( $asOf, $ageNew, $timeTillRefresh, $now ) {
+               $age = $now - $asOf;
                $timeOld = $age - $ageNew;
                if ( $timeOld <= 0 ) {
                        return false;
index 6996ce5..d84c959 100644 (file)
  */
 class WinCacheBagOStuff extends BagOStuff {
        protected function doGet( $key, $flags = 0 ) {
-               $casToken = null;
-
-               return $this->getWithToken( $key, $casToken, $flags );
-       }
-
-       protected function getWithToken( $key, &$casToken, $flags = 0 ) {
                $val = wincache_ucache_get( $key );
-
-               $casToken = $val;
-
                if ( is_string( $val ) ) {
                        $val = unserialize( $val );
                }
@@ -54,10 +45,6 @@ class WinCacheBagOStuff extends BagOStuff {
                return ( is_array( $result ) && $result === [] ) || $result;
        }
 
-       protected function cas( $casToken, $key, $value, $exptime = 0 ) {
-               return wincache_ucache_cas( $key, $casToken, serialize( $value ) );
-       }
-
        public function delete( $key ) {
                wincache_ucache_delete( $key );
 
diff --git a/includes/libs/rdbms/ChronologyProtector.php b/includes/libs/rdbms/ChronologyProtector.php
new file mode 100644 (file)
index 0000000..88af1db
--- /dev/null
@@ -0,0 +1,326 @@
+<?php
+/**
+ * Generator of database load balancing objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Database
+ */
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Wikimedia\WaitConditionLoop;
+
+/**
+ * Class for ensuring a consistent ordering of events as seen by the user, despite replication.
+ * Kind of like Hawking's [[Chronology Protection Agency]].
+ */
+class ChronologyProtector implements LoggerAwareInterface {
+       /** @var BagOStuff */
+       protected $store;
+       /** @var LoggerInterface */
+       protected $logger;
+
+       /** @var string Storage key name */
+       protected $key;
+       /** @var string Hash of client parameters */
+       protected $clientId;
+       /** @var float|null Minimum UNIX timestamp of 1+ expected startup positions */
+       protected $waitForPosTime;
+       /** @var int Max seconds to wait on positions to appear */
+       protected $waitForPosTimeout = self::POS_WAIT_TIMEOUT;
+       /** @var bool Whether to no-op all method calls */
+       protected $enabled = true;
+       /** @var bool Whether to check and wait on positions */
+       protected $wait = true;
+
+       /** @var bool Whether the client data was loaded */
+       protected $initialized = false;
+       /** @var DBMasterPos[] Map of (DB master name => position) */
+       protected $startupPositions = [];
+       /** @var DBMasterPos[] Map of (DB master name => position) */
+       protected $shutdownPositions = [];
+       /** @var float[] Map of (DB master name => 1) */
+       protected $shutdownTouchDBs = [];
+
+       /** @var integer Seconds to store positions */
+       const POSITION_TTL = 60;
+       /** @var integer Max time to wait for positions to appear */
+       const POS_WAIT_TIMEOUT = 5;
+
+       /**
+        * @param BagOStuff $store
+        * @param array $client Map of (ip: <IP>, agent: <user-agent>)
+        * @param float $posTime UNIX timestamp
+        * @since 1.27
+        */
+       public function __construct( BagOStuff $store, array $client, $posTime = null ) {
+               $this->store = $store;
+               $this->clientId = md5( $client['ip'] . "\n" . $client['agent'] );
+               $this->key = $store->makeGlobalKey( __CLASS__, $this->clientId );
+               $this->waitForPosTime = $posTime;
+               $this->logger = new \Psr\Log\NullLogger();
+       }
+
+       public function setLogger( LoggerInterface $logger ) {
+               $this->logger = $logger;
+       }
+
+       /**
+        * @param bool $enabled Whether to no-op all method calls
+        * @since 1.27
+        */
+       public function setEnabled( $enabled ) {
+               $this->enabled = $enabled;
+       }
+
+       /**
+        * @param bool $enabled Whether to check and wait on positions
+        * @since 1.27
+        */
+       public function setWaitEnabled( $enabled ) {
+               $this->wait = $enabled;
+       }
+
+       /**
+        * Initialise a ILoadBalancer to give it appropriate chronology protection.
+        *
+        * If the stash has a previous master position recorded, this will try to
+        * make sure that the next query to a replica DB of that master will see changes up
+        * to that position by delaying execution. The delay may timeout and allow stale
+        * data if no non-lagged replica DBs are available.
+        *
+        * @param ILoadBalancer $lb
+        * @return void
+        */
+       public function initLB( ILoadBalancer $lb ) {
+               if ( !$this->enabled || $lb->getServerCount() <= 1 ) {
+                       return; // non-replicated setup or disabled
+               }
+
+               $this->initPositions();
+
+               $masterName = $lb->getServerName( $lb->getWriterIndex() );
+               if ( !empty( $this->startupPositions[$masterName] ) ) {
+                       $pos = $this->startupPositions[$masterName];
+                       $this->logger->info( __METHOD__ . ": LB for '$masterName' set to pos $pos\n" );
+                       $lb->waitFor( $pos );
+               }
+       }
+
+       /**
+        * Notify the ChronologyProtector that the ILoadBalancer is about to shut
+        * down. Saves replication positions.
+        *
+        * @param ILoadBalancer $lb
+        * @return void
+        */
+       public function shutdownLB( ILoadBalancer $lb ) {
+               if ( !$this->enabled ) {
+                       return; // not enabled
+               } elseif ( !$lb->hasOrMadeRecentMasterChanges( INF ) ) {
+                       // Only save the position if writes have been done on the connection
+                       return;
+               }
+
+               $masterName = $lb->getServerName( $lb->getWriterIndex() );
+               if ( $lb->getServerCount() > 1 ) {
+                       $pos = $lb->getMasterPos();
+                       $this->logger->info( __METHOD__ . ": LB for '$masterName' has pos $pos\n" );
+                       $this->shutdownPositions[$masterName] = $pos;
+               } else {
+                       $this->logger->info( __METHOD__ . ": DB '$masterName' touched\n" );
+               }
+               $this->shutdownTouchDBs[$masterName] = 1;
+       }
+
+       /**
+        * Notify the ChronologyProtector that the LBFactory is done calling shutdownLB() for now.
+        * May commit chronology data to persistent storage.
+        *
+        * @param callable|null $workCallback Work to do instead of waiting on syncing positions
+        * @param string $mode One of (sync, async); whether to wait on remote datacenters
+        * @return DBMasterPos[] Empty on success; returns the (db name => position) map on failure
+        */
+       public function shutdown( callable $workCallback = null, $mode = 'sync' ) {
+               if ( !$this->enabled ) {
+                       return [];
+               }
+
+               $store = $this->store;
+               // Some callers might want to know if a user recently touched a DB.
+               // These writes do not need to block on all datacenters receiving them.
+               foreach ( $this->shutdownTouchDBs as $dbName => $unused ) {
+                       $store->set(
+                               $this->getTouchedKey( $this->store, $dbName ),
+                               microtime( true ),
+                               $store::TTL_DAY
+                       );
+               }
+
+               if ( !count( $this->shutdownPositions ) ) {
+                       return []; // nothing to save
+               }
+
+               $this->logger->info( __METHOD__ . ": saving master pos for " .
+                       implode( ', ', array_keys( $this->shutdownPositions ) ) . "\n"
+               );
+
+               // CP-protected writes should overwhemingly go to the master datacenter, so get DC-local
+               // lock to merge the values. Use a DC-local get() and a synchronous all-DC set(). This
+               // makes it possible for the BagOStuff class to write in parallel to all DCs with one RTT.
+               if ( $store->lock( $this->key, 3 ) ) {
+                       if ( $workCallback ) {
+                               // Let the store run the work before blocking on a replication sync barrier. By the
+                               // time it's done with the work, the barrier should be fast if replication caught up.
+                               $store->addBusyCallback( $workCallback );
+                       }
+                       $ok = $store->set(
+                               $this->key,
+                               self::mergePositions( $store->get( $this->key ), $this->shutdownPositions ),
+                               self::POSITION_TTL,
+                               ( $mode === 'sync' ) ? $store::WRITE_SYNC : 0
+                       );
+                       $store->unlock( $this->key );
+               } else {
+                       $ok = false;
+               }
+
+               if ( !$ok ) {
+                       $bouncedPositions = $this->shutdownPositions;
+                       // Raced out too many times or stash is down
+                       $this->logger->warning( __METHOD__ . ": failed to save master pos for " .
+                               implode( ', ', array_keys( $this->shutdownPositions ) ) . "\n"
+                       );
+               } elseif ( $mode === 'sync' &&
+                       $store->getQoS( $store::ATTR_SYNCWRITES ) < $store::QOS_SYNCWRITES_BE
+               ) {
+                       // Positions may not be in all datacenters, force LBFactory to play it safe
+                       $this->logger->info( __METHOD__ . ": store may not support synchronous writes." );
+                       $bouncedPositions = $this->shutdownPositions;
+               } else {
+                       $bouncedPositions = [];
+               }
+
+               return $bouncedPositions;
+       }
+
+       /**
+        * @param string $dbName DB master name (e.g. "db1052")
+        * @return float|bool UNIX timestamp when client last touched the DB; false if not on record
+        * @since 1.28
+        */
+       public function getTouched( $dbName ) {
+               return $this->store->get( $this->getTouchedKey( $this->store, $dbName ) );
+       }
+
+       /**
+        * @param BagOStuff $store
+        * @param string $dbName
+        * @return string
+        */
+       private function getTouchedKey( BagOStuff $store, $dbName ) {
+               return $store->makeGlobalKey( __CLASS__, 'mtime', $this->clientId, $dbName );
+       }
+
+       /**
+        * Load in previous master positions for the client
+        */
+       protected function initPositions() {
+               if ( $this->initialized ) {
+                       return;
+               }
+
+               $this->initialized = true;
+               if ( $this->wait ) {
+                       // If there is an expectation to see master positions with a certain min
+                       // timestamp, then block until they appear, or until a timeout is reached.
+                       if ( $this->waitForPosTime > 0.0 ) {
+                               $data = null;
+                               $loop = new WaitConditionLoop(
+                                       function () use ( &$data ) {
+                                               $data = $this->store->get( $this->key );
+
+                                               return ( self::minPosTime( $data ) >= $this->waitForPosTime )
+                                                       ? WaitConditionLoop::CONDITION_REACHED
+                                                       : WaitConditionLoop::CONDITION_CONTINUE;
+                                       },
+                                       $this->waitForPosTimeout
+                               );
+                               $result = $loop->invoke();
+                               $waitedMs = $loop->getLastWaitTime() * 1e3;
+
+                               if ( $result == $loop::CONDITION_REACHED ) {
+                                       $msg = "expected and found pos time {$this->waitForPosTime} ({$waitedMs}ms)";
+                                       $this->logger->debug( $msg );
+                               } else {
+                                       $msg = "expected but missed pos time {$this->waitForPosTime} ({$waitedMs}ms)";
+                                       $this->logger->info( $msg );
+                               }
+                       } else {
+                               $data = $this->store->get( $this->key );
+                       }
+
+                       $this->startupPositions = $data ? $data['positions'] : [];
+                       $this->logger->info( __METHOD__ . ": key is {$this->key} (read)\n" );
+               } else {
+                       $this->startupPositions = [];
+                       $this->logger->info( __METHOD__ . ": key is {$this->key} (unread)\n" );
+               }
+       }
+
+       /**
+        * @param array|bool $data
+        * @return float|null
+        */
+       private static function minPosTime( $data ) {
+               if ( !isset( $data['positions'] ) ) {
+                       return null;
+               }
+
+               $min = null;
+               foreach ( $data['positions'] as $pos ) {
+                       /** @var DBMasterPos $pos */
+                       $min = $min ? min( $pos->asOfTime(), $min ) : $pos->asOfTime();
+               }
+
+               return $min;
+       }
+
+       /**
+        * @param array|bool $curValue
+        * @param DBMasterPos[] $shutdownPositions
+        * @return array
+        */
+       private static function mergePositions( $curValue, array $shutdownPositions ) {
+               /** @var $curPositions DBMasterPos[] */
+               if ( $curValue === false ) {
+                       $curPositions = $shutdownPositions;
+               } else {
+                       $curPositions = $curValue['positions'];
+                       // Use the newest positions for each DB master
+                       foreach ( $shutdownPositions as $db => $pos ) {
+                               if ( !isset( $curPositions[$db] )
+                                       || $pos->asOfTime() > $curPositions[$db]->asOfTime()
+                               ) {
+                                       $curPositions[$db] = $pos;
+                               }
+                       }
+               }
+
+               return [ 'positions' => $curPositions ];
+       }
+}
index 4d2b28f..bf5e299 100644 (file)
@@ -80,11 +80,15 @@ class TransactionProfiler implements LoggerAwareInterface {
        }
 
        /**
-        * @param bool $value
+        * @param bool $value New value
+        * @return bool Old value
         * @since 1.28
         */
        public function setSilenced( $value ) {
+               $old = $this->silenced;
                $this->silenced = $value;
+
+               return $old;
        }
 
        /**
@@ -295,13 +299,15 @@ class TransactionProfiler implements LoggerAwareInterface {
                        }
                }
                if ( $slow ) {
-                       $dbs = implode( ', ', array_keys( $this->dbTrxHoldingLocks[$name]['conns'] ) );
-                       $msg = "Sub-optimal transaction on DB(s) [{$dbs}]:\n";
+                       $trace = '';
                        foreach ( $this->dbTrxMethodTimes[$name] as $i => $info ) {
                                list( $query, $sTime, $end ) = $info;
-                               $msg .= sprintf( "%d\t%.6f\t%s\n", $i, ( $end - $sTime ), $query );
+                               $trace .= sprintf( "%d\t%.6f\t%s\n", $i, ( $end - $sTime ), $query );
                        }
-                       $this->logger->info( $msg );
+                       $this->logger->info( "Sub-optimal transaction on DB(s) [{dbs}]: \n{trace}", [
+                               'dbs' => implode( ', ', array_keys( $this->dbTrxHoldingLocks[$name]['conns'] ) ),
+                               'trace' => $trace
+                       ] );
                }
                unset( $this->dbTrxHoldingLocks[$name] );
                unset( $this->dbTrxMethodTimes[$name] );
diff --git a/includes/libs/rdbms/chronologyprotector/ChronologyProtector.php b/includes/libs/rdbms/chronologyprotector/ChronologyProtector.php
deleted file mode 100644 (file)
index 94a3b6c..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-<?php
-/**
- * Generator of database load balancing objects.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Database
- */
-use Psr\Log\LoggerAwareInterface;
-use Psr\Log\LoggerInterface;
-
-/**
- * Class for ensuring a consistent ordering of events as seen by the user, despite replication.
- * Kind of like Hawking's [[Chronology Protection Agency]].
- */
-class ChronologyProtector implements LoggerAwareInterface{
-       /** @var BagOStuff */
-       protected $store;
-       /** @var LoggerInterface */
-       protected $logger;
-
-       /** @var string Storage key name */
-       protected $key;
-       /** @var string Hash of client parameters */
-       protected $clientId;
-       /** @var float|null Minimum UNIX timestamp of 1+ expected startup positions */
-       protected $waitForPosTime;
-       /** @var int Max seconds to wait on positions to appear */
-       protected $waitForPosTimeout = self::POS_WAIT_TIMEOUT;
-       /** @var bool Whether to no-op all method calls */
-       protected $enabled = true;
-       /** @var bool Whether to check and wait on positions */
-       protected $wait = true;
-
-       /** @var bool Whether the client data was loaded */
-       protected $initialized = false;
-       /** @var DBMasterPos[] Map of (DB master name => position) */
-       protected $startupPositions = [];
-       /** @var DBMasterPos[] Map of (DB master name => position) */
-       protected $shutdownPositions = [];
-       /** @var float[] Map of (DB master name => 1) */
-       protected $shutdownTouchDBs = [];
-
-       /** @var integer Seconds to store positions */
-       const POSITION_TTL = 60;
-       /** @var integer Max time to wait for positions to appear */
-       const POS_WAIT_TIMEOUT = 5;
-
-       /**
-        * @param BagOStuff $store
-        * @param array $client Map of (ip: <IP>, agent: <user-agent>)
-        * @param float $posTime UNIX timestamp
-        * @since 1.27
-        */
-       public function __construct( BagOStuff $store, array $client, $posTime = null ) {
-               $this->store = $store;
-               $this->clientId = md5( $client['ip'] . "\n" . $client['agent'] );
-               $this->key = $store->makeGlobalKey( __CLASS__, $this->clientId );
-               $this->waitForPosTime = $posTime;
-               $this->logger = new \Psr\Log\NullLogger();
-       }
-
-       public function setLogger( LoggerInterface $logger ) {
-               $this->logger = $logger;
-       }
-
-       /**
-        * @param bool $enabled Whether to no-op all method calls
-        * @since 1.27
-        */
-       public function setEnabled( $enabled ) {
-               $this->enabled = $enabled;
-       }
-
-       /**
-        * @param bool $enabled Whether to check and wait on positions
-        * @since 1.27
-        */
-       public function setWaitEnabled( $enabled ) {
-               $this->wait = $enabled;
-       }
-
-       /**
-        * Initialise a ILoadBalancer to give it appropriate chronology protection.
-        *
-        * If the stash has a previous master position recorded, this will try to
-        * make sure that the next query to a replica DB of that master will see changes up
-        * to that position by delaying execution. The delay may timeout and allow stale
-        * data if no non-lagged replica DBs are available.
-        *
-        * @param ILoadBalancer $lb
-        * @return void
-        */
-       public function initLB( ILoadBalancer $lb ) {
-               if ( !$this->enabled || $lb->getServerCount() <= 1 ) {
-                       return; // non-replicated setup or disabled
-               }
-
-               $this->initPositions();
-
-               $masterName = $lb->getServerName( $lb->getWriterIndex() );
-               if ( !empty( $this->startupPositions[$masterName] ) ) {
-                       $pos = $this->startupPositions[$masterName];
-                       $this->logger->info( __METHOD__ . ": LB for '$masterName' set to pos $pos\n" );
-                       $lb->waitFor( $pos );
-               }
-       }
-
-       /**
-        * Notify the ChronologyProtector that the ILoadBalancer is about to shut
-        * down. Saves replication positions.
-        *
-        * @param ILoadBalancer $lb
-        * @return void
-        */
-       public function shutdownLB( ILoadBalancer $lb ) {
-               if ( !$this->enabled ) {
-                       return; // not enabled
-               } elseif ( !$lb->hasOrMadeRecentMasterChanges( INF ) ) {
-                       // Only save the position if writes have been done on the connection
-                       return;
-               }
-
-               $masterName = $lb->getServerName( $lb->getWriterIndex() );
-               if ( $lb->getServerCount() > 1 ) {
-                       $pos = $lb->getMasterPos();
-                       $this->logger->info( __METHOD__ . ": LB for '$masterName' has pos $pos\n" );
-                       $this->shutdownPositions[$masterName] = $pos;
-               } else {
-                       $this->logger->info( __METHOD__ . ": DB '$masterName' touched\n" );
-               }
-               $this->shutdownTouchDBs[$masterName] = 1;
-       }
-
-       /**
-        * Notify the ChronologyProtector that the LBFactory is done calling shutdownLB() for now.
-        * May commit chronology data to persistent storage.
-        *
-        * @param callable|null $workCallback Work to do instead of waiting on syncing positions
-        * @param string $mode One of (sync, async); whether to wait on remote datacenters
-        * @return DBMasterPos[] Empty on success; returns the (db name => position) map on failure
-        */
-       public function shutdown( callable $workCallback = null, $mode = 'sync' ) {
-               if ( !$this->enabled ) {
-                       return [];
-               }
-
-               $store = $this->store;
-               // Some callers might want to know if a user recently touched a DB.
-               // These writes do not need to block on all datacenters receiving them.
-               foreach ( $this->shutdownTouchDBs as $dbName => $unused ) {
-                       $store->set(
-                               $this->getTouchedKey( $this->store, $dbName ),
-                               microtime( true ),
-                               $store::TTL_DAY
-                       );
-               }
-
-               if ( !count( $this->shutdownPositions ) ) {
-                       return []; // nothing to save
-               }
-
-               $this->logger->info( __METHOD__ . ": saving master pos for " .
-                       implode( ', ', array_keys( $this->shutdownPositions ) ) . "\n"
-               );
-
-               // CP-protected writes should overwhemingly go to the master datacenter, so get DC-local
-               // lock to merge the values. Use a DC-local get() and a synchronous all-DC set(). This
-               // makes it possible for the BagOStuff class to write in parallel to all DCs with one RTT.
-               if ( $store->lock( $this->key, 3 ) ) {
-                       if ( $workCallback ) {
-                               // Let the store run the work before blocking on a replication sync barrier. By the
-                               // time it's done with the work, the barrier should be fast if replication caught up.
-                               $store->addBusyCallback( $workCallback );
-                       }
-                       $ok = $store->set(
-                               $this->key,
-                               self::mergePositions( $store->get( $this->key ), $this->shutdownPositions ),
-                               self::POSITION_TTL,
-                               ( $mode === 'sync' ) ? $store::WRITE_SYNC : 0
-                       );
-                       $store->unlock( $this->key );
-               } else {
-                       $ok = false;
-               }
-
-               if ( !$ok ) {
-                       $bouncedPositions = $this->shutdownPositions;
-                       // Raced out too many times or stash is down
-                       $this->logger->warning( __METHOD__ . ": failed to save master pos for " .
-                               implode( ', ', array_keys( $this->shutdownPositions ) ) . "\n"
-                       );
-               } elseif ( $mode === 'sync' &&
-                       $store->getQoS( $store::ATTR_SYNCWRITES ) < $store::QOS_SYNCWRITES_BE
-               ) {
-                       // Positions may not be in all datacenters, force LBFactory to play it safe
-                       $this->logger->info( __METHOD__ . ": store may not support synchronous writes." );
-                       $bouncedPositions = $this->shutdownPositions;
-               } else {
-                       $bouncedPositions = [];
-               }
-
-               return $bouncedPositions;
-       }
-
-       /**
-        * @param string $dbName DB master name (e.g. "db1052")
-        * @return float|bool UNIX timestamp when client last touched the DB; false if not on record
-        * @since 1.28
-        */
-       public function getTouched( $dbName ) {
-               return $this->store->get( $this->getTouchedKey( $this->store, $dbName ) );
-       }
-
-       /**
-        * @param BagOStuff $store
-        * @param string $dbName
-        * @return string
-        */
-       private function getTouchedKey( BagOStuff $store, $dbName ) {
-               return $store->makeGlobalKey( __CLASS__, 'mtime', $this->clientId, $dbName );
-       }
-
-       /**
-        * Load in previous master positions for the client
-        */
-       protected function initPositions() {
-               if ( $this->initialized ) {
-                       return;
-               }
-
-               $this->initialized = true;
-               if ( $this->wait ) {
-                       // If there is an expectation to see master positions with a certain min
-                       // timestamp, then block until they appear, or until a timeout is reached.
-                       if ( $this->waitForPosTime > 0.0 ) {
-                               $data = null;
-                               $loop = new WaitConditionLoop(
-                                       function () use ( &$data ) {
-                                               $data = $this->store->get( $this->key );
-
-                                               return ( self::minPosTime( $data ) >= $this->waitForPosTime )
-                                                       ? WaitConditionLoop::CONDITION_REACHED
-                                                       : WaitConditionLoop::CONDITION_CONTINUE;
-                                       },
-                                       $this->waitForPosTimeout
-                               );
-                               $result = $loop->invoke();
-                               $waitedMs = $loop->getLastWaitTime() * 1e3;
-
-                               if ( $result == $loop::CONDITION_REACHED ) {
-                                       $msg = "expected and found pos time {$this->waitForPosTime} ({$waitedMs}ms)";
-                                       $this->logger->debug( $msg );
-                               } else {
-                                       $msg = "expected but missed pos time {$this->waitForPosTime} ({$waitedMs}ms)";
-                                       $this->logger->info( $msg );
-                               }
-                       } else {
-                               $data = $this->store->get( $this->key );
-                       }
-
-                       $this->startupPositions = $data ? $data['positions'] : [];
-                       $this->logger->info( __METHOD__ . ": key is {$this->key} (read)\n" );
-               } else {
-                       $this->startupPositions = [];
-                       $this->logger->info( __METHOD__ . ": key is {$this->key} (unread)\n" );
-               }
-       }
-
-       /**
-        * @param array|bool $data
-        * @return float|null
-        */
-       private static function minPosTime( $data ) {
-               if ( !isset( $data['positions'] ) ) {
-                       return null;
-               }
-
-               $min = null;
-               foreach ( $data['positions'] as $pos ) {
-                       /** @var DBMasterPos $pos */
-                       $min = $min ? min( $pos->asOfTime(), $min ) : $pos->asOfTime();
-               }
-
-               return $min;
-       }
-
-       /**
-        * @param array|bool $curValue
-        * @param DBMasterPos[] $shutdownPositions
-        * @return array
-        */
-       private static function mergePositions( $curValue, array $shutdownPositions ) {
-               /** @var $curPositions DBMasterPos[] */
-               if ( $curValue === false ) {
-                       $curPositions = $shutdownPositions;
-               } else {
-                       $curPositions = $curValue['positions'];
-                       // Use the newest positions for each DB master
-                       foreach ( $shutdownPositions as $db => $pos ) {
-                               if ( !isset( $curPositions[$db] )
-                                       || $pos->asOfTime() > $curPositions[$db]->asOfTime()
-                               ) {
-                                       $curPositions[$db] = $pos;
-                               }
-                       }
-               }
-
-               return [ 'positions' => $curPositions ];
-       }
-}
index 2b058e9..3d35d76 100644 (file)
@@ -25,6 +25,7 @@
  */
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerInterface;
+use Wikimedia\ScopedCallback;
 
 /**
  * Relational database abstraction object
@@ -50,8 +51,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        /** @var string SQL query */
        protected $mLastQuery = '';
-       /** @var bool */
-       protected $mDoneWrites = false;
+       /** @var float|bool UNIX timestamp of last write query */
+       protected $mLastWriteTime = false;
        /** @var string|bool */
        protected $mPHPError = false;
        /** @var string */
@@ -78,7 +79,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        /** @var callback Error logging callback */
        protected $errorLogger;
 
-       /** @var resource Database connection */
+       /** @var resource|null Database connection */
        protected $mConn = null;
        /** @var bool */
        protected $mOpened = false;
@@ -352,7 +353,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                } else {
                        $driver = $dbType;
                }
-               if ( $driver === false ) {
+               if ( $driver === false || $driver === '' ) {
                        throw new InvalidArgumentException( __METHOD__ .
                                " no viable database extension found for type '$dbType'" );
                }
@@ -382,7 +383,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        }
                        if ( !isset( $p['errorLogger'] ) ) {
                                $p['errorLogger'] = function ( Exception $e ) {
-                                       trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_WARNING );
+                                       trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_USER_WARNING );
                                };
                        }
 
@@ -511,11 +512,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        public function doneWrites() {
-               return (bool)$this->mDoneWrites;
+               return (bool)$this->mLastWriteTime;
        }
 
        public function lastDoneWrites() {
-               return $this->mDoneWrites ?: false;
+               return $this->mLastWriteTime ?: false;
        }
 
        public function writesPending() {
@@ -608,6 +609,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                return !!( $this->mFlags & $flag );
        }
 
+       /**
+        * @param string $name Class field name
+        * @return mixed
+        * @deprecated Since 1.28
+        */
        public function getProperty( $name ) {
                return $this->$name;
        }
@@ -651,14 +657,22 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                if ( $this->htmlErrors !== false ) {
                        ini_set( 'html_errors', $this->htmlErrors );
                }
+
+               return $this->getLastPHPError();
+       }
+
+       /**
+        * @return string|bool Last PHP error for this DB (typically connection errors)
+        */
+       protected function getLastPHPError() {
                if ( $this->mPHPError ) {
                        $error = preg_replace( '!\[<a.*</a>\]!', '', $this->mPHPError );
                        $error = preg_replace( '!^.*?:\s?(.*)$!', '$1', $error );
 
                        return $error;
-               } else {
-                       return false;
                }
+
+               return false;
        }
 
        /**
@@ -773,8 +787,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @return bool
         */
        protected function isTransactableQuery( $sql ) {
-               $verb = $this->getQueryVerb( $sql );
-               return !in_array( $verb, [ 'BEGIN', 'COMMIT', 'ROLLBACK', 'SHOW', 'SET' ], true );
+               return !in_array(
+                       $this->getQueryVerb( $sql ),
+                       [ 'BEGIN', 'COMMIT', 'ROLLBACK', 'SHOW', 'SET', 'CREATE', 'ALTER' ],
+                       true
+               );
        }
 
        /**
@@ -820,7 +837,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                throw new DBReadOnlyError( $this, "Database is read-only: $reason" );
                        }
                        # Set a flag indicating that writes have been done
-                       $this->mDoneWrites = microtime( true );
+                       $this->mLastWriteTime = microtime( true );
                }
 
                // Add trace comment to the begin of the sql string, right after the operator.
@@ -881,7 +898,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                if ( false === $ret ) {
                        # Deadlocks cause the entire transaction to abort, not just the statement.
-                       # http://dev.mysql.com/doc/refman/5.7/en/innodb-error-handling.html
+                       # https://dev.mysql.com/doc/refman/5.7/en/innodb-error-handling.html
                        # https://www.postgresql.org/docs/9.1/static/explicit-locking.html
                        if ( $this->wasDeadlock() ) {
                                if ( $this->explicitTrxActive() || $priorWritesPending ) {
@@ -1704,9 +1721,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                } elseif ( count( $dbDetails ) == 2 ) {
                        list( $database, $table ) = $dbDetails;
                        # We don't want any prefix added in this case
+                       $prefix = '';
                        # In dbs that support it, $database may actually be the schema
                        # but that doesn't affect any of the functionality here
-                       $prefix = '';
                        $schema = '';
                } else {
                        list( $table ) = $dbDetails;
@@ -1728,29 +1745,35 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                # Quote $table and apply the prefix if not quoted.
                # $tableName might be empty if this is called from Database::replaceVars()
                $tableName = "{$prefix}{$table}";
-               if ( $format == 'quoted'
-                       && !$this->isQuotedIdentifier( $tableName ) && $tableName !== ''
+               if ( $format === 'quoted'
+                       && !$this->isQuotedIdentifier( $tableName )
+                       && $tableName !== ''
                ) {
                        $tableName = $this->addIdentifierQuotes( $tableName );
                }
 
-               # Quote $schema and merge it with the table name if needed
-               if ( strlen( $schema ) ) {
-                       if ( $format == 'quoted' && !$this->isQuotedIdentifier( $schema ) ) {
-                               $schema = $this->addIdentifierQuotes( $schema );
-                       }
-                       $tableName = $schema . '.' . $tableName;
-               }
+               # Quote $schema and $database and merge them with the table name if needed
+               $tableName = $this->prependDatabaseOrSchema( $schema, $tableName, $format );
+               $tableName = $this->prependDatabaseOrSchema( $database, $tableName, $format );
+
+               return $tableName;
+       }
 
-               # Quote $database and merge it with the table name if needed
-               if ( $database !== '' ) {
-                       if ( $format == 'quoted' && !$this->isQuotedIdentifier( $database ) ) {
-                               $database = $this->addIdentifierQuotes( $database );
+       /**
+        * @param string|null $namespace Database or schema
+        * @param string $relation Name of table, view, sequence, etc...
+        * @param string $format One of (raw, quoted)
+        * @return string Relation name with quoted and merged $namespace as needed
+        */
+       private function prependDatabaseOrSchema( $namespace, $relation, $format ) {
+               if ( strlen( $namespace ) ) {
+                       if ( $format === 'quoted' && !$this->isQuotedIdentifier( $namespace ) ) {
+                               $namespace = $this->addIdentifierQuotes( $namespace );
                        }
-                       $tableName = $database . '.' . $tableName;
+                       $relation = $namespace . '.' . $relation;
                }
 
-               return $tableName;
+               return $relation;
        }
 
        public function tableNames() {
@@ -2682,7 +2705,6 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->mTrxTimestamp = microtime( true );
                $this->mTrxFname = $fname;
                $this->mTrxDoneWrites = false;
-               $this->mTrxAutomatic = ( $mode === self::TRANSACTION_INTERNAL );
                $this->mTrxAutomaticAtomic = false;
                $this->mTrxAtomicLevels = [];
                $this->mTrxShortId = sprintf( '%06x', mt_rand( 0, 0xffffff ) );
@@ -2696,6 +2718,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                // as lag itself just to be safe
                $status = $this->getApproximateLagStatus();
                $this->mTrxReplicaLag = $status['lag'] + ( microtime( true ) - $status['since'] );
+               // T147697: make explicitTrxActive() return true until begin() finishes. This way, no
+               // caller will think its OK to muck around with the transaction just because startAtomic()
+               // has not yet completed (e.g. setting mTrxAtomicLevels).
+               $this->mTrxAutomatic = ( $mode === self::TRANSACTION_INTERNAL );
        }
 
        /**
@@ -2748,7 +2774,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $writeTime = $this->pendingWriteQueryDuration( self::ESTIMATE_DB_APPLY );
                $this->doCommit( $fname );
                if ( $this->mTrxDoneWrites ) {
-                       $this->mDoneWrites = microtime( true );
+                       $this->mLastWriteTime = microtime( true );
                        $this->trxProfiler->transactionWritingOut(
                                $this->mServer, $this->mDBname, $this->mTrxShortId, $writeTime );
                }
@@ -2825,7 +2851,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $fnames = implode( ', ', $this->pendingWriteAndCallbackCallers() );
                        throw new DBUnexpectedError(
                                $this,
-                               "$fname: Cannot COMMIT to clear snapshot because writes are pending ($fnames)."
+                               "$fname: Cannot flush snapshot because writes are pending ($fnames)."
                        );
                }
 
@@ -3037,10 +3063,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        public function sourceFile(
                $filename,
-               $lineCallback = false,
-               $resultCallback = false,
+               callable $lineCallback = null,
+               callable $resultCallback = null,
                $fname = false,
-               $inputCallback = false
+               callable $inputCallback = null
        ) {
                MediaWiki\suppressWarnings();
                $fp = fopen( $filename, 'r' );
@@ -3073,10 +3099,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        public function sourceStream(
                $fp,
-               $lineCallback = false,
-               $resultCallback = false,
+               callable $lineCallback = null,
+               callable $resultCallback = null,
                $fname = __METHOD__,
-               $inputCallback = false
+               callable $inputCallback = null
        ) {
                $cmd = '';
 
@@ -3246,7 +3272,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $fnames = implode( ', ', $this->pendingWriteAndCallbackCallers() );
                        throw new DBUnexpectedError(
                                $this,
-                               "$fname: Cannot COMMIT to clear snapshot because writes are pending ($fnames)."
+                               "$fname: Cannot flush pre-lock snapshot because writes are pending ($fnames)."
                        );
                }
 
@@ -3365,6 +3391,28 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                return true;
        }
 
+       /**
+        * Get the underlying binding handle, mConn
+        *
+        * Makes sure that mConn is set (disconnects and ping() failure can unset it).
+        * This catches broken callers than catch and ignore disconnection exceptions.
+        * Unlike checking isOpen(), this is safe to call inside of open().
+        *
+        * @return resource|object
+        * @throws DBUnexpectedError
+        * @since 1.26
+        */
+       protected function getBindingHandle() {
+               if ( !$this->mConn ) {
+                       throw new DBUnexpectedError(
+                               $this,
+                               'DB connection was already closed or the connection dropped.'
+                       );
+               }
+
+               return $this->mConn;
+       }
+
        /**
         * @since 1.19
         * @return string
@@ -3419,10 +3467,15 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                if ( $this->mConn ) {
-                       // Avoid connection leaks for sanity
+                       // Avoid connection leaks for sanity. Normally, resources close at script completion.
+                       // The connection might already be closed in zend/hhvm by now, so suppress warnings.
+                       \MediaWiki\suppressWarnings();
                        $this->closeConnection();
+                       \MediaWiki\restoreWarnings();
                        $this->mConn = false;
                        $this->mOpened = false;
                }
        }
 }
+
+class_alias( 'Database', 'DatabaseBase' );
diff --git a/includes/libs/rdbms/database/DatabaseBase.php b/includes/libs/rdbms/database/DatabaseBase.php
deleted file mode 100644 (file)
index 71e5f93..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-/**
- * @defgroup Database Database
- *
- * This file deals with database interface functions
- * and query specifics/optimisations.
- *
- * 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 Database
- */
-
-/**
- * Database abstraction object
- * @ingroup Database
- */
-abstract class DatabaseBase extends Database {
-       // Backwards-compatibility alias for type-hints
-}
index 01b6b21..a3ae6f1 100644 (file)
@@ -51,7 +51,6 @@ class DatabaseDomain {
                        throw new InvalidArgumentException( "Prefix must be a string." );
                }
                $this->prefix = $prefix;
-               $this->equivalentString = $this->convertToString();
        }
 
        /**
@@ -105,7 +104,7 @@ class DatabaseDomain {
                        );
                }
 
-               return ( $this->equivalentString === $other );
+               return ( $this->getId() === $other );
        }
 
        /**
@@ -133,6 +132,10 @@ class DatabaseDomain {
         * @return string
         */
        public function getId() {
+               if ( $this->equivalentString === null ) {
+                       $this->equivalentString = $this->convertToString();
+               }
+
                return $this->equivalentString;
        }
 
index c31b9f9..668443b 100644 (file)
@@ -29,7 +29,7 @@
  * @since 1.22
  * @see Database
  */
-abstract class DatabaseMysqlBase extends DatabaseBase {
+abstract class DatabaseMysqlBase extends Database {
        /** @var MysqlMasterPos */
        protected $lastKnownReplicaPos;
        /** @var string Method to detect replica DB lag */
@@ -72,8 +72,6 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @param array $params
         */
        function __construct( array $params ) {
-               parent::__construct( $params );
-
                $this->lagDetectionMethod = isset( $params['lagDetectionMethod'] )
                        ? $params['lagDetectionMethod']
                        : 'Seconds_Behind_Master';
@@ -89,12 +87,14 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                }
                $this->sqlMode = isset( $params['sqlMode'] ) ? $params['sqlMode'] : '';
                $this->utf8Mode = !empty( $params['utf8Mode'] );
+
+               parent::__construct( $params );
        }
 
        /**
         * @return string
         */
-       function getType() {
+       public function getType() {
                return 'mysql';
        }
 
@@ -106,7 +106,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @throws Exception|DBConnectionError
         * @return bool
         */
-       function open( $server, $user, $password, $dbName ) {
+       public function open( $server, $user, $password, $dbName ) {
                # Close/unset connection handle
                $this->close();
 
@@ -129,14 +129,14 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                        if ( !$error ) {
                                $error = $this->lastError();
                        }
-                       $this->queryLogger->error(
+                       $this->connLogger->error(
                                "Error connecting to {db_server}: {error}",
                                $this->getLogContext( [
                                        'method' => __METHOD__,
                                        'error' => $error,
                                ] )
                        );
-                       $this->queryLogger->debug( "DB connection error\n" .
+                       $this->connLogger->debug( "DB connection error\n" .
                                "Server: $server, User: $user, Password: " .
                                substr( $password, 0, 3 ) . "..., error: " . $error . "\n" );
 
@@ -237,7 +237,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @param ResultWrapper|resource $res
         * @throws DBUnexpectedError
         */
-       function freeResult( $res ) {
+       public function freeResult( $res ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
@@ -262,7 +262,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @return stdClass|bool
         * @throws DBUnexpectedError
         */
-       function fetchObject( $res ) {
+       public function fetchObject( $res ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
@@ -274,7 +274,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                // Unfortunately, mysql_fetch_object does not reset the last errno.
                // Only check for CR_SERVER_LOST and CR_UNKNOWN_ERROR, as
                // these are the only errors mysql_fetch_object can cause.
-               // See http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
+               // See https://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
                if ( $errno == 2000 || $errno == 2013 ) {
                        throw new DBUnexpectedError(
                                $this,
@@ -298,7 +298,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @return array|bool
         * @throws DBUnexpectedError
         */
-       function fetchRow( $res ) {
+       public function fetchRow( $res ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
@@ -310,7 +310,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                // Unfortunately, mysql_fetch_array does not reset the last errno.
                // Only check for CR_SERVER_LOST and CR_UNKNOWN_ERROR, as
                // these are the only errors mysql_fetch_array can cause.
-               // See http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
+               // See https://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
                if ( $errno == 2000 || $errno == 2013 ) {
                        throw new DBUnexpectedError(
                                $this,
@@ -345,7 +345,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                // Unfortunately, mysql_num_rows does not reset the last errno.
                // We are not checking for any errors here, since
                // these are no errors mysql_num_rows can cause.
-               // See http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
+               // See https://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html.
                // See https://phabricator.wikimedia.org/T44430
                return $n;
        }
@@ -362,7 +362,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @param ResultWrapper|resource $res
         * @return int
         */
-       function numFields( $res ) {
+       public function numFields( $res ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
@@ -383,7 +383,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @param int $n
         * @return string
         */
-       function fieldName( $res, $n ) {
+       public function fieldName( $res, $n ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
@@ -428,7 +428,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @param int $row
         * @return bool
         */
-       function dataSeek( $res, $row ) {
+       public function dataSeek( $res, $row ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
@@ -448,7 +448,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
        /**
         * @return string
         */
-       function lastError() {
+       public function lastError() {
                if ( $this->mConn ) {
                        # Even if it's non-zero, it can still be invalid
                        MediaWiki\suppressWarnings();
@@ -482,7 +482,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @param string $fname
         * @return ResultWrapper
         */
-       function replace( $table, $uniqueIndexes, $rows, $fname = __METHOD__ ) {
+       public function replace( $table, $uniqueIndexes, $rows, $fname = __METHOD__ ) {
                return $this->nativeReplace( $table, $rows, $fname );
        }
 
@@ -518,7 +518,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                return (int)$rows;
        }
 
-       function tableExists( $table, $fname = __METHOD__ ) {
+       public function tableExists( $table, $fname = __METHOD__ ) {
                $table = $this->tableName( $table, 'raw' );
                if ( isset( $this->mSessionTempTables[$table] ) ) {
                        return true; // already known to exist and won't show in SHOW TABLES anyway
@@ -534,7 +534,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @param string $field
         * @return bool|MySQLField
         */
-       function fieldInfo( $table, $field ) {
+       public function fieldInfo( $table, $field ) {
                $table = $this->tableName( $table );
                $res = $this->query( "SELECT * FROM $table LIMIT 1", __METHOD__, true );
                if ( !$res ) {
@@ -569,10 +569,10 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @param string $fname
         * @return bool|array|null False or null on failure
         */
-       function indexInfo( $table, $index, $fname = __METHOD__ ) {
+       public function indexInfo( $table, $index, $fname = __METHOD__ ) {
                # SHOW INDEX works in MySQL 3.23.58, but SHOW INDEXES does not.
                # SHOW INDEX should work for 3.x and up:
-               # http://dev.mysql.com/doc/mysql/en/SHOW_INDEX.html
+               # https://dev.mysql.com/doc/mysql/en/SHOW_INDEX.html
                $table = $this->tableName( $table );
                $index = $this->indexName( $index );
 
@@ -598,7 +598,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @param string $s
         * @return string
         */
-       function strencode( $s ) {
+       public function strencode( $s ) {
                return $this->mysqlRealEscapeString( $s );
        }
 
@@ -608,6 +608,16 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         */
        abstract protected function mysqlRealEscapeString( $s );
 
+       public function addQuotes( $s ) {
+               if ( is_bool( $s ) ) {
+                       // Parent would transform to int, which does not play nice with MySQL type juggling.
+                       // When searching for an int in a string column, the strings are cast to int, which
+                       // means false would match any string not starting with a number.
+                       $s = (string)(int)$s;
+               }
+               return parent::addQuotes( $s );
+       }
+
        /**
         * MySQL uses `backticks` for identifier quoting instead of the sql standard "double quotes".
         *
@@ -628,7 +638,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                return strlen( $name ) && $name[0] == '`' && substr( $name, -1, 1 ) == '`';
        }
 
-       function getLag() {
+       public function getLag() {
                if ( $this->getLagDetectionMethod() === 'pt-heartbeat' ) {
                        return $this->getLagFromPtHeartbeat();
                } else {
@@ -758,7 +768,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                return [ $row ? $row->ts : null, microtime( true ) ];
        }
 
-       public function getApproximateLagStatus() {
+       protected function getApproximateLagStatus() {
                if ( $this->getLagDetectionMethod() === 'pt-heartbeat' ) {
                        // Disable caching since this is fast enough and we don't wan't
                        // to be *too* pessimistic by having both the cache TTL and the
@@ -776,7 +786,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                return $approxLag;
        }
 
-       function masterPosWait( DBMasterPos $pos, $timeout ) {
+       public function masterPosWait( DBMasterPos $pos, $timeout ) {
                if ( !( $pos instanceof MySQLMasterPos ) ) {
                        throw new InvalidArgumentException( "Position not an instance of MySQLMasterPos" );
                }
@@ -829,7 +839,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         *
         * @return MySQLMasterPos|bool
         */
-       function getReplicaPos() {
+       public function getReplicaPos() {
                $res = $this->query( 'SHOW SLAVE STATUS', __METHOD__ );
                $row = $this->fetchObject( $res );
 
@@ -857,7 +867,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         *
         * @return MySQLMasterPos|bool
         */
-       function getMasterPos() {
+       public function getMasterPos() {
                $res = $this->query( 'SHOW MASTER STATUS', __METHOD__ );
                $row = $this->fetchObject( $res );
 
@@ -1003,7 +1013,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
 
        /**
         * FROM MYSQL DOCS:
-        * http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_release-lock
+        * https://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_release-lock
         * @param string $lockName
         * @param string $method
         * @return bool
@@ -1024,7 +1034,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
        }
 
        private function makeLockName( $lockName ) {
-               // http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_get-lock
+               // https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_get-lock
                // Newer version enforce a 64 char length limit.
                return ( strlen( $lockName ) > 64 ) ? sha1( $lockName ) : $lockName;
        }
@@ -1098,7 +1108,9 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @throws DBUnexpectedError
         * @return bool|ResultWrapper
         */
-       function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = __METHOD__ ) {
+       public function deleteJoin(
+               $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = __METHOD__
+       ) {
                if ( !$conds ) {
                        throw new DBUnexpectedError( $this, __METHOD__ . ' called with empty $conds' );
                }
@@ -1152,7 +1164,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         *
         * @return int
         */
-       function getServerUptime() {
+       public function getServerUptime() {
                $vars = $this->getMysqlStatus( 'Uptime' );
 
                return (int)$vars['Uptime'];
@@ -1163,7 +1175,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         *
         * @return bool
         */
-       function wasDeadlock() {
+       public function wasDeadlock() {
                return $this->lastErrno() == 1213;
        }
 
@@ -1172,11 +1184,11 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         *
         * @return bool
         */
-       function wasLockTimeout() {
+       public function wasLockTimeout() {
                return $this->lastErrno() == 1205;
        }
 
-       function wasErrorReissuable() {
+       public function wasErrorReissuable() {
                return $this->lastErrno() == 2013 || $this->lastErrno() == 2006;
        }
 
@@ -1185,37 +1197,15 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         *
         * @return bool
         */
-       function wasReadOnlyError() {
+       public function wasReadOnlyError() {
                return $this->lastErrno() == 1223 ||
                        ( $this->lastErrno() == 1290 && strpos( $this->lastError(), '--read-only' ) !== false );
        }
 
-       function wasConnectionError( $errno ) {
+       public function wasConnectionError( $errno ) {
                return $errno == 2013 || $errno == 2006;
        }
 
-       /**
-        * Get the underlying binding handle, mConn
-        *
-        * Makes sure that mConn is set (disconnects and ping() failure can unset it).
-        * This catches broken callers than catch and ignore disconnection exceptions.
-        * Unlike checking isOpen(), this is safe to call inside of open().
-        *
-        * @return resource|object
-        * @throws DBUnexpectedError
-        * @since 1.26
-        */
-       protected function getBindingHandle() {
-               if ( !$this->mConn ) {
-                       throw new DBUnexpectedError(
-                               $this,
-                               'DB connection was already closed or the connection dropped.'
-                       );
-               }
-
-               return $this->mConn;
-       }
-
        /**
         * @param string $oldName
         * @param string $newName
@@ -1223,7 +1213,9 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @param string $fname
         * @return bool
         */
-       function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = __METHOD__ ) {
+       public function duplicateTableStructure(
+               $oldName, $newName, $temporary = false, $fname = __METHOD__
+       ) {
                $tmp = $temporary ? 'TEMPORARY ' : '';
                $newName = $this->addIdentifierQuotes( $newName );
                $oldName = $this->addIdentifierQuotes( $oldName );
@@ -1239,7 +1231,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @param string $fname Calling function name
         * @return array
         */
-       function listTables( $prefix = null, $fname = __METHOD__ ) {
+       public function listTables( $prefix = null, $fname = __METHOD__ ) {
                $result = $this->query( "SHOW TABLES", $fname );
 
                $endArray = [];
@@ -1275,7 +1267,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @param string $which
         * @return array
         */
-       function getMysqlStatus( $which = "%" ) {
+       private function getMysqlStatus( $which = "%" ) {
                $res = $this->query( "SHOW STATUS LIKE '{$which}'" );
                $status = [];
 
index c34f901..2f27ff9 100644 (file)
@@ -29,8 +29,7 @@
  * @see Database
  */
 class DatabaseMysqli extends DatabaseMysqlBase {
-       /** @var mysqli */
-       protected $mConn;
+       /** @var $mConn mysqli */
 
        /**
         * @param string $sql
index a69a5fa..cd02177 100644 (file)
  * @file
  * @ingroup Database
  */
+use Wikimedia\WaitConditionLoop;
 
 /**
  * @ingroup Database
  */
-class DatabasePostgres extends DatabaseBase {
+class DatabasePostgres extends Database {
        /** @var int|bool */
        protected $port;
 
@@ -41,44 +42,48 @@ class DatabasePostgres extends DatabaseBase {
        private $connectString;
        /** @var string */
        private $mCoreSchema;
+       /** @var string[] Map of (reserved table name => alternate table name) */
+       private $keywordTableMap = [];
 
+       /**
+        * @see Database::__construct()
+        * @param array $params Additional parameters include:
+        *   - keywordTableMap : Map of reserved table names to alternative table names to use
+        */
        public function __construct( array $params ) {
                $this->port = isset( $params['port'] ) ? $params['port'] : false;
+               $this->keywordTableMap = isset( $params['keywordTableMap'] )
+                       ? $params['keywordTableMap']
+                       : [];
+
                parent::__construct( $params );
        }
 
-       function getType() {
+       public function getType() {
                return 'postgres';
        }
 
-       function implicitGroupby() {
+       public function implicitGroupby() {
                return false;
        }
 
-       function implicitOrderby() {
+       public function implicitOrderby() {
                return false;
        }
 
-       function hasConstraint( $name ) {
+       public function hasConstraint( $name ) {
+               $conn = $this->getBindingHandle();
+
                $sql = "SELECT 1 FROM pg_catalog.pg_constraint c, pg_catalog.pg_namespace n " .
                        "WHERE c.connamespace = n.oid AND conname = '" .
-                       pg_escape_string( $this->mConn, $name ) . "' AND n.nspname = '" .
-                       pg_escape_string( $this->mConn, $this->getCoreSchema() ) . "'";
+                       pg_escape_string( $conn, $name ) . "' AND n.nspname = '" .
+                       pg_escape_string( $conn, $this->getCoreSchema() ) . "'";
                $res = $this->doQuery( $sql );
 
                return $this->numRows( $res );
        }
 
-       /**
-        * Usually aborts on failure
-        * @param string $server
-        * @param string $user
-        * @param string $password
-        * @param string $dbName
-        * @throws DBConnectionError|Exception
-        * @return resource|bool|null
-        */
-       function open( $server, $user, $password, $dbName ) {
+       public function open( $server, $user, $password, $dbName ) {
                # Test for Postgres support, to avoid suppressed fatal error
                if ( !function_exists( 'pg_connect' ) ) {
                        throw new DBConnectionError(
@@ -89,10 +94,6 @@ class DatabasePostgres extends DatabaseBase {
                        );
                }
 
-               if ( !strlen( $user ) ) { # e.g. the class is being loaded
-                       return null;
-               }
-
                $this->mServer = $server;
                $this->mUser = $user;
                $this->mPassword = $password;
@@ -118,7 +119,8 @@ class DatabasePostgres extends DatabaseBase {
                $this->installErrorHandler();
 
                try {
-                       $this->mConn = pg_connect( $this->connectString );
+                       // Use new connections to let LoadBalancer/LBFactory handle reuse
+                       $this->mConn = pg_connect( $this->connectString, PGSQL_CONNECT_FORCE_NEW );
                } catch ( Exception $ex ) {
                        $this->restoreErrorHandler();
                        throw $ex;
@@ -127,10 +129,11 @@ class DatabasePostgres extends DatabaseBase {
                $phpError = $this->restoreErrorHandler();
 
                if ( !$this->mConn ) {
-                       $this->queryLogger->debug( "DB connection error\n" );
                        $this->queryLogger->debug(
+                               "DB connection error\n" .
                                "Server: $server, Database: $dbName, User: $user, Password: " .
-                               substr( $password, 0, 3 ) . "...\n" );
+                               substr( $password, 0, 3 ) . "...\n"
+                       );
                        $this->queryLogger->debug( $this->lastError() . "\n" );
                        throw new DBConnectionError( $this, str_replace( "\n", ' ', $phpError ) );
                }
@@ -151,6 +154,8 @@ class DatabasePostgres extends DatabaseBase {
                }
 
                $this->determineCoreSchema( $this->mSchema );
+               // The schema to be used is now in the search path; no need for explicit qualification
+               $this->mSchema = '';
 
                return $this->mConn;
        }
@@ -161,7 +166,7 @@ class DatabasePostgres extends DatabaseBase {
         * @param string $db
         * @return bool
         */
-       function selectDB( $db ) {
+       public function selectDB( $db ) {
                if ( $this->mDBname !== $db ) {
                        return (bool)$this->open( $this->mServer, $this->mUser, $this->mPassword, $db );
                } else {
@@ -169,7 +174,11 @@ class DatabasePostgres extends DatabaseBase {
                }
        }
 
-       function makeConnectionString( $vars ) {
+       /**
+        * @param string[] $vars
+        * @return string
+        */
+       private function makeConnectionString( $vars ) {
                $s = '';
                foreach ( $vars as $name => $value ) {
                        $s .= "$name='" . str_replace( "'", "\\'", $value ) . "' ";
@@ -178,25 +187,22 @@ class DatabasePostgres extends DatabaseBase {
                return $s;
        }
 
-       /**
-        * Closes a database connection, if it is open
-        * Returns success, true if already closed
-        * @return bool
-        */
        protected function closeConnection() {
-               return pg_close( $this->mConn );
+               return $this->mConn ? pg_close( $this->mConn ) : true;
        }
 
        public function doQuery( $sql ) {
+               $conn = $this->getBindingHandle();
+
                $sql = mb_convert_encoding( $sql, 'UTF-8' );
                // Clear previously left over PQresult
-               while ( $res = pg_get_result( $this->mConn ) ) {
+               while ( $res = pg_get_result( $conn ) ) {
                        pg_free_result( $res );
                }
-               if ( pg_send_query( $this->mConn, $sql ) === false ) {
+               if ( pg_send_query( $conn, $sql ) === false ) {
                        throw new DBUnexpectedError( $this, "Unable to post new query to PostgreSQL\n" );
                }
-               $this->mLastResult = pg_get_result( $this->mConn );
+               $this->mLastResult = pg_get_result( $conn );
                $this->mAffectedRows = null;
                if ( pg_result_error( $this->mLastResult ) ) {
                        return false;
@@ -226,7 +232,7 @@ class DatabasePostgres extends DatabaseBase {
                }
        }
 
-       function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
+       public function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
                if ( $tempIgnore ) {
                        /* Check for constraint violation */
                        if ( $errno === '23505' ) {
@@ -244,15 +250,7 @@ class DatabasePostgres extends DatabaseBase {
                parent::reportQueryError( $error, $errno, $sql, $fname, false );
        }
 
-       function queryIgnore( $sql, $fname = __METHOD__ ) {
-               return $this->query( $sql, $fname, true );
-       }
-
-       /**
-        * @param stdClass|ResultWrapper $res
-        * @throws DBUnexpectedError
-        */
-       function freeResult( $res ) {
+       public function freeResult( $res ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
@@ -264,12 +262,7 @@ class DatabasePostgres extends DatabaseBase {
                }
        }
 
-       /**
-        * @param ResultWrapper|stdClass $res
-        * @return stdClass
-        * @throws DBUnexpectedError
-        */
-       function fetchObject( $res ) {
+       public function fetchObject( $res ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
@@ -280,51 +273,56 @@ class DatabasePostgres extends DatabaseBase {
 
                # @todo hashar: not sure if the following test really trigger if the object
                #          fetching failed.
-               if ( pg_last_error( $this->mConn ) ) {
+               $conn = $this->getBindingHandle();
+               if ( pg_last_error( $conn ) ) {
                        throw new DBUnexpectedError(
                                $this,
-                               'SQL error: ' . htmlspecialchars( pg_last_error( $this->mConn ) )
+                               'SQL error: ' . htmlspecialchars( pg_last_error( $conn ) )
                        );
                }
 
                return $row;
        }
 
-       function fetchRow( $res ) {
+       public function fetchRow( $res ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
                MediaWiki\suppressWarnings();
                $row = pg_fetch_array( $res );
                MediaWiki\restoreWarnings();
-               if ( pg_last_error( $this->mConn ) ) {
+
+               $conn = $this->getBindingHandle();
+               if ( pg_last_error( $conn ) ) {
                        throw new DBUnexpectedError(
                                $this,
-                               'SQL error: ' . htmlspecialchars( pg_last_error( $this->mConn ) )
+                               'SQL error: ' . htmlspecialchars( pg_last_error( $conn ) )
                        );
                }
 
                return $row;
        }
 
-       function numRows( $res ) {
+       public function numRows( $res ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
                MediaWiki\suppressWarnings();
                $n = pg_num_rows( $res );
                MediaWiki\restoreWarnings();
-               if ( pg_last_error( $this->mConn ) ) {
+
+               $conn = $this->getBindingHandle();
+               if ( pg_last_error( $conn ) ) {
                        throw new DBUnexpectedError(
                                $this,
-                               'SQL error: ' . htmlspecialchars( pg_last_error( $this->mConn ) )
+                               'SQL error: ' . htmlspecialchars( pg_last_error( $conn ) )
                        );
                }
 
                return $n;
        }
 
-       function numFields( $res ) {
+       public function numFields( $res ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
@@ -332,7 +330,7 @@ class DatabasePostgres extends DatabaseBase {
                return pg_num_fields( $res );
        }
 
-       function fieldName( $res, $n ) {
+       public function fieldName( $res, $n ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
@@ -346,16 +344,11 @@ class DatabasePostgres extends DatabaseBase {
         *
         * @return int|null
         */
-       function insertId() {
+       public function insertId() {
                return $this->mInsertId;
        }
 
-       /**
-        * @param mixed $res
-        * @param int $row
-        * @return bool
-        */
-       function dataSeek( $res, $row ) {
+       public function dataSeek( $res, $row ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
@@ -363,19 +356,19 @@ class DatabasePostgres extends DatabaseBase {
                return pg_result_seek( $res, $row );
        }
 
-       function lastError() {
+       public function lastError() {
                if ( $this->mConn ) {
                        if ( $this->mLastResult ) {
                                return pg_result_error( $this->mLastResult );
                        } else {
                                return pg_last_error();
                        }
-               } else {
-                       return 'No database connection';
                }
+
+               return $this->getLastPHPError() ?: 'No database connection';
        }
 
-       function lastErrno() {
+       public function lastErrno() {
                if ( $this->mLastResult ) {
                        return pg_result_error_field( $this->mLastResult, PGSQL_DIAG_SQLSTATE );
                } else {
@@ -383,7 +376,7 @@ class DatabasePostgres extends DatabaseBase {
                }
        }
 
-       function affectedRows() {
+       public function affectedRows() {
                if ( !is_null( $this->mAffectedRows ) ) {
                        // Forced result for simulated queries
                        return $this->mAffectedRows;
@@ -409,7 +402,7 @@ class DatabasePostgres extends DatabaseBase {
         * @param array $options
         * @return int
         */
-       function estimateRowCount( $table, $vars = '*', $conds = '',
+       public function estimateRowCount( $table, $vars = '*', $conds = '',
                $fname = __METHOD__, $options = []
        ) {
                $options['EXPLAIN'] = true;
@@ -426,16 +419,7 @@ class DatabasePostgres extends DatabaseBase {
                return $rows;
        }
 
-       /**
-        * Returns information about an index
-        * If errors are explicitly ignored, returns NULL on failure
-        *
-        * @param string $table
-        * @param string $index
-        * @param string $fname
-        * @return bool|null
-        */
-       function indexInfo( $table, $index, $fname = __METHOD__ ) {
+       public function indexInfo( $table, $index, $fname = __METHOD__ ) {
                $sql = "SELECT indexname FROM pg_indexes WHERE tablename='$table'";
                $res = $this->query( $sql, $fname );
                if ( !$res ) {
@@ -450,15 +434,7 @@ class DatabasePostgres extends DatabaseBase {
                return false;
        }
 
-       /**
-        * Returns is of attributes used in index
-        *
-        * @since 1.19
-        * @param string $index
-        * @param bool|string $schema
-        * @return array
-        */
-       function indexAttributes( $index, $schema = false ) {
+       public function indexAttributes( $index, $schema = false ) {
                if ( $schema === false ) {
                        $schema = $this->getCoreSchema();
                }
@@ -515,7 +491,7 @@ __INDEXATTR__;
                return $a;
        }
 
-       function indexUnique( $table, $index, $fname = __METHOD__ ) {
+       public function indexUnique( $table, $index, $fname = __METHOD__ ) {
                $sql = "SELECT indexname FROM pg_indexes WHERE tablename='{$table}'" .
                        " AND indexdef LIKE 'CREATE UNIQUE%(" .
                        $this->strencode( $this->indexName( $index ) ) .
@@ -528,7 +504,7 @@ __INDEXATTR__;
                return $res->numRows() > 0;
        }
 
-       function selectSQLText(
+       public function selectSQLText(
                $table, $vars, $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
        ) {
                // Change the FOR UPDATE option as necessary based on the join conditions. Then pass
@@ -570,7 +546,7 @@ __INDEXATTR__;
         * @param array|string $options String or array. Valid options: IGNORE
         * @return bool Success of insert operation. IGNORE always returns true.
         */
-       function insert( $table, $args, $fname = __METHOD__, $options = [] ) {
+       public function insert( $table, $args, $fname = __METHOD__, $options = [] ) {
                if ( !count( $args ) ) {
                        return true;
                }
@@ -696,8 +672,10 @@ __INDEXATTR__;
         * @param array $selectOptions
         * @return bool
         */
-       function nativeInsertSelect( $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__,
-               $insertOptions = [], $selectOptions = [] ) {
+       public function nativeInsertSelect(
+               $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__,
+               $insertOptions = [], $selectOptions = []
+       ) {
                $destTable = $this->tableName( $destTable );
 
                if ( !is_array( $insertOptions ) ) {
@@ -759,30 +737,31 @@ __INDEXATTR__;
                return $res;
        }
 
-       function tableName( $name, $format = 'quoted' ) {
-               # Replace reserved words with better ones
-               switch ( $name ) {
-                       case 'user':
-                               return $this->realTableName( 'mwuser', $format );
-                       case 'text':
-                               return $this->realTableName( 'pagecontent', $format );
-                       default:
-                               return $this->realTableName( $name, $format );
-               }
-       }
+       public function tableName( $name, $format = 'quoted' ) {
+               // Replace reserved words with better ones
+               $name = $this->remappedTableName( $name );
 
-       /* Don't cheat on installer */
-       function realTableName( $name, $format = 'quoted' ) {
                return parent::tableName( $name, $format );
        }
 
        /**
-        * Return the next in a sequence, save the value for retrieval via insertId()
-        *
-        * @param string $seqName
-        * @return int|null
+        * @param string $name
+        * @return string Value of $name or remapped name if $name is a reserved keyword
         */
-       function nextSequenceValue( $seqName ) {
+       public function remappedTableName( $name ) {
+               return isset( $this->keywordTableMap[$name] ) ? $this->keywordTableMap[$name] : $name;
+       }
+
+       /**
+        * @param string $name
+        * @param string $format
+        * @return string Qualified and encoded (if requested) table name
+        */
+       public function realTableName( $name, $format = 'quoted' ) {
+               return parent::tableName( $name, $format );
+       }
+
+       public function nextSequenceValue( $seqName ) {
                $safeseq = str_replace( "'", "''", $seqName );
                $res = $this->query( "SELECT nextval('$safeseq')" );
                $row = $this->fetchRow( $res );
@@ -797,7 +776,7 @@ __INDEXATTR__;
         * @param string $seqName
         * @return int
         */
-       function currentSequenceValue( $seqName ) {
+       public function currentSequenceValue( $seqName ) {
                $safeseq = str_replace( "'", "''", $seqName );
                $res = $this->query( "SELECT currval('$safeseq')" );
                $row = $this->fetchRow( $res );
@@ -806,8 +785,7 @@ __INDEXATTR__;
                return $currval;
        }
 
-       # Returns the size of a text field, or -1 for "unlimited"
-       function textFieldSize( $table, $field ) {
+       public function textFieldSize( $table, $field ) {
                $table = $this->tableName( $table );
                $sql = "SELECT t.typname as ftype,a.atttypmod as size
                        FROM pg_class c, pg_attribute a, pg_type t
@@ -824,15 +802,15 @@ __INDEXATTR__;
                return $size;
        }
 
-       function limitResult( $sql, $limit, $offset = false ) {
+       public function limitResult( $sql, $limit, $offset = false ) {
                return "$sql LIMIT $limit " . ( is_numeric( $offset ) ? " OFFSET {$offset} " : '' );
        }
 
-       function wasDeadlock() {
+       public function wasDeadlock() {
                return $this->lastErrno() == '40P01';
        }
 
-       function duplicateTableStructure(
+       public function duplicateTableStructure(
                $oldName, $newName, $temporary = false, $fname = __METHOD__
        ) {
                $newName = $this->addIdentifierQuotes( $newName );
@@ -842,7 +820,7 @@ __INDEXATTR__;
                        "(LIKE $oldName INCLUDING DEFAULTS)", $fname );
        }
 
-       function listTables( $prefix = null, $fname = __METHOD__ ) {
+       public function listTables( $prefix = null, $fname = __METHOD__ ) {
                $eschema = $this->addQuotes( $this->getCoreSchema() );
                $result = $this->query(
                        "SELECT tablename FROM pg_tables WHERE schemaname = $eschema", $fname );
@@ -859,7 +837,7 @@ __INDEXATTR__;
                return $endArray;
        }
 
-       function timestamp( $ts = 0 ) {
+       public function timestamp( $ts = 0 ) {
                $ct = new ConvertibleTimestamp( $ts );
 
                return $ct->getTimestamp( TS_POSTGRES );
@@ -867,7 +845,7 @@ __INDEXATTR__;
 
        /**
         * Posted by cc[plus]php[at]c2se[dot]com on 25-Mar-2009 09:12
-        * to http://www.php.net/manual/en/ref.pgsql.php
+        * to https://secure.php.net/manual/en/ref.pgsql.php
         *
         * Parsing a postgres array can be a tricky problem, he's my
         * take on this, it handles multi-dimensional arrays plus
@@ -883,7 +861,7 @@ __INDEXATTR__;
         * @param int $offset
         * @return string
         */
-       function pg_array_parse( $text, &$output, $limit = false, $offset = 1 ) {
+       private function pg_array_parse( $text, &$output, $limit = false, $offset = 1 ) {
                if ( false === $limit ) {
                        $limit = strlen( $text ) - 1;
                        $output = [];
@@ -910,19 +888,10 @@ __INDEXATTR__;
                return $output;
        }
 
-       /**
-        * Return aggregated value function call
-        * @param array $valuedata
-        * @param string $valuename
-        * @return array
-        */
        public function aggregateValue( $valuedata, $valuename = 'value' ) {
                return $valuedata;
        }
 
-       /**
-        * @return string Wikitext of a link to the server software's web site
-        */
        public function getSoftwareLink() {
                return '[{{int:version-db-postgres-url}} PostgreSQL]';
        }
@@ -934,7 +903,7 @@ __INDEXATTR__;
         * @since 1.19
         * @return string Default schema for the current session
         */
-       function getCurrentSchema() {
+       public function getCurrentSchema() {
                $res = $this->query( "SELECT current_schema()", __METHOD__ );
                $row = $this->fetchRow( $res );
 
@@ -951,7 +920,7 @@ __INDEXATTR__;
         * @since 1.19
         * @return array List of actual schemas for the current sesson
         */
-       function getSchemas() {
+       public function getSchemas() {
                $res = $this->query( "SELECT current_schemas(false)", __METHOD__ );
                $row = $this->fetchRow( $res );
                $schemas = [];
@@ -970,7 +939,7 @@ __INDEXATTR__;
         * @since 1.19
         * @return array How to search for table names schemas for the current user
         */
-       function getSearchPath() {
+       public function getSearchPath() {
                $res = $this->query( "SHOW search_path", __METHOD__ );
                $row = $this->fetchRow( $res );
 
@@ -986,7 +955,7 @@ __INDEXATTR__;
         *
         * @param array $search_path List of schemas to be searched by default
         */
-       function setSearchPath( $search_path ) {
+       private function setSearchPath( $search_path ) {
                $this->query( "SET search_path = " . implode( ", ", $search_path ) );
        }
 
@@ -1004,7 +973,7 @@ __INDEXATTR__;
         *
         * @param string $desiredSchema
         */
-       function determineCoreSchema( $desiredSchema ) {
+       public function determineCoreSchema( $desiredSchema ) {
                $this->begin( __METHOD__, self::TRANSACTION_INTERNAL );
                if ( $this->schemaExists( $desiredSchema ) ) {
                        if ( in_array( $desiredSchema, $this->getSchemas() ) ) {
@@ -1032,7 +1001,7 @@ __INDEXATTR__;
                                $this->mCoreSchema . "\"\n" );
                }
                /* Commit SET otherwise it will be rollbacked on error or IGNORE SELECT */
-               $this->commit( __METHOD__ );
+               $this->commit( __METHOD__, self::FLUSHING_INTERNAL );
        }
 
        /**
@@ -1041,16 +1010,14 @@ __INDEXATTR__;
         * @since 1.19
         * @return string Core schema name
         */
-       function getCoreSchema() {
+       public function getCoreSchema() {
                return $this->mCoreSchema;
        }
 
-       /**
-        * @return string Version information from the database
-        */
-       function getServerVersion() {
+       public function getServerVersion() {
                if ( !isset( $this->numericVersion ) ) {
-                       $versionInfo = pg_version( $this->mConn );
+                       $conn = $this->getBindingHandle();
+                       $versionInfo = pg_version( $conn );
                        if ( version_compare( $versionInfo['client'], '7.4.0', 'lt' ) ) {
                                // Old client, abort install
                                $this->numericVersion = '7.3 or earlier';
@@ -1059,7 +1026,7 @@ __INDEXATTR__;
                                $this->numericVersion = $versionInfo['server'];
                        } else {
                                // Bug 16937: broken pgsql extension from PHP<5.3
-                               $this->numericVersion = pg_parameter_status( $this->mConn, 'server_version' );
+                               $this->numericVersion = pg_parameter_status( $conn, 'server_version' );
                        }
                }
 
@@ -1074,14 +1041,13 @@ __INDEXATTR__;
         * @param bool|string $schema
         * @return bool
         */
-       function relationExists( $table, $types, $schema = false ) {
+       private function relationExists( $table, $types, $schema = false ) {
                if ( !is_array( $types ) ) {
                        $types = [ $types ];
                }
-               if ( !$schema ) {
+               if ( $schema === false ) {
                        $schema = $this->getCoreSchema();
                }
-               $table = $this->realTableName( $table, 'raw' );
                $etable = $this->addQuotes( $table );
                $eschema = $this->addQuotes( $schema );
                $sql = "SELECT 1 FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n "
@@ -1094,22 +1060,21 @@ __INDEXATTR__;
        }
 
        /**
-        * For backward compatibility, this function checks both tables and
-        * views.
+        * For backward compatibility, this function checks both tables and views.
         * @param string $table
         * @param string $fname
         * @param bool|string $schema
         * @return bool
         */
-       function tableExists( $table, $fname = __METHOD__, $schema = false ) {
+       public function tableExists( $table, $fname = __METHOD__, $schema = false ) {
                return $this->relationExists( $table, [ 'r', 'v' ], $schema );
        }
 
-       function sequenceExists( $sequence, $schema = false ) {
+       public function sequenceExists( $sequence, $schema = false ) {
                return $this->relationExists( $sequence, 'S', $schema );
        }
 
-       function triggerExists( $table, $trigger ) {
+       public function triggerExists( $table, $trigger ) {
                $q = <<<SQL
        SELECT 1 FROM pg_class, pg_namespace, pg_trigger
                WHERE relnamespace=pg_namespace.oid AND relkind='r'
@@ -1132,7 +1097,7 @@ SQL;
                return $rows;
        }
 
-       function ruleExists( $table, $rule ) {
+       public function ruleExists( $table, $rule ) {
                $exists = $this->selectField( 'pg_rules', 'rulename',
                        [
                                'rulename' => $rule,
@@ -1144,7 +1109,7 @@ SQL;
                return $exists === $rule;
        }
 
-       function constraintExists( $table, $constraint ) {
+       public function constraintExists( $table, $constraint ) {
                $sql = sprintf( "SELECT 1 FROM information_schema.table_constraints " .
                        "WHERE constraint_schema = %s AND table_name = %s AND constraint_name = %s",
                        $this->addQuotes( $this->getCoreSchema() ),
@@ -1165,9 +1130,13 @@ SQL;
         * @param string $schema
         * @return bool
         */
-       function schemaExists( $schema ) {
-               $exists = $this->selectField( '"pg_catalog"."pg_namespace"', 1,
-                       [ 'nspname' => $schema ], __METHOD__ );
+       public function schemaExists( $schema ) {
+               if ( !strlen( $schema ) ) {
+                       return false; // short-circuit
+               }
+
+               $exists = $this->selectField(
+                       '"pg_catalog"."pg_namespace"', 1, [ 'nspname' => $schema ], __METHOD__ );
 
                return (bool)$exists;
        }
@@ -1177,7 +1146,7 @@ SQL;
         * @param string $roleName
         * @return bool
         */
-       function roleExists( $roleName ) {
+       public function roleExists( $roleName ) {
                $exists = $this->selectField( '"pg_catalog"."pg_roles"', 1,
                        [ 'rolname' => $roleName ], __METHOD__ );
 
@@ -1189,7 +1158,7 @@ SQL;
         * @var string $field
         * @return PostgresField|null
         */
-       function fieldInfo( $table, $field ) {
+       public function fieldInfo( $table, $field ) {
                return PostgresField::fromText( $this, $table, $field );
        }
 
@@ -1199,7 +1168,7 @@ SQL;
         * @param int $index Field number, starting from 0
         * @return string
         */
-       function fieldType( $res, $index ) {
+       public function fieldType( $res, $index ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
@@ -1207,15 +1176,11 @@ SQL;
                return pg_field_type( $res, $index );
        }
 
-       /**
-        * @param string $b
-        * @return Blob
-        */
-       function encodeBlob( $b ) {
+       public function encodeBlob( $b ) {
                return new PostgresBlob( pg_escape_bytea( $b ) );
        }
 
-       function decodeBlob( $b ) {
+       public function decodeBlob( $b ) {
                if ( $b instanceof PostgresBlob ) {
                        $b = $b->fetch();
                } elseif ( $b instanceof Blob ) {
@@ -1225,17 +1190,14 @@ SQL;
                return pg_unescape_bytea( $b );
        }
 
-       function strencode( $s ) {
+       public function strencode( $s ) {
                // Should not be called by us
-
-               return pg_escape_string( $this->mConn, $s );
+               return pg_escape_string( $this->getBindingHandle(), $s );
        }
 
-       /**
-        * @param string|int|null|bool|Blob $s
-        * @return string|int
-        */
-       function addQuotes( $s ) {
+       public function addQuotes( $s ) {
+               $conn = $this->getBindingHandle();
+
                if ( is_null( $s ) ) {
                        return 'NULL';
                } elseif ( is_bool( $s ) ) {
@@ -1244,12 +1206,12 @@ SQL;
                        if ( $s instanceof PostgresBlob ) {
                                $s = $s->fetch();
                        } else {
-                               $s = pg_escape_bytea( $this->mConn, $s->fetch() );
+                               $s = pg_escape_bytea( $conn, $s->fetch() );
                        }
                        return "'$s'";
                }
 
-               return "'" . pg_escape_string( $this->mConn, $s ) . "'";
+               return "'" . pg_escape_string( $conn, $s ) . "'";
        }
 
        /**
@@ -1274,14 +1236,7 @@ SQL;
                return $ins;
        }
 
-       /**
-        * Various select options
-        *
-        * @param array $options An associative array of options to be turned into
-        *   an SQL query, valid keys are listed in the function.
-        * @return array
-        */
-       function makeSelectOptions( $options ) {
+       public function makeSelectOptions( $options ) {
                $preLimitTail = $postLimitTail = '';
                $startOpts = $useIndex = $ignoreIndex = '';
 
@@ -1316,15 +1271,15 @@ SQL;
                return [ $startOpts, $useIndex, $preLimitTail, $postLimitTail, $ignoreIndex ];
        }
 
-       function getDBname() {
+       public function getDBname() {
                return $this->mDBname;
        }
 
-       function getServer() {
+       public function getServer() {
                return $this->mServer;
        }
 
-       function buildConcat( $stringList ) {
+       public function buildConcat( $stringList ) {
                return implode( ' || ', $stringList );
        }
 
@@ -1336,11 +1291,6 @@ SQL;
                return '(' . $this->selectSQLText( $table, $fld, $conds, null, [], $join_conds ) . ')';
        }
 
-       /**
-        * @param string $field Field or column to cast
-        * @return string
-        * @since 1.28
-        */
        public function buildStringCast( $field ) {
                return $field . '::text';
        }
@@ -1358,16 +1308,8 @@ SQL;
                return parent::streamStatementEnd( $sql, $newLine );
        }
 
-       /**
-        * Check to see if a named lock is available. This is non-blocking.
-        * See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
-        *
-        * @param string $lockName Name of lock to poll
-        * @param string $method Name of method calling us
-        * @return bool
-        * @since 1.20
-        */
        public function lockIsFree( $lockName, $method ) {
+               // http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
                $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
                $result = $this->query( "SELECT (CASE(pg_try_advisory_lock($key))
                        WHEN 'f' THEN 'f' ELSE pg_advisory_unlock($key) END) AS lockstatus", $method );
@@ -1376,14 +1318,8 @@ SQL;
                return ( $row->lockstatus === 't' );
        }
 
-       /**
-        * See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
-        * @param string $lockName
-        * @param string $method
-        * @param int $timeout
-        * @return bool
-        */
        public function lock( $lockName, $method, $timeout = 5 ) {
+               // http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
                $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
                $loop = new WaitConditionLoop(
                        function () use ( $lockName, $key, $timeout, $method ) {
@@ -1402,14 +1338,8 @@ SQL;
                return ( $loop->invoke() === $loop::CONDITION_REACHED );
        }
 
-       /**
-        * See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKSFROM
-        * PG DOCS: http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
-        * @param string $lockName
-        * @param string $method
-        * @return bool
-        */
        public function unlock( $lockName, $method ) {
+               // http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
                $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
                $result = $this->query( "SELECT pg_advisory_unlock($key) as lockstatus", $method );
                $row = $this->fetchObject( $result );
index 156e525..7317d54 100644 (file)
 /**
  * @ingroup Database
  */
-class DatabaseSqlite extends DatabaseBase {
+class DatabaseSqlite extends Database {
        /** @var bool Whether full text is enabled */
        private static $fulltextEnabled = null;
 
        /** @var string Directory */
        protected $dbDir;
-
        /** @var string File name for SQLite database file */
        protected $dbPath;
-
        /** @var string Transaction mode */
        protected $trxMode;
 
        /** @var int The number of rows affected as an integer */
        protected $mAffectedRows;
-
        /** @var resource */
        protected $mLastResult;
 
-       /** @var PDO */
+       /** @var $mConn PDO */
        protected $mConn;
 
        /** @var FSLockManager (hopefully on the same server as the DB) */
@@ -145,7 +142,7 @@ class DatabaseSqlite extends DatabaseBase {
         * @param string $dbName
         *
         * @throws DBConnectionError
-        * @return PDO
+        * @return bool
         */
        function open( $server, $user, $pass, $dbName ) {
                $this->close();
@@ -156,7 +153,7 @@ class DatabaseSqlite extends DatabaseBase {
                }
                $this->openFile( $fileName );
 
-               return $this->mConn;
+               return (bool)$this->mConn;
        }
 
        /**
@@ -199,6 +196,10 @@ class DatabaseSqlite extends DatabaseBase {
                return false;
        }
 
+       public function selectDB( $db ) {
+               return false; // doesn't make sense
+       }
+
        /**
         * @return string SQLite DB file path
         * @since 1.25
@@ -267,7 +268,7 @@ class DatabaseSqlite extends DatabaseBase {
        }
 
        /**
-        * Attaches external database to our connection, see http://sqlite.org/lang_attach.html
+        * Attaches external database to our connection, see https://sqlite.org/lang_attach.html
         * for details.
         *
         * @param string $name Database name to be used in queries like
@@ -494,15 +495,12 @@ class DatabaseSqlite extends DatabaseBase {
         * @param string $table
         * @param string $index
         * @param string $fname
-        * @return array
+        * @return array|false
         */
        function indexInfo( $table, $index, $fname = __METHOD__ ) {
                $sql = 'PRAGMA index_info(' . $this->addQuotes( $this->indexName( $index ) ) . ')';
                $res = $this->query( $sql, $fname );
-               if ( !$res ) {
-                       return null;
-               }
-               if ( $res->numRows() == 0 ) {
+               if ( !$res || $res->numRows() == 0 ) {
                        return false;
                }
                $info = [];
index c32a7ff..48d76c4 100644 (file)
@@ -23,6 +23,7 @@
  * @file
  * @ingroup Database
  */
+use Wikimedia\ScopedCallback;
 
 /**
  * Basic database interface for live and lazy-loaded relation database handles
@@ -321,14 +322,6 @@ interface IDatabase {
         */
        public function getFlag( $flag );
 
-       /**
-        * General read-only accessor
-        *
-        * @param string $name
-        * @return string
-        */
-       public function getProperty( $name );
-
        /**
         * @return string
         */
@@ -393,7 +386,7 @@ interface IDatabase {
 
        /**
         * Get the number of fields in a result object
-        * @see http://www.php.net/mysql_num_fields
+        * @see https://secure.php.net/mysql_num_fields
         *
         * @param mixed $res A SQL result
         * @return int
@@ -402,7 +395,7 @@ interface IDatabase {
 
        /**
         * Get a field name in a result object
-        * @see http://www.php.net/mysql_field_name
+        * @see https://secure.php.net/mysql_field_name
         *
         * @param mixed $res A SQL result
         * @param int $n
@@ -426,7 +419,7 @@ interface IDatabase {
 
        /**
         * Change the position of the cursor in a result object
-        * @see http://www.php.net/mysql_data_seek
+        * @see https://secure.php.net/mysql_data_seek
         *
         * @param mixed $res A SQL result
         * @param int $row
@@ -435,7 +428,7 @@ interface IDatabase {
 
        /**
         * Get the last error number
-        * @see http://www.php.net/mysql_errno
+        * @see https://secure.php.net/mysql_errno
         *
         * @return int
         */
@@ -443,7 +436,7 @@ interface IDatabase {
 
        /**
         * Get a description of the last error
-        * @see http://www.php.net/mysql_error
+        * @see https://secure.php.net/mysql_error
         *
         * @return string
         */
@@ -462,7 +455,7 @@ interface IDatabase {
 
        /**
         * Get the number of rows affected by the last write query
-        * @see http://www.php.net/mysql_affected_rows
+        * @see https://secure.php.net/mysql_affected_rows
         *
         * @return int
         */
@@ -470,7 +463,7 @@ interface IDatabase {
 
        /**
         * Returns a wikitext link to the DB's website, e.g.,
-        *   return "[http://www.mysql.com/ MySQL]";
+        *   return "[https://www.mysql.com/ MySQL]";
         * Should at least contain plain text, if for some reason
         * your database has no website.
         *
@@ -1095,7 +1088,7 @@ interface IDatabase {
         *
         * Any implementation of this function should *not* involve reusing
         * sequence numbers created for rolled-back transactions.
-        * See http://bugs.mysql.com/bug.php?id=30767 for details.
+        * See https://bugs.mysql.com/bug.php?id=30767 for details.
         * @param string $seqName
         * @return null|int
         */
@@ -1640,7 +1633,7 @@ interface IDatabase {
         * IDatabase::insert().
         *
         * @param string $b
-        * @return string
+        * @return string|Blob
         */
        public function encodeBlob( $b );
 
index f65e0dd..8395359 100644 (file)
@@ -96,21 +96,21 @@ interface IMaintainableDatabase extends IDatabase {
         * on object's error ignore settings).
         *
         * @param string $filename File name to open
-        * @param bool|callable $lineCallback Optional function called before reading each line
-        * @param bool|callable $resultCallback Optional function called for each MySQL result
+        * @param callable|null $lineCallback Optional function called before reading each line
+        * @param callable|null $resultCallback Optional function called for each MySQL result
         * @param bool|string $fname Calling function name or false if name should be
         *   generated dynamically using $filename
-        * @param bool|callable $inputCallback Optional function called for each
+        * @param callable|null $inputCallback Optional function called for each
         *   complete line sent
         * @return bool|string
         * @throws Exception
         */
        public function sourceFile(
                $filename,
-               $lineCallback = false,
-               $resultCallback = false,
+               callable $lineCallback = null,
+               callable $resultCallback = null,
                $fname = false,
-               $inputCallback = false
+               callable $inputCallback = null
        );
 
        /**
@@ -120,18 +120,18 @@ interface IMaintainableDatabase extends IDatabase {
         * on object's error ignore settings).
         *
         * @param resource $fp File handle
-        * @param bool|callable $lineCallback Optional function called before reading each query
-        * @param bool|callable $resultCallback Optional function called for each MySQL result
+        * @param callable|null $lineCallback Optional function called before reading each query
+        * @param callable|null $resultCallback Optional function called for each MySQL result
         * @param string $fname Calling function name
-        * @param bool|callable $inputCallback Optional function called for each complete query sent
+        * @param callable|null $inputCallback Optional function called for each complete query sent
         * @return bool|string
         */
        public function sourceStream(
                $fp,
-               $lineCallback = false,
-               $resultCallback = false,
+               callable $lineCallback = null,
+               callable $resultCallback = null,
                $fname = __METHOD__,
-               $inputCallback = false
+               callable $inputCallback = null
        );
 
        /**
index 71fbe7e..7b49ce9 100644 (file)
@@ -117,8 +117,8 @@ class MySQLMasterPos implements DBMasterPos {
        }
 
        /**
-        * @see http://dev.mysql.com/doc/refman/5.7/en/show-master-status.html
-        * @see http://dev.mysql.com/doc/refman/5.7/en/show-slave-status.html
+        * @see https://dev.mysql.com/doc/refman/5.7/en/show-master-status.html
+        * @see https://dev.mysql.com/doc/refman/5.7/en/show-slave-status.html
         * @return array|bool (binlog, (integer file number, integer position)) or false
         */
        protected function getBinlogCoordinates() {
index ec4d09f..8ae78e9 100644 (file)
@@ -47,7 +47,7 @@ class SavepointPostgres {
                $this->didbegin = false;
                /* If we are not in a transaction, we need to be for savepoint trickery */
                if ( !$dbw->trxLevel() ) {
-                       $dbw->begin( "FOR SAVEPOINT", DatabasePostgres::TRANSACTION_INTERNAL );
+                       $dbw->begin( __CLASS__, DatabasePostgres::TRANSACTION_INTERNAL );
                        $this->didbegin = true;
                }
        }
@@ -61,7 +61,7 @@ class SavepointPostgres {
 
        public function commit() {
                if ( $this->didbegin ) {
-                       $this->dbw->commit();
+                       $this->dbw->commit( __CLASS__, DatabasePostgres::FLUSHING_INTERNAL );
                        $this->didbegin = false;
                }
        }
index c00082c..864dea0 100644 (file)
@@ -25,6 +25,6 @@
  */
 class DBAccessError extends DBUnexpectedError {
        public function __construct() {
-               parent::__construct( "Database access has been disabled." );
+               parent::__construct( null, "Database access has been disabled." );
        }
 }
index 36337e2..d34c125 100644 (file)
@@ -9,7 +9,7 @@ class PostgresField implements Field {
         * @param string $field
         * @return null|PostgresField
         */
-       static function fromText( $db, $table, $field ) {
+       static function fromText( DatabasePostgres $db, $table, $field ) {
                $q = <<<SQL
 SELECT
  attnotnull, attlen, conname AS conname,
@@ -34,7 +34,7 @@ AND relname=%s
 AND attname=%s;
 SQL;
 
-               $table = $db->tableName( $table, 'raw' );
+               $table = $db->remappedTableName( $table );
                $res = $db->query(
                        sprintf( $q,
                                $db->addQuotes( $db->getCoreSchema() ),
index d7ca7cd..5288c24 100644 (file)
@@ -86,28 +86,41 @@ interface ILBFactory {
 
        /**
         * Create a new load balancer for external storage. The resulting object will be
-        * untracked, not chronology-protected, and the caller is responsible for
-        * cleaning it up.
+        * untracked, not chronology-protected, and the caller is responsible for cleaning it up.
         *
         * This method is for only advanced usage and callers should almost always use
         * getExternalLB() instead. This method can be useful when a table is used as a
         * key/value store. In that cases, one might want to query it in autocommit mode
         * (DBO_TRX off) but still use DBO_TRX transaction rounds on other tables.
         *
-        * @param string $cluster External storage cluster, or false for core
-        * @param bool|string $domain Domain ID, or false for the current domain
+        * @param string $cluster External storage cluster name
         * @return ILoadBalancer
         */
-       public function newExternalLB( $cluster, $domain = false );
+       public function newExternalLB( $cluster );
 
        /**
         * Get a cached (tracked) load balancer for external storage
         *
-        * @param string $cluster External storage cluster, or false for core
-        * @param bool|string $domain Domain ID, or false for the current domain
+        * @param string $cluster External storage cluster name
         * @return ILoadBalancer
         */
-       public function getExternalLB( $cluster, $domain = false );
+       public function getExternalLB( $cluster );
+
+       /**
+        * Get cached (tracked) load balancers for all main database clusters
+        *
+        * @return LoadBalancer[] Map of (cluster name => LoadBalancer)
+        * @since 1.29
+        */
+       public function getAllMainLBs();
+
+       /**
+        * Get cached (tracked) load balancers for all external database clusters
+        *
+        * @return LoadBalancer[] Map of (cluster name => LoadBalancer)
+        * @since 1.29
+        */
+       public function getAllExternalLBs();
 
        /**
         * Execute a function for each tracked load balancer
@@ -136,9 +149,9 @@ interface ILBFactory {
        public function flushReplicaSnapshots( $fname = __METHOD__ );
 
        /**
-        * Commit on all connections. Done for two reasons:
-        * 1. To commit changes to the masters.
-        * 2. To release the snapshot on all connections, master and replica DB.
+        * Commit open transactions on all connections. This is useful for two main cases:
+        *   - a) To commit changes to the masters.
+        *   - b) To release the snapshot on all connections, master and replica DBs.
         * @param string $fname Caller name
         * @param array $options Options map:
         *   - maxWriteDuration: abort if more than this much time was spent in write queries
index 85194bc..15a5c0d 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use Psr\Log\LoggerInterface;
+use Wikimedia\ScopedCallback;
 
 /**
  * An interface for generating database load balancers
@@ -96,7 +97,7 @@ abstract class LBFactory implements ILBFactory {
                $this->errorLogger = isset( $conf['errorLogger'] )
                        ? $conf['errorLogger']
                        : function ( Exception $e ) {
-                               trigger_error( E_WARNING, get_class( $e ) . ': ' . $e->getMessage() );
+                               trigger_error( E_USER_WARNING, get_class( $e ) . ': ' . $e->getMessage() );
                        };
 
                $this->profiler = isset( $params['profiler'] ) ? $params['profiler'] : null;
@@ -135,6 +136,34 @@ abstract class LBFactory implements ILBFactory {
                $this->commitMasterChanges( __METHOD__ ); // sanity
        }
 
+       /**
+        * @see ILBFactory::newMainLB()
+        * @param bool $domain
+        * @return LoadBalancer
+        */
+       abstract public function newMainLB( $domain = false );
+
+       /**
+        * @see ILBFactory::getMainLB()
+        * @param bool $domain
+        * @return LoadBalancer
+        */
+       abstract public function getMainLB( $domain = false );
+
+       /**
+        * @see ILBFactory::newExternalLB()
+        * @param string $cluster
+        * @return LoadBalancer
+        */
+       abstract public function newExternalLB( $cluster );
+
+       /**
+        * @see ILBFactory::getExternalLB()
+        * @param string $cluster
+        * @return LoadBalancer
+        */
+       abstract public function getExternalLB( $cluster );
+
        /**
         * Call a method of each tracked load balancer
         *
@@ -178,6 +207,8 @@ abstract class LBFactory implements ILBFactory {
                                "$fname: transaction round '{$this->trxRoundId}' still running."
                        );
                }
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedPHPBehaviorForCommit(); // try to ignore client aborts
                // Run pre-commit callbacks and suppress post-commit callbacks, aborting on failure
                $this->forEachLBCallMethod( 'finalizeMasterChanges' );
                $this->trxRoundId = false;
@@ -324,6 +355,7 @@ abstract class LBFactory implements ILBFactory {
 
                if ( $failed ) {
                        throw new DBReplicationWaitError(
+                               null,
                                "Could not wait for replica DBs to catch up to " .
                                implode( ', ', $failed )
                        );
@@ -516,6 +548,23 @@ abstract class LBFactory implements ILBFactory {
                $this->requestInfo = $info + $this->requestInfo;
        }
 
+       /**
+        * Make PHP ignore user aborts/disconnects until the returned
+        * value leaves scope. This returns null and does nothing in CLI mode.
+        *
+        * @return ScopedCallback|null
+        */
+       final protected function getScopedPHPBehaviorForCommit() {
+               if ( PHP_SAPI != 'cli' ) { // https://bugs.php.net/bug.php?id=47540
+                       $old = ignore_user_abort( true ); // avoid half-finished operations
+                       return new ScopedCallback( function () use ( $old ) {
+                               ignore_user_abort( $old );
+                       } );
+               }
+
+               return null;
+       }
+
        function __destruct() {
                $this->destroy();
        }
index 2fb8c4b..1d22873 100644 (file)
@@ -95,7 +95,7 @@ class LBFactoryMulti extends LBFactory {
        private $extLBs = [];
 
        /** @var string */
-       private $loadMonitorClass;
+       private $loadMonitorClass = 'LoadMonitor';
 
        /** @var string */
        private $lastDomain;
@@ -255,13 +255,7 @@ class LBFactoryMulti extends LBFactory {
                return $this->mainLBs[$section];
        }
 
-       /**
-        * @param string $cluster
-        * @param DatabaseDomain|string|bool $domain Domain ID, or false for the current domain
-        * @throws InvalidArgumentException
-        * @return LoadBalancer
-        */
-       public function newExternalLB( $cluster, $domain = false ) {
+       public function newExternalLB( $cluster ) {
                if ( !isset( $this->externalLoads[$cluster] ) ) {
                        throw new InvalidArgumentException( __METHOD__ . ": Unknown cluster \"$cluster\"" );
                }
@@ -281,20 +275,35 @@ class LBFactoryMulti extends LBFactory {
                );
        }
 
-       /**
-        * @param string $cluster External storage cluster, or false for core
-        * @param DatabaseDomain|string|bool $domain Domain ID, or false for the current domain
-        * @return LoadBalancer
-        */
-       public function getExternalLB( $cluster, $domain = false ) {
+       public function getExternalLB( $cluster ) {
                if ( !isset( $this->extLBs[$cluster] ) ) {
-                       $this->extLBs[$cluster] = $this->newExternalLB( $cluster, $domain );
+                       $this->extLBs[$cluster] = $this->newExternalLB( $cluster );
                        $this->getChronologyProtector()->initLB( $this->extLBs[$cluster] );
                }
 
                return $this->extLBs[$cluster];
        }
 
+       public function getAllMainLBs() {
+               $lbs = [];
+               foreach ( $this->sectionsByDB as $db => $section ) {
+                       if ( !isset( $lbs[$section] ) ) {
+                               $lbs[$section] = $this->getMainLB( $db );
+                       }
+               }
+
+               return $lbs;
+       }
+
+       public function getAllExternalLBs() {
+               $lbs = [];
+               foreach ( $this->externalLoads as $cluster => $unused ) {
+                       $lbs[$cluster] = $this->getExternalLB( $cluster );
+               }
+
+               return $lbs;
+       }
+
        /**
         * Make a new load balancer object based on template and load array
         *
@@ -309,7 +318,7 @@ class LBFactoryMulti extends LBFactory {
                        $this->baseLoadBalancerParams(),
                        [
                                'servers' => $this->makeServerArray( $template, $loads, $groupLoads ),
-                               'loadMonitor' => $this->loadMonitorClass,
+                               'loadMonitor' => [ 'class' => $this->loadMonitorClass ],
                                'readOnlyReason' => $readOnlyReason
                        ]
                ) );
index 610052f..5bf5032 100644 (file)
@@ -67,7 +67,7 @@ class LBFactorySimple extends LBFactory {
                        : [];
                $this->loadMonitorClass = isset( $conf['loadMonitorClass'] )
                        ? $conf['loadMonitorClass']
-                       : null;
+                       : 'LoadMonitor';
        }
 
        /**
@@ -91,13 +91,7 @@ class LBFactorySimple extends LBFactory {
                return $this->mainLB;
        }
 
-       /**
-        * @param string $cluster
-        * @param bool|string $domain
-        * @return LoadBalancer
-        * @throws InvalidArgumentException
-        */
-       public function newExternalLB( $cluster, $domain = false ) {
+       public function newExternalLB( $cluster ) {
                if ( !isset( $this->externalClusters[$cluster] ) ) {
                        throw new InvalidArgumentException( __METHOD__ . ": Unknown cluster \"$cluster\"." );
                }
@@ -105,26 +99,34 @@ class LBFactorySimple extends LBFactory {
                return $this->newLoadBalancer( $this->externalClusters[$cluster] );
        }
 
-       /**
-        * @param string $cluster
-        * @param bool|string $domain
-        * @return LoadBalancer
-        */
-       public function getExternalLB( $cluster, $domain = false ) {
+       public function getExternalLB( $cluster ) {
                if ( !isset( $this->extLBs[$cluster] ) ) {
-                       $this->extLBs[$cluster] = $this->newExternalLB( $cluster, $domain );
+                       $this->extLBs[$cluster] = $this->newExternalLB( $cluster );
                        $this->getChronologyProtector()->initLB( $this->extLBs[$cluster] );
                }
 
                return $this->extLBs[$cluster];
        }
 
+       public function getAllMainLBs() {
+               return [ 'DEFAULT' => $this->getMainLB() ];
+       }
+
+       public function getAllExternalLBs() {
+               $lbs = [];
+               foreach ( $this->externalClusters as $cluster => $unused ) {
+                       $lbs[$cluster] = $this->getExternalLB( $cluster );
+               }
+
+               return $lbs;
+       }
+
        private function newLoadBalancer( array $servers ) {
                $lb = new LoadBalancer( array_merge(
                        $this->baseLoadBalancerParams(),
                        [
                                'servers' => $servers,
-                               'loadMonitor' => $this->loadMonitorClass,
+                               'loadMonitor' => [ 'class' => $this->loadMonitorClass ],
                        ]
                ) );
                $this->initLoadBalancer( $lb );
index af4a350..819375d 100644 (file)
@@ -39,7 +39,9 @@ class LBFactorySingle extends LBFactory {
                        throw new InvalidArgumentException( "Missing 'connection' argument." );
                }
 
-               $this->lb = new LoadBalancerSingle( array_merge( $this->baseLoadBalancerParams(), $conf ) );
+               $lb = new LoadBalancerSingle( array_merge( $this->baseLoadBalancerParams(), $conf ) );
+               $this->initLoadBalancer( $lb );
+               $this->lb = $lb;
        }
 
        /**
@@ -53,37 +55,41 @@ class LBFactorySingle extends LBFactory {
        }
 
        /**
-        * @param bool|string $wiki
+        * @param bool|string $domain (unused)
         * @return LoadBalancerSingle
         */
-       public function newMainLB( $wiki = false ) {
+       public function newMainLB( $domain = false ) {
                return $this->lb;
        }
 
        /**
-        * @param bool|string $wiki
+        * @param bool|string $domain (unused)
         * @return LoadBalancerSingle
         */
-       public function getMainLB( $wiki = false ) {
+       public function getMainLB( $domain = false ) {
                return $this->lb;
        }
 
+       public function newExternalLB( $cluster ) {
+               throw new BadMethodCallException( "Method is not supported." );
+       }
+
+       public function getExternalLB( $cluster ) {
+               throw new BadMethodCallException( "Method is not supported." );
+       }
+
        /**
-        * @param string $cluster External storage cluster, or false for core
-        * @param bool|string $wiki Wiki ID, or false for the current wiki
-        * @return LoadBalancerSingle
+        * @return LoadBalancerSingle[] Map of (cluster name => LoadBalancer)
         */
-       public function newExternalLB( $cluster, $wiki = false ) {
-               return $this->lb;
+       public function getAllMainLBs() {
+               return [ 'DEFAULT' => $this->lb ];
        }
 
        /**
-        * @param string $cluster External storage cluster, or false for core
-        * @param bool|string $wiki Wiki ID, or false for the current wiki
-        * @return LoadBalancerSingle
+        * @return LoadBalancerSingle[] Map of (cluster name => LoadBalancer)
         */
-       public function getExternalLB( $cluster, $wiki = false ) {
-               return $this->lb;
+       public function getAllExternalLBs() {
+               return [];
        }
 
        /**
index aa7d1b4..8854479 100644 (file)
@@ -78,6 +78,9 @@ interface ILoadBalancer {
        /** @var integer Request a master DB connection */
        const DB_MASTER = -2;
 
+       /** @var string Domain specifier when no specific database needs to be selected */
+       const DOMAIN_ANY = '';
+
        /**
         * Construct a manager of IDatabase connection objects
         *
@@ -517,13 +520,6 @@ interface ILoadBalancer {
         */
        public function safeWaitForMasterPos( IDatabase $conn, $pos = false, $timeout = null );
 
-       /**
-        * Clear the cache for slag lag delay times
-        *
-        * This is only used for testing
-        */
-       public function clearLagTimeCache();
-
        /**
         * Set a callback via IDatabase::setTransactionListener() on
         * all current and future master connections of this load balancer
index a60e741..d42fed9 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Database
  */
 use Psr\Log\LoggerInterface;
+use Wikimedia\ScopedCallback;
 
 /**
  * Database connection, tracking, load balancing, and transaction manager for a cluster
@@ -32,7 +33,7 @@ class LoadBalancer implements ILoadBalancer {
        private $mServers;
        /** @var array[] Map of (local/foreignUsed/foreignFree => server index => IDatabase array) */
        private $mConns;
-       /** @var array Map of (server index => weight) */
+       /** @var float[] Map of (server index => weight) */
        private $mLoads;
        /** @var array[] Map of (group => server index => weight) */
        private $mGroupLoads;
@@ -40,13 +41,13 @@ class LoadBalancer implements ILoadBalancer {
        private $mAllowLagged;
        /** @var integer Seconds to spend waiting on replica DB lag to resolve */
        private $mWaitTimeout;
-       /** @var string The LoadMonitor subclass name */
-       private $mLoadMonitorClass;
+       /** @var array The LoadMonitor configuration */
+       private $loadMonitorConfig;
        /** @var array[] $aliases Map of (table => (dbname, schema, prefix) map) */
        private $tableAliases = [];
 
        /** @var ILoadMonitor */
-       private $mLoadMonitor;
+       private $loadMonitor;
        /** @var BagOStuff */
        private $srvCache;
        /** @var BagOStuff */
@@ -105,10 +106,9 @@ class LoadBalancer implements ILoadBalancer {
 
        /** @var integer Warn when this many connection are held */
        const CONN_HELD_WARN_THRESHOLD = 10;
+
        /** @var integer Default 'max lag' when unspecified */
        const MAX_LAG_DEFAULT = 10;
-       /** @var integer Max time to wait for a replica DB to catch up (e.g. ChronologyProtector) */
-       const POS_WAIT_TIMEOUT = 10;
        /** @var integer Seconds to cache master server read-only status */
        const TTL_CACHE_READONLY = 5;
 
@@ -130,9 +130,7 @@ class LoadBalancer implements ILoadBalancer {
                        $this->localDomainIdAlias = $this->localDomain->getDatabase();
                }
 
-               $this->mWaitTimeout = isset( $params['waitTimeout'] )
-                       ? $params['waitTimeout']
-                       : self::POS_WAIT_TIMEOUT;
+               $this->mWaitTimeout = isset( $params['waitTimeout'] ) ? $params['waitTimeout'] : 10;
 
                $this->mReadIndex = -1;
                $this->mConns = [
@@ -150,14 +148,9 @@ class LoadBalancer implements ILoadBalancer {
                }
 
                if ( isset( $params['loadMonitor'] ) ) {
-                       $this->mLoadMonitorClass = $params['loadMonitor'];
+                       $this->loadMonitorConfig = $params['loadMonitor'];
                } else {
-                       $master = reset( $params['servers'] );
-                       if ( isset( $master['type'] ) && $master['type'] === 'mysql' ) {
-                               $this->mLoadMonitorClass = 'LoadMonitorMySQL';
-                       } else {
-                               $this->mLoadMonitorClass = 'LoadMonitorNull';
-                       }
+                       $this->loadMonitorConfig = [ 'class' => 'LoadMonitorNull' ];
                }
 
                foreach ( $params['servers'] as $i => $server ) {
@@ -197,7 +190,7 @@ class LoadBalancer implements ILoadBalancer {
                $this->errorLogger = isset( $params['errorLogger'] )
                        ? $params['errorLogger']
                        : function ( Exception $e ) {
-                               trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_WARNING );
+                               trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_USER_WARNING );
                        };
 
                foreach ( [ 'replLogger', 'connLogger', 'queryLogger', 'perfLogger' ] as $key ) {
@@ -217,13 +210,14 @@ class LoadBalancer implements ILoadBalancer {
         * @return ILoadMonitor
         */
        private function getLoadMonitor() {
-               if ( !isset( $this->mLoadMonitor ) ) {
-                       $class = $this->mLoadMonitorClass;
-                       $this->mLoadMonitor = new $class( $this, $this->srvCache, $this->memCache );
-                       $this->mLoadMonitor->setLogger( $this->replLogger );
+               if ( !isset( $this->loadMonitor ) ) {
+                       $class = $this->loadMonitorConfig['class'];
+                       $this->loadMonitor = new $class(
+                               $this, $this->srvCache, $this->memCache, $this->loadMonitorConfig );
+                       $this->loadMonitor->setLogger( $this->replLogger );
                }
 
-               return $this->mLoadMonitor;
+               return $this->loadMonitor;
        }
 
        /**
@@ -305,7 +299,7 @@ class LoadBalancer implements ILoadBalancer {
                }
 
                # Scale the configured load ratios according to the dynamic load if supported
-               $this->getLoadMonitor()->scaleLoads( $nonErrorLoads, $group, $domain );
+               $this->getLoadMonitor()->scaleLoads( $nonErrorLoads, $domain );
 
                $laggedReplicaMode = false;
 
@@ -481,7 +475,7 @@ class LoadBalancer implements ILoadBalancer {
 
                                return false;
                        } else {
-                               $conn = $this->openConnection( $index, '' );
+                               $conn = $this->openConnection( $index, self::DOMAIN_ANY );
                                if ( !$conn ) {
                                        $this->replLogger->warning( __METHOD__ . ": failed to connect to $server" );
 
@@ -559,7 +553,7 @@ class LoadBalancer implements ILoadBalancer {
                if ( $i == self::DB_REPLICA ) {
                        $this->mLastError = 'Unknown error'; // reset error string
                        # Try the general server pool if $groups are unavailable.
-                       $i = in_array( false, $groups, true )
+                       $i = ( $groups === [ false ] )
                                ? false // don't bother with this if that is what was tried above
                                : $this->getReaderIndex( false, $domain );
                        # Couldn't find a working server in getReaderIndex()?
@@ -618,10 +612,17 @@ class LoadBalancer implements ILoadBalancer {
                        return;
                }
 
+               if ( $this->disabled ) {
+                       return; // DBConnRef handle probably survived longer than the LoadBalancer
+               }
+
                $domain = $conn->getDomainID();
-               if ( $this->mConns['foreignUsed'][$serverIndex][$domain] !== $conn ) {
+               if ( !isset( $this->mConns['foreignUsed'][$serverIndex][$domain] ) ) {
+                       throw new InvalidArgumentException( __METHOD__ .
+                               ": connection $serverIndex/$domain not found; it may have already been freed." );
+               } elseif ( $this->mConns['foreignUsed'][$serverIndex][$domain] !== $conn ) {
                        throw new InvalidArgumentException( __METHOD__ .
-                               ": connection not found, has the connection been freed already?" );
+                               ": connection $serverIndex/$domain mismatched; it may have already been freed." );
                }
                $conn->setLBInfo( 'foreignPoolRefCount', --$refCount );
                if ( $refCount <= 0 ) {
@@ -667,6 +668,10 @@ class LoadBalancer implements ILoadBalancer {
                } elseif ( isset( $this->mConns['local'][$i][0] ) ) {
                        $conn = $this->mConns['local'][$i][0];
                } else {
+                       if ( !isset( $this->mServers[$i] ) || !is_array( $this->mServers[$i] ) ) {
+                               throw new InvalidArgumentException( "No server with index '$i'." );
+                       }
+                       // Open a new connection
                        $server = $this->mServers[$i];
                        $server['serverIndex'] = $i;
                        $conn = $this->reallyOpenConnection( $server, false );
@@ -747,6 +752,9 @@ class LoadBalancer implements ILoadBalancer {
                                        ": reusing free connection from $oldDomain for $domain" );
                        }
                } else {
+                       if ( !isset( $this->mServers[$i] ) || !is_array( $this->mServers[$i] ) ) {
+                               throw new InvalidArgumentException( "No server with index '$i'." );
+                       }
                        // Open a new connection
                        $server = $this->mServers[$i];
                        $server['serverIndex'] = $i;
@@ -799,17 +807,11 @@ class LoadBalancer implements ILoadBalancer {
         * @throws DBAccessError
         * @throws InvalidArgumentException
         */
-       protected function reallyOpenConnection( $server, $dbNameOverride = false ) {
+       protected function reallyOpenConnection( array $server, $dbNameOverride = false ) {
                if ( $this->disabled ) {
                        throw new DBAccessError();
                }
 
-               if ( !is_array( $server ) ) {
-                       throw new InvalidArgumentException(
-                               'You must update your load-balancing configuration. ' .
-                               'See DefaultSettings.php entry for $wgDBservers.' );
-               }
-
                if ( $dbNameOverride !== false ) {
                        $server['dbname'] = $dbNameOverride;
                }
@@ -885,7 +887,7 @@ class LoadBalancer implements ILoadBalancer {
                        // If all servers were busy, mLastError will contain something sensible
                        throw new DBConnectionError( null, $this->mLastError );
                } else {
-                       $context['db_server'] = $conn->getProperty( 'mServer' );
+                       $context['db_server'] = $conn->getServer();
                        $this->connLogger->warning(
                                "Connection error: {last_error} ({db_server})",
                                $context
@@ -1101,6 +1103,9 @@ class LoadBalancer implements ILoadBalancer {
        public function commitMasterChanges( $fname = __METHOD__ ) {
                $failures = [];
 
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedPHPBehaviorForCommit(); // try to ignore client aborts
+
                $restore = ( $this->trxRoundId !== false );
                $this->trxRoundId = false;
                $this->forEachOpenMasterConnection(
@@ -1320,7 +1325,7 @@ class LoadBalancer implements ILoadBalancer {
                        $cache->makeGlobalKey( __CLASS__, 'server-read-only', $masterServer ),
                        self::TTL_CACHE_READONLY,
                        function () use ( $domain, $conn ) {
-                               $this->trxProfiler->setSilenced( true );
+                               $old = $this->trxProfiler->setSilenced( true );
                                try {
                                        $dbw = $conn ?: $this->getConnection( self::DB_MASTER, [], $domain );
                                        $readOnly = (int)$dbw->serverIsReadOnly();
@@ -1330,7 +1335,7 @@ class LoadBalancer implements ILoadBalancer {
                                } catch ( DBError $e ) {
                                        $readOnly = 0;
                                }
-                               $this->trxProfiler->setSilenced( false );
+                               $this->trxProfiler->setSilenced( $old );
                                return $readOnly;
                        },
                        [ 'pcTTL' => $cache::TTL_PROC_LONG, 'busyValue' => 0 ]
@@ -1448,10 +1453,15 @@ class LoadBalancer implements ILoadBalancer {
                }
 
                if ( !$pos ) {
-                       // Get the current master position
-                       $dbw = $this->getConnection( self::DB_MASTER );
-                       $pos = $dbw->getMasterPos();
-                       $this->reuseConnection( $dbw );
+                       // Get the current master position, opening a connection if needed
+                       $masterConn = $this->getAnyOpenConnection( $this->getWriterIndex() );
+                       if ( $masterConn ) {
+                               $pos = $masterConn->getMasterPos();
+                       } else {
+                               $masterConn = $this->openConnection( $this->getWriterIndex(), self::DOMAIN_ANY );
+                               $pos = $masterConn->getMasterPos();
+                               $this->closeConnection( $masterConn );
+                       }
                }
 
                if ( $pos instanceof DBMasterPos ) {
@@ -1472,10 +1482,6 @@ class LoadBalancer implements ILoadBalancer {
                return $ok;
        }
 
-       public function clearLagTimeCache() {
-               $this->getLoadMonitor()->clearCaches();
-       }
-
        public function setTransactionListener( $name, callable $callback = null ) {
                if ( $callback ) {
                        $this->trxRecurringCallbacks[$name] = $callback;
@@ -1516,8 +1522,25 @@ class LoadBalancer implements ILoadBalancer {
                } );
        }
 
+       /**
+        * Make PHP ignore user aborts/disconnects until the returned
+        * value leaves scope. This returns null and does nothing in CLI mode.
+        *
+        * @return ScopedCallback|null
+        */
+       final protected function getScopedPHPBehaviorForCommit() {
+               if ( PHP_SAPI != 'cli' ) { // https://bugs.php.net/bug.php?id=47540
+                       $old = ignore_user_abort( true ); // avoid half-finished operations
+                       return new ScopedCallback( function () use ( $old ) {
+                               ignore_user_abort( $old );
+                       } );
+               }
+
+               return null;
+       }
+
        function __destruct() {
                // Avoid connection leaks for sanity
-               $this->closeAll();
+               $this->disable();
        }
 }
index 9de4850..0a05202 100644 (file)
@@ -68,14 +68,7 @@ class LoadBalancerSingle extends LoadBalancer {
                return new static( [ 'connection' => $db ] + $params );
        }
 
-       /**
-        *
-        * @param string $server
-        * @param bool $dbNameOverride
-        *
-        * @return IDatabase
-        */
-       protected function reallyOpenConnection( $server, $dbNameOverride = false ) {
+       protected function reallyOpenConnection( array $server, $dbNameOverride = false ) {
                return $this->db;
        }
 }
index e355c03..14a52c5 100644 (file)
@@ -34,16 +34,19 @@ interface ILoadMonitor extends LoggerAwareInterface {
         * @param ILoadBalancer $lb LoadBalancer this instance serves
         * @param BagOStuff $sCache Local server memory cache
         * @param BagOStuff $cCache Local cluster memory cache
+        * @param array $options Options map
         */
-       public function __construct( ILoadBalancer $lb, BagOStuff $sCache, BagOStuff $cCache );
+       public function __construct(
+               ILoadBalancer $lb, BagOStuff $sCache, BagOStuff $cCache, array $options = []
+       );
 
        /**
-        * Perform pre-connection load ratio adjustment.
-        * @param int[] &$loads
-        * @param string|bool $group The selected query group. Default: false
-        * @param string|bool $domain Default: false
+        * Perform load ratio adjustment before deciding which server to use
+        *
+        * @param int[] &$weightByServer Map of (server index => float weight)
+        * @param string|bool $domain
         */
-       public function scaleLoads( &$loads, $group = false, $domain = false );
+       public function scaleLoads( array &$weightByServer, $domain );
 
        /**
         * Get an estimate of replication lag (in seconds) for each server
@@ -52,14 +55,7 @@ interface ILoadMonitor extends LoggerAwareInterface {
         *
         * @param integer[] $serverIndexes
         * @param string $domain
-        *
         * @return array Map of (server index => float|int|bool)
         */
-       public function getLagTimes( $serverIndexes, $domain );
-
-       /**
-        * Clear any process and persistent cache of lag times
-        * @since 1.27
-        */
-       public function clearCaches();
+       public function getLagTimes( array $serverIndexes, $domain );
 }
index 1da8f4e..da4909d 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 use Psr\Log\LoggerInterface;
+use Wikimedia\ScopedCallback;
 
 /**
  * Basic DB load monitor with no external dependencies
@@ -37,27 +38,59 @@ class LoadMonitor implements ILoadMonitor {
        /** @var LoggerInterface */
        protected $replLogger;
 
-       public function __construct( ILoadBalancer $lb, BagOStuff $srvCache, BagOStuff $cache ) {
+       /** @var float Moving average ratio (e.g. 0.1 for 10% weight to new weight) */
+       private $movingAveRatio;
+
+       const VERSION = 1; // cache key version
+
+       public function __construct(
+               ILoadBalancer $lb, BagOStuff $srvCache, BagOStuff $cache, array $options = []
+       ) {
                $this->parent = $lb;
                $this->srvCache = $srvCache;
                $this->mainCache = $cache;
                $this->replLogger = new \Psr\Log\NullLogger();
+
+               $this->movingAveRatio = isset( $options['movingAveRatio'] )
+                       ? $options['movingAveRatio']
+                       : 0.1;
        }
 
        public function setLogger( LoggerInterface $logger ) {
                $this->replLogger = $logger;
        }
 
-       public function scaleLoads( &$loads, $group = false, $domain = false ) {
+       public function scaleLoads( array &$weightByServer, $domain ) {
+               $serverIndexes = array_keys( $weightByServer );
+               $states = $this->getServerStates( $serverIndexes, $domain );
+               $coefficientsByServer = $states['weightScales'];
+               foreach ( $weightByServer as $i => $weight ) {
+                       if ( isset( $coefficientsByServer[$i] ) ) {
+                               $weightByServer[$i] = $weight * $coefficientsByServer[$i];
+                       } else { // server recently added to config?
+                               $host = $this->parent->getServerName( $i );
+                               $this->replLogger->error( __METHOD__ . ": host $host not in cache" );
+                       }
+               }
        }
 
-       public function getLagTimes( $serverIndexes, $domain ) {
-               if ( count( $serverIndexes ) == 1 && reset( $serverIndexes ) == 0 ) {
+       public function getLagTimes( array $serverIndexes, $domain ) {
+               $states = $this->getServerStates( $serverIndexes, $domain );
+
+               return $states['lagTimes'];
+       }
+
+       protected function getServerStates( array $serverIndexes, $domain ) {
+               $writerIndex = $this->parent->getWriterIndex();
+               if ( count( $serverIndexes ) == 1 && reset( $serverIndexes ) == $writerIndex ) {
                        # Single server only, just return zero without caching
-                       return [ 0 => 0 ];
+                       return [
+                               'lagTimes' => [ $writerIndex => 0 ],
+                               'weightScales' => [ $writerIndex => 1.0 ]
+                       ];
                }
 
-               $key = $this->getLagTimeCacheKey();
+               $key = $this->getCacheKey( $serverIndexes );
                # Randomize TTLs to reduce stampedes (4.0 - 5.0 sec)
                $ttl = mt_rand( 4e6, 5e6 ) / 1e6;
                # Keep keys around longer as fallbacks
@@ -67,7 +100,7 @@ class LoadMonitor implements ILoadMonitor {
                $value = $this->srvCache->get( $key );
                if ( $value && $value['timestamp'] > ( microtime( true ) - $ttl ) ) {
                        $this->replLogger->debug( __METHOD__ . ": got lag times ($key) from local cache" );
-                       return $value['lagTimes']; // cache hit
+                       return $value; // cache hit
                }
                $staleValue = $value ?: false;
 
@@ -77,7 +110,7 @@ class LoadMonitor implements ILoadMonitor {
                        $this->srvCache->set( $key, $value, $staleTTL );
                        $this->replLogger->debug( __METHOD__ . ": got lag times ($key) from main cache" );
 
-                       return $value['lagTimes']; // cache hit
+                       return $value; // cache hit
                }
                $staleValue = $value ?: $staleValue;
 
@@ -91,13 +124,16 @@ class LoadMonitor implements ILoadMonitor {
                        } );
                } elseif ( $staleValue ) {
                        # Could not acquire lock but an old cache exists, so use it
-                       return $staleValue['lagTimes'];
+                       return $staleValue;
                }
 
                $lagTimes = [];
+               $weightScales = [];
+               $movAveRatio = $this->movingAveRatio;
                foreach ( $serverIndexes as $i ) {
                        if ( $i == $this->parent->getWriterIndex() ) {
                                $lagTimes[$i] = 0; // master always has no lag
+                               $weightScales[$i] = 1.0; // nominal weight
                                continue;
                        }
 
@@ -109,17 +145,30 @@ class LoadMonitor implements ILoadMonitor {
                                $close = true; // new connection
                        }
 
+                       $lastWeight = isset( $staleValue['weightScales'][$i] )
+                               ? $staleValue['weightScales'][$i]
+                               : 1.0;
+                       $coefficient = $this->getWeightScale( $i, $conn ?: null );
+                       $newWeight = $movAveRatio * $coefficient + ( 1 - $movAveRatio ) * $lastWeight;
+
+                       // Scale from 10% to 100% of nominal weight
+                       $weightScales[$i] = max( $newWeight, .10 );
+
                        if ( !$conn ) {
                                $lagTimes[$i] = false;
                                $host = $this->parent->getServerName( $i );
-                               $this->replLogger->error( __METHOD__ . ": host $host (#$i) is unreachable" );
+                               $this->replLogger->error( __METHOD__ . ": host $host is unreachable" );
                                continue;
                        }
 
-                       $lagTimes[$i] = $conn->getLag();
-                       if ( $lagTimes[$i] === false ) {
-                               $host = $this->parent->getServerName( $i );
-                               $this->replLogger->error( __METHOD__ . ": host $host (#$i) is not replicating?" );
+                       if ( $conn->getLBInfo( 'is static' ) ) {
+                               $lagTimes[$i] = 0;
+                       } else {
+                               $lagTimes[$i] = $conn->getLag();
+                               if ( $lagTimes[$i] === false ) {
+                                       $host = $this->parent->getServerName( $i );
+                                       $this->replLogger->error( __METHOD__ . ": host $host is not replicating?" );
+                               }
                        }
 
                        if ( $close ) {
@@ -132,26 +181,35 @@ class LoadMonitor implements ILoadMonitor {
                }
 
                # Add a timestamp key so we know when it was cached
-               $value = [ 'lagTimes' => $lagTimes, 'timestamp' => microtime( true ) ];
+               $value = [
+                       'lagTimes' => $lagTimes,
+                       'weightScales' => $weightScales,
+                       'timestamp' => microtime( true )
+               ];
                $this->mainCache->set( $key, $value, $staleTTL );
                $this->srvCache->set( $key, $value, $staleTTL );
                $this->replLogger->info( __METHOD__ . ": re-calculated lag times ($key)" );
 
-               return $value['lagTimes'];
+               return $value;
        }
 
-       public function clearCaches() {
-               $key = $this->getLagTimeCacheKey();
-               $this->srvCache->delete( $key );
-               $this->mainCache->delete( $key );
+       /**
+        * @param integer $index Server index
+        * @param IDatabase|null $conn Connection handle or null on connection failure
+        * @return float
+        */
+       protected function getWeightScale( $index, IDatabase $conn = null ) {
+               return $conn ? 1.0 : 0.0;
        }
 
-       private function getLagTimeCacheKey() {
-               $writerIndex = $this->parent->getWriterIndex();
+       private function getCacheKey( array $serverIndexes ) {
+               sort( $serverIndexes );
                // Lag is per-server, not per-DB, so key on the master DB name
                return $this->srvCache->makeGlobalKey(
                        'lag-times',
-                       $this->parent->getServerName( $writerIndex )
+                       self::VERSION,
+                       $this->parent->getServerName( $this->parent->getWriterIndex() ),
+                       implode( '-', $serverIndexes )
                );
        }
 }
index 7286417..45b1d83 100644 (file)
  * @ingroup Database
  */
 class LoadMonitorMySQL extends LoadMonitor {
-       public function scaleLoads( &$loads, $group = false, $domain = false ) {
-               // @TODO: maybe use Threads_running/Threads_created ratio to guess load
-               // and Queries/Uptime to guess if a server is warming up the buffer pool
+       /** @var float What buffer pool use ratio counts as "warm" (e.g. 0.5 for 50% usage) */
+       private $warmCacheRatio;
+
+       public function __construct(
+               ILoadBalancer $lb, BagOStuff $srvCache, BagOStuff $cache, array $options = []
+       ) {
+               parent::__construct( $lb, $srvCache, $cache, $options );
+
+               $this->warmCacheRatio = isset( $options['warmCacheRatio'] )
+                       ? $options['warmCacheRatio']
+                       : 0.0;
+       }
+
+       protected function getWeightScale( $index, IDatabase $conn = null ) {
+               if ( !$conn ) {
+                       return 0.0;
+               }
+
+               $weight = 1.0;
+               if ( $this->warmCacheRatio > 0 ) {
+                       $res = $conn->query( 'SHOW STATUS', false );
+                       $s = $res ? $conn->fetchObject( $res ) : false;
+                       if ( $s === false ) {
+                               $host = $this->parent->getServerName( $index );
+                               $this->replLogger->error( __METHOD__ . ": could not get status for $host" );
+                       } else {
+                               // https://dev.mysql.com/doc/refman/5.7/en/server-status-variables.html
+                               if ( $s->Innodb_buffer_pool_pages_total > 0 ) {
+                                       $ratio = $s->Innodb_buffer_pool_pages_data / $s->Innodb_buffer_pool_pages_total;
+                               } elseif ( $s->Qcache_total_blocks > 0 ) {
+                                       $ratio = 1.0 - $s->Qcache_free_blocks / $s->Qcache_total_blocks;
+                               } else {
+                                       $ratio = 1.0;
+                               }
+                               // Stop caring once $ratio >= $this->warmCacheRatio
+                               $weight *= min( $ratio / $this->warmCacheRatio, 1.0 );
+                       }
+               }
+
+               return $weight;
        }
 }
index 8062001..c4e25dc 100644 (file)
 use Psr\Log\LoggerInterface;
 
 class LoadMonitorNull implements ILoadMonitor {
-       public function __construct( ILoadBalancer $lb, BagOStuff $sCache, BagOStuff $cCache ) {
+       public function __construct(
+               ILoadBalancer $lb, BagOStuff $sCache, BagOStuff $cCache, array $options = []
+       ) {
 
        }
 
        public function setLogger( LoggerInterface $logger ) {
        }
 
-       public function scaleLoads( &$loads, $group = false, $domain = false ) {
+       public function scaleLoads( array &$loads, $domain ) {
 
        }
 
-       public function getLagTimes( $serverIndexes, $domain ) {
+       public function getLagTimes( array $serverIndexes, $domain ) {
                return array_fill_keys( $serverIndexes, 0 );
        }
 
index b02985a..c830b4e 100644 (file)
@@ -90,7 +90,7 @@ class ConvertibleTimestamp {
                        # TS_MW
                } elseif ( preg_match( '/^(-?\d{1,13})(\.\d+)?$/D', $ts, $m ) ) {
                        # TS_UNIX
-                       $strtime = "@{$m[1]}"; // http://php.net/manual/en/datetime.formats.compound.php
+                       $strtime = "@{$m[1]}"; // https://secure.php.net/manual/en/datetime.formats.compound.php
                } elseif ( preg_match( '/^\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}.\d{6}$/', $ts ) ) {
                        # TS_ORACLE // session altered to DD-MM-YYYY HH24:MI:SS.FF6
                        $strtime = preg_replace( '/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
index da47d35..a148a39 100644 (file)
@@ -103,7 +103,6 @@ class ParsoidVirtualRESTService extends VirtualRESTService {
                                continue;
                        }
                        if ( $targetWiki !== 'local' ) {
-
                                throw new Exception( "Only 'local' target wiki is currently supported" );
                        }
                        if ( $reqType !== 'page' && $reqType !== 'transform' ) {
@@ -150,7 +149,6 @@ class ParsoidVirtualRESTService extends VirtualRESTService {
         * API.  We now translate these to the "real" Parsoid v3 API.
         */
        public function onParsoid1Request( array $req, Closure $idGeneratorFunc ) {
-
                $parts = explode( '/', $req['url'] );
                list(
                        $targetWiki, // 'local'
@@ -221,7 +219,6 @@ class ParsoidVirtualRESTService extends VirtualRESTService {
                }
 
                return $req;
-
        }
 
 }
index 3afbaa3..35c45de 100644 (file)
@@ -78,7 +78,6 @@ class RestbaseVirtualRESTService extends VirtualRESTService {
        }
 
        public function onRequests( array $reqs, Closure $idGenFunc ) {
-
                if ( $this->params['parsoidCompat'] ) {
                        return $this->onParsoidRequests( $reqs, $idGenFunc );
                }
@@ -117,7 +116,6 @@ class RestbaseVirtualRESTService extends VirtualRESTService {
         * Remaps Parsoid v1/v3 requests to RESTBase v1 requests.
         */
        public function onParsoidRequests( array $reqs, Closure $idGeneratorFunc ) {
-
                $result = [];
                foreach ( $reqs as $key => $req ) {
                        $version = explode( '/', $req['url'] )[1];
@@ -131,7 +129,6 @@ class RestbaseVirtualRESTService extends VirtualRESTService {
                }
 
                return $result;
-
        }
 
        /**
@@ -223,7 +220,6 @@ class RestbaseVirtualRESTService extends VirtualRESTService {
                }
 
                return $req;
-
        }
 
        /**
@@ -241,7 +237,6 @@ class RestbaseVirtualRESTService extends VirtualRESTService {
         *   * $revision is optional
         */
        public function onParsoid3Request( array $req, Closure $idGeneratorFunc ) {
-
                $parts = explode( '/', $req['url'] );
                list(
                        $targetWiki, // 'local'
@@ -272,7 +267,6 @@ class RestbaseVirtualRESTService extends VirtualRESTService {
                }
 
                return $req;
-
        }
 
 }
index 70f67b7..29bbf40 100644 (file)
@@ -24,6 +24,7 @@
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerInterface;
 use Psr\Log\NullLogger;
+use Wikimedia\ScopedCallback;
 
 /**
  * Class for reading xmp data containing properties relevant to
index 1059d7b..c8e9999 100644 (file)
@@ -283,7 +283,7 @@ class UserMailer {
                        ->getFullURL( '', false, PROTO_CANONICAL ) . '>';
 
                // Line endings need to be different on Unix and Windows due to
-               // the bug described at http://trac.wordpress.org/ticket/2603
+               // the bug described at https://core.trac.wordpress.org/ticket/2603
                $endl = PHP_EOL;
 
                if ( is_array( $body ) ) {
index ed361eb..5e8f8c8 100644 (file)
@@ -254,7 +254,7 @@ class DjVuImage {
 
                if ( isset( $wgDjvuDump ) ) {
                        # djvudump is faster as of version 3.5
-                       # http://sourceforge.net/tracker/index.php?func=detail&aid=1704049&group_id=32953&atid=406583
+                       # https://sourceforge.net/p/djvu/bugs/71/
                        $cmd = wfEscapeShellArg( $wgDjvuDump ) . ' ' . wfEscapeShellArg( $this->mFilename );
                        $dump = wfShellExec( $cmd );
                        $xml = $this->convertDumpToXML( $dump );
index 78b0296..51a0135 100644 (file)
@@ -102,7 +102,6 @@ class FormatMetadata extends ContextSource {
                unset( $tags['ResolutionUnit'] );
 
                foreach ( $tags as $tag => &$vals ) {
-
                        // This seems ugly to wrap non-array's in an array just to unwrap again,
                        // especially when most of the time it is not an array
                        if ( !is_array( $tags[$tag] ) ) {
@@ -165,7 +164,6 @@ class FormatMetadata extends ContextSource {
                        }
 
                        foreach ( $vals as &$val ) {
-
                                switch ( $tag ) {
                                        case 'Compression':
                                                switch ( $val ) {
@@ -866,6 +864,7 @@ class FormatMetadata extends ContextSource {
                                        // are included here as we really don't want
                                        // commas inserted.
                                        case 'ImageDescription':
+                                       case 'UserComment':
                                        case 'Artist':
                                        case 'Copyright':
                                        case 'RelatedSoundFile':
@@ -1682,7 +1681,6 @@ class FormatMetadata extends ContextSource {
        protected function getExtendedMetadataFromHook( File $file, array $extendedMetadata,
                &$maxCacheTime
        ) {
-
                Hooks::run( 'GetExtendedMetadata', [
                        &$extendedMetadata,
                        $file,
@@ -1806,7 +1804,6 @@ class FormatMetadata extends ContextSource {
                                $field['value'] = $this->resolveMultivalueValue( $field['value'] );
                        }
                }
-
        }
 
        /**
index 81722c6..67c957a 100644 (file)
@@ -82,9 +82,10 @@ class JpegMetadataExtractor {
                                // this is just a sanity check
                                throw new MWException( 'Too many jpeg segments. Aborting' );
                        }
-                       if ( $buffer !== "\xFF" ) {
-                               throw new MWException( "Error reading jpeg file marker. " .
-                                       "Expected 0xFF but got " . bin2hex( $buffer ) );
+                       while ( $buffer !== "\xFF" ) {
+                               // In theory JPEG files are not allowed to contain anything between the sections,
+                               // but in practice they sometimes do. It's customary to ignore the garbage data.
+                               $buffer = fread( $fh, 1 );
                        }
 
                        $buffer = fread( $fh, 1 );
@@ -155,7 +156,7 @@ class JpegMetadataExtractor {
                        } else {
                                // segment we don't care about, so skip
                                $size = wfUnpack( "nint", fread( $fh, 2 ), 2 );
-                               if ( $size['int'] <= 2 ) {
+                               if ( $size['int'] < 2 ) {
                                        throw new MWException( "invalid marker size in jpeg" );
                                }
                                fseek( $fh, $size['int'] - 2, SEEK_CUR );
@@ -173,9 +174,13 @@ class JpegMetadataExtractor {
         */
        private static function jpegExtractMarker( &$fh ) {
                $size = wfUnpack( "nint", fread( $fh, 2 ), 2 );
-               if ( $size['int'] <= 2 ) {
+               if ( $size['int'] < 2 ) {
                        throw new MWException( "invalid marker size in jpeg" );
                }
+               if ( $size['int'] === 2 ) {
+                       // fread( ..., 0 ) generates a warning
+                       return '';
+               }
                $segment = fread( $fh, $size['int'] - 2 );
                if ( strlen( $segment ) !== $size['int'] - 2 ) {
                        throw new MWException( "Segment shorter than expected" );
index 4bc36ba..2a735a2 100644 (file)
@@ -104,7 +104,7 @@ abstract class MediaHandler {
         *   Warning, FSFile::getPropsFromPath might pass an FSFile instead of File (!)
         * @param string $path The filename
         * @return array|bool Follow the format of PHP getimagesize() internal function.
-        *   See http://www.php.net/getimagesize. MediaWiki will only ever use the
+        *   See https://secure.php.net/getimagesize. MediaWiki will only ever use the
         *   first two array keys (the width and height), and the 'bits' associative
         *   key. All other array keys are ignored. Returning a 'bits' key is optional
         *   as not all formats have a notion of "bitdepth". Returns false on failure.
index f4f29dd..d0517d7 100644 (file)
@@ -47,7 +47,7 @@ class PNGMetadataExtractor {
                self::$pngSig = pack( "C8", 137, 80, 78, 71, 13, 10, 26, 10 );
                self::$crcSize = 4;
                /* based on list at http://owl.phy.queensu.ca/~phil/exiftool/TagNames/PNG.html#TextualData
-                * and http://www.w3.org/TR/PNG/#11keywords
+                * and https://www.w3.org/TR/PNG/#11keywords
                 */
                self::$textChunks = [
                        'xml:com.adobe.xmp' => 'xmp',
@@ -123,7 +123,7 @@ class PNGMetadataExtractor {
                                }
                                $bitDepth = ord( substr( $buf, 8, 1 ) );
                                // Detect the color type in British English as per the spec
-                               // http://www.w3.org/TR/PNG/#11IHDR
+                               // https://www.w3.org/TR/PNG/#11IHDR
                                switch ( ord( substr( $buf, 9, 1 ) ) ) {
                                        case 0:
                                                $colorType = 'greyscale';
index 8360920..f3b33ac 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup Media
  */
+use Wikimedia\ScopedCallback;
 
 /**
  * Handler for SVG images.
index 62b5c2c..6a974c7 100644 (file)
@@ -264,7 +264,7 @@ class SVGReader {
                        ) {
                                $sysLang = $this->reader->getAttribute( 'systemLanguage' );
                                if ( !is_null( $sysLang ) && $sysLang !== '' ) {
-                                       // See http://www.w3.org/TR/SVG/struct.html#SystemLanguageAttribute
+                                       // See https://www.w3.org/TR/SVG/struct.html#SystemLanguageAttribute
                                        $langList = explode( ',', $sysLang );
                                        foreach ( $langList as $langItem ) {
                                                $langItem = trim( $langItem );
@@ -369,7 +369,7 @@ class SVGReader {
 
        /**
         * Return a rounded pixel equivalent for a labeled CSS/SVG length.
-        * http://www.w3.org/TR/SVG11/coords.html#UnitIdentifiers
+        * https://www.w3.org/TR/SVG11/coords.html#Units
         *
         * @param string $length CSS/SVG length.
         * @param float|int $viewportSize Optional scale for percentage units...
index 3ebda75..e33c27e 100644 (file)
@@ -25,6 +25,7 @@
  * @file
  * @ingroup Media
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * Handler for images that need to be transformed
@@ -509,22 +510,23 @@ abstract class TransformationalImageHandler extends ImageHandler {
         * @return string|bool Representing the IM version; false on error
         */
        protected function getMagickVersion() {
-               $cache = ObjectCache::getLocalServerInstance( CACHE_NONE );
+               $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
+               $method = __METHOD__;
                return $cache->getWithSetCallback(
                        'imagemagick-version',
                        $cache::TTL_HOUR,
-                       function () {
+                       function () use ( $method ) {
                                global $wgImageMagickConvertCommand;
 
                                $cmd = wfEscapeShellArg( $wgImageMagickConvertCommand ) . ' -version';
-                               wfDebug( __METHOD__ . ": Running convert -version\n" );
+                               wfDebug( $method . ": Running convert -version\n" );
                                $retval = '';
                                $return = wfShellExec( $cmd, $retval );
                                $x = preg_match(
                                        '/Version: ImageMagick ([0-9]*\.[0-9]*\.[0-9]*)/', $return, $matches
                                );
                                if ( $x != 1 ) {
-                                       wfDebug( __METHOD__ . ": ImageMagick version check failed\n" );
+                                       wfDebug( $method . ": ImageMagick version check failed\n" );
                                        return false;
                                }
 
index 108d6fb..c419524 100644 (file)
@@ -67,7 +67,7 @@ class XCFHandler extends BitmapHandler {
                }
 
                # Forge a return array containing metadata information just like getimagesize()
-               # See PHP documentation at: http://www.php.net/getimagesize
+               # See PHP documentation at: https://secure.php.net/getimagesize
                return [
                        0 => $header['width'],
                        1 => $header['height'],
diff --git a/includes/mime.info b/includes/mime.info
deleted file mode 100644 (file)
index b04d3c6..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-# MIME type info file.
-# the first MIME type in each line is the "main" MIME type,
-# the others are aliases for this type
-# the media type is given in upper case and square brackets,
-# like [BITMAP], and must indicate a media type as defined by
-# the MEDIATYPE_xxx constants in Defines.php
-
-
-image/gif      [BITMAP]
-image/png image/x-png  [BITMAP]
-image/ief      [BITMAP]
-image/jpeg image/pjpeg [BITMAP]
-image/jp2      [BITMAP]
-image/xbm      [BITMAP]
-image/tiff     [BITMAP]
-image/x-icon image/x-ico image/vnd.microsoft.icon      [BITMAP]
-image/x-rgb    [BITMAP]
-image/x-portable-pixmap                [BITMAP]
-image/x-portable-graymap image/x-portable-greymap      [BITMAP]
-image/x-bmp image/x-ms-bmp image/bmp application/x-bmp application/bmp [BITMAP]
-image/x-photoshop image/psd image/x-psd image/photoshop image/vnd.adobe.photoshop      [BITMAP]
-image/vnd.djvu image/x.djvu image/x-djvu [BITMAP]
-image/webp     [BITMAP]
-
-image/svg+xml application/svg+xml application/svg image/svg    [DRAWING]
-application/postscript [DRAWING]
-application/x-latex    [DRAWING]
-application/x-tex      [DRAWING]
-application/x-dia-diagram [DRAWING]
-
-
-audio/mpeg audio/mp3 audio/mpeg3       [AUDIO]
-audio/mp4                              [AUDIO]
-audio/wav audio/x-wav audio/wave       [AUDIO]
-audio/midi audio/mid   [AUDIO]
-audio/basic            [AUDIO]
-audio/ogg              [AUDIO]
-audio/x-aiff           [AUDIO]
-audio/x-pn-realaudio   [AUDIO]
-audio/x-realaudio      [AUDIO]
-audio/webm             [AUDIO]
-audio/x-matroska       [AUDIO]
-audio/x-flac           [AUDIO]
-audio/flac             [AUDIO]
-
-video/mpeg application/mpeg    [VIDEO]
-video/ogg                      [VIDEO]
-video/x-sgi-video              [VIDEO]
-video/x-flv                    [VIDEO]
-video/webm                     [VIDEO]
-video/x-matroska               [VIDEO]
-video/mp4                      [VIDEO]
-
-application/ogg application/x-ogg audio/ogg audio/x-ogg video/ogg video/x-ogg          [MULTIMEDIA]
-
-application/x-shockwave-flash  [MULTIMEDIA]
-audio/x-pn-realaudio-plugin    [MULTIMEDIA]
-model/iges     [MULTIMEDIA]
-model/mesh     [MULTIMEDIA]
-model/vrml     [MULTIMEDIA]
-video/quicktime        [MULTIMEDIA]
-video/x-msvideo        [MULTIMEDIA]
-
-text/plain     [TEXT]
-text/html application/xhtml+xml        [TEXT]
-application/xml text/xml       [TEXT]
-text   [TEXT]
-application/json       [TEXT]
-text/csv       [TEXT]
-text/tab-separated-values      [TEXT]
-
-application/zip application/x-zip      [ARCHIVE]
-application/x-gzip     [ARCHIVE]
-application/x-bzip     [ARCHIVE]
-application/x-bzip2    [ARCHIVE]
-application/x-tar      [ARCHIVE]
-application/x-stuffit  [ARCHIVE]
-application/x-opc+zip  [ARCHIVE]
-application/x-7z-compressed [ARCHIVE]
-
-application/javascript text/javascript application/x-javascript application/x-ecmascript text/ecmascript       [EXECUTABLE]
-application/x-bash     [EXECUTABLE]
-application/x-sh       [EXECUTABLE]
-application/x-csh      [EXECUTABLE]
-application/x-tcsh     [EXECUTABLE]
-application/x-tcl      [EXECUTABLE]
-application/x-perl     [EXECUTABLE]
-application/x-python   [EXECUTABLE]
-
-application/pdf application/acrobat    [OFFICE]
-application/msword             [OFFICE]
-application/vnd.ms-excel       [OFFICE]
-application/vnd.ms-powerpoint  [OFFICE]
-application/x-director         [OFFICE]
-text/rtf                       [OFFICE]
-
-application/vnd.openxmlformats-officedocument.wordprocessingml.document        [OFFICE]
-application/vnd.openxmlformats-officedocument.wordprocessingml.template                [OFFICE]
-application/vnd.ms-word.document.macroEnabled.12                               [OFFICE]
-application/vnd.ms-word.template.macroEnabled.12                               [OFFICE]
-application/vnd.openxmlformats-officedocument.presentationml.template          [OFFICE]
-application/vnd.openxmlformats-officedocument.presentationml.slideshow         [OFFICE]
-application/vnd.openxmlformats-officedocument.presentationml.presentation      [OFFICE]
-application/vnd.ms-powerpoint.addin.macroEnabled.12                            [OFFICE]
-application/vnd.ms-powerpoint.presentation.macroEnabled.12                     [OFFICE]
-application/vnd.ms-powerpoint.presentation.macroEnabled.12                     [OFFICE]
-application/vnd.ms-powerpoint.slideshow.macroEnabled.12                                [OFFICE]
-application/vnd.openxmlformats-officedocument.spreadsheetml.sheet              [OFFICE]
-application/vnd.openxmlformats-officedocument.spreadsheetml.template           [OFFICE]
-application/vnd.ms-excel.sheet.macroEnabled.12                                 [OFFICE]
-application/vnd.ms-excel.template.macroEnabled.12                              [OFFICE]
-application/vnd.ms-excel.addin.macroEnabled.12                                 [OFFICE]
-application/vnd.ms-excel.sheet.binary.macroEnabled.12                          [OFFICE]
-application/acad application/x-acad application/autocad_dwg image/x-dwg application/dwg application/x-dwg application/x-autocad image/vnd.dwg drawing/dwg [DRAWING]
-chemical/x-mdl-molfile     [DRAWING]
-chemical/x-mdl-sdfile      [DRAWING]
-chemical/x-mdl-rxnfile     [DRAWING]
-chemical/x-mdl-rdfile      [DRAWING]
-chemical/x-mdl-rgfile      [DRAWING]
diff --git a/includes/mime.types b/includes/mime.types
deleted file mode 100644 (file)
index b4f515a..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-application/acad dwg
-application/andrew-inset ez
-application/mac-binhex40 hqx
-application/mac-compactpro cpt
-application/mathml+xml mathml
-application/msword doc dot
-application/octet-stream bin dms lha lzh exe class so dll
-application/oda oda
-application/ogg ogx ogg ogm ogv oga spx opus
-application/pdf pdf
-application/postscript ai eps ps
-application/rdf+xml rdf
-application/smil smi smil
-application/srgs gram
-application/srgs+xml grxml
-application/vnd.mif mif
-application/vnd.ms-excel xls xlt xla
-application/vnd.ms-powerpoint ppt pot pps ppa
-application/vnd.wap.wbxml wbxml
-application/vnd.wap.wmlc wmlc
-application/vnd.wap.wmlscriptc wmlsc
-application/voicexml+xml vxml
-application/x-7z-compressed 7z
-application/x-bcpio bcpio
-application/x-bzip bz
-application/x-bzip2 bz2
-application/x-cdlink vcd
-application/x-chess-pgn pgn
-application/x-cpio cpio
-application/x-csh csh
-application/x-dia-diagram dia
-application/x-director dcr dir dxr
-application/x-dvi dvi
-application/x-futuresplash spl
-application/x-gtar gtar tar
-application/x-gzip gz
-application/x-hdf hdf
-application/x-jar jar
-application/javascript js
-application/json json
-application/x-koan skp skd skt skm
-application/x-latex latex
-application/x-netcdf nc cdf
-application/x-sh sh
-application/x-shar shar
-application/x-shockwave-flash swf
-application/x-stuffit sit
-application/x-sv4cpio sv4cpio
-application/x-sv4crc sv4crc
-application/x-tar tar
-application/x-tcl tcl
-application/x-tex tex
-application/x-texinfo texinfo texi
-application/x-troff t tr roff
-application/x-troff-man man
-application/x-troff-me me
-application/x-troff-ms ms
-application/x-ustar ustar
-application/x-wais-source src
-application/x-xpinstall xpi
-application/xhtml+xml xhtml xht
-application/xslt+xml xslt
-application/xml xml xsl xsd kml
-application/xml-dtd dtd
-application/zip zip jar xpi sxc stc sxd std sxi sti sxm stm sxw stw
-application/x-rar rar
-application/font-woff woff
-application/font-woff2 woff2
-application/vnd.ms-fontobject eot
-application/x-font-ttf ttf
-audio/basic au snd
-audio/midi mid midi kar
-audio/mpeg mpga mp2 mp3
-audio/ogg oga ogg spx opus
-video/webm webm
-audio/webm webm
-audio/x-aiff aif aiff aifc
-audio/x-matroska mka mkv
-audio/x-mpegurl m3u
-audio/x-ogg oga ogg spx opus
-audio/x-pn-realaudio ram rm
-audio/x-pn-realaudio-plugin rpm
-audio/x-realaudio ra
-audio/x-wav wav
-audio/wav wav
-audio/x-flac flac
-audio/flac flac
-chemical/x-pdb pdb
-chemical/x-xyz xyz
-image/bmp bmp
-image/cgm cgm
-image/gif gif
-image/ief ief
-image/jp2 j2k jp2 jpg2
-image/jpeg jpeg jpg jpe
-image/png png apng
-image/svg+xml svg
-image/tiff tiff tif
-image/vnd.djvu djvu djv
-image/vnd.microsoft.icon ico
-image/vnd.wap.wbmp wbmp
-image/webp webp
-image/x-cmu-raster ras
-image/x-icon ico
-image/x-ms-bmp bmp
-image/x-portable-anymap pnm
-image/x-portable-bitmap pbm
-image/x-portable-graymap pgm
-image/x-portable-pixmap ppm
-image/x-rgb rgb
-image/x-photoshop psd
-image/x-xbitmap xbm
-image/x-xpixmap xpm
-image/x-xwindowdump xwd
-model/iges igs iges
-model/mesh msh mesh silo
-model/vrml wrl vrml
-text/calendar ics ifb
-text/css css
-text/csv csv
-text/html html htm
-text/plain txt
-text/richtext rtx
-text/rtf rtf
-text/sgml sgml sgm
-text/tab-separated-values tsv
-text/vnd.wap.wml wml
-text/vnd.wap.wmlscript wmls
-text/xml xml xsl xslt rss rdf
-text/x-component htc
-text/x-setext etx
-text/x-sawfish jl
-video/mpeg mpeg mpg mpe
-video/mp4 mp4 m4a m4p m4b m4r m4v
-audio/mp4 m4a
-video/ogg ogv ogm ogg
-video/quicktime qt mov
-video/vnd.mpegurl mxu
-video/x-flv flv
-video/x-matroska mkv mka
-video/x-msvideo avi
-video/x-ogg ogv ogm ogg
-video/x-sgi-movie movie
-x-conference/x-cooltalk ice
-application/vnd.oasis.opendocument.chart odc
-application/vnd.oasis.opendocument.chart-template otc
-application/vnd.oasis.opendocument.database odb
-application/vnd.oasis.opendocument.formula odf
-application/vnd.oasis.opendocument.formula-template otf
-application/vnd.oasis.opendocument.graphics odg
-application/vnd.oasis.opendocument.graphics-template otg
-application/vnd.oasis.opendocument.image odi
-application/vnd.oasis.opendocument.image-template oti
-application/vnd.oasis.opendocument.presentation odp
-application/vnd.oasis.opendocument.presentation-template otp
-application/vnd.oasis.opendocument.spreadsheet ods
-application/vnd.oasis.opendocument.spreadsheet-template ots
-application/vnd.oasis.opendocument.text odt
-application/vnd.oasis.opendocument.text-master odm
-application/vnd.oasis.opendocument.text-template ott
-application/vnd.oasis.opendocument.text-web oth
-application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
-application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
-application/vnd.ms-word.document.macroEnabled.12 docm
-application/vnd.ms-word.template.macroEnabled.12 dotm
-application/vnd.openxmlformats-officedocument.presentationml.template potx
-application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
-application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
-application/vnd.ms-powerpoint.addin.macroEnabled.12 ppam
-application/vnd.ms-powerpoint.presentation.macroEnabled.12 pptm
-application/vnd.ms-powerpoint.presentation.macroEnabled.12 potm
-application/vnd.ms-powerpoint.slideshow.macroEnabled.12 ppsm
-application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
-application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
-application/vnd.ms-excel.sheet.macroEnabled.12 xlsm
-application/vnd.ms-excel.template.macroEnabled.12 xltm
-application/vnd.ms-excel.addin.macroEnabled.12 xlam
-application/vnd.ms-excel.sheet.binary.macroEnabled.12 xlsb
-model/vnd.dwfx+xps dwfx
-application/vnd.ms-xpsdocument xps
-application/x-opc+zip docx dotx docm dotm potx ppsx pptx ppam pptm potm ppsm xlsx xltx xlsm xltm xlam xlsb dwfx xps
-chemical/x-mdl-molfile mol
-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 d81f9e1..0a4f0ed 100644 (file)
@@ -50,7 +50,7 @@ use MediaWiki\MediaWikiServices;
  *
  * - ObjectCache::getLocalServerInstance( $fallbackType )
  *   Purpose: Memory cache for very hot keys.
- *   Stored only on the individual web server (typically APC for web requests,
+ *   Stored only on the individual web server (typically APC or APCu for web requests,
  *   and EmptyBagOStuff in CLI mode).
  *   Not replicated to the other servers.
  *
@@ -190,7 +190,7 @@ class ObjectCache {
                                ? $params['reportDupes']
                                : true;
                        // Do b/c logic for SqlBagOStuff
-                       if ( is_subclass_of( $class, SqlBagOStuff::class ) ) {
+                       if ( is_a( $class, SqlBagOStuff::class, true ) ) {
                                if ( isset( $params['server'] ) && !isset( $params['servers'] ) ) {
                                        $params['servers'] = [ $params['server'] ];
                                        unset( $params['server'] );
@@ -265,7 +265,7 @@ class ObjectCache {
        /**
         * Factory function for CACHE_ACCEL (referenced from DefaultSettings.php)
         *
-        * This will look for any APC style server-local cache.
+        * This will look for any APC or APCu style server-local cache.
         * A fallback cache can be specified if none is found.
         *
         *     // Direct calls
@@ -280,39 +280,15 @@ class ObjectCache {
         * @since 1.27
         */
        public static function getLocalServerInstance( $fallback = CACHE_NONE ) {
-               if ( function_exists( 'apc_fetch' ) ) {
-                       $id = 'apc';
-               } elseif ( function_exists( 'xcache_get' ) && wfIniGetBool( 'xcache.var_size' ) ) {
-                       $id = 'xcache';
-               } elseif ( function_exists( 'wincache_ucache_get' ) ) {
-                       $id = 'wincache';
-               } else {
+               $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
+               if ( $cache instanceof EmptyBagOStuff ) {
                        if ( is_array( $fallback ) ) {
-                               $id = isset( $fallback['fallback'] ) ? $fallback['fallback'] : CACHE_NONE;
-                       } else {
-                               $id = $fallback;
+                               $fallback = isset( $fallback['fallback'] ) ? $fallback['fallback'] : CACHE_NONE;
                        }
+                       $cache = self::getInstance( $fallback );
                }
 
-               return self::getInstance( $id );
-       }
-
-       /**
-        * @param array $params [optional] Array key 'fallback' for $fallback.
-        * @param int|string $fallback Fallback cache, e.g. (CACHE_NONE, "hash") (since 1.24)
-        * @return BagOStuff
-        * @deprecated since 1.27
-        */
-       public static function newAccelerator( $params = [], $fallback = null ) {
-               if ( $fallback === null ) {
-                       if ( is_array( $params ) && isset( $params['fallback'] ) ) {
-                               $fallback = $params['fallback'];
-                       } elseif ( !is_array( $params ) ) {
-                               $fallback = $params;
-                       }
-               }
-
-               return self::getLocalServerInstance( $fallback );
+               return $cache;
        }
 
        /**
@@ -350,9 +326,9 @@ class ObjectCache {
         * @throws UnexpectedValueException
         */
        public static function newWANCacheFromParams( array $params ) {
+               $erGroup = MediaWikiServices::getInstance()->getEventRelayerGroup();
                foreach ( $params['channels'] as $action => $channel ) {
-                       $params['relayers'][$action] = MediaWikiServices::getInstance()->getEventRelayerGroup()
-                               ->getRelayer( $channel );
+                       $params['relayers'][$action] = $erGroup->getRelayer( $channel );
                        $params['channels'][$action] = $channel;
                }
                $params['cache'] = self::newFromParams( $params['store'] );
@@ -383,11 +359,10 @@ class ObjectCache {
         *
         * @since 1.26
         * @return WANObjectCache
+        * @deprecated Since 1.28 Use MediaWikiServices::getMainWANCache()
         */
        public static function getMainWANInstance() {
-               global $wgMainWANCache;
-
-               return self::getWANInstance( $wgMainWANCache );
+               return MediaWikiServices::getInstance()->getMainWANObjectCache();
        }
 
        /**
@@ -407,11 +382,10 @@ class ObjectCache {
         *
         * @return BagOStuff
         * @since 1.26
+        * @deprecated Since 1.28 Use MediaWikiServices::getMainObjectStash
         */
        public static function getMainStashInstance() {
-               global $wgMainStash;
-
-               return self::getInstance( $wgMainStash );
+               return MediaWikiServices::getInstance()->getMainObjectStash();
        }
 
        /**
index 770ae31..9a2a8e2 100644 (file)
@@ -210,7 +210,7 @@ class Article implements Page {
         * @return string Return the text of this revision
         */
        public function getContent() {
-               ContentHandler::deprecated( __METHOD__, '1.21' );
+               wfDeprecated( __METHOD__, '1.21' );
                $content = $this->getContentObject();
                return ContentHandler::getContentText( $content );
        }
@@ -347,7 +347,11 @@ class Article implements Page {
 
                // @todo Get rid of mContent everywhere!
                $this->mContent = ContentHandler::getContentText( $content );
-               ContentHandler::runLegacyHooks( 'ArticleAfterFetchContent', [ &$this, &$this->mContent ] );
+               ContentHandler::runLegacyHooks(
+                       'ArticleAfterFetchContent',
+                       [ &$this, &$this->mContent ],
+                       '1.21'
+               );
 
                return $this->mContent;
        }
@@ -424,7 +428,11 @@ class Article implements Page {
                $this->mContentObject = $content;
                $this->mRevIdFetched = $this->mRevision->getId();
 
-               Hooks::run( 'ArticleAfterFetchContentObject', [ &$this, &$this->mContentObject ] );
+               ContentHandler::runLegacyHooks(
+                       'ArticleAfterFetchContentObject',
+                       [ &$this, &$this->mContentObject ],
+                       '1.21'
+               );
 
                return $this->mContentObject;
        }
@@ -623,9 +631,11 @@ class Article implements Page {
 
                                                # Allow extensions do their own custom view for certain pages
                                                $outputDone = true;
-                                       } elseif ( !ContentHandler::runLegacyHooks( 'ArticleViewCustom',
-                                                       [ $this->fetchContentObject(), $this->getTitle(), $outputPage ] ) ) {
-
+                                       } elseif ( !ContentHandler::runLegacyHooks(
+                                               'ArticleViewCustom',
+                                               [ $this->fetchContentObject(), $this->getTitle(), $outputPage ],
+                                               '1.21'
+                                       ) ) {
                                                # Allow extensions do their own custom view for certain pages
                                                $outputDone = true;
                                        }
@@ -696,6 +706,10 @@ class Article implements Page {
                        }
                }
 
+               # Use adaptive TTLs for CDN so delayed/failed purges are noticed less often.
+               # This could use getTouched(), but that could be scary for major template edits.
+               $outputPage->adaptCdnTTL( $this->mPage->getTimestamp(), IExpiringStore::TTL_DAY );
+
                # Check for any __NOINDEX__ tags on the page using $pOutput
                $policy = $this->getRobotPolicy( 'view', $pOutput );
                $outputPage->setIndexPolicy( $policy['index'] );
@@ -705,7 +719,6 @@ class Article implements Page {
                $this->mPage->doViewUpdates( $user, $oldid );
 
                $outputPage->addModules( 'mediawiki.action.view.postEdit' );
-
        }
 
        /**
@@ -798,8 +811,9 @@ class Article implements Page {
                        // Give hooks a chance to customise the output
                        if ( ContentHandler::runLegacyHooks(
                                'ShowRawCssJs',
-                               [ $this->mContentObject, $this->getTitle(), $outputPage ] )
-                       ) {
+                               [ $this->mContentObject, $this->getTitle(), $outputPage ],
+                               '1.24'
+                       ) ) {
                                // If no legacy hooks ran, display the content of the parser output, including RL modules,
                                // but excluding metadata like categories and language links
                                $po = $this->mContentObject->getParserOutput( $this->getTitle() );
@@ -1170,10 +1184,6 @@ class Article implements Page {
                        return false;
                }
 
-               $rcid = $rc->getAttribute( 'rc_id' );
-
-               $token = $user->getEditToken( $rcid );
-
                $outputPage->preventClickjacking();
                if ( $wgEnableAPI && $wgEnableWriteAPI && $user->isAllowed( 'writeapi' ) ) {
                        $outputPage->addModules( 'mediawiki.page.patrol.ajax' );
@@ -1185,8 +1195,7 @@ class Article implements Page {
                        [],
                        [
                                'action' => 'markpatrolled',
-                               'rcid' => $rcid,
-                               'token' => $token,
+                               'rcid' => $rc->getAttribute( 'rc_id' ),
                        ]
                );
 
@@ -2114,7 +2123,7 @@ class Article implements Page {
         * @deprecated since 1.21: use doEditContent() instead.
         */
        public function doEdit( $text, $summary, $flags = 0, $baseRevId = false, $user = null ) {
-               ContentHandler::deprecated( __METHOD__, '1.21' );
+               wfDeprecated( __METHOD__, '1.21' );
                return $this->mPage->doEdit( $text, $summary, $flags, $baseRevId, $user );
        }
 
@@ -2154,18 +2163,6 @@ class Article implements Page {
                return $this->mPage->getLastPurgeTimestamp();
        }
 
-       /**
-        * Call to WikiPage function for backwards compatibility.
-        * @see WikiPage::doQuickEditContent
-        */
-       public function doQuickEditContent(
-               Content $content, User $user, $comment = '', $minor = false, $serialFormat = null
-       ) {
-               return $this->mPage->doQuickEditContent(
-                       $content, $user, $comment, $minor, $serialFormat
-               );
-       }
-
        /**
         * Call to WikiPage function for backwards compatibility.
         * @see WikiPage::doViewUpdates
@@ -2508,6 +2505,7 @@ class Article implements Page {
 
        /**
         * Call to WikiPage function for backwards compatibility.
+        * @deprecated since 1.21, use prepareContentForEdit
         * @see WikiPage::prepareTextForEdit
         */
        public function prepareTextForEdit( $text, $revid = null, User $user = null ) {
index 865471c..6d2be51 100644 (file)
@@ -68,6 +68,10 @@ class CategoryPage extends Article {
                if ( $title->inNamespace( NS_CATEGORY ) ) {
                        $this->closeShowCategory();
                }
+
+               # Use adaptive TTLs for CDN so delayed/failed purges are noticed less often
+               $outputPage = $this->getContext()->getOutput();
+               $outputPage->adaptCdnTTL( $this->mPage->getTouched(), IExpiringStore::TTL_MINUTE );
        }
 
        function openShowCategory() {
index af77868..db3ec14 100644 (file)
@@ -215,7 +215,6 @@ class ImagePage extends Article {
                        'filepage', // always show the local local Filepage.css, bug 29277
                        'mediawiki.action.view.filepage', // Add MediaWiki styles for a file page
                ] );
-
        }
 
        /**
index c478550..74566cb 100644 (file)
@@ -205,7 +205,7 @@ class WikiFilePage extends WikiPage {
 
                /** @var LocalRepo $repo */
                $repo = $file->getRepo();
-               $dbr = $repo->getSlaveDB();
+               $dbr = $repo->getReplicaDB();
 
                $res = $dbr->select(
                        [ 'page', 'categorylinks' ],
index 41e9e4f..56a22c5 100644 (file)
@@ -121,6 +121,11 @@ class WikiPage implements Page, IDBAccessObject {
                        throw new MWException( "Invalid or virtual namespace $ns given." );
                }
 
+               $page = null;
+               if ( !Hooks::run( 'WikiPageFactory', [ $title, &$page ] ) ) {
+                       return $page;
+               }
+
                switch ( $ns ) {
                        case NS_FILE:
                                $page = new WikiFilePage( $title );
@@ -619,7 +624,7 @@ class WikiPage implements Page, IDBAccessObject {
                        // SELECT. Thus we need S1 to also gets the revision row FOR UPDATE; otherwise, it
                        // may not find it since a page row UPDATE and revision row INSERT by S2 may have
                        // happened after the first S1 SELECT.
-                       // http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_repeatable-read
+                       // https://dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_repeatable-read
                        $flags = Revision::READ_LOCKING;
                        $revision = Revision::newFromPageId( $this->getId(), $latest, $flags );
                } elseif ( $this->mDataLoadedFrom == self::READ_LATEST ) {
@@ -693,7 +698,7 @@ class WikiPage implements Page, IDBAccessObject {
         * @deprecated since 1.21, getContent() should be used instead.
         */
        public function getText( $audience = Revision::FOR_PUBLIC, User $user = null ) {
-               ContentHandler::deprecated( __METHOD__, '1.21' );
+               wfDeprecated( __METHOD__, '1.21' );
 
                $this->loadLastEdit();
                if ( $this->mLastRevision ) {
@@ -933,8 +938,8 @@ class WikiPage implements Page, IDBAccessObject {
                $dbw->startAtomic( __METHOD__ );
 
                if ( !$oldLatest || $oldLatest == $this->lockAndGetLatest() ) {
-                       $dbw->replace( 'redirect',
-                               [ 'rd_from' ],
+                       $dbw->upsert(
+                               'redirect',
                                [
                                        'rd_from' => $this->getId(),
                                        'rd_namespace' => $rt->getNamespace(),
@@ -942,6 +947,13 @@ class WikiPage implements Page, IDBAccessObject {
                                        'rd_fragment' => $rt->getFragment(),
                                        'rd_interwiki' => $rt->getInterwiki(),
                                ],
+                               [ 'rd_from' ],
+                               [
+                                       'rd_namespace' => $rt->getNamespace(),
+                                       'rd_title' => $rt->getDBkey(),
+                                       'rd_fragment' => $rt->getFragment(),
+                                       'rd_interwiki' => $rt->getInterwiki(),
+                               ],
                                __METHOD__
                        );
                }
@@ -1161,22 +1173,8 @@ class WikiPage implements Page, IDBAccessObject {
                }
 
                if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
-                       // @todo move this logic to MessageCache
-                       if ( $this->exists() ) {
-                               // NOTE: use transclusion text for messages.
-                               //       This is consistent with  MessageCache::getMsgFromNamespace()
-
-                               $content = $this->getContent();
-                               $text = $content === null ? null : $content->getWikitextForTransclusion();
-
-                               if ( $text === null ) {
-                                       $text = false;
-                               }
-                       } else {
-                               $text = false;
-                       }
-
-                       MessageCache::singleton()->replace( $this->mTitle->getDBkey(), $text );
+                       $messageCache = MessageCache::singleton();
+                       $messageCache->updateMessageOverride( $this->mTitle, $this->getContent() );
                }
 
                return true;
@@ -1577,7 +1575,7 @@ class WikiPage implements Page, IDBAccessObject {
         * @deprecated since 1.21: use doEditContent() instead.
         */
        public function doEdit( $text, $summary, $flags = 0, $baseRevId = false, $user = null ) {
-               ContentHandler::deprecated( __METHOD__, '1.21' );
+               wfDeprecated( __METHOD__, '1.21' );
 
                $content = ContentHandler::makeContent( $text, $this->getTitle() );
 
@@ -1678,7 +1676,7 @@ class WikiPage implements Page, IDBAccessObject {
                                                        $flags & EDIT_MINOR, null, null, &$flags, &$hookStatus ];
                // Check if the hook rejected the attempted save
                if ( !Hooks::run( 'PageContentSave', $hook_args )
-                       || !ContentHandler::runLegacyHooks( 'ArticleSave', $hook_args )
+                       || !ContentHandler::runLegacyHooks( 'ArticleSave', $hook_args, '1.21' )
                ) {
                        if ( $hookStatus->isOK() ) {
                                // Hook returned false but didn't call fatal(); use generic message
@@ -2023,11 +2021,11 @@ class WikiPage implements Page, IDBAccessObject {
                                        // Trigger post-create hook
                                        $params = [ &$this, &$user, $content, $summary,
                                                $flags & EDIT_MINOR, null, null, &$flags, $revision ];
-                                       ContentHandler::runLegacyHooks( 'ArticleInsertComplete', $params );
+                                       ContentHandler::runLegacyHooks( 'ArticleInsertComplete', $params, '1.21' );
                                        Hooks::run( 'PageContentInsertComplete', $params );
                                        // Trigger post-save hook
                                        $params = array_merge( $params, [ &$status, $meta['baseRevId'] ] );
-                                       ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $params );
+                                       ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $params, '1.21' );
                                        Hooks::run( 'PageContentSaveComplete', $params );
 
                                }
@@ -2075,7 +2073,7 @@ class WikiPage implements Page, IDBAccessObject {
         * @return object
         */
        public function prepareTextForEdit( $text, $revid = null, User $user = null ) {
-               ContentHandler::deprecated( __METHOD__, '1.21' );
+               wfDeprecated( __METHOD__, '1.21' );
                $content = ContentHandler::makeContent( $text, $this->getTitle() );
                return $this->prepareContentForEdit( $content, $revid, $user );
        }
@@ -2238,7 +2236,7 @@ class WikiPage implements Page, IDBAccessObject {
         *   - 'no-change': don't update the article count, ever
         */
        public function doEditUpdates( Revision $revision, User $user, array $options = [] ) {
-               global $wgRCWatchCategoryMembership, $wgContLang;
+               global $wgRCWatchCategoryMembership;
 
                $options += [
                        'changed' => true,
@@ -2376,17 +2374,7 @@ class WikiPage implements Page, IDBAccessObject {
                }
 
                if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
-                       // XXX: could skip pseudo-messages like js/css here, based on content model.
-                       $msgtext = $content ? $content->getWikitextForTransclusion() : null;
-                       if ( $msgtext === false || $msgtext === null ) {
-                               $msgtext = '';
-                       }
-
-                       MessageCache::singleton()->replace( $shortTitle, $msgtext );
-
-                       if ( $wgContLang->hasVariants() ) {
-                               $wgContLang->updateConversionTable( $this->mTitle );
-                       }
+                       MessageCache::singleton()->updateMessageOverride( $this->mTitle, $content );
                }
 
                if ( $options['created'] ) {
@@ -2394,41 +2382,10 @@ class WikiPage implements Page, IDBAccessObject {
                } elseif ( $options['changed'] ) { // bug 50785
                        self::onArticleEdit( $this->mTitle, $revision );
                }
-       }
-
-       /**
-        * Edit an article without doing all that other stuff
-        * The article must already exist; link tables etc
-        * are not updated, caches are not flushed.
-        *
-        * @param Content $content Content submitted
-        * @param User $user The relevant user
-        * @param string $comment Comment submitted
-        * @param bool $minor Whereas it's a minor modification
-        * @param string $serialFormat Format for storing the content in the database
-        */
-       public function doQuickEditContent(
-               Content $content, User $user, $comment = '', $minor = false, $serialFormat = null
-       ) {
-
-               $serialized = $content->serialize( $serialFormat );
-
-               $dbw = wfGetDB( DB_MASTER );
-               $revision = new Revision( [
-                       'title'      => $this->getTitle(), // for determining the default content model
-                       'page'       => $this->getId(),
-                       'user_text'  => $user->getName(),
-                       'user'       => $user->getId(),
-                       'text'       => $serialized,
-                       'length'     => $content->getSize(),
-                       'comment'    => $comment,
-                       'minor_edit' => $minor ? 1 : 0,
-               ] ); // XXX: set the content object?
-               $revision->insertOn( $dbw );
-               $this->updateRevisionOn( $dbw, $revision );
-
-               Hooks::run( 'NewRevisionFromEditComplete', [ $this, $revision, false, $user ] );
 
+               ResourceLoaderWikiModule::invalidateModuleCache(
+                       $this->mTitle, $options['oldrevision'], $revision, wfWikiID()
+               );
        }
 
        /**
@@ -2511,13 +2468,13 @@ class WikiPage implements Page, IDBAccessObject {
                }
 
                if ( !$protect ) { // No protection at all means unprotection
-                       $revCommentMsg = 'unprotectedarticle';
+                       $revCommentMsg = 'unprotectedarticle-comment';
                        $logAction = 'unprotect';
                } elseif ( $isProtected ) {
-                       $revCommentMsg = 'modifiedarticleprotection';
+                       $revCommentMsg = 'modifiedarticleprotection-comment';
                        $logAction = 'modify';
                } else {
-                       $revCommentMsg = 'protectedarticle';
+                       $revCommentMsg = 'protectedarticle-comment';
                        $logAction = 'protect';
                }
 
@@ -2701,16 +2658,14 @@ class WikiPage implements Page, IDBAccessObject {
        public function insertProtectNullRevision( $revCommentMsg, array $limit,
                array $expiry, $cascade, $reason, $user = null
        ) {
-               global $wgContLang;
                $dbw = wfGetDB( DB_MASTER );
 
                // Prepare a null revision to be added to the history
-               $editComment = $wgContLang->ucfirst(
-                       wfMessage(
-                               $revCommentMsg,
-                               $this->mTitle->getPrefixedText()
-                       )->inContentLanguage()->text()
-               );
+               $editComment = wfMessage(
+                       $revCommentMsg,
+                       $this->mTitle->getPrefixedText(),
+                       $user ? $user->getName() : ''
+               )->inContentLanguage()->text();
                if ( $reason ) {
                        $editComment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
                }
@@ -2942,6 +2897,7 @@ class WikiPage implements Page, IDBAccessObject {
                // unless they actually try to catch exceptions (which is rare).
 
                // we need to remember the old content so we can use it to generate all deletion updates.
+               $revision = $this->getRevision();
                try {
                        $content = $this->getContent( Revision::RAW );
                } catch ( Exception $ex ) {
@@ -2951,17 +2907,13 @@ class WikiPage implements Page, IDBAccessObject {
                        $content = null;
                }
 
+               $fields = Revision::selectFields();
+               $bitfield = false;
+
                // Bitfields to further suppress the content
                if ( $suppress ) {
-                       $bitfield = 0;
-                       // This should be 15...
-                       $bitfield |= Revision::DELETED_TEXT;
-                       $bitfield |= Revision::DELETED_COMMENT;
-                       $bitfield |= Revision::DELETED_USER;
-                       $bitfield |= Revision::DELETED_RESTRICTED;
-                       $deletionFields = [ $dbw->addQuotes( $bitfield ) . ' AS deleted' ];
-               } else {
-                       $deletionFields = [ 'rev_deleted AS deleted' ];
+                       $bitfield = Revision::SUPPRESSED_ALL;
+                       $fields = array_diff( $fields, [ 'rev_deleted' ] );
                }
 
                // For now, shunt the revision data into the archive table.
@@ -2972,10 +2924,9 @@ class WikiPage implements Page, IDBAccessObject {
                // the rev_deleted field, which is reserved for this purpose.
 
                // Get all of the page revisions
-               $fields = array_diff( Revision::selectFields(), [ 'rev_deleted' ] );
                $res = $dbw->select(
                        'revision',
-                       array_merge( $fields, $deletionFields ),
+                       $fields,
                        [ 'rev_page' => $id ],
                        __METHOD__,
                        'FOR UPDATE'
@@ -2998,7 +2949,7 @@ class WikiPage implements Page, IDBAccessObject {
                                'ar_flags'      => '',
                                'ar_len'        => $row->rev_len,
                                'ar_page_id'    => $id,
-                               'ar_deleted'    => $row->deleted,
+                               'ar_deleted'    => $suppress ? $bitfield : $row->rev_deleted,
                                'ar_sha1'       => $row->rev_sha1,
                        ];
                        if ( $wgContentHandlerUseDB ) {
@@ -3041,7 +2992,7 @@ class WikiPage implements Page, IDBAccessObject {
 
                $dbw->endAtomic( __METHOD__ );
 
-               $this->doDeleteUpdates( $id, $content );
+               $this->doDeleteUpdates( $id, $content, $revision );
 
                Hooks::run( 'ArticleDeleteComplete', [
                        &$wikiPageBeforeDelete,
@@ -3088,11 +3039,12 @@ class WikiPage implements Page, IDBAccessObject {
         * Do some database updates after deletion
         *
         * @param int $id The page_id value of the page being deleted
-        * @param Content $content Optional page content to be used when determining
+        * @param Content|null $content Optional page content to be used when determining
         *   the required updates. This may be needed because $this->getContent()
         *   may already return null when the page proper was deleted.
+        * @param Revision|null $revision The latest page revision
         */
-       public function doDeleteUpdates( $id, Content $content = null ) {
+       public function doDeleteUpdates( $id, Content $content = null, Revision $revision = null ) {
                try {
                        $countable = $this->isCountable();
                } catch ( Exception $ex ) {
@@ -3120,6 +3072,9 @@ class WikiPage implements Page, IDBAccessObject {
 
                // Clear caches
                WikiPage::onArticleDelete( $this->mTitle );
+               ResourceLoaderWikiModule::invalidateModuleCache(
+                       $this->mTitle, $revision, null, wfWikiID()
+               );
 
                // Reset this object and the Title object
                $this->loadFromRow( false, self::READ_LATEST );
@@ -3417,8 +3372,6 @@ class WikiPage implements Page, IDBAccessObject {
         * @param Title $title
         */
        public static function onArticleDelete( Title $title ) {
-               global $wgContLang;
-
                // Update existence markers on article/talk tabs...
                $other = $title->getOtherPage();
 
@@ -3435,11 +3388,7 @@ class WikiPage implements Page, IDBAccessObject {
 
                // Messages
                if ( $title->getNamespace() == NS_MEDIAWIKI ) {
-                       MessageCache::singleton()->replace( $title->getDBkey(), false );
-
-                       if ( $wgContLang->hasVariants() ) {
-                               $wgContLang->updateConversionTable( $title );
-                       }
+                       MessageCache::singleton()->updateMessageOverride( $title, null );
                }
 
                // Images
@@ -3553,7 +3502,7 @@ class WikiPage implements Page, IDBAccessObject {
                // NOTE: stub for backwards-compatibility. assumes the given text is
                // wikitext. will break horribly if it isn't.
 
-               ContentHandler::deprecated( __METHOD__, '1.21' );
+               wfDeprecated( __METHOD__, '1.21' );
 
                $handler = ContentHandler::getForModelID( CONTENT_MODEL_WIKITEXT );
                $oldContent = is_null( $oldtext ) ? null : $handler->unserializeContent( $oldtext );
@@ -3577,107 +3526,103 @@ class WikiPage implements Page, IDBAccessObject {
         * Update all the appropriate counts in the category table, given that
         * we've added the categories $added and deleted the categories $deleted.
         *
+        * This should only be called from deferred updates or jobs to avoid contention.
+        *
         * @param array $added The names of categories that were added
         * @param array $deleted The names of categories that were deleted
         * @param integer $id Page ID (this should be the original deleted page ID)
         */
        public function updateCategoryCounts( array $added, array $deleted, $id = 0 ) {
                $id = $id ?: $this->getId();
+               $ns = $this->getTitle()->getNamespace();
+
+               $addFields = [ 'cat_pages = cat_pages + 1' ];
+               $removeFields = [ 'cat_pages = cat_pages - 1' ];
+               if ( $ns == NS_CATEGORY ) {
+                       $addFields[] = 'cat_subcats = cat_subcats + 1';
+                       $removeFields[] = 'cat_subcats = cat_subcats - 1';
+               } elseif ( $ns == NS_FILE ) {
+                       $addFields[] = 'cat_files = cat_files + 1';
+                       $removeFields[] = 'cat_files = cat_files - 1';
+               }
+
                $dbw = wfGetDB( DB_MASTER );
-               $method = __METHOD__;
-               // Do this at the end of the commit to reduce lock wait timeouts
-               $dbw->onTransactionPreCommitOrIdle(
-                       function () use ( $dbw, $added, $deleted, $id, $method ) {
-                               $ns = $this->getTitle()->getNamespace();
-
-                               $addFields = [ 'cat_pages = cat_pages + 1' ];
-                               $removeFields = [ 'cat_pages = cat_pages - 1' ];
-                               if ( $ns == NS_CATEGORY ) {
-                                       $addFields[] = 'cat_subcats = cat_subcats + 1';
-                                       $removeFields[] = 'cat_subcats = cat_subcats - 1';
-                               } elseif ( $ns == NS_FILE ) {
-                                       $addFields[] = 'cat_files = cat_files + 1';
-                                       $removeFields[] = 'cat_files = cat_files - 1';
-                               }
 
-                               if ( count( $added ) ) {
-                                       $existingAdded = $dbw->selectFieldValues(
-                                               'category',
-                                               'cat_title',
-                                               [ 'cat_title' => $added ],
-                                               $method
-                                       );
+               if ( count( $added ) ) {
+                       $existingAdded = $dbw->selectFieldValues(
+                               'category',
+                               'cat_title',
+                               [ 'cat_title' => $added ],
+                               __METHOD__
+                       );
 
-                                       // For category rows that already exist, do a plain
-                                       // UPDATE instead of INSERT...ON DUPLICATE KEY UPDATE
-                                       // to avoid creating gaps in the cat_id sequence.
-                                       if ( count( $existingAdded ) ) {
-                                               $dbw->update(
-                                                       'category',
-                                                       $addFields,
-                                                       [ 'cat_title' => $existingAdded ],
-                                                       $method
-                                               );
-                                       }
+                       // For category rows that already exist, do a plain
+                       // UPDATE instead of INSERT...ON DUPLICATE KEY UPDATE
+                       // to avoid creating gaps in the cat_id sequence.
+                       if ( count( $existingAdded ) ) {
+                               $dbw->update(
+                                       'category',
+                                       $addFields,
+                                       [ 'cat_title' => $existingAdded ],
+                                       __METHOD__
+                               );
+                       }
 
-                                       $missingAdded = array_diff( $added, $existingAdded );
-                                       if ( count( $missingAdded ) ) {
-                                               $insertRows = [];
-                                               foreach ( $missingAdded as $cat ) {
-                                                       $insertRows[] = [
-                                                               'cat_title'   => $cat,
-                                                               'cat_pages'   => 1,
-                                                               'cat_subcats' => ( $ns == NS_CATEGORY ) ? 1 : 0,
-                                                               'cat_files'   => ( $ns == NS_FILE ) ? 1 : 0,
-                                                       ];
-                                               }
-                                               $dbw->upsert(
-                                                       'category',
-                                                       $insertRows,
-                                                       [ 'cat_title' ],
-                                                       $addFields,
-                                                       $method
-                                               );
-                                       }
+                       $missingAdded = array_diff( $added, $existingAdded );
+                       if ( count( $missingAdded ) ) {
+                               $insertRows = [];
+                               foreach ( $missingAdded as $cat ) {
+                                       $insertRows[] = [
+                                               'cat_title'   => $cat,
+                                               'cat_pages'   => 1,
+                                               'cat_subcats' => ( $ns == NS_CATEGORY ) ? 1 : 0,
+                                               'cat_files'   => ( $ns == NS_FILE ) ? 1 : 0,
+                                       ];
                                }
+                               $dbw->upsert(
+                                       'category',
+                                       $insertRows,
+                                       [ 'cat_title' ],
+                                       $addFields,
+                                       __METHOD__
+                               );
+                       }
+               }
 
-                               if ( count( $deleted ) ) {
-                                       $dbw->update(
-                                               'category',
-                                               $removeFields,
-                                               [ 'cat_title' => $deleted ],
-                                               $method
-                                       );
-                               }
+               if ( count( $deleted ) ) {
+                       $dbw->update(
+                               'category',
+                               $removeFields,
+                               [ 'cat_title' => $deleted ],
+                               __METHOD__
+                       );
+               }
 
-                               foreach ( $added as $catName ) {
-                                       $cat = Category::newFromName( $catName );
-                                       Hooks::run( 'CategoryAfterPageAdded', [ $cat, $this ] );
-                               }
+               foreach ( $added as $catName ) {
+                       $cat = Category::newFromName( $catName );
+                       Hooks::run( 'CategoryAfterPageAdded', [ $cat, $this ] );
+               }
 
-                               foreach ( $deleted as $catName ) {
-                                       $cat = Category::newFromName( $catName );
-                                       Hooks::run( 'CategoryAfterPageRemoved', [ $cat, $this, $id ] );
-                               }
+               foreach ( $deleted as $catName ) {
+                       $cat = Category::newFromName( $catName );
+                       Hooks::run( 'CategoryAfterPageRemoved', [ $cat, $this, $id ] );
+               }
 
-                               // Refresh counts on categories that should be empty now, to
-                               // trigger possible deletion. Check master for the most
-                               // up-to-date cat_pages.
-                               if ( count( $deleted ) ) {
-                                       $rows = $dbw->select(
-                                               'category',
-                                               [ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
-                                               [ 'cat_title' => $deleted, 'cat_pages <= 0' ],
-                                               $method
-                                       );
-                                       foreach ( $rows as $row ) {
-                                               $cat = Category::newFromRow( $row );
-                                               $cat->refreshCounts();
-                                       }
-                               }
-                       },
-                       __METHOD__
-               );
+               // Refresh counts on categories that should be empty now, to
+               // trigger possible deletion. Check master for the most
+               // up-to-date cat_pages.
+               if ( count( $deleted ) ) {
+                       $rows = $dbw->select(
+                               'category',
+                               [ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
+                               [ 'cat_title' => $deleted, 'cat_pages <= 0' ],
+                               __METHOD__
+                       );
+                       foreach ( $rows as $row ) {
+                               $cat = Category::newFromRow( $row );
+                               $cat->refreshCounts();
+                       }
+               }
        }
 
        /**
index 4895b4f..6f325c9 100644 (file)
@@ -80,7 +80,7 @@ abstract class ReverseChronologicalPager extends IndexPager {
 
                // If year and month are false, don't update the mOffset
                if ( !$this->mYear && !$this->mMonth ) {
-                       return;
+                       return null;
                }
 
                // Given an optional year, month, and day, we need to generate a timestamp
@@ -150,7 +150,13 @@ abstract class ReverseChronologicalPager extends IndexPager {
                $timestamp = MWTimestamp::getInstance( "${ymd}000000" );
                $timestamp->setTimezone( $this->getConfig()->get( 'Localtimezone' ) );
 
-               $this->mOffset = $this->mDb->timestamp( $timestamp->getTimestamp() );
+               try {
+                       $this->mOffset = $this->mDb->timestamp( $timestamp->getTimestamp() );
+               } catch ( TimestampException $e ) {
+                       // Invalid user provided timestamp (T149257)
+                       return null;
+               }
+
                return $this->mOffset;
        }
 }
index 0a89e4e..f2fca68 100644 (file)
@@ -315,7 +315,7 @@ abstract class TablePager extends IndexPager {
                foreach ( $labels as $type => $label ) {
                        // We want every cell to have the same width. We could use table-layout: fixed; in CSS,
                        // but it only works if we specify the width of a cell or the table and we don't want to.
-                       // There is no better way. <http://www.w3.org/TR/CSS2/tables.html#fixed-table-layout>
+                       // There is no better way. <https://www.w3.org/TR/CSS2/tables.html#fixed-table-layout>
                        $s .= Html::rawElement( 'td',
                                [ 'style' => "width: $width;", 'class' => "TablePager_nav-$type" ],
                                $links[$type] ) . "\n";
index b32f43b..e7712f2 100644 (file)
@@ -267,10 +267,8 @@ class LinkHolderArray {
         * @param string $text
         */
        public function replace( &$text ) {
-
                $this->replaceInternal( $text );
                $this->replaceInterwiki( $text );
-
        }
 
        /**
@@ -414,7 +412,6 @@ class LinkHolderArray {
                        $replacer->cb(),
                        $text
                );
-
        }
 
        /**
@@ -614,7 +611,6 @@ class LinkHolderArray {
         * @return string
         */
        public function replaceText( $text ) {
-
                $text = preg_replace_callback(
                        '/<!--(LINK|IWLINK) (.*?)-->/',
                        [ &$this, 'replaceTextCallback' ],
index 590d51e..10dfd26 100644 (file)
@@ -22,6 +22,7 @@
  */
 use MediaWiki\Linker\LinkRenderer;
 use MediaWiki\MediaWikiServices;
+use Wikimedia\ScopedCallback;
 
 /**
  * @defgroup Parser Parser
@@ -506,46 +507,60 @@ class Parser {
                                [ $this->mHighestExpansionDepth, $this->mOptions->getMaxPPExpandDepth() ]
                        );
                        $this->mOutput->setLimitReportData( 'limitreport-expensivefunctioncount',
-                               [ $this->mExpensiveFunctionCount,
-                                       $this->mOptions->getExpensiveParserFunctionLimit() ]
+                               [ $this->mExpensiveFunctionCount, $this->mOptions->getExpensiveParserFunctionLimit() ]
                        );
                        Hooks::run( 'ParserLimitReportPrepare', [ $this, $this->mOutput ] );
 
-                       $limitReport = '';
-                       Hooks::run( 'ParserLimitReport', [ $this, &$limitReport ] );
-                       if ( $limitReport != '' ) {
-                               // Sanitize for comment. Note '‐' in the replacement is U+2010,
-                               // which looks much like the problematic '-'.
-                               $limitReport = str_replace( [ '-', '&' ], [ '‐', '&amp;' ], $limitReport );
-                               $text .= "\n<!-- \nNewPP limit report\n$limitReport-->\n";
+                       $limitReport = "NewPP limit report\n";
+                       if ( $wgShowHostnames ) {
+                               $limitReport .= 'Parsed by ' . wfHostname() . "\n";
+                       }
+                       $limitReport .= 'Cached time: ' . $this->mOutput->getCacheTime() . "\n";
+                       $limitReport .= 'Cache expiry: ' . $this->mOutput->getCacheExpiry() . "\n";
+                       $limitReport .= 'Dynamic content: ' .
+                               ( $this->mOutput->hasDynamicContent() ? 'true' : 'false' ) .
+                               "\n";
+
+                       foreach ( $this->mOutput->getLimitReportData() as $key => $value ) {
+                               if ( Hooks::run( 'ParserLimitReportFormat',
+                                       [ $key, &$value, &$limitReport, false, false ]
+                               ) ) {
+                                       $keyMsg = wfMessage( $key )->inLanguage( 'en' )->useDatabase( false );
+                                       $valueMsg = wfMessage( [ "$key-value-text", "$key-value" ] )
+                                               ->inLanguage( 'en' )->useDatabase( false );
+                                       if ( !$valueMsg->exists() ) {
+                                               $valueMsg = new RawMessage( '$1' );
+                                       }
+                                       if ( !$keyMsg->isDisabled() && !$valueMsg->isDisabled() ) {
+                                               $valueMsg->params( $value );
+                                               $limitReport .= "{$keyMsg->text()}: {$valueMsg->text()}\n";
+                                       }
+                               }
                        }
+                       // Since we're not really outputting HTML, decode the entities and
+                       // then re-encode the things that need hiding inside HTML comments.
+                       $limitReport = htmlspecialchars_decode( $limitReport );
+                       Hooks::run( 'ParserLimitReport', [ $this, &$limitReport ] );
+
+                       // Sanitize for comment. Note '‐' in the replacement is U+2010,
+                       // which looks much like the problematic '-'.
+                       $limitReport = str_replace( [ '-', '&' ], [ '‐', '&amp;' ], $limitReport );
+                       $text .= "\n<!-- \n$limitReport-->\n";
 
-                       // Add on template profiling data in human/machine readable way
+                       // Add on template profiling data
                        $dataByFunc = $this->mProfiler->getFunctionStats();
                        uasort( $dataByFunc, function ( $a, $b ) {
                                return $a['real'] < $b['real']; // descending order
                        } );
-                       $profileReport = [];
+                       $profileReport = "Transclusion expansion time report (%,ms,calls,template)\n";
                        foreach ( array_slice( $dataByFunc, 0, 10 ) as $item ) {
-                               $profileReport[] = sprintf( "%6.2f%% %8.3f %6d %s",
-                                       $item['%real'], $item['real'], $item['calls'], $item['name'] );
+                               $profileReport .= sprintf( "%6.2f%% %8.3f %6d - %s\n",
+                                       $item['%real'], $item['real'], $item['calls'],
+                                       htmlspecialchars( $item['name'] ) );
                        }
-                       $this->mOutput->setLimitReportData( 'limitreport-timingprofile', $profileReport );
+                       $text .= "\n<!-- \n$profileReport-->\n";
 
-                       // Add other cache related metadata
-                       if ( $wgShowHostnames ) {
-                               $this->mOutput->setLimitReportData( 'cachereport-origin', wfHostname() );
-                       }
-                       $this->mOutput->setLimitReportData( 'cachereport-timestamp',
-                               $this->mOutput->getCacheTime() );
-                       $this->mOutput->setLimitReportData( 'cachereport-ttl',
-                               $this->mOutput->getCacheExpiry() );
-                       $this->mOutput->setLimitReportData( 'cachereport-transientcontent',
-                               $this->mOutput->hasDynamicContent() );
-
-                       if ( $this->mGeneratedPPNodeCount
-                               > $this->mOptions->getMaxGeneratedPPNodeCount() / 10
-                       ) {
+                       if ( $this->mGeneratedPPNodeCount > $this->mOptions->getMaxGeneratedPPNodeCount() / 10 ) {
                                wfDebugLog( 'generated-pp-node-count', $this->mGeneratedPPNodeCount . ' ' .
                                        $this->mTitle->getPrefixedDBkey() );
                        }
@@ -1445,6 +1460,7 @@ class Parser {
                                $keyword = 'RFC';
                                $urlmsg = 'rfcurl';
                                $cssClass = 'mw-magiclink-rfc';
+                               $trackingCat = 'magiclink-tracking-rfc';
                                $id = $m[5];
                        } elseif ( substr( $m[0], 0, 4 ) === 'PMID' ) {
                                if ( !$this->mOptions->getMagicPMIDLinks() ) {
@@ -1453,12 +1469,14 @@ class Parser {
                                $keyword = 'PMID';
                                $urlmsg = 'pubmedurl';
                                $cssClass = 'mw-magiclink-pmid';
+                               $trackingCat = 'magiclink-tracking-pmid';
                                $id = $m[5];
                        } else {
                                throw new MWException( __METHOD__ . ': unrecognised match type "' .
                                        substr( $m[0], 0, 20 ) . '"' );
                        }
                        $url = wfMessage( $urlmsg, $id )->inContentLanguage()->text();
+                       $this->addTrackingCategory( $trackingCat );
                        return Linker::makeExternalLink( $url, "{$keyword} {$id}", true, $cssClass, [], $this->mTitle );
                } elseif ( isset( $m[6] ) && $m[6] !== ''
                        && $this->mOptions->getMagicISBNLinks()
@@ -1472,6 +1490,7 @@ class Parser {
                                ' ' => '',
                                'x' => 'X',
                        ] );
+                       $this->addTrackingCategory( 'magiclink-tracking-isbn' );
                        return $this->getLinkRenderer()->makeKnownLink(
                                SpecialPage::getTitleFor( 'Booksources', $num ),
                                "ISBN $isbn",
@@ -3580,6 +3599,9 @@ class Parser {
                                $content = $rev->getContent();
                                $text = $content ? $content->getWikitextForTransclusion() : null;
 
+                               Hooks::run( 'ParserFetchTemplate',
+                                       [ $parser, $title, $rev, &$text, &$deps ] );
+
                                if ( $text === false || $text === null ) {
                                        $text = false;
                                        break;
@@ -3784,9 +3806,27 @@ class Parser {
         * @return string
         */
        public function extensionSubstitution( $params, $frame ) {
+               static $errorStr = '<span class="error">';
+               static $errorLen = 20;
+
                $name = $frame->expand( $params['name'] );
+               if ( substr( $name, 0, $errorLen ) === $errorStr ) {
+                       // Probably expansion depth or node count exceeded. Just punt the
+                       // error up.
+                       return $name;
+               }
+
                $attrText = !isset( $params['attr'] ) ? null : $frame->expand( $params['attr'] );
+               if ( substr( $attrText, 0, $errorLen ) === $errorStr ) {
+                       // See above
+                       return $attrText;
+               }
+
+               // We can't safely check if the expansion for $content resulted in an
+               // error, because the content could happen to be the error string
+               // (T149622).
                $content = !isset( $params['inner'] ) ? null : $frame->expand( $params['inner'] );
+
                $marker = self::MARKER_PREFIX . "-$name-"
                        . sprintf( '%08X', $this->mMarkerIndex++ ) . self::MARKER_SUFFIX;
 
@@ -3844,6 +3884,10 @@ class Parser {
                                $output = "<$name$attrText/>";
                        } else {
                                $close = is_null( $params['close'] ) ? '' : $frame->expand( $params['close'] );
+                               if ( substr( $close, 0, $errorLen ) === $errorStr ) {
+                                       // See above
+                                       return $close;
+                               }
                                $output = "<$name$attrText>$content$close";
                        }
                }
@@ -4138,12 +4182,13 @@ class Parser {
                        # * <b> (r105284)
                        # * <bdi> (bug 72884)
                        # * <span dir="rtl"> and <span dir="ltr"> (bug 35167)
+                       # * <s> and <strike> (T35715)
                        # We strip any parameter from accepted tags (second regex), except dir="rtl|ltr" from <span>,
                        # to allow setting directionality in toc items.
                        $tocline = preg_replace(
                                [
-                                       '#<(?!/?(span|sup|sub|bdi|i|b)(?: [^>]*)?>).*?>#',
-                                       '#<(/?(?:span(?: dir="(?:rtl|ltr)")?|sup|sub|bdi|i|b))(?: .*?)?>#'
+                                       '#<(?!/?(span|sup|sub|bdi|i|b|s|strike)(?: [^>]*)?>).*?>#',
+                                       '#<(/?(?:span(?: dir="(?:rtl|ltr)")?|sup|sub|bdi|i|b|s|strike))(?: .*?)?>#'
                                ],
                                [ '', '<$1>' ],
                                $safeHeadline
@@ -4189,7 +4234,7 @@ class Parser {
 
                        # HTML names must be case-insensitively unique (bug 10721).
                        # This does not apply to Unicode characters per
-                       # http://www.w3.org/TR/html5/infrastructure.html#case-sensitivity-and-string-comparison
+                       # https://www.w3.org/TR/html5/infrastructure.html#case-sensitivity-and-string-comparison
                        # @todo FIXME: We may be changing them depending on the current locale.
                        $arrayKey = strtolower( $safeHeadline );
                        if ( $legacyHeadline === false ) {
index 25c2aa4..2900f41 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup Parser
  */
+use Wikimedia\ScopedCallback;
 
 /**
  * @brief Set options of the Parser
@@ -732,7 +733,6 @@ class ParserOptions {
                $this->mThumbSize = $user->getOption( 'thumbsize' );
                $this->mStubThreshold = $user->getStubThreshold();
                $this->mUserLang = $lang;
-
        }
 
        /**
index 9dfa97c..d2ef5e3 100644 (file)
@@ -188,7 +188,9 @@ class ParserOutput extends CacheTime {
         */
        private $mExtensionData = [];
 
-       /** @var array $mLimitReportData Parser limit report data. */
+       /**
+        * @var array $mLimitReportData Parser limit report data.
+        */
        private $mLimitReportData = [];
 
        /**
@@ -991,34 +993,24 @@ class ParserOutput extends CacheTime {
        /**
         * Sets parser limit report data for a key
         *
-        * If $value consist of a list of two floats, it will be interpreted as
-        * (actual value, maximum allowed value). The presence of a "-" in $key will cause
-        * the first part of the key to be interpreted as a namespace.
+        * The key is used as the prefix for various messages used for formatting:
+        *  - $key: The label for the field in the limit report
+        *  - $key-value-text: Message used to format the value in the "NewPP limit
+        *      report" HTML comment. If missing, uses $key-format.
+        *  - $key-value-html: Message used to format the value in the preview
+        *      limit report table. If missing, uses $key-format.
+        *  - $key-value: Message used to format the value. If missing, uses "$1".
+        *
+        * Note that all values are interpreted as wikitext, and so should be
+        * encoded with htmlspecialchars() as necessary, but should avoid complex
+        * HTML for sanity of display in the "NewPP limit report" comment.
         *
         * @since 1.22
-        * @param string $key Data key
-        * @param mixed $value Data value One of (float, string, bool, JSON serializable array)
+        * @param string $key Message key
+        * @param mixed $value Appropriate for Message::params()
         */
        public function setLimitReportData( $key, $value ) {
-               if ( is_array( $value ) ) {
-                       if ( array_keys( $value ) === [ 0, 1 ]
-                               && is_numeric( $value[0] )
-                               && is_numeric( $value[1] )
-                       ) {
-                               $data = [ 'value' => $value[0], 'limit' => $value[1] ];
-                       } else {
-                               $data = $value;
-                       }
-               } else {
-                       $data = $value;
-               }
-
-               if ( strpos( $key, '-' ) ) {
-                       list( $ns, $name ) = explode( '-', $key, 2 );
-                       $this->mLimitReportData[$ns][$name] = $data;
-               } else {
-                       $this->mLimitReportData[$key] = $data;
-               }
+               $this->mLimitReportData[$key] = $value;
        }
 
        /**
index 7b3d9f9..0ea3c63 100644 (file)
@@ -41,20 +41,33 @@ class EncryptedPassword extends ParameterizedPassword {
        public function crypt( $password ) {
                $secret = $this->config['secrets'][$this->params['secret']];
 
+               // Clear error string
+               while ( openssl_error_string() !== false );
+
                if ( $this->hash ) {
-                       $underlyingPassword = $this->factory->newFromCiphertext( openssl_decrypt(
-                                       base64_decode( $this->hash ), $this->params['cipher'],
-                                       $secret, 0, base64_decode( $this->args[0] )
-                               ) );
+                       $decrypted = openssl_decrypt(
+                                       $this->hash, $this->params['cipher'],
+                                       $secret, 0, base64_decode( $this->args[0] ) );
+                       if ( $decrypted === false ) {
+                               throw new PasswordError( 'Error decrypting password: ' . openssl_error_string() );
+                       }
+                       $underlyingPassword = $this->factory->newFromCiphertext( $decrypted );
                } else {
                        $underlyingPassword = $this->factory->newFromType( $this->config['underlying'] );
                }
 
                $underlyingPassword->crypt( $password );
-               $iv = MWCryptRand::generate( openssl_cipher_iv_length( $this->params['cipher'] ), true );
+               if ( count( $this->args ) ) {
+                       $iv = base64_decode( $this->args[0] );
+               } else {
+                       $iv = MWCryptRand::generate( openssl_cipher_iv_length( $this->params['cipher'] ), true );
+               }
 
                $this->hash = openssl_encrypt(
                        $underlyingPassword->toString(), $this->params['cipher'], $secret, 0, $iv );
+               if ( $this->hash === false ) {
+                       throw new PasswordError( 'Error encrypting password: ' . openssl_error_string() );
+               }
                $this->args = [ base64_encode( $iv ) ];
        }
 
@@ -65,32 +78,42 @@ class EncryptedPassword extends ParameterizedPassword {
         * @return bool True if the password was updated
         */
        public function update() {
-               if ( count( $this->args ) != 2 || $this->params == $this->getDefaultParams() ) {
+               if ( count( $this->args ) != 1 || $this->params == $this->getDefaultParams() ) {
                        // Hash does not need updating
                        return false;
                }
 
+               // Clear error string
+               while ( openssl_error_string() !== false );
+
                // Decrypt the underlying hash
                $underlyingHash = openssl_decrypt(
-                       base64_decode( $this->args[1] ),
+                       $this->hash,
                        $this->params['cipher'],
                        $this->config['secrets'][$this->params['secret']],
                        0,
                        base64_decode( $this->args[0] )
                );
+               if ( $underlyingHash === false ) {
+                       throw new PasswordError( 'Error decrypting password: ' . openssl_error_string() );
+               }
 
                // Reset the params
                $this->params = $this->getDefaultParams();
 
                // Check the key size with the new params
                $iv = MWCryptRand::generate( openssl_cipher_iv_length( $this->params['cipher'] ), true );
-               $this->hash = base64_encode( openssl_encrypt(
+               $this->hash = openssl_encrypt(
                                $underlyingHash,
                                $this->params['cipher'],
                                $this->config['secrets'][$this->params['secret']],
                                0,
                                $iv
-                       ) );
+                       );
+               if ( $this->hash === false ) {
+                       throw new PasswordError( 'Error encrypting password: ' . openssl_error_string() );
+               }
+
                $this->args = [ base64_encode( $iv ) ];
 
                return true;
index 84675c1..c48b6e6 100644 (file)
@@ -36,9 +36,11 @@ class MWOldPassword extends ParameterizedPassword {
        }
 
        public function crypt( $plaintext ) {
-               global $wgPasswordSalt;
-
-               if ( $wgPasswordSalt && count( $this->args ) === 1 ) {
+               if ( count( $this->args ) === 1 ) {
+                       // Accept (but do not generate) salted passwords with :A: prefix.
+                       // These are actually B-type passwords, but an error in a previous
+                       // version of MediaWiki caused them to be written with an :A:
+                       // prefix.
                        $this->hash = md5( $this->args[0] . '-' . md5( $plaintext ) );
                } else {
                        $this->args = [];
index 297dcb2..8b4f01a 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Profiler
  * @defgroup Profiler Profiler
  */
+use Wikimedia\ScopedCallback;
 
 /**
  * Profiler base class that defines the interface and some trivial
@@ -162,9 +163,9 @@ abstract class Profiler {
        abstract public function scopedProfileIn( $section );
 
        /**
-        * @param ScopedCallback $section
+        * @param SectionProfileCallback $section
         */
-       public function scopedProfileOut( ScopedCallback &$section = null ) {
+       public function scopedProfileOut( SectionProfileCallback &$section = null ) {
                $section = null;
        }
 
index 65ac6e6..7e3c398 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Profiler
  * @author Aaron Schulz
  */
+use Wikimedia\ScopedCallback;
 
 /**
  * Custom PHP profiler for parser/DB type section names that xhprof/xdebug can't handle
@@ -57,7 +58,7 @@ class SectionProfiler {
 
        /**
         * @param string $section
-        * @return ScopedCallback
+        * @return SectionProfileCallback
         */
        public function scopedProfileIn( $section ) {
                $this->profileInInternal( $section );
index 745c233..207f884 100644 (file)
@@ -8,50 +8,52 @@ class ExtensionProcessor implements Processor {
         * @var array
         */
        protected static $globalSettings = [
-               'ResourceLoaderSources',
-               'ResourceLoaderLESSVars',
-               'DefaultUserOptions',
-               'HiddenPrefs',
-               'GroupPermissions',
-               'RevokePermissions',
-               'GrantPermissions',
-               'GrantPermissionGroups',
-               'ImplicitGroups',
-               'GroupsAddToSelf',
-               'GroupsRemoveFromSelf',
+               'ActionFilteredLogs',
+               'Actions',
                'AddGroups',
-               'RemoveGroups',
-               'AvailableRights',
-               'ContentHandlers',
-               'ConfigRegistry',
-               'SessionProviders',
+               'APIFormatModules',
+               'APIListModules',
+               'APIMetaModules',
+               'APIModules',
+               'APIPropModules',
                'AuthManagerAutoConfig',
+               'AvailableRights',
                'CentralIdLookupProviders',
                'ChangeCredentialsBlacklist',
-               'RemoveCredentialsBlacklist',
-               'RateLimits',
-               'RecentChangesFlags',
-               'MediaHandlers',
-               'ExtensionFunctions',
+               'ConfigRegistry',
+               'ContentHandlers',
+               'DefaultUserOptions',
                'ExtensionEntryPointListFiles',
-               'SpecialPages',
-               'JobClasses',
-               'LogTypes',
-               'LogRestrictions',
+               'ExtensionFunctions',
+               'FeedClasses',
+               'FileExtensions',
                'FilterLogTypes',
-               'ActionFilteredLogs',
-               'LogNames',
-               'LogHeaders',
+               'GrantPermissionGroups',
+               'GrantPermissions',
+               'GroupPermissions',
+               'GroupsAddToSelf',
+               'GroupsRemoveFromSelf',
+               'HiddenPrefs',
+               'ImplicitGroups',
+               'JobClasses',
                'LogActions',
                'LogActionsHandlers',
-               'Actions',
-               'APIModules',
-               'APIFormatModules',
-               'APIMetaModules',
-               'APIPropModules',
-               'APIListModules',
+               'LogHeaders',
+               'LogNames',
+               'LogRestrictions',
+               'LogTypes',
+               'MediaHandlers',
+               'PasswordPolicy',
+               'RateLimits',
+               'RecentChangesFlags',
+               'RemoveCredentialsBlacklist',
+               'RemoveGroups',
+               'ResourceLoaderLESSVars',
+               'ResourceLoaderSources',
+               'RevokePermissions',
+               'SessionProviders',
+               'SpecialPages',
                'ValidSkinNames',
-               'FeedClasses',
        ];
 
        /**
@@ -62,18 +64,19 @@ class ExtensionProcessor implements Processor {
         * @var array
         */
        protected static $mergeStrategies = [
-               'wgGroupPermissions' => 'array_plus_2d',
-               'wgRevokePermissions' => 'array_plus_2d',
-               'wgGrantPermissions' => 'array_plus_2d',
-               'wgHooks' => 'array_merge_recursive',
+               'wgAuthManagerAutoConfig' => 'array_plus_2d',
+               'wgCapitalLinkOverrides' => 'array_plus',
                'wgExtensionCredits' => 'array_merge_recursive',
                'wgExtraGenderNamespaces' => 'array_plus',
-               'wgNamespacesWithSubpages' => 'array_plus',
+               'wgGrantPermissions' => 'array_plus_2d',
+               'wgGroupPermissions' => 'array_plus_2d',
+               'wgHooks' => 'array_merge_recursive',
                'wgNamespaceContentModels' => 'array_plus',
                'wgNamespaceProtection' => 'array_plus',
-               'wgCapitalLinkOverrides' => 'array_plus',
+               'wgNamespacesWithSubpages' => 'array_plus',
+               'wgPasswordPolicy' => 'array_merge_recursive',
                'wgRateLimits' => 'array_plus_2d',
-               'wgAuthManagerAutoConfig' => 'array_plus_2d',
+               'wgRevokePermissions' => 'array_plus_2d',
        ];
 
        /**
@@ -397,7 +400,7 @@ class ExtensionProcessor implements Processor {
                if ( isset( $info['config'] ) ) {
                        foreach ( $info['config'] as $key => $data ) {
                                $value = $data['value'];
-                               if ( isset( $value['merge_strategy'] ) ) {
+                               if ( isset( $data['merge_strategy'] ) ) {
                                        $value[ExtensionRegistry::MERGE_STRATEGY] = $data['merge_strategy'];
                                }
                                if ( isset( $data['path'] ) && $data['path'] ) {
index 3bec457..b5c70e9 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * ExtensionRegistry class
  *
@@ -82,11 +84,10 @@ class ExtensionRegistry {
        }
 
        public function __construct() {
-               // We use a try/catch instead of the $fallback parameter because
-               // we don't want to fail here if $wgObjectCaches is not configured
-               // properly for APC setup
+               // We use a try/catch because we don't want to fail here
+               // if $wgObjectCaches is not configured properly for APC setup
                try {
-                       $this->cache = ObjectCache::getLocalServerInstance();
+                       $this->cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
                } catch ( MWException $e ) {
                        $this->cache = new EmptyBagOStuff();
                }
@@ -186,6 +187,19 @@ class ExtensionRegistry {
                        if ( !is_array( $info ) ) {
                                throw new Exception( "$path is not a valid JSON file." );
                        }
+
+                       // Check any constraints against MediaWiki core
+                       $requires = $processor->getRequirements( $info );
+                       if ( isset( $requires[self::MEDIAWIKI_CORE] )
+                               && !$coreVersionParser->check( $requires[self::MEDIAWIKI_CORE] )
+                       ) {
+                               // Doesn't match, mark it as incompatible.
+                               $incompatible[] = "{$info['name']} is not compatible with the current "
+                                       . "MediaWiki core (version {$wgVersion}), it requires: " . $requires[self::MEDIAWIKI_CORE]
+                                       . '.';
+                               continue;
+                       }
+
                        if ( !isset( $info['manifest_version'] ) ) {
                                // For backwards-compatability, assume a version of 1
                                $info['manifest_version'] = 1;
@@ -194,21 +208,12 @@ class ExtensionRegistry {
                        if ( $version < self::OLDEST_MANIFEST_VERSION || $version > self::MANIFEST_VERSION ) {
                                throw new Exception( "$path: unsupported manifest_version: {$version}" );
                        }
+
                        $autoload = $this->processAutoLoader( dirname( $path ), $info );
                        // Set up the autoloader now so custom processors will work
                        $GLOBALS['wgAutoloadClasses'] += $autoload;
                        $autoloadClasses += $autoload;
-                       // Check any constraints against MediaWiki core
-                       $requires = $processor->getRequirements( $info );
-                       if ( isset( $requires[self::MEDIAWIKI_CORE] )
-                               && !$coreVersionParser->check( $requires[self::MEDIAWIKI_CORE] )
-                       ) {
-                               // Doesn't match, mark it as incompatible.
-                               $incompatible[] = "{$info['name']} is not compatible with the current "
-                                       . "MediaWiki core (version {$wgVersion}), it requires: " . $requires[self::MEDIAWIKI_CORE]
-                                       . '.';
-                               continue;
-                       }
+
                        // Get extra paths for later inclusion
                        $autoloaderPaths = array_merge( $autoloaderPaths,
                                $processor->getExtraAutoloaderPaths( dirname( $path ), $info ) );
@@ -257,6 +262,9 @@ class ExtensionRegistry {
                                case 'array_merge_recursive':
                                        $GLOBALS[$key] = array_merge_recursive( $GLOBALS[$key], $val );
                                        break;
+                               case 'array_replace_recursive':
+                                       $GLOBALS[$key] = array_replace_recursive( $GLOBALS[$key], $val );
+                                       break;
                                case 'array_plus_2d':
                                        $GLOBALS[$key] = wfArrayPlus2d( $GLOBALS[$key], $val );
                                        break;
index 34a0a99..1073de0 100644 (file)
@@ -388,7 +388,6 @@ class ResourceLoader implements LoggerAwareInterface {
                                }
                        }
                }
-
        }
 
        /**
@@ -428,7 +427,6 @@ class ResourceLoader implements LoggerAwareInterface {
                        // Keep track of their names so that they can be loaded together
                        $this->testModuleNames[$id] = array_keys( $testModules[$id] );
                }
-
        }
 
        /**
@@ -670,7 +668,7 @@ class ResourceLoader implements LoggerAwareInterface {
                // back for subsequent output, resulting in invalid GZIP. So we have to wrap
                // the whole thing in our own output buffer to be sure the active buffer
                // doesn't use ob_gzhandler.
-               // See http://bugs.php.net/bug.php?id=36514
+               // See https://bugs.php.net/bug.php?id=36514
                ob_start();
 
                // Find out which modules are missing and instantiate the others
@@ -716,7 +714,7 @@ class ResourceLoader implements LoggerAwareInterface {
                }
 
                // See RFC 2616 § 3.11 Entity Tags
-               // http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.11
+               // https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.11
                $etag = 'W/"' . $versionHash . '"';
 
                // Try the client-side cache first
@@ -779,7 +777,6 @@ class ResourceLoader implements LoggerAwareInterface {
 
                $this->errors = [];
                echo $response;
-
        }
 
        /**
@@ -824,7 +821,7 @@ class ResourceLoader implements LoggerAwareInterface {
                        header( 'Content-Type: text/javascript; charset=utf-8' );
                }
                // See RFC 2616 § 14.19 ETag
-               // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19
+               // https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19
                header( 'ETag: ' . $etag );
                if ( $context->getDebug() ) {
                        // Do not cache debug responses
@@ -849,7 +846,7 @@ class ResourceLoader implements LoggerAwareInterface {
         */
        protected function tryRespondNotModified( ResourceLoaderContext $context, $etag ) {
                // See RFC 2616 § 14.26 If-None-Match
-               // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26
+               // https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26
                $clientKeys = $context->getRequest()->getHeader( 'If-None-Match', WebRequest::GETHEADER_LIST );
                // Never send 304s in debug mode
                if ( $clientKeys !== false && !$context->getDebug() && in_array( $etag, $clientKeys ) ) {
@@ -859,7 +856,7 @@ class ResourceLoader implements LoggerAwareInterface {
                        // response (because the gzip header is always there). This is
                        // a problem because 304 responses have to be completely empty
                        // per the HTTP spec, and Firefox behaves buggily when they're not.
-                       // See also http://bugs.php.net/bug.php?id=51579
+                       // See also https://bugs.php.net/bug.php?id=51579
                        // To work around this, we tear down all output buffering before
                        // sending the 304.
                        wfResetOutputBuffers( /* $resetGzipEncoding = */ true );
@@ -1009,6 +1006,7 @@ MESSAGE;
                foreach ( $modules as $name => $module ) {
                        try {
                                $content = $module->getModuleContent( $context );
+                               $implementKey = $name . '@' . $module->getVersionHash( $context );
                                $strContent = '';
 
                                // Append output
@@ -1020,7 +1018,7 @@ MESSAGE;
                                                        $strContent = $scripts;
                                                } elseif ( is_array( $scripts ) ) {
                                                        // ...except when $scripts is an array of URLs
-                                                       $strContent = self::makeLoaderImplementScript( $name, $scripts, [], [], [] );
+                                                       $strContent = self::makeLoaderImplementScript( $implementKey, $scripts, [], [], [] );
                                                }
                                                break;
                                        case 'styles':
@@ -1046,7 +1044,7 @@ MESSAGE;
                                                        }
                                                }
                                                $strContent = self::makeLoaderImplementScript(
-                                                       $name,
+                                                       $implementKey,
                                                        $scripts,
                                                        isset( $content['styles'] ) ? $content['styles'] : [],
                                                        isset( $content['messagesBlob'] ) ? new XmlJsCode( $content['messagesBlob'] ) : [],
@@ -1125,7 +1123,7 @@ MESSAGE;
        /**
         * Return JS code that calls mw.loader.implement with given module properties.
         *
-        * @param string $name Module name
+        * @param string $name Module name or implement key (format "`[name]@[version]`")
         * @param XmlJsCode|array|string $scripts Code as XmlJsCode (to be wrapped in a closure),
         *  list of URLs to JavaScript files, or a string of JavaScript for `$.globalEval`.
         * @param mixed $styles Array of CSS strings keyed by media type, or an array of lists of URLs
@@ -1141,7 +1139,6 @@ MESSAGE;
        protected static function makeLoaderImplementScript(
                $name, $scripts, $styles, $messages, $templates
        ) {
-
                if ( $scripts instanceof XmlJsCode ) {
                        $scripts = new XmlJsCode( "function ( $, jQuery, require, module ) {\n{$scripts->value}\n}" );
                } elseif ( !is_string( $scripts ) && !is_array( $scripts ) ) {
@@ -1433,14 +1430,13 @@ MESSAGE;
         * the given value.
         *
         * @param array $configuration List of configuration values keyed by variable name
-        * @param bool $pretty Pretty-print with extra whitespace
         * @return string
         */
-       public static function makeConfigSetScript( array $configuration, $pretty = null ) {
+       public static function makeConfigSetScript( array $configuration ) {
                return Xml::encodeJsCall(
                        'mw.config.set',
                        [ $configuration ],
-                       ( $pretty === null ) ? ResourceLoader::inDebugMode() : $pretty
+                       ResourceLoader::inDebugMode()
                );
        }
 
index 5729218..91e0b02 100644 (file)
@@ -130,26 +130,15 @@ class ResourceLoaderClientHtml {
                        'states' => [
                                // moduleName => state
                        ],
-                       'general' => [
-                               // position => [ moduleName ]
-                               'top' => [],
-                               'bottom' => [],
-                       ],
+                       'general' => [],
                        'styles' => [
                                // moduleName
                        ],
-                       'scripts' => [
-                               // position => [ moduleName ]
-                               'top' => [],
-                               'bottom' => [],
-                       ],
+                       'scripts' => [],
                        // Embedding for private modules
                        'embed' => [
                                'styles' => [],
-                               'general' => [
-                                       'top' => [],
-                                       'bottom' => [],
-                               ],
+                               'general' => [],
                        ],
 
                ];
@@ -161,16 +150,15 @@ class ResourceLoaderClientHtml {
                        }
 
                        $group = $module->getGroup();
-                       $position = $module->getPosition();
 
                        if ( $group === 'private' ) {
                                // Embed via mw.loader.implement per T36907.
-                               $data['embed']['general'][$position][] = $name;
+                               $data['embed']['general'][] = $name;
                                // Avoid duplicate request from mw.loader
                                $data['states'][$name] = 'loading';
                        } else {
                                // Load via mw.loader.load()
-                               $data['general'][$position][] = $name;
+                               $data['general'][] = $name;
                        }
                }
 
@@ -216,14 +204,13 @@ class ResourceLoaderClientHtml {
                        }
 
                        $group = $module->getGroup();
-                       $position = $module->getPosition();
                        $context = $this->getContext( $group, ResourceLoaderModule::TYPE_SCRIPTS );
                        if ( $module->isKnownEmpty( $context ) ) {
                                // Avoid needless request for empty module
                                $data['states'][$name] = 'ready';
                        } else {
                                // Load from load.php?only=scripts via <script src></script>
-                               $data['scripts'][$position][] = $name;
+                               $data['scripts'][] = $name;
 
                                // Avoid duplicate request from mw.loader
                                $data['states'][$name] = 'loading';
@@ -282,24 +269,24 @@ class ResourceLoaderClientHtml {
                }
 
                // Inline RLQ: Embedded modules
-               if ( $data['embed']['general']['top'] ) {
+               if ( $data['embed']['general'] ) {
                        $chunks[] = $this->getLoad(
-                               $data['embed']['general']['top'],
+                               $data['embed']['general'],
                                ResourceLoaderModule::TYPE_COMBINED
                        );
                }
 
                // Inline RLQ: Load general modules
-               if ( $data['general']['top'] ) {
+               if ( $data['general'] ) {
                        $chunks[] = ResourceLoader::makeInlineScript(
-                               Xml::encodeJsCall( 'mw.loader.load', [ $data['general']['top'] ] )
+                               Xml::encodeJsCall( 'mw.loader.load', [ $data['general'] ] )
                        );
                }
 
                // Inline RLQ: Load only=scripts
-               if ( $data['scripts']['top'] ) {
+               if ( $data['scripts'] ) {
                        $chunks[] = $this->getLoad(
-                               $data['scripts']['top'],
+                               $data['scripts'],
                                ResourceLoaderModule::TYPE_SCRIPTS
                        );
                }
@@ -336,33 +323,7 @@ class ResourceLoaderClientHtml {
         * @return string|WrappedStringList HTML
         */
        public function getBodyHtml() {
-               $data = $this->getData();
-               $chunks = [];
-
-               // Inline RLQ: Embedded modules
-               if ( $data['embed']['general']['bottom'] ) {
-                       $chunks[] = $this->getLoad(
-                               $data['embed']['general']['bottom'],
-                               ResourceLoaderModule::TYPE_COMBINED
-                       );
-               }
-
-               // Inline RLQ: Load only=scripts
-               if ( $data['scripts']['bottom'] ) {
-                       $chunks[] = $this->getLoad(
-                               $data['scripts']['bottom'],
-                               ResourceLoaderModule::TYPE_SCRIPTS
-                       );
-               }
-
-               // Inline RLQ: Load general modules
-               if ( $data['general']['bottom'] ) {
-                       $chunks[] = ResourceLoader::makeInlineScript(
-                               Xml::encodeJsCall( 'mw.loader.load', [ $data['general']['bottom'] ] )
-                       );
-               }
-
-               return WrappedStringList::join( "\n", $chunks );
+               return '';
        }
 
        private function getContext( $group, $type ) {
index 4a2f759..b17200f 100644 (file)
@@ -26,7 +26,7 @@ use MediaWiki\Logger\LoggerFactory;
 
 /**
  * Object passed around to modules which contains information about the state
- * of a specific loader request
+ * of a specific loader request.
  */
 class ResourceLoaderContext {
        protected $resourceLoader;
@@ -62,26 +62,33 @@ class ResourceLoaderContext {
                $this->request = $request;
                $this->logger = $resourceLoader->getLogger();
 
+               // Future developers: Avoid use of getVal() in this class, which performs
+               // expensive UTF normalisation by default. Use getRawVal() instead.
+               // Values here are either one of a finite number of internal IDs,
+               // or previously-stored user input (e.g. titles, user names) that were passed
+               // to this endpoint by ResourceLoader itself from the canonical value.
+               // Values do not come directly from user input and need not match.
+
                // List of modules
-               $modules = $request->getVal( 'modules' );
+               $modules = $request->getRawVal( 'modules' );
                $this->modules = $modules ? self::expandModuleNames( $modules ) : [];
 
                // Various parameters
-               $this->user = $request->getVal( 'user' );
+               $this->user = $request->getRawVal( 'user' );
                $this->debug = $request->getFuzzyBool(
                        'debug',
                        $resourceLoader->getConfig()->get( 'ResourceLoaderDebug' )
                );
-               $this->only = $request->getVal( 'only', null );
-               $this->version = $request->getVal( 'version', null );
+               $this->only = $request->getRawVal( 'only', null );
+               $this->version = $request->getRawVal( 'version', null );
                $this->raw = $request->getFuzzyBool( 'raw' );
 
                // Image requests
-               $this->image = $request->getVal( 'image' );
-               $this->variant = $request->getVal( 'variant' );
-               $this->format = $request->getVal( 'format' );
+               $this->image = $request->getRawVal( 'image' );
+               $this->variant = $request->getRawVal( 'variant' );
+               $this->format = $request->getRawVal( 'format' );
 
-               $this->skin = $request->getVal( 'skin' );
+               $this->skin = $request->getRawVal( 'skin' );
                $skinnames = Skin::getSkinNames();
                // If no skin is specified, or we don't recognize the skin, use the default skin
                if ( !$this->skin || !isset( $skinnames[$this->skin] ) ) {
@@ -171,7 +178,7 @@ class ResourceLoaderContext {
                if ( $this->language === null ) {
                        // Must be a valid language code after this point (T64849)
                        // Only support uselang values that follow built-in conventions (T102058)
-                       $lang = $this->getRequest()->getVal( 'lang', '' );
+                       $lang = $this->getRequest()->getRawVal( 'lang', '' );
                        // Stricter version of RequestContext::sanitizeLangCode()
                        if ( !Language::isValidBuiltInCode( $lang ) ) {
                                wfDebug( "Invalid user language code\n" );
@@ -187,7 +194,7 @@ class ResourceLoaderContext {
         */
        public function getDirection() {
                if ( $this->direction === null ) {
-                       $this->direction = $this->getRequest()->getVal( 'dir' );
+                       $this->direction = $this->getRequest()->getRawVal( 'dir' );
                        if ( !$this->direction ) {
                                // Determine directionality based on user language (bug 6100)
                                $this->direction = Language::factory( $this->getLanguage() )->getDir();
index 2dcc841..07649e3 100644 (file)
@@ -128,6 +128,9 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
 
        protected $targets = [ 'desktop' ];
 
+       /** @var bool Whether CSSJanus flipping should be skipped for this module */
+       protected $noflip = false;
+
        /**
         * @var bool Whether getStyleURLsForDebug should return raw file paths,
         * or return load.php urls
@@ -277,6 +280,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                                // Single booleans
                                case 'debugRaw':
                                case 'raw':
+                               case 'noflip':
                                        $this->{$member} = (bool)$option;
                                        break;
                        }
@@ -913,7 +917,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         * @return bool
         */
        public function getFlip( $context ) {
-               return $context->getDirection() === 'rtl';
+               return $context->getDirection() === 'rtl' && !$this->noflip;
        }
 
        /**
index 1630269..ef942fa 100644 (file)
@@ -41,6 +41,7 @@ class ResourceLoaderLanguageDataModule extends ResourceLoaderModule {
                        'digitTransformTable' => $language->digitTransformTable(),
                        'separatorTransformTable' => $language->separatorTransformTable(),
                        'grammarForms' => $language->getGrammarForms(),
+                       'grammarTransformations' => $language->getGrammarTransformations(),
                        'pluralRules' => $language->getPluralRules(),
                        'digitGroupingPattern' => $language->digitGroupingPattern(),
                        'fallbackLanguages' => $language->getFallbackLanguages(),
index 3e94460..4456517 100644 (file)
@@ -25,6 +25,7 @@
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerInterface;
 use Psr\Log\NullLogger;
+use Wikimedia\ScopedCallback;
 
 /**
  * Abstraction for ResourceLoader modules, with name registration and maxage functionality.
@@ -329,14 +330,13 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
        }
 
        /**
-        * Where on the HTML page should this module's JS be loaded?
-        *  - 'top': in the "<head>"
-        *  - 'bottom': at the bottom of the "<body>"
+        * From where in the page HTML should this module be loaded?
         *
+        * @deprecated since 1.29 Obsolete. All modules load async from `<head>`.
         * @return string
         */
        public function getPosition() {
-               return 'bottom';
+               return 'top';
        }
 
        /**
index 4d0bff7..aef1c74 100644 (file)
@@ -55,12 +55,6 @@ class ResourceLoaderUserCSSPrefsModule extends ResourceLoaderModule {
                        $rules[] = "a { text-decoration: " .
                                ( $options['underline'] ? 'underline' : 'none' ) . "; }";
                }
-               if ( $options['editfont'] !== 'default' ) {
-                       // Double-check that $options['editfont'] consists of safe characters only
-                       if ( preg_match( '/^[a-zA-Z0-9_, -]+$/', $options['editfont'] ) ) {
-                               $rules[] = "textarea { font-family: {$options['editfont']}; }\n";
-                       }
-               }
                $style = implode( "\n", $rules );
                if ( $this->getFlip( $context ) ) {
                        $style = CSSJanus::transform( $style, true, false );
index 4fdd86e..ccb336f 100644 (file)
@@ -26,7 +26,8 @@
  * Abstraction for ResourceLoader modules which pull from wiki pages
  *
  * This can only be used for wiki pages in the MediaWiki and User namespaces,
- * because of its dependence on the functionality of Title::isCssJsSubpage.
+ * because of its dependence on the functionality of Title::isCssJsSubpage
+ * and Title::isCssOrJsPage().
  *
  * This module supports being used as a placeholder for a module on a remote wiki.
  * To do so, getDB() must be overloaded to return a foreign database object that
@@ -143,7 +144,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
        }
 
        /**
-        * @param string $title
+        * @param string $titleText
         * @return null|string
         */
        protected function getContent( $titleText ) {
@@ -161,11 +162,12 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                        return null;
                }
 
-               $revision = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
+               $revision = Revision::newKnownCurrent( wfGetDB( DB_REPLICA ), $title->getArticleID(),
+                       $title->getLatestRevID() );
                if ( !$revision ) {
                        return null;
                }
-
+               $revision->setTitle( $title );
                $content = $revision->getContent( Revision::RAW );
 
                if ( !$content ) {
@@ -305,7 +307,11 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                $titleInfo = [];
                $batch = new LinkBatch;
                foreach ( $pages as $titleText ) {
-                       $batch->addObj( Title::newFromText( $titleText ) );
+                       $title = Title::newFromText( $titleText );
+                       if ( $title ) {
+                               // Page name may be invalid if user-provided (e.g. gadgets)
+                               $batch->addObj( $title );
+                       }
                }
                if ( !$batch->isEmpty() ) {
                        $res = $db->select( 'page',
@@ -332,7 +338,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
         * @since 1.28
         * @param ResourceLoaderContext $context
         * @param IDatabase $db
-        * @param string[] $modules
+        * @param string[] $moduleNames
         */
        public static function preloadTitleInfo(
                ResourceLoaderContext $context, IDatabase $db, array $moduleNames
@@ -341,6 +347,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                // getDB() can be overridden to point to a foreign database.
                // For now, only preload local. In the future, we could preload by wikiID.
                $allPages = [];
+               /** @var ResourceLoaderWikiModule[] $wikiModules */
                $wikiModules = [];
                foreach ( $moduleNames as $name ) {
                        $module = $rl->getModule( $name );
@@ -353,23 +360,79 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                                }
                        }
                }
-               $allInfo = static::fetchTitleInfo( $db, array_keys( $allPages ), __METHOD__ );
-               foreach ( $wikiModules as $module ) {
-                       $pages = $module->getPages( $context );
+
+               $pageNames = array_keys( $allPages );
+               sort( $pageNames );
+               $hash = sha1( implode( '|', $pageNames ) );
+
+               // Avoid Zend bug where "static::" does not apply LSB in the closure
+               $func = [ static::class, 'fetchTitleInfo' ];
+               $fname = __METHOD__;
+
+               $cache = ObjectCache::getMainWANInstance();
+               $allInfo = $cache->getWithSetCallback(
+                       $cache->makeGlobalKey( 'resourceloader', 'titleinfo', $db->getWikiID(), $hash ),
+                       $cache::TTL_HOUR,
+                       function ( $curVal, &$ttl, array &$setOpts ) use ( $func, $pageNames, $db, $fname ) {
+                               $setOpts += Database::getCacheSetOptions( $db );
+
+                               return call_user_func( $func, $db, $pageNames, $fname );
+                       },
+                       [ 'checkKeys' => [ $cache->makeGlobalKey( 'resourceloader', 'titleinfo', $db->getWikiID() ) ] ]
+               );
+
+               foreach ( $wikiModules as $wikiModule ) {
+                       $pages = $wikiModule->getPages( $context );
                        // Before we intersect, map the names to canonical form (T145673).
                        $intersect = [];
                        foreach ( $pages as $page => $unused ) {
-                               $title = Title::newFromText( $page )->getPrefixedText();
-                               $intersect[$title] = 1;
+                               $title = Title::newFromText( $page );
+                               if ( $title ) {
+                                       $intersect[ $title->getPrefixedText() ] = 1;
+                               } else {
+                                       // Page name may be invalid if user-provided (e.g. gadgets)
+                                       $rl->getLogger()->info(
+                                               'Invalid wiki page title "{title}" in ' . __METHOD__,
+                                               [ 'title' => $page ]
+                                       );
+                               }
                        }
                        $info = array_intersect_key( $allInfo, $intersect );
-
                        $pageNames = array_keys( $pages );
                        sort( $pageNames );
                        $key = implode( '|', $pageNames );
-                       $module->setTitleInfo( $key, $info );
+                       $wikiModule->setTitleInfo( $key, $info );
+               }
+       }
+
+       /**
+        * Clear the preloadTitleInfo() cache for all wiki modules on this wiki on
+        * page change if it was a JS or CSS page
+        *
+        * @param Title $title
+        * @param Revision|null $old Prior page revision
+        * @param Revision|null $new New page revision
+        * @param string $wikiId
+        * @since 1.28
+        */
+       public static function invalidateModuleCache(
+               Title $title, Revision $old = null, Revision $new = null, $wikiId
+       ) {
+               static $formats = [ CONTENT_FORMAT_CSS, CONTENT_FORMAT_JAVASCRIPT ];
+
+               if ( $old && in_array( $old->getContentFormat(), $formats ) ) {
+                       $purge = true;
+               } elseif ( $new && in_array( $new->getContentFormat(), $formats ) ) {
+                       $purge = true;
+               } else {
+                       $purge = ( $title->isCssOrJsPage() || $title->isCssJsSubpage() );
+               }
+
+               if ( $purge ) {
+                       $cache = ObjectCache::getMainWANInstance();
+                       $key = $cache->makeGlobalKey( 'resourceloader', 'titleinfo', $wikiId );
+                       $cache->touchCheckKey( $key );
                }
-               return $allInfo;
        }
 
        /**
index 696facb..90bfebd 100644 (file)
@@ -547,13 +547,20 @@ abstract class SearchEngine {
                        return $sugg->getSuggestedTitle()->getPrefixedText();
                } );
 
-               // Rescore results with an exact title match
-               // NOTE: in some cases like cross-namespace redirects
-               // (frequently used as shortcuts e.g. WP:WP on huwiki) some
-               // backends like Cirrus will return no results. We should still
-               // try an exact title match to workaround this limitation
-               $rescorer = new SearchExactMatchRescorer();
-               $rescoredResults = $rescorer->rescore( $search, $this->namespaces, $results, $this->limit );
+               if ( $this->offset === 0 ) {
+                       // Rescore results with an exact title match
+                       // NOTE: in some cases like cross-namespace redirects
+                       // (frequently used as shortcuts e.g. WP:WP on huwiki) some
+                       // backends like Cirrus will return no results. We should still
+                       // try an exact title match to workaround this limitation
+                       $rescorer = new SearchExactMatchRescorer();
+                       $rescoredResults = $rescorer->rescore( $search, $this->namespaces, $results, $this->limit );
+               } else {
+                       // No need to rescore if offset is not 0
+                       // The exact match must have been returned at position 0
+                       // if it existed.
+                       $rescoredResults = $results;
+               }
 
                if ( count( $rescoredResults ) > 0 ) {
                        $found = array_search( $rescoredResults[0], $results );
index 8ba49b6..5a50b17 100644 (file)
@@ -62,7 +62,6 @@ class SearchPostgres extends SearchDatabase {
         * @return string
         */
        function parseQuery( $term ) {
-
                wfDebug( "parseQuery received: $term \n" );
 
                # # No backslashes allowed
@@ -115,7 +114,6 @@ class SearchPostgres extends SearchDatabase {
                wfDebug( "parseQuery returned: $searchstring \n" );
 
                return $searchstring;
-
        }
 
        /**
index 695ce5a..084ac05 100644 (file)
@@ -162,12 +162,39 @@ class PHPSessionHandler implements \SessionHandlerInterface {
                }
        }
 
+       /**
+        * Workaround for PHP5 bug
+        *
+        * PHP5 has a bug in handling boolean return values for
+        * SessionHandlerInterface methods, it expects 0 or -1 instead of true or
+        * false. See <https://wiki.php.net/rfc/session.user.return-value>.
+        *
+        * PHP7 and HHVM are not affected.
+        *
+        * @todo When we drop support for Zend PHP 5, this can be removed.
+        * @return bool|int
+        * @codeCoverageIgnore
+        */
+       protected static function returnSuccess() {
+               return defined( 'HHVM_VERSION' ) || version_compare( PHP_VERSION, '7.0.0', '>=' ) ? true : 0;
+       }
+
+       /**
+        * Workaround for PHP5 bug
+        * @see self::returnSuccess()
+        * @return bool|int
+        * @codeCoverageIgnore
+        */
+       protected static function returnFailure() {
+               return defined( 'HHVM_VERSION' ) || version_compare( PHP_VERSION, '7.0.0', '>=' ) ? false : -1;
+       }
+
        /**
         * Initialize the session (handler)
         * @private For internal use only
         * @param string $save_path Path used to store session files (ignored)
         * @param string $session_name Session name (ignored)
-        * @return bool Success
+        * @return bool|int Success (see self::returnSuccess())
         */
        public function open( $save_path, $session_name ) {
                if ( self::$instance !== $this ) {
@@ -176,20 +203,20 @@ class PHPSessionHandler implements \SessionHandlerInterface {
                if ( !$this->enable ) {
                        throw new \BadMethodCallException( 'Attempt to use PHP session management' );
                }
-               return true;
+               return self::returnSuccess();
        }
 
        /**
         * Close the session (handler)
         * @private For internal use only
-        * @return bool Success
+        * @return bool|int Success (see self::returnSuccess())
         */
        public function close() {
                if ( self::$instance !== $this ) {
                        throw new \UnexpectedValueException( __METHOD__ . ': Wrong instance called!' );
                }
                $this->sessionFieldCache = [];
-               return true;
+               return self::returnSuccess();
        }
 
        /**
@@ -224,7 +251,7 @@ class PHPSessionHandler implements \SessionHandlerInterface {
         * @param string $dataStr Session data. Not that you should ever call this
         *   directly, but note that this has the same issues with code injection
         *   via user-controlled data as does PHP's unserialize function.
-        * @return bool Success
+        * @return bool|int Success (see self::returnSuccess())
         */
        public function write( $id, $dataStr ) {
                if ( self::$instance !== $this ) {
@@ -243,14 +270,14 @@ class PHPSessionHandler implements \SessionHandlerInterface {
                                [
                                        'session' => $id,
                        ] );
-                       return true;
+                       return self::returnSuccess();
                }
 
                // First, decode the string PHP handed us
                $data = \Wikimedia\PhpSessionSerializer::decode( $dataStr );
                if ( $data === null ) {
                        // @codeCoverageIgnoreStart
-                       return false;
+                       return self::returnFailure();
                        // @codeCoverageIgnoreEnd
                }
 
@@ -323,14 +350,14 @@ class PHPSessionHandler implements \SessionHandlerInterface {
 
                $session->persist();
 
-               return true;
+               return self::returnSuccess();
        }
 
        /**
         * Destroy a session
         * @private For internal use only
         * @param string $id Session id
-        * @return bool Success
+        * @return bool|int Success (see self::returnSuccess())
         */
        public function destroy( $id ) {
                if ( self::$instance !== $this ) {
@@ -343,14 +370,15 @@ class PHPSessionHandler implements \SessionHandlerInterface {
                if ( $session ) {
                        $session->clear();
                }
-               return true;
+               return self::returnSuccess();
        }
 
        /**
         * Execute garbage collection.
         * @private For internal use only
         * @param int $maxlifetime Maximum session life time (ignored)
-        * @return bool Success
+        * @return bool|int Success (see self::returnSuccess())
+        * @codeCoverageIgnore See T135576
         */
        public function gc( $maxlifetime ) {
                if ( self::$instance !== $this ) {
@@ -358,6 +386,6 @@ class PHPSessionHandler implements \SessionHandlerInterface {
                }
                $before = date( 'YmdHis', time() );
                $this->store->deleteObjectsExpiringBefore( $before );
-               return true;
+               return self::returnSuccess();
        }
 }
index 31761c3..12f16b6 100644 (file)
@@ -600,7 +600,7 @@ final class Session implements \Countable, \Iterator, \ArrayAccess {
         *
         * Calls to save() or clear() will not be delayed.
         *
-        * @return \ScopedCallback When this goes out of scope, a save will be triggered
+        * @return \Wikimedia\ScopedCallback When this goes out of scope, a save will be triggered
         */
        public function delaySave() {
                return $this->backend->delaySave();
index 263cb11..8633715 100644 (file)
@@ -586,11 +586,11 @@ final class SessionBackend {
         *
         * Calls to save() will not be delayed.
         *
-        * @return \ScopedCallback When this goes out of scope, a save will be triggered
+        * @return \Wikimedia\ScopedCallback When this goes out of scope, a save will be triggered
         */
        public function delaySave() {
                $this->delaySave++;
-               return new \ScopedCallback( function () {
+               return new \Wikimedia\ScopedCallback( function () {
                        if ( --$this->delaySave <= 0 ) {
                                $this->delaySave = 0;
                                $this->save();
@@ -642,7 +642,11 @@ final class SessionBackend {
                        ] );
                        $this->user->setToken();
                        if ( !wfReadOnly() ) {
-                               $this->user->saveSettings();
+                               // Promise that the token set here will be valid; save it at end of request
+                               $user = $this->user;
+                               \DeferredUpdates::addCallableUpdate( function () use ( $user ) {
+                                       $user->saveSettings();
+                               } );
                        }
                        $this->metaDirty = true;
                }
@@ -747,7 +751,7 @@ final class SessionBackend {
        private function checkPHPSession() {
                if ( !$this->checkPHPSessionRecursionGuard ) {
                        $this->checkPHPSessionRecursionGuard = true;
-                       $reset = new \ScopedCallback( function () {
+                       $reset = new \Wikimedia\ScopedCallback( function () {
                                $this->checkPHPSessionRecursionGuard = false;
                        } );
 
index 87fdcd3..b8e480f 100644 (file)
@@ -880,7 +880,7 @@ final class SessionManager implements SessionManagerInterface {
                        $session->resetId();
                }
 
-               \ScopedCallback::consume( $delay );
+               \Wikimedia\ScopedCallback::consume( $delay );
                return $session;
        }
 
index 432d5ce..e5247f2 100644 (file)
@@ -130,8 +130,6 @@ class DBSiteStore implements SiteStore {
                                $this->sites->setSite( $site );
                        }
                }
-
-               $this->dbLoadBalancer->reuseConnection( $dbr );
        }
 
        /**
@@ -249,8 +247,6 @@ class DBSiteStore implements SiteStore {
 
                $dbw->endAtomic( __METHOD__ );
 
-               $this->dbLoadBalancer->reuseConnection( $dbw );
-
                $this->reset();
 
                return $success;
@@ -280,8 +276,6 @@ class DBSiteStore implements SiteStore {
                $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok;
                $dbw->endAtomic( __METHOD__ );
 
-               $this->dbLoadBalancer->reuseConnection( $dbw );
-
                $this->reset();
 
                return $ok;
index 87865df..65eb9b7 100644 (file)
@@ -29,10 +29,11 @@ abstract class BaseTemplate extends QuickTemplate {
         * Get a Message object with its context set
         *
         * @param string $name Message name
+        * @param ... $params Message params
         * @return Message
         */
-       public function getMsg( $name ) {
-               return $this->getSkin()->msg( $name );
+       public function getMsg( $name /* ... */ ) {
+               return call_user_func_array( [ $this->getSkin(), 'msg' ], func_get_args() );
        }
 
        function msg( $str ) {
@@ -288,7 +289,6 @@ abstract class BaseTemplate extends QuickTemplate {
                if ( $content !== '' ) {
                        echo "<div class='after-portlet after-portlet-$name'>$content</div>";
                }
-
        }
 
        /**
index b60aa10..96812ea 100644 (file)
@@ -217,6 +217,17 @@ abstract class Skin extends ContextSource {
                        }
                }
 
+               // Footer links (used by SkinTemplate::prepareQuickTemplate)
+               foreach ( [
+                       $this->footerLinkTitle( 'privacy', 'privacypage' ),
+                       $this->footerLinkTitle( 'aboutsite', 'aboutpage' ),
+                       $this->footerLinkTitle( 'disclaimers', 'disclaimerpage' ),
+               ] as $title ) {
+                       if ( $title ) {
+                               $titles[] = $title;
+                       }
+               }
+
                Hooks::run( 'SkinPreloadExistence', [ &$titles, $this ] );
 
                if ( $titles ) {
@@ -921,25 +932,34 @@ abstract class Skin extends ContextSource {
         * @return string HTML anchor
         */
        public function footerLink( $desc, $page ) {
-               // if the link description has been set to "-" in the default language,
-               if ( $this->msg( $desc )->inContentLanguage()->isDisabled() ) {
-                       // then it is disabled, for all languages.
+               $title = $this->footerLinkTitle( $desc, $page );
+               if ( !$title ) {
                        return '';
-               } else {
-                       // Otherwise, we display the link for the user, described in their
-                       // language (which may or may not be the same as the default language),
-                       // but we make the link target be the one site-wide page.
-                       $title = Title::newFromText( $this->msg( $page )->inContentLanguage()->text() );
+               }
 
-                       if ( !$title ) {
-                               return '';
-                       }
+               return Linker::linkKnown(
+                       $title,
+                       $this->msg( $desc )->escaped()
+               );
+       }
 
-                       return Linker::linkKnown(
-                               $title,
-                               $this->msg( $desc )->escaped()
-                       );
+       /**
+        * @param string $desc
+        * @param string $page
+        * @return Title|null
+        */
+       private function footerLinkTitle( $desc, $page ) {
+               // If the link description has been set to "-" in the default language,
+               if ( $this->msg( $desc )->inContentLanguage()->isDisabled() ) {
+                       // then it is disabled, for all languages.
+                       return null;
                }
+               // Otherwise, we display the link for the user, described in their
+               // language (which may or may not be the same as the default language),
+               // but we make the link target be the one site-wide page.
+               $title = Title::newFromText( $this->msg( $page )->inContentLanguage()->text() );
+
+               return $title ?: null;
        }
 
        /**
index ed7c6df..9c5600d 100644 (file)
@@ -180,6 +180,7 @@ class SkinTemplate extends Skin {
                                        'text' => $ilLangName,
                                        'title' => $ilTitle,
                                        'class' => $class,
+                                       'link-class' => 'interlanguage-link-target',
                                        'lang' => $ilInterwikiCodeBCP47,
                                        'hreflang' => $ilInterwikiCodeBCP47,
                                ];
@@ -195,7 +196,6 @@ class SkinTemplate extends Skin {
        }
 
        protected function setupTemplateForOutput() {
-
                $request = $this->getRequest();
                $user = $this->getUser();
                $title = $this->getTitle();
@@ -256,7 +256,6 @@ class SkinTemplate extends Skin {
                if ( $oldContext ) {
                        $this->setContext( $oldContext );
                }
-
        }
 
        /**
@@ -1170,7 +1169,6 @@ class SkinTemplate extends Skin {
         * @return array
         */
        private function buildContentActionUrls( $content_navigation ) {
-
                // content_actions has been replaced with content_navigation for backwards
                // compatibility and also for skins that just want simple tabs content_actions
                // is now built by flattening the content_navigation arrays into one
index c28c456..66c7d47 100644 (file)
@@ -107,14 +107,15 @@ abstract class FormSpecialPage extends SpecialPage {
                        $form->addHeaderText( $headerMsg->parseAsBlock() );
                }
 
-               // Retain query parameters (uselang etc)
-               $params = array_diff_key(
-                       $this->getRequest()->getQueryValues(), [ 'title' => null ] );
-               $form->addHiddenField( 'redirectparams', wfArrayToCgi( $params ) );
-
                $form->addPreText( $this->preText() );
                $form->addPostText( $this->postText() );
                $this->alterForm( $form );
+               if ( $form->getMethod() == 'post' ) {
+                       // Retain query parameters (uselang etc) on POST requests
+                       $params = array_diff_key(
+                               $this->getRequest()->getQueryValues(), [ 'title' => null ] );
+                       $form->addHiddenField( 'redirectparams', wfArrayToCgi( $params ) );
+               }
 
                // Give hooks a chance to alter the form, adding extra fields or text etc
                Hooks::run( 'SpecialPageBeforeFormDisplay', [ $this->getName(), &$form ] );
index bf83e7b..1e03774 100644 (file)
@@ -156,7 +156,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                        [
                                'returnto' => $this->mReturnTo,
                                'returntoquery' => $this->mReturnToQuery,
-                               'uselang' => $this->mLanguage,
+                               'uselang' => $this->mLanguage ?: null,
                                'fromhttp' => $wgSecureLogin && $this->mFromHTTP ? '1' : null,
                        ]
                );
@@ -508,7 +508,11 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                }
 
                // warning header for non-standard workflows (e.g. security reauthentication)
-               if ( !$this->isSignup() && $this->getUser()->isLoggedIn() ) {
+               if (
+                       !$this->isSignup() &&
+                       $this->getUser()->isLoggedIn() &&
+                       $this->authAction !== AuthManager::ACTION_LOGIN_CONTINUE
+               ) {
                        $reauthMessage = $this->securityLevel ? 'userlogin-reauth' : 'userlogin-loggedin';
                        $submitStatus->warning( $reauthMessage, $this->getUser()->getName() );
                }
@@ -615,7 +619,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                $form = HTMLForm::factory( 'vform', $formDescriptor, $context );
 
                $form->addHiddenField( 'authAction', $this->authAction );
-               if ( $wgLoginLanguageSelector ) {
+               if ( $wgLoginLanguageSelector && $this->mLanguage ) {
                        $form->addHiddenField( 'uselang', $this->mLanguage );
                }
                $form->addHiddenField( 'force', $this->securityLevel );
@@ -655,7 +659,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                // make a best effort to get the value of fields which used to be fixed in the old login
                // template but now might or might not exist depending on what providers are used
                $request = $this->getRequest();
-               $data = (object) [
+               $data = (object)[
                        'mUsername' => $request->getText( 'wpName' ),
                        'mPassword' => $request->getText( 'wpPassword' ),
                        'mRetype' => $request->getText( 'wpRetype' ),
@@ -759,14 +763,21 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                $wgAuth->modifyUITemplate( $template, $action );
 
                $oldTemplate = $template;
-               $hookName = $this->isSignup() ? 'UserCreateForm' : 'UserLoginForm';
-               Hooks::run( $hookName, [ &$template ] );
-               if ( $oldTemplate !== $template ) {
-                       wfDeprecated( "reference in $hookName hook", '1.27' );
+
+               // Both Hooks::run are explicit here to make findHooks.php happy
+               if ( $this->isSignup() ) {
+                       Hooks::run( 'UserCreateForm', [ &$template ] );
+                       if ( $oldTemplate !== $template ) {
+                               wfDeprecated( "reference in UserCreateForm hook", '1.27' );
+                       }
+               } else {
+                       Hooks::run( 'UserLoginForm', [ &$template ] );
+                       if ( $oldTemplate !== $template ) {
+                               wfDeprecated( "reference in UserLoginForm hook", '1.27' );
+                       }
                }
 
                return $template;
-
        }
 
        public function onAuthChangeFormFields(
@@ -1070,7 +1081,7 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                }
                if ( !$this->isSignup() && $this->showExtraInformation() ) {
                        $passwordReset = new PasswordReset( $this->getConfig(), AuthManager::singleton() );
-                       if ( $passwordReset->isAllowed( $this->getUser() ) ) {
+                       if ( $passwordReset->isAllowed( $this->getUser() )->isGood() ) {
                                $fieldDefinitions['passwordReset'] = [
                                        'type' => 'info',
                                        'raw' => true,
index 97f004f..3bb3f85 100644 (file)
@@ -36,17 +36,7 @@ abstract class PageQueryPage extends QueryPage {
         * @param ResultWrapper $res
         */
        public function preprocessResults( $db, $res ) {
-               if ( !$res->numRows() ) {
-                       return;
-               }
-
-               $batch = new LinkBatch();
-               foreach ( $res as $row ) {
-                       $batch->add( $row->namespace, $row->title );
-               }
-               $batch->execute();
-
-               $res->seek( 0 );
+               $this->executeLBFromResultWrapper( $res );
        }
 
        /**
index afbc581..3592500 100644 (file)
@@ -825,4 +825,28 @@ abstract class QueryPage extends SpecialPage {
        function feedUrl() {
                return $this->getPageTitle()->getFullURL();
        }
+
+       /**
+        * Creates a new LinkBatch object, adds all pages from the passed ResultWrapper (MUST include
+        * title and optional the namespace field) and executes the batch. This operation will pre-cache
+        * LinkCache information like page existence and information for stub color and redirect hints.
+        *
+        * @param ResultWrapper $res The ResultWrapper object to process. Needs to include the title
+        *  field and namespace field, if the $ns parameter isn't set.
+        * @param null $ns Use this namespace for the given titles in the ResultWrapper object,
+        *  instead of the namespace value of $res.
+        */
+       protected function executeLBFromResultWrapper( ResultWrapper $res, $ns = null ) {
+               if ( !$res->numRows() ) {
+                       return;
+               }
+
+               $batch = new LinkBatch;
+               foreach ( $res as $row ) {
+                       $batch->add( $ns !== null ? $ns : $row->namespace, $row->title );
+               }
+               $batch->execute();
+
+               $res->seek( 0 );
+       }
 }
index 4356bc5..daabded 100644 (file)
@@ -188,7 +188,6 @@ class SpecialPageFactory {
 
        private static $list;
        private static $aliases;
-       private static $pageObjectCache = [];
 
        /**
         * Reset the internal list of special pages. Useful when changing $wgSpecialPages after
@@ -197,7 +196,6 @@ class SpecialPageFactory {
        public static function resetList() {
                self::$list = null;
                self::$aliases = null;
-               self::$pageObjectCache = [];
        }
 
        /**
@@ -379,10 +377,6 @@ class SpecialPageFactory {
        public static function getPage( $name ) {
                list( $realName, /*...*/ ) = self::resolveAlias( $name );
 
-               if ( isset( self::$pageObjectCache[$realName] ) ) {
-                       return self::$pageObjectCache[$realName];
-               }
-
                $specialPageList = self::getPageList();
 
                if ( isset( $specialPageList[$realName] ) ) {
@@ -410,7 +404,6 @@ class SpecialPageFactory {
                                $page = null;
                        }
 
-                       self::$pageObjectCache[$realName] = $page;
                        if ( $page instanceof SpecialPage ) {
                                return $page;
                        } else {
index 1c19f3c..39e3649 100644 (file)
@@ -41,18 +41,7 @@ abstract class WantedQueryPage extends QueryPage {
         * @param ResultWrapper $res
         */
        function preprocessResults( $db, $res ) {
-               if ( !$res->numRows() ) {
-                       return;
-               }
-
-               $batch = new LinkBatch;
-               foreach ( $res as $row ) {
-                       $batch->add( $row->namespace, $row->title );
-               }
-               $batch->execute();
-
-               // Back to start for display
-               $res->seek( 0 );
+               $this->executeLBFromResultWrapper( $res );
        }
 
        /**
index 2da441b..531c330 100644 (file)
@@ -51,8 +51,7 @@ class SpecialActiveUsers extends SpecialPage {
                $opts = new FormOptions();
 
                $opts->add( 'username', '' );
-               $opts->add( 'hidebots', false, FormOptions::BOOL );
-               $opts->add( 'hidesysops', false, FormOptions::BOOL );
+               $opts->add( 'groups', [] );
 
                $opts->fetchValuesFromRequest( $this->getRequest() );
 
@@ -60,32 +59,32 @@ class SpecialActiveUsers extends SpecialPage {
                        $opts->setValue( 'username', $par );
                }
 
-               // Mention the level of cache staleness...
-               $cacheText = '';
-               $dbr = wfGetDB( DB_REPLICA, 'recentchanges' );
-               $rcMax = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', '', __METHOD__ );
-               if ( $rcMax ) {
-                       $cTime = $dbr->selectField( 'querycache_info',
-                               'qci_timestamp',
-                               [ 'qci_type' => 'activeusers' ],
-                               __METHOD__
+               $pager = new ActiveUsersPager( $this->getContext(), $opts );
+               $usersBody = $pager->getBody();
+
+               $this->buildForm();
+
+               if ( $usersBody ) {
+                       $out->addHTML(
+                               $pager->getNavigationBar() .
+                               Html::rawElement( 'ul', [], $usersBody ) .
+                               $pager->getNavigationBar()
                        );
-                       if ( $cTime ) {
-                               $secondsOld = wfTimestamp( TS_UNIX, $rcMax ) - wfTimestamp( TS_UNIX, $cTime );
-                       } else {
-                               $rcMin = $dbr->selectField( 'recentchanges', 'MIN(rc_timestamp)' );
-                               $secondsOld = time() - wfTimestamp( TS_UNIX, $rcMin );
-                       }
-                       if ( $secondsOld > 0 ) {
-                               $cacheTxt = '<br>' . $this->msg( 'cachedspecial-viewing-cached-ttl' )
-                                       ->durationParams( $secondsOld );
-                       }
+               } else {
+                       $out->addWikiMsg( 'activeusers-noresult' );
                }
+       }
 
-               $pager = new ActiveUsersPager( $this->getContext(), $opts );
-               $usersBody = $pager->getBody();
+       /**
+        * Generate and output the form
+        */
+       protected function buildForm() {
+               $groups = User::getAllGroups();
 
-               $days = $this->getConfig()->get( 'ActiveUserDays' );
+               foreach ( $groups as $group ) {
+                       $msg = User::getGroupName( $group );
+                       $options[$msg] = $group;
+               }
 
                $formDescriptor = [
                        'username' => [
@@ -94,38 +93,60 @@ class SpecialActiveUsers extends SpecialPage {
                                '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,
+                       'groups' => [
+                               'type' => 'multiselect',
+                               'dropdown' => true,
+                               'flatlist' => true,
+                               'name' => 'groups',
+                               'label-message' => 'activeusers-groups',
+                               'options' => $options,
                        ],
                ];
 
-               $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
-                       ->setIntro( $this->msg( 'activeusers-intro' )->numParams( $days ) . $cacheText )
+               HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
+                       // For the 'multiselect' field values to be preserved on submit
+                       ->setFormIdentifier( 'specialactiveusers' )
+                       ->setIntro( $this->getIntroText() )
                        ->setWrapperLegendMsg( 'activeusers' )
                        ->setSubmitTextMsg( 'activeusers-submit' )
+                       // prevent setting subpage and 'username' parameter at the same time
+                       ->setAction( $this->getPageTitle()->getLocalURL() )
                        ->setMethod( 'get' )
                        ->prepareForm()
                        ->displayForm( false );
+       }
 
-               if ( $usersBody ) {
-                       $out->addHTML(
-                               $pager->getNavigationBar() .
-                               Html::rawElement( 'ul', [], $usersBody ) .
-                               $pager->getNavigationBar()
+       /**
+        * Return introductory message.
+        * @return string
+        */
+       protected function getIntroText() {
+               $days = $this->getConfig()->get( 'ActiveUserDays' );
+
+               $intro = $this->msg( 'activeusers-intro' )->numParams( $days )->parse();
+
+               // Mention the level of cache staleness...
+               $dbr = wfGetDB( DB_REPLICA, 'recentchanges' );
+               $rcMax = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', '', __METHOD__ );
+               if ( $rcMax ) {
+                       $cTime = $dbr->selectField( 'querycache_info',
+                               'qci_timestamp',
+                               [ 'qci_type' => 'activeusers' ],
+                               __METHOD__
                        );
-               } else {
-                       $out->addWikiMsg( 'activeusers-noresult' );
+                       if ( $cTime ) {
+                               $secondsOld = wfTimestamp( TS_UNIX, $rcMax ) - wfTimestamp( TS_UNIX, $cTime );
+                       } else {
+                               $rcMin = $dbr->selectField( 'recentchanges', 'MIN(rc_timestamp)' );
+                               $secondsOld = time() - wfTimestamp( TS_UNIX, $rcMin );
+                       }
+                       if ( $secondsOld > 0 ) {
+                               $intro .= $this->msg( 'cachedspecial-viewing-cached-ttl' )
+                                       ->durationParams( $secondsOld )->parseAsBlock();
+                       }
                }
+
+               return $intro;
        }
 
        protected function getGroupName() {
index 724435b..9ee1b75 100644 (file)
@@ -64,6 +64,10 @@ class AncientPagesPage extends QueryPage {
                return false;
        }
 
+       public function preprocessResults( $db, $res ) {
+               $this->executeLBFromResultWrapper( $res );
+       }
+
        /**
         * @param Skin $skin
         * @param object $result Result row
index c4fb316..0899d58 100644 (file)
@@ -103,13 +103,15 @@ class SpecialBlockList extends SpecialPage {
                $context = new DerivativeContext( $this->getContext() );
                $context->setTitle( $this->getPageTitle() ); // Remove subpage
                $form = HTMLForm::factory( 'ooui', $fields, $context );
-               $form->setMethod( 'get' );
-               $form->setWrapperLegendMsg( 'ipblocklist-legend' );
-               $form->setSubmitTextMsg( 'ipblocklist-submit' );
-               $form->setSubmitProgressive();
-               $form->prepareForm();
+               $form
+                       ->setMethod( 'get' )
+                       ->setFormIdentifier( 'blocklist' )
+                       ->setWrapperLegendMsg( 'ipblocklist-legend' )
+                       ->setSubmitTextMsg( 'ipblocklist-submit' )
+                       ->setSubmitProgressive()
+                       ->prepareForm()
+                       ->displayForm( false );
 
-               $form->displayForm( '' );
                $this->showList( $pager );
        }
 
index 11faa28..72e0b88 100644 (file)
  * @ingroup SpecialPage
  */
 class SpecialBookSources extends SpecialPage {
-       /**
-        * ISBN passed to the page, if any
-        */
-       protected $isbn = '';
-
        public function __construct() {
                parent::__construct( 'Booksources' );
        }
@@ -49,19 +44,21 @@ class SpecialBookSources extends SpecialPage {
                $this->setHeaders();
                $this->outputHeader();
 
-               $this->isbn = self::cleanIsbn( $isbn ?: $this->getRequest()->getText( 'isbn' ) );
+               // User provided ISBN
+               $isbn = $isbn ?: $this->getRequest()->getText( 'isbn' );
+               $isbn = trim( $isbn );
 
-               $this->buildForm();
+               $this->buildForm( $isbn );
 
-               if ( $this->isbn !== '' ) {
-                       if ( !self::isValidISBN( $this->isbn ) ) {
+               if ( $isbn !== '' ) {
+                       if ( !self::isValidISBN( $isbn ) ) {
                                $out->wrapWikiMsg(
                                        "<div class=\"error\">\n$1\n</div>",
                                        'booksources-invalid-isbn'
                                );
                        }
 
-                       $this->showList();
+                       $this->showList( $isbn );
                }
        }
 
@@ -121,20 +118,24 @@ class SpecialBookSources extends SpecialPage {
 
        /**
         * Generate a form to allow users to enter an ISBN
+        *
+        * @param string $isbn
         */
-       private function buildForm() {
+       private function buildForm( $isbn ) {
                $formDescriptor = [
                        'isbn' => [
                                'type' => 'text',
                                'name' => 'isbn',
                                'label-message' => 'booksources-isbn',
-                               'default' => $this->isbn,
+                               'default' => $isbn,
                                'autofocus' => true,
                                'required' => true,
                        ],
                ];
 
-               $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
+               $context = new DerivativeContext( $this->getContext() );
+               $context->setTitle( $this->getPageTitle() );
+               HTMLForm::factory( 'ooui', $formDescriptor, $context )
                        ->setWrapperLegendMsg( 'booksources-search-legend' )
                        ->setSubmitTextMsg( 'booksources-search' )
                        ->setMethod( 'get' )
@@ -146,17 +147,19 @@ class SpecialBookSources extends SpecialPage {
         * Determine where to get the list of book sources from,
         * format and output them
         *
+        * @param string $isbn
         * @throws MWException
         * @return bool
         */
-       private function showList() {
+       private function showList( $isbn ) {
                $out = $this->getOutput();
 
                global $wgContLang;
 
+               $isbn = self::cleanIsbn( $isbn );
                # Hook to allow extensions to insert additional HTML,
                # e.g. for API-interacting plugins and so on
-               Hooks::run( 'BookInformation', [ $this->isbn, $out ] );
+               Hooks::run( 'BookInformation', [ $isbn, $out ] );
 
                # Check for a local page such as Project:Book_sources and use that if available
                $page = $this->msg( 'booksources' )->inContentLanguage()->text();
@@ -169,7 +172,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();
-                               $out->addWikiText( str_replace( 'MAGICNUMBER', $this->isbn, $text ) );
+                               $out->addWikiText( str_replace( 'MAGICNUMBER', $isbn, $text ) );
 
                                return true;
                        } else {
@@ -182,7 +185,7 @@ class SpecialBookSources extends SpecialPage {
                $out->addHTML( '<ul>' );
                $items = $wgContLang->getBookstoreList();
                foreach ( $items as $label => $url ) {
-                       $out->addHTML( $this->makeListItem( $label, $url ) );
+                       $out->addHTML( $this->makeListItem( $isbn, $label, $url ) );
                }
                $out->addHTML( '</ul>' );
 
@@ -192,12 +195,13 @@ class SpecialBookSources extends SpecialPage {
        /**
         * Format a book source list item
         *
+        * @param string $isbn
         * @param string $label Book source label
         * @param string $url Book source URL
         * @return string
         */
-       private function makeListItem( $label, $url ) {
-               $url = str_replace( '$1', $this->isbn, $url );
+       private function makeListItem( $isbn, $label, $url ) {
+               $url = str_replace( '$1', $isbn, $url );
 
                return Html::rawElement( 'li', [],
                        Html::element( 'a', [ 'href' => $url, 'class' => 'external' ], $label )
index ed3cd5e..1dd78d7 100644 (file)
@@ -224,7 +224,7 @@ class SpecialBotPasswords extends FormSpecialPage {
                                        'name' => 'op',
                                        'value' => 'create',
                                        'label-message' => 'botpasswords-label-create',
-                                       'flags' => [ 'primary', 'constructive' ],
+                                       'flags' => [ 'primary', 'progressive' ],
                                ] );
                        }
 
index b9b2051..1753396 100644 (file)
@@ -171,18 +171,7 @@ class BrokenRedirectsPage extends QueryPage {
         * @param ResultWrapper $res
         */
        function preprocessResults( $db, $res ) {
-               if ( !$res->numRows() ) {
-                       return;
-               }
-
-               $batch = new LinkBatch;
-               foreach ( $res as $row ) {
-                       $batch->add( $row->namespace, $row->title );
-               }
-               $batch->execute();
-
-               // Back to start for display
-               $res->seek( 0 );
+               $this->executeLBFromResultWrapper( $res );
        }
 
        protected function getGroupName() {
index 7b4e9db..f494b9d 100644 (file)
@@ -69,9 +69,9 @@ class EmailConfirmation extends UnlistedSpecialPage {
                                $this->getOutput()->addWikiMsg( 'confirmemail_noemail' );
                        }
                } else {
-                       $trxProfiler->setSilenced( true );
+                       $old = $trxProfiler->setSilenced( true );
                        $this->attemptConfirm( $code );
-                       $trxProfiler->setSilenced( false );
+                       $trxProfiler->setSilenced( $old );
                }
        }
 
index 0858b18..3cd4d4d 100644 (file)
@@ -554,7 +554,7 @@ class SpecialContributions extends IncludableSpecialPage {
                                $this->msg( 'namespace' )->text(),
                                'namespace',
                                ''
-                       ) .
+                       ) . '&#160;' .
                        Html::namespaceSelector(
                                [ 'selected' => $this->opts['namespace'], 'all' => '' ],
                                [
index a5a45d5..0defcd1 100644 (file)
@@ -68,8 +68,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
         */
        private function initServices() {
                if ( !$this->titleParser ) {
-                       $lang = $this->getContext()->getLanguage();
-                       $this->titleParser = new MediaWikiTitleCodec( $lang, GenderCache::singleton() );
+                       $this->titleParser = MediaWikiServices::getInstance()->getTitleParser();
                }
        }
 
@@ -205,7 +204,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                        }
                }
 
-               GenderCache::singleton()->doTitlesArray( $titles );
+               MediaWikiServices::getInstance()->getGenderCache()->doTitlesArray( $titles );
 
                $list = [];
                /** @var Title $title */
@@ -355,7 +354,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                                }
                        }
 
-                       GenderCache::singleton()->doTitlesArray( $titles );
+                       MediaWikiServices::getInstance()->getGenderCache()->doTitlesArray( $titles );
 
                        foreach ( $titles as $title ) {
                                $list[] = $title->getPrefixedText();
@@ -431,20 +430,22 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                }
 
                $user = $this->getUser();
-               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
-
-               foreach ( $this->badItems as $row ) {
-                       list( $title, $namespace, $dbKey ) = $row;
-                       $action = $title ? 'cleaning up' : 'deleting';
-                       wfDebug( "User {$user->getName()} has broken watchlist item ns($namespace):$dbKey, $action.\n" );
-
-                       $store->removeWatch( $user, new TitleValue( (int)$namespace, $dbKey ) );
-
-                       // Can't just do an UPDATE instead of DELETE/INSERT due to unique index
-                       if ( $title ) {
-                               $user->addWatch( $title );
+               $badItems = $this->badItems;
+               DeferredUpdates::addCallableUpdate( function () use ( $user, $badItems ) {
+                       $store = MediaWikiServices::getInstance()->getWatchedItemStore();
+                       foreach ( $badItems as $row ) {
+                               list( $title, $namespace, $dbKey ) = $row;
+                               $action = $title ? 'cleaning up' : 'deleting';
+                               wfDebug( "User {$user->getName()} has broken watchlist item " .
+                                       "ns($namespace):$dbKey, $action.\n" );
+
+                               $store->removeWatch( $user, new TitleValue( (int)$namespace, $dbKey ) );
+                               // Can't just do an UPDATE instead of DELETE/INSERT due to unique index
+                               if ( $title ) {
+                                       $user->addWatch( $title );
+                               }
                        }
-               }
+               } );
        }
 
        /**
index d2e3e7f..c54abad 100644 (file)
@@ -45,9 +45,9 @@ class EmailInvalidation extends UnlistedSpecialPage {
                $this->checkReadOnly();
                $this->checkPermissions();
 
-               $trxProfiler->setSilenced( true );
+               $old = $trxProfiler->setSilenced( true );
                $this->attemptInvalidate( $code );
-               $trxProfiler->setSilenced( false );
+               $trxProfiler->setSilenced( $old );
        }
 
        /**
index fe1dd98..c58af60 100644 (file)
@@ -594,9 +594,13 @@ class ImportReporter extends ContextSource {
                $this->mPageCount++;
 
                if ( $successCount > 0 ) {
+                       // <bdi> prevents jumbling of the versions count
+                       // in RTL wikis in case the page title is LTR
                        $this->getOutput()->addHTML(
                                "<li>" . Linker::linkKnown( $title ) . " " .
+                                       "<bdi>" .
                                        $this->msg( 'import-revision-count' )->numParams( $successCount )->escaped() .
+                                       "</bdi>" .
                                        "</li>\n"
                        );
 
index 307d6c3..a2fa844 100644 (file)
@@ -225,16 +225,7 @@ class LinkSearchPage extends QueryPage {
         * @param ResultWrapper $res
         */
        function preprocessResults( $db, $res ) {
-               if ( $res->numRows() > 0 ) {
-                       $linkBatch = new LinkBatch();
-
-                       foreach ( $res as $row ) {
-                               $linkBatch->add( $row->namespace, $row->title );
-                       }
-
-                       $res->seek( 0 );
-                       $linkBatch->execute();
-               }
+               $this->executeLBFromResultWrapper( $res );
        }
 
        /**
index 49fa417..dbe5c2f 100644 (file)
@@ -75,16 +75,7 @@ class ListDuplicatedFilesPage extends QueryPage {
         * @param ResultWrapper $res
         */
        function preprocessResults( $db, $res ) {
-               if ( $res->numRows() > 0 ) {
-                       $linkBatch = new LinkBatch();
-
-                       foreach ( $res as $row ) {
-                               $linkBatch->add( $row->namespace, $row->title );
-                       }
-
-                       $res->seek( 0 );
-                       $linkBatch->execute();
-               }
+               $this->executeLBFromResultWrapper( $res );
        }
 
        /**
index e3be225..1d02a4f 100644 (file)
@@ -35,7 +35,7 @@ class MIMEsearchPage extends QueryPage {
        }
 
        public function isExpensive() {
-               return true;
+               return false;
        }
 
        function isSyndicated() {
@@ -199,6 +199,10 @@ class MIMEsearchPage extends QueryPage {
                return in_array( $type, $types );
        }
 
+       public function preprocessResults( $db, $res ) {
+               $this->executeLBFromResultWrapper( $res );
+       }
+
        protected function getGroupName() {
                return 'media';
        }
index ec87716..7683ad8 100644 (file)
@@ -353,6 +353,7 @@ class MediaStatisticsPage extends QueryPage {
         * @param ResultWrapper $res
         */
        public function preprocessResults( $dbr, $res ) {
+               $this->executeLBFromResultWrapper( $res );
                $this->totalCount = $this->totalBytes = 0;
                foreach ( $res as $row ) {
                        $mediaStats = $this->splitFakeTitle( $row->title );
index 06d21d5..015701d 100644 (file)
@@ -69,19 +69,7 @@ class MostcategoriesPage extends QueryPage {
         * @param ResultWrapper $res
         */
        function preprocessResults( $db, $res ) {
-               # There's no point doing a batch check if we aren't caching results;
-               # the page must exist for it to have been pulled out of the table
-               if ( !$this->isCached() || !$res->numRows() ) {
-                       return;
-               }
-
-               $batch = new LinkBatch();
-               foreach ( $res as $row ) {
-                       $batch->add( $row->namespace, $row->title );
-               }
-               $batch->execute();
-
-               $res->seek( 0 );
+               $this->executeLBFromResultWrapper( $res );
        }
 
        /**
index 8271d16..3e78352 100644 (file)
@@ -75,20 +75,7 @@ class MostinterwikisPage extends QueryPage {
         * @param ResultWrapper $res
         */
        function preprocessResults( $db, $res ) {
-               # There's no point doing a batch check if we aren't caching results;
-               # the page must exist for it to have been pulled out of the table
-               if ( !$this->isCached() || !$res->numRows() ) {
-                       return;
-               }
-
-               $batch = new LinkBatch;
-               foreach ( $res as $row ) {
-                       $batch->add( $row->namespace, $row->title );
-               }
-               $batch->execute();
-
-               // Back to start for display
-               $res->seek( 0 );
+               $this->executeLBFromResultWrapper( $res );
        }
 
        /**
index 3663647..01eb39e 100644 (file)
@@ -78,16 +78,7 @@ class MostlinkedPage extends QueryPage {
         * @param ResultWrapper $res
         */
        function preprocessResults( $db, $res ) {
-               if ( $res->numRows() > 0 ) {
-                       $linkBatch = new LinkBatch();
-
-                       foreach ( $res as $row ) {
-                               $linkBatch->add( $row->namespace, $row->title );
-                       }
-
-                       $res->seek( 0 );
-                       $linkBatch->execute();
-               }
+               $this->executeLBFromResultWrapper( $res );
        }
 
        /**
index 3ead08a..41678cb 100644 (file)
@@ -59,18 +59,7 @@ class MostlinkedCategoriesPage extends QueryPage {
         * @param ResultWrapper $res
         */
        function preprocessResults( $db, $res ) {
-               if ( !$res->numRows() ) {
-                       return;
-               }
-
-               $batch = new LinkBatch;
-               foreach ( $res as $row ) {
-                       $batch->add( NS_CATEGORY, $row->title );
-               }
-               $batch->execute();
-
-               // Back to start for display
-               $res->seek( 0 );
+               $this->executeLBFromResultWrapper( $res );
        }
 
        /**
index 950241f..7fcb9d8 100644 (file)
@@ -79,17 +79,7 @@ class MostlinkedTemplatesPage extends QueryPage {
         * @param ResultWrapper $res
         */
        public function preprocessResults( $db, $res ) {
-               if ( !$res->numRows() ) {
-                       return;
-               }
-
-               $batch = new LinkBatch();
-               foreach ( $res as $row ) {
-                       $batch->add( $row->namespace, $row->title );
-               }
-               $batch->execute();
-
-               $res->seek( 0 );
+               $this->executeLBFromResultWrapper( $res );
        }
 
        /**
index 3a12cf3..298d6c4 100644 (file)
@@ -462,7 +462,7 @@ class MovePageForm extends UnlistedSpecialPage {
                                'name' => 'wpMove',
                                'value' => $this->msg( 'movepagebtn' )->text(),
                                'label' => $this->msg( 'movepagebtn' )->text(),
-                               'flags' => [ 'constructive', 'primary' ],
+                               'flags' => [ 'primary', 'progressive' ],
                                'type' => 'submit',
                        ] ),
                        [
@@ -783,32 +783,57 @@ class MovePageForm extends UnlistedSpecialPage {
                LogEventsList::showLogExtract( $out, 'move', $title );
        }
 
+       /**
+        * Show subpages of the page being moved. Section is not shown if both current
+        * namespace does not support subpages and no talk subpages were found.
+        *
+        * @param Title $title Page being moved.
+        */
        function showSubpages( $title ) {
-               if ( !MWNamespace::hasSubpages( $title->getNamespace() ) ) {
+               $nsHasSubpages = MWNamespace::hasSubpages( $title->getNamespace() );
+               $subpages = $title->getSubpages();
+               $count = $subpages instanceof TitleArray ? $subpages->count() : 0;
+
+               $titleIsTalk = $title->isTalkPage();
+               $subpagesTalk = $title->getTalkPage()->getSubpages();
+               $countTalk = $subpagesTalk instanceof TitleArray ? $subpagesTalk->count() : 0;
+               $totalCount = $count + $countTalk;
+
+               if ( !$nsHasSubpages && $countTalk == 0 ) {
                        return;
                }
 
-               $subpages = $title->getSubpages();
-               $count = $subpages instanceof TitleArray ? $subpages->count() : 0;
+               $this->getOutput()->wrapWikiMsg(
+                       '== $1 ==',
+                       [ 'movesubpage', ( $titleIsTalk ? $count : $totalCount ) ]
+               );
+
+               if ( $nsHasSubpages ) {
+                       $this->showSubpagesList( $subpages, $count, 'movesubpagetext', true );
+               }
 
+               if ( !$titleIsTalk && $countTalk > 0 ) {
+                       $this->showSubpagesList( $subpagesTalk, $countTalk, 'movesubpagetalktext' );
+               }
+       }
+
+       function showSubpagesList( $subpages, $pagecount, $wikiMsg, $noSubpageMsg = false ) {
                $out = $this->getOutput();
-               $out->wrapWikiMsg( '== $1 ==', [ 'movesubpage', $count ] );
 
                # No subpages.
-               if ( $count == 0 ) {
+               if ( $pagecount == 0 && $noSubpageMsg ) {
                        $out->addWikiMsg( 'movenosubpage' );
-
                        return;
                }
 
-               $out->addWikiMsg( 'movesubpagetext', $this->getLanguage()->formatNum( $count ) );
+               $out->addWikiMsg( $wikiMsg, $this->getLanguage()->formatNum( $pagecount ) );
                $out->addHTML( "<ul>\n" );
 
                $linkBatch = new LinkBatch( $subpages );
                $linkBatch->setCaller( __METHOD__ );
                $linkBatch->execute();
-
                $linkRenderer = $this->getLinkRenderer();
+
                foreach ( $subpages as $subpage ) {
                        $link = $linkRenderer->makeLink( $subpage );
                        $out->addHTML( "<li>$link</li>\n" );
old mode 100644 (file)
new mode 100755 (executable)
index 718a6dc..be8ad8f
@@ -54,6 +54,8 @@ class SpecialNewpages extends IncludableSpecialPage {
                $opts->add( 'feed', '' );
                $opts->add( 'tagfilter', '' );
                $opts->add( 'invert', false );
+               $opts->add( 'size-mode', 'max' );
+               $opts->add( 'size', 0 );
 
                $this->customFilters = [];
                Hooks::run( 'SpecialNewPagesFilters', [ $this, &$this->customFilters ] );
@@ -214,6 +216,9 @@ class SpecialNewpages extends IncludableSpecialPage {
                $tagFilterVal = $this->opts->consumeValue( 'tagfilter' );
                $nsinvert = $this->opts->consumeValue( 'invert' );
 
+               $size = $this->opts->consumeValue( 'size' );
+               $max = $this->opts->consumeValue( 'size-mode' ) === 'max';
+
                // Check username input validity
                $ut = Title::makeTitleSafe( NS_USER, $username );
                $userText = $ut ? $ut->getText() : '';
@@ -254,6 +259,11 @@ class SpecialNewpages extends IncludableSpecialPage {
                                'size' => 30,
                                'cssclass' => 'mw-autocomplete-user', // used by mediawiki.userSuggest
                        ],
+                       'size' => [
+                               'type' => 'sizefilter',
+                               'name' => 'size',
+                               'default' => -$max * $size,
+                       ],
                ];
 
                $htmlForm = new HTMLForm( $form, $this->getContext() );
@@ -376,7 +386,11 @@ class SpecialNewpages extends IncludableSpecialPage {
 
                if ( !$title->equals( $oldTitle ) ) {
                        $oldTitleText = $oldTitle->getPrefixedText();
-                       $oldTitleText = $this->msg( 'rc-old-title' )->params( $oldTitleText )->escaped();
+                       $oldTitleText = Html::rawElement(
+                               'span',
+                               [ 'class' => 'mw-newpages-oldtitle' ],
+                               $this->msg( 'rc-old-title' )->params( $oldTitleText )->escaped()
+                       );
                }
 
                return "<li{$css}>{$time} {$dm}{$plink} {$hist} {$dm}{$length} "
index 9746ef6..5e5f2f1 100644 (file)
@@ -34,7 +34,7 @@ use MediaWiki\Auth\AuthManager;
  */
 class SpecialPasswordReset extends FormSpecialPage {
        /** @var PasswordReset */
-       private $passwordReset;
+       private $passwordReset = null;
 
        /**
         * @var string[] Temporary storage for the passwords which have been sent out, keyed by username.
@@ -53,7 +53,13 @@ class SpecialPasswordReset extends FormSpecialPage {
 
        public function __construct() {
                parent::__construct( 'PasswordReset', 'editmyprivateinfo' );
-               $this->passwordReset = new PasswordReset( $this->getConfig(), AuthManager::singleton() );
+       }
+
+       private function getPasswordReset() {
+               if ( $this->passwordReset === null ) {
+                       $this->passwordReset = new PasswordReset( $this->getConfig(), AuthManager::singleton() );
+               }
+               return $this->passwordReset;
        }
 
        public function doesWrites() {
@@ -61,11 +67,11 @@ class SpecialPasswordReset extends FormSpecialPage {
        }
 
        public function userCanExecute( User $user ) {
-               return $this->passwordReset->isAllowed( $user )->isGood();
+               return $this->getPasswordReset()->isAllowed( $user )->isGood();
        }
 
        public function checkExecutePermissions( User $user ) {
-               $status = Status::wrap( $this->passwordReset->isAllowed( $user ) );
+               $status = Status::wrap( $this->getPasswordReset()->isAllowed( $user ) );
                if ( !$status->isGood() ) {
                        throw new ErrorPageError( 'internalerror', $status->getMessage() );
                }
@@ -150,7 +156,7 @@ class SpecialPasswordReset extends FormSpecialPage {
 
                $this->method = $username ? 'username' : 'email';
                $this->result = Status::wrap(
-                       $this->passwordReset->execute( $this->getUser(), $username, $email, $capture ) );
+                       $this->getPasswordReset()->execute( $this->getUser(), $username, $email, $capture ) );
                if ( $capture && $this->result->isOK() ) {
                        $this->passwords = $this->result->getValue();
                }
@@ -164,8 +170,6 @@ class SpecialPasswordReset extends FormSpecialPage {
 
        public function onSuccess() {
                if ( $this->getUser()->isAllowed( 'passwordreset' ) && $this->passwords ) {
-                       // @todo Logging
-
                        if ( $this->result->isGood() ) {
                                $this->getOutput()->addWikiMsg( 'passwordreset-emailsent-capture2',
                                        count( $this->passwords ) );
@@ -199,7 +203,7 @@ class SpecialPasswordReset extends FormSpecialPage {
         * @return bool
         */
        public function isListed() {
-               if ( $this->passwordReset->isAllowed( $this->getUser() )->isGood() ) {
+               if ( $this->getPasswordReset()->isAllowed( $this->getUser() )->isGood() ) {
                        return parent::isListed();
                }
 
index fcd4ab5..dcaff4d 100644 (file)
@@ -106,7 +106,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
        ];
 
        public function __construct() {
-               parent::__construct( 'Revisiondelete', 'deletedhistory' );
+               parent::__construct( 'Revisiondelete', 'deleterevision' );
        }
 
        public function doesWrites() {
@@ -210,17 +210,19 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                        $this->showForm();
                }
 
-               $qc = $this->getLogQueryCond();
-               # Show relevant lines from the deletion log
-               $deleteLogPage = new LogPage( 'delete' );
-               $output->addHTML( "<h2>" . $deleteLogPage->getName()->escaped() . "</h2>\n" );
-               LogEventsList::showLogExtract(
-                       $output,
-                       'delete',
-                       $this->targetObj,
-                       '', /* user */
-                       [ 'lim' => 25, 'conds' => $qc, 'useMaster' => $this->wasSaved ]
-               );
+               if ( $user->isAllowed( 'deletedhistory' ) ) {
+                       $qc = $this->getLogQueryCond();
+                       # Show relevant lines from the deletion log
+                       $deleteLogPage = new LogPage( 'delete' );
+                       $output->addHTML( "<h2>" . $deleteLogPage->getName()->escaped() . "</h2>\n" );
+                       LogEventsList::showLogExtract(
+                               $output,
+                               'delete',
+                               $this->targetObj,
+                               '', /* user */
+                               [ 'lim' => 25, 'conds' => $qc, 'useMaster' => $this->wasSaved ]
+                       );
+               }
                # Show relevant lines from the suppression log
                if ( $user->isAllowed( 'suppressionlog' ) ) {
                        $suppressLogPage = new LogPage( 'suppress' );
index 6daf19f..9280b04 100644 (file)
@@ -234,11 +234,6 @@ class SpecialSearch extends SpecialPage {
 
                        return;
                }
-               # No match, generate an edit URL
-               $title = Title::newFromText( $term );
-               if ( !is_null( $title ) ) {
-                       Hooks::run( 'SpecialSearchNogomatch', [ &$title ] );
-               }
                $this->showResults( $term );
        }
 
@@ -422,7 +417,12 @@ class SpecialSearch extends SpecialPage {
                                $out->addHTML( '<div class="error">' .
                                        $textStatus->getMessage( 'search-error' ) . '</div>' );
                        } else {
-                               $this->showCreateLink( $title, $num, $titleMatches, $textMatches );
+                               if ( !$this->offset ) {
+                                       // If we have an offset the create link was rendered earlier in this function.
+                                       // This class needs a good de-spaghettification, but for now this will
+                                       // do the job.
+                                       $this->showCreateLink( $title, $num, $titleMatches, $textMatches );
+                               }
                                $out->wrapWikiMsg( "<p class=\"mw-search-nonefound\">\n$1</p>",
                                        [ $hasOtherResults ? 'search-nonefound-thiswiki' : 'search-nonefound',
                                                        wfEscapeWikiText( $term )
@@ -455,7 +455,6 @@ class SpecialSearch extends SpecialPage {
                $out->addHTML( "</div>" );
 
                Hooks::run( 'SpecialSearchResultsAppend', [ $this, $out, $term ] );
-
        }
 
        /**
@@ -470,25 +469,6 @@ class SpecialSearch extends SpecialPage {
                return "<p class=\"mw-search-interwiki-header mw-search-visualclear\">\n$wikiMsg</p>";
        }
 
-       /**
-        * Decide if the suggested query should be run, and it's results returned
-        * instead of the provided $textMatches
-        *
-        * @param SearchResultSet $textMatches The results of a users query
-        * @return bool
-        */
-       protected function shouldRunSuggestedQuery( SearchResultSet $textMatches ) {
-               if ( !$this->runSuggestion ||
-                       !$textMatches->hasSuggestion() ||
-                       $textMatches->numRows() > 0 ||
-                       $textMatches->searchContainedSyntax()
-               ) {
-                       return false;
-               }
-
-               return $this->getConfig()->get( 'SearchRunSuggestedQuery' );
-       }
-
        /**
         * Generates HTML shown to the user when we have a suggestion about a query
         * that might give more results than their current query.
@@ -752,7 +732,6 @@ class SpecialSearch extends SpecialPage {
         * @return string
         */
        protected function showHit( SearchResult $result, $terms, $position ) {
-
                if ( $result->isBrokenTitle() ) {
                        return '';
                }
@@ -972,7 +951,6 @@ class SpecialSearch extends SpecialPage {
         * @return string
         */
        protected function showInterwikiHit( $result, $lastInterwiki, $query ) {
-
                if ( $result->isBrokenTitle() ) {
                        return '';
                }
@@ -1335,24 +1313,6 @@ class SpecialSearch extends SpecialPage {
                return false;
        }
 
-       /**
-        * Check if query starts with all: prefix
-        *
-        * @param string $term The string to check
-        * @return bool
-        */
-       protected function startsWithAll( $term ) {
-
-               $allkeyword = $this->msg( 'searchall' )->inContentLanguage()->text();
-
-               $parts = explode( ':', $term );
-               if ( count( $parts ) > 1 ) {
-                       return $parts[0] == $allkeyword;
-               }
-
-               return false;
-       }
-
        /**
         * @since 1.18
         *
index a76b511..a78b082 100644 (file)
@@ -71,19 +71,7 @@ class ShortPagesPage extends QueryPage {
         * @param ResultWrapper $res
         */
        function preprocessResults( $db, $res ) {
-               # There's no point doing a batch check if we aren't caching results;
-               # the page must exist for it to have been pulled out of the table
-               if ( !$this->isCached() || !$res->numRows() ) {
-                       return;
-               }
-
-               $batch = new LinkBatch();
-               foreach ( $res as $row ) {
-                       $batch->add( $row->namespace, $row->title );
-               }
-               $batch->execute();
-
-               $res->seek( 0 );
+               $this->executeLBFromResultWrapper( $res );
        }
 
        function sortDescending() {
index 898d170..ea40cb8 100644 (file)
@@ -176,7 +176,7 @@ class SpecialTags extends SpecialPage {
                $newRow .= Xml::tags( 'td', null, Xml::element( 'code', null, $tag ) );
 
                $linkRenderer = $this->getLinkRenderer();
-               $disp = ChangeTags::tagDescription( $tag );
+               $disp = ChangeTags::tagDescription( $tag, $this->getContext() );
                if ( $showEditLinks ) {
                        $disp .= ' ';
                        $editLink = $linkRenderer->makeLink(
index 4c892b2..4c6a345 100644 (file)
@@ -87,6 +87,8 @@ class SpecialTrackingCategories extends SpecialPage {
                }
                $batch->execute();
 
+               Hooks::run( 'SpecialTrackingCategories::preprocess', [ $this, $trackingCategories ] );
+
                foreach ( $trackingCategories as $catMsg => $data ) {
                        $allMsgs = [];
                        $catDesc = $catMsg . '-desc';
@@ -97,11 +99,15 @@ class SpecialTrackingCategories extends SpecialPage {
                        );
 
                        foreach ( $data['cats'] as $catTitle ) {
-                               $catTitleText = Linker::link(
+                               $html = Linker::link(
                                        $catTitle,
                                        htmlspecialchars( $catTitle->getText() )
                                );
-                               $allMsgs[] = $catTitleText;
+
+                               Hooks::run( 'SpecialTrackingCategories::generateCatLink',
+                                       [ $this, $catTitle, &$html ] );
+
+                               $allMsgs[] = $html;
                        }
 
                        # Extra message, when no category was found
@@ -145,6 +151,19 @@ class SpecialTrackingCategories extends SpecialPage {
                        ExtensionRegistry::getInstance()->getAttribute( 'TrackingCategories' ),
                        $this->getConfig()->get( 'TrackingCategories' ) // deprecated
                );
+
+               // Only show magic link tracking categories if they are enabled
+               $enableMagicLinks = $this->getConfig()->get( 'EnableMagicLinks' );
+               if ( $enableMagicLinks['ISBN'] ) {
+                       $categories[] = 'magiclink-tracking-isbn';
+               }
+               if ( $enableMagicLinks['RFC'] ) {
+                       $categories[] = 'magiclink-tracking-rfc';
+               }
+               if ( $enableMagicLinks['PMID'] ) {
+                       $categories[] = 'magiclink-tracking-pmid';
+               }
+
                $trackingCategories = [];
                foreach ( $categories as $catMsg ) {
                        /*
index 45efaf3..88c0e21 100644 (file)
@@ -76,4 +76,8 @@ class UnusedCategoriesPage extends QueryPage {
        protected function getGroupName() {
                return 'maintenance';
        }
+
+       public function preprocessResults( $db, $res ) {
+               $this->executeLBFromResultWrapper( $res );
+       }
 }
index df57744..ae375b2 100644 (file)
@@ -43,7 +43,28 @@ class UnwatchedpagesPage extends QueryPage {
                return false;
        }
 
+       /**
+        * Pre-cache page existence to speed up link generation
+        *
+        * @param IDatabase $db
+        * @param ResultWrapper $res
+        */
+       public function preprocessResults( $db, $res ) {
+               if ( !$res->numRows() ) {
+                       return;
+               }
+
+               $batch = new LinkBatch();
+               foreach ( $res as $row ) {
+                       $batch->add( $row->namespace, $row->title );
+               }
+               $batch->execute();
+
+               $res->seek( 0 );
+       }
+
        public function getQueryInfo() {
+               $dbr = wfGetDB( DB_REPLICA );
                return [
                        'tables' => [ 'page', 'watchlist' ],
                        'fields' => [
@@ -54,7 +75,7 @@ class UnwatchedpagesPage extends QueryPage {
                        'conds' => [
                                'wl_title IS NULL',
                                'page_is_redirect' => 0,
-                               "page_namespace != '" . NS_MEDIAWIKI . "'"
+                               'page_namespace != ' . $dbr->addQuotes( NS_MEDIAWIKI ),
                        ],
                        'join_conds' => [ 'watchlist' => [
                                'LEFT JOIN', [ 'wl_title = page_title',
index 9573f33..8478e94 100644 (file)
@@ -60,7 +60,7 @@ class SpecialUploadStash extends UnlistedSpecialPage {
         * Execute page -- can output a file directly or show a listing of them.
         *
         * @param string $subPage Subpage, e.g. in
-        *   http://example.com/wiki/Special:UploadStash/foo.jpg, the "foo.jpg" part
+        *   https://example.com/wiki/Special:UploadStash/foo.jpg, the "foo.jpg" part
         * @return bool Success
         */
        public function execute( $subPage ) {
index 76b721c..c37ecbd 100644 (file)
@@ -49,6 +49,7 @@ class WantedPagesPage extends WantedQueryPage {
        }
 
        function getQueryInfo() {
+               $dbr = wfGetDB( DB_REPLICA );
                $count = $this->getConfig()->get( 'WantedPagesThreshold' ) - 1;
                $query = [
                        'tables' => [
@@ -63,13 +64,13 @@ class WantedPagesPage extends WantedQueryPage {
                        ],
                        'conds' => [
                                'pg1.page_namespace IS NULL',
-                               "pl_namespace NOT IN ( '" . NS_USER . "', '" . NS_USER_TALK . "' )",
-                               "pg2.page_namespace != '" . NS_MEDIAWIKI . "'"
+                               'pl_namespace NOT IN (' . $dbr->makeList( [ NS_USER, NS_USER_TALK ] ) . ')',
+                               'pg2.page_namespace != ' . $dbr->addQuotes( NS_MEDIAWIKI ),
                        ],
                        'options' => [
                                'HAVING' => [
-                                       "COUNT(*) > $count",
-                                       "COUNT(*) > SUM(pg2.page_is_redirect)"
+                                       'COUNT(*) > ' . $dbr->addQuotes( $count ),
+                                       'COUNT(*) > SUM(pg2.page_is_redirect)'
                                ],
                                'GROUP BY' => [ 'pl_namespace', 'pl_title' ]
                        ],
index 99f9c7c..4824961 100644 (file)
@@ -618,9 +618,10 @@ class SpecialWatchlist extends ChangesListSpecialPage {
 
                $form .= Xml::openElement( 'form', [
                        'method' => 'get',
-                       'action' => $this->getPageTitle()->getLocalURL(),
+                       'action' => wfScript(),
                        'id' => 'mw-watchlist-form'
                ] );
+               $form .= Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() );
                $form .= Xml::fieldset(
                        $this->msg( 'watchlist-options' )->text(),
                        false,
index 73ab0ad..ea906b7 100644 (file)
@@ -36,14 +36,9 @@ class ActiveUsersPager extends UsersPager {
        protected $opts;
 
        /**
-        * @var array
-        */
-       protected $hideGroups = [];
-
-       /**
-        * @var array
+        * @var string[]
         */
-       protected $hideRights = [];
+       protected $groups;
 
        /**
         * @var array
@@ -68,12 +63,7 @@ class ActiveUsersPager extends UsersPager {
                        }
                }
 
-               if ( $opts->getValue( 'hidebots' ) == 1 ) {
-                       $this->hideRights[] = 'bot';
-               }
-               if ( $opts->getValue( 'hidesysops' ) == 1 ) {
-                       $this->hideGroups[] = 'sysop';
-               }
+               $this->groups = $opts->getValue( 'groups' );
        }
 
        function getIndexField() {
@@ -85,6 +75,7 @@ class ActiveUsersPager extends UsersPager {
 
                $activeUserSeconds = $this->getConfig()->get( 'ActiveUserDays' ) * 86400;
                $timestamp = $dbr->timestamp( wfTimestamp( TS_UNIX ) - $activeUserSeconds );
+               $tables = [ 'querycachetwo', 'user', 'recentchanges' ];
                $conds = [
                        'qcc_type' => 'activeusers',
                        'qcc_namespace' => NS_USER,
@@ -98,6 +89,11 @@ class ActiveUsersPager extends UsersPager {
                if ( $this->requestedUser != '' ) {
                        $conds[] = 'qcc_title >= ' . $dbr->addQuotes( $this->requestedUser );
                }
+               if ( $this->groups !== [] ) {
+                       $tables[] = 'user_groups';
+                       $conds[] = 'ug_user = user_id';
+                       $conds['ug_group'] = $this->groups;
+               }
                if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
                        $conds[] = 'NOT EXISTS (' . $dbr->selectSQLText(
                                        'ipblocks', '1', [ 'ipb_user=user_id', 'ipb_deleted' => 1 ]
@@ -111,7 +107,7 @@ class ActiveUsersPager extends UsersPager {
                }
 
                return [
-                       'tables' => [ 'querycachetwo', 'user', 'recentchanges' ],
+                       'tables' => $tables,
                        'fields' => [ 'user_name', 'user_id', 'recentedits' => 'COUNT(*)', 'qcc_title' ],
                        'options' => $options,
                        'conds' => $conds
@@ -154,26 +150,8 @@ class ActiveUsersPager extends UsersPager {
                $list = [];
                $user = User::newFromId( $row->user_id );
 
-               // User right filter
-               foreach ( $this->hideRights as $right ) {
-                       // Calling User::getRights() within the loop so that
-                       // if the hideRights() filter is empty, we don't have to
-                       // trigger the lazy-init of the big userrights array in the
-                       // User object
-                       if ( in_array( $right, $user->getRights() ) ) {
-                               return '';
-                       }
-               }
-
-               // User group filter
-               // Note: This is a different loop than for user rights,
-               // because we're reusing it to build the group links
-               // at the same time
                $groups_list = self::getGroups( intval( $row->user_id ), $this->userGroupCache );
                foreach ( $groups_list as $group ) {
-                       if ( in_array( $group, $this->hideGroups ) ) {
-                               return '';
-                       }
                        $list[] = self::buildGroupLink( $group, $userName );
                }
 
index 2d39f99..e298f10 100644 (file)
@@ -48,6 +48,15 @@ class NewPagesPager extends ReverseChronologicalPager {
                $username = $this->opts->getValue( 'username' );
                $user = Title::makeTitleSafe( NS_USER, $username );
 
+               $size = abs( intval( $this->opts->getValue( 'size' ) ) );
+               if ( $size > 0 ) {
+                       if ( $this->opts->getValue( 'size-mode' ) === 'max' ) {
+                               $conds[] = 'page_len <= ' . $size;
+                       } else {
+                               $conds[] = 'page_len >= ' . $size;
+                       }
+               }
+
                $rcIndexes = [];
 
                if ( $namespace !== false ) {
index 069b460..1346e1c 100644 (file)
@@ -328,7 +328,7 @@ class BalanceElement {
        /**
         * Parent of this element, or the string "flat" if this element has
         * already been flattened into its parent.
-        * @var string|null $parent
+        * @var BalanceElement|string|null $parent
         */
        public $parent;
 
@@ -337,7 +337,7 @@ class BalanceElement {
         * child will be an actual BalanceElement object; the rest will
         * be strings, representing either text nodes or flattened
         * BalanceElement objects.
-        * @var array $children
+        * @var BalanceElement[]|string[] $children
         */
        public $children;
 
@@ -465,6 +465,7 @@ class BalanceElement {
         * in its parent by that string.
         *
         * @param array $config Balancer configuration; see Balancer::__construct().
+        * @return string
         *
         * @see __toString()
         */
@@ -653,7 +654,7 @@ class BalanceElement {
 class BalanceStack implements IteratorAggregate {
        /**
         * Backing storage for the stack.
-        * @var array $elements
+        * @var BalanceElement[] $elements
         */
        private $elements = [];
        /**
@@ -717,6 +718,7 @@ class BalanceStack implements IteratorAggregate {
        /**
         * Insert text at the appropriate place for inserting a node.
         * @param string $value
+        * @param bool $isComment
         * @see https://html.spec.whatwg.org/multipage/syntax.html#appropriate-place-for-inserting-a-node
         */
        public function insertText( $value, $isComment = false ) {
@@ -906,7 +908,7 @@ class BalanceStack implements IteratorAggregate {
        /**
         * Return an iterator over this stack which visits the current node
         * first, and the root node last.
-        * @return Iterator
+        * @return \Iterator
         */
        public function getIterator() {
                return new ReverseArrayIterator( $this->elements );
@@ -1080,6 +1082,8 @@ class BalanceStack implements IteratorAggregate {
        /**
         * Foster parent the given $elt in the stack of open elements.
         * @param BalanceElement|string $elt
+        * @return BalanceElement|string
+        *
         * @see https://html.spec.whatwg.org/multipage/syntax.html#foster-parent
         */
        private function fosterParent( $elt ) {
@@ -1520,6 +1524,7 @@ class BalanceActiveFormattingElements {
 
        /**
         * Determine whether an element is in the list of formatting elements.
+        * @param BalanceElement $elt
         * @return boolean
         */
        public function isInList( BalanceElement $elt ) {
@@ -1529,6 +1534,8 @@ class BalanceActiveFormattingElements {
        /**
         * Find the element $elt in the list and remove it.
         * Used when parsing &lt;a&gt; in body mode.
+        *
+        * @param BalanceElement $elt
         */
        public function remove( BalanceElement $elt ) {
                if ( $this->head !== $elt && !$elt->prevAFE ) {
@@ -1597,6 +1604,9 @@ class BalanceActiveFormattingElements {
 
        /**
         * Find element $a in the list and replace it with element $b
+        *
+        * @param BalanceElement $a
+        * @param BalanceElement $b
         */
        public function replace( BalanceElement $a, BalanceElement $b ) {
                if ( $this->head !== $a && !$a->prevAFE ) {
@@ -1628,6 +1638,9 @@ class BalanceActiveFormattingElements {
 
        /**
         * Find $a in the list and insert $b after it.
+
+        * @param BalanceElement $a
+        * @param BalanceElement $b
         */
        public function insertAfter( BalanceElement $a, BalanceElement $b ) {
                if ( $this->head !== $a && !$a->prevAFE ) {
@@ -1778,9 +1791,12 @@ class BalanceActiveFormattingElements {
  */
 class Balancer {
        private $parseMode;
+       /** @var \Iterator */
        private $bitsIterator;
        private $allowedHtmlElements;
+       /** @var BalanceActiveFormattingElements */
        private $afe;
+       /** @var BalanceStack */
        private $stack;
        private $strict;
        private $allowComments;
@@ -1795,6 +1811,11 @@ class Balancer {
        private $inRCDATA;
        private $inRAWTEXT;
 
+       /** @var callable|null */
+       private $processingCallback;
+       /** @var array */
+       private $processingArgs;
+
        /**
         * Valid HTML5 comments.
         * Regex borrowed from Tim Starling's "remex-html" project.
@@ -2582,7 +2603,7 @@ class Balancer {
                        case 'tt':
                        case 'u':
                                $this->afe->reconstruct( $this->stack );
-                               $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ), $attribs );
+                               $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ) );
                                return true;
 
                        case 'nobr':
@@ -2591,7 +2612,7 @@ class Balancer {
                                        $this->inBodyMode( 'endtag', 'nobr' );
                                        $this->afe->reconstruct( $this->stack );
                                }
-                               $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ), $attribs );
+                               $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ) );
                                return true;
 
                        case 'applet':
index 1ce14b6..e5642d9 100644 (file)
@@ -32,7 +32,7 @@ class RaggettInternalPHP extends RaggettBase {
                $retval = $tidy->getStatus();
                if ( $retval == 2 ) {
                        // 2 is magic number for fatal error
-                       // http://www.php.net/manual/en/function.tidy-get-status.php
+                       // https://secure.php.net/manual/en/tidy.getstatus.php
                        $cleansource = null;
                } else {
                        $cleansource = tidy_get_output( $tidy );
index 91b4133..ea6ef30 100644 (file)
@@ -1440,7 +1440,11 @@ abstract class UploadBase {
                        'http://www.w3.org/tr/rec-rdf-syntax/',
                ];
 
-               if ( !in_array( $namespace, $validNamespaces ) ) {
+               // Inkscape mangles namespace definitions created by Adobe Illustrator.
+               // This is nasty but harmless. (T144827)
+               $isBuggyInkscape = preg_match( '/^&(#38;)*ns_[a-z_]+;$/', $namespace );
+
+               if ( !( $isBuggyInkscape || in_array( $namespace, $validNamespaces ) ) ) {
                        wfDebug( __METHOD__ . ": Non-svg namespace '$namespace' in uploaded file.\n" );
                        /** @todo Return a status object to a closure in XmlTypeCheck, for MW1.21+ */
                        $this->mSVGNSError = $namespace;
@@ -1503,6 +1507,7 @@ abstract class UploadBase {
                        # fragment links are allowed. For all other tags, only data:
                        # and fragment are allowed.
                        if ( $stripped == 'href'
+                               && $value !== ''
                                && strpos( $value, 'data:' ) !== 0
                                && strpos( $value, '#' ) !== 0
                        ) {
index b7160b3..48477f8 100644 (file)
@@ -432,7 +432,7 @@ class UploadStash {
                                . ' No user is logged in, files must belong to users' );
                }
 
-               $dbr = $this->repo->getSlaveDB();
+               $dbr = $this->repo->getReplicaDB();
                $res = $dbr->select(
                        'uploadstash',
                        'us_key',
@@ -511,7 +511,7 @@ class UploadStash {
                        // sometimes reading from the master is necessary, if there's replication lag.
                        $dbr = $this->repo->getMasterDB();
                } else {
-                       $dbr = $this->repo->getSlaveDB();
+                       $dbr = $this->repo->getReplicaDB();
                }
 
                $row = $dbr->selectRow(
index eae57f4..57610fc 100644 (file)
@@ -68,7 +68,7 @@ class BotPassword implements IDBAccessObject {
        /**
         * Get a database connection for the bot passwords database
         * @param int $db Index of the connection to get, e.g. DB_MASTER or DB_REPLICA.
-        * @return DatabaseBase
+        * @return Database
         */
        public static function getDB( $db ) {
                global $wgBotPasswordsCluster, $wgBotPasswordsDatabase;
index 889ec92..530580d 100644 (file)
@@ -22,6 +22,9 @@
 
 use MediaWiki\Auth\AuthManager;
 use MediaWiki\Auth\TemporaryPasswordAuthenticationRequest;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use MediaWiki\Logger\LoggerFactory;
 
 /**
  * Helper class for the password reset functionality shared by the web UI and the API.
@@ -30,13 +33,16 @@ use MediaWiki\Auth\TemporaryPasswordAuthenticationRequest;
  * EmailNotificationSecondaryAuthenticationProvider (or something providing equivalent
  * functionality) to be enabled.
  */
-class PasswordReset {
+class PasswordReset implements LoggerAwareInterface {
        /** @var Config */
        protected $config;
 
        /** @var AuthManager */
        protected $authManager;
 
+       /** @var LoggerInterface */
+       protected $logger;
+
        /**
         * In-process cache for isAllowed lookups, by username. Contains pairs of StatusValue objects
         * (for false and true value of $displayPassword, respectively).
@@ -48,6 +54,17 @@ class PasswordReset {
                $this->config = $config;
                $this->authManager = $authManager;
                $this->permissionCache = new HashBagOStuff( [ 'maxKeys' => 1 ] );
+               $this->logger = LoggerFactory::getInstance( 'authentication' );
+       }
+
+       /**
+        * Set the logger instance to use.
+        *
+        * @param LoggerInterface $logger
+        * @since 1.29
+        */
+       public function setLogger( LoggerInterface $logger ) {
+               $this->logger = $logger;
        }
 
        /**
@@ -134,12 +151,14 @@ class PasswordReset {
                if ( $resetRoutes['username'] && $username ) {
                        $method = 'username';
                        $users = [ User::newFromName( $username ) ];
+                       $email = null;
                } elseif ( $resetRoutes['email'] && $email ) {
                        if ( !Sanitizer::validateEmail( $email ) ) {
                                return StatusValue::newFatal( 'passwordreset-invalidemail' );
                        }
                        $method = 'email';
                        $users = $this->getUsersByEmail( $email );
+                       $username = null;
                } else {
                        // The user didn't supply any data
                        return StatusValue::newFatal( 'passwordreset-nodata' );
@@ -214,7 +233,20 @@ class PasswordReset {
                        }
                }
 
+               $logContext = [
+                       'requestingIp' => $ip,
+                       'requestingUser' => $performingUser->getName(),
+                       'targetUsername' => $username,
+                       'targetEmail' => $email,
+                       'actualUser' => $firstUser->getName(),
+                       'capture' => $displayPassword,
+               ];
+
                if ( !$result->isGood() ) {
+                       $this->logger->info(
+                               "{requestingUser} attempted password reset of {actualUser} but failed",
+                               $logContext + [ 'errors' => $result->getErrors() ]
+                       );
                        return $result;
                }
 
@@ -227,6 +259,20 @@ class PasswordReset {
                        }
                }
 
+               if ( $displayPassword ) {
+                       // The password capture thing is scary, so log
+                       // at a higher warning level.
+                       $this->logger->warning(
+                               "{requestingUser} did password reset of {actualUser} with password capturing!",
+                               $logContext
+                       );
+               } else {
+                       $this->logger->info(
+                               "{requestingUser} did password reset of {actualUser}",
+                               $logContext
+                       );
+               }
+
                return StatusValue::newGood( $passwords );
        }
 
index 6083db9..b69b5bc 100644 (file)
@@ -26,6 +26,7 @@ use MediaWiki\Session\Token;
 use MediaWiki\Auth\AuthManager;
 use MediaWiki\Auth\AuthenticationResponse;
 use MediaWiki\Auth\AuthenticationRequest;
+use Wikimedia\ScopedCallback;
 
 /**
  * String Some punctuation to prevent editing from broken text-mangling proxies.
@@ -300,6 +301,11 @@ class User implements IDBAccessObject {
        /** @var integer User::READ_* constant bitfield used to load data */
        protected $queryFlagsUsed = self::READ_NORMAL;
 
+       /** @var string Indicates type of block (used for eventlogging)
+        * Permitted values: 'cookie-block', 'proxy-block', 'openproxy-block', 'xff-block'
+        */
+       public $blockTrigger = false;
+
        public static $idCacheByName = [];
 
        /**
@@ -320,7 +326,7 @@ class User implements IDBAccessObject {
         * @return string
         */
        public function __toString() {
-               return $this->getName();
+               return (string)$this->getName();
        }
 
        /**
@@ -1199,13 +1205,29 @@ class User implements IDBAccessObject {
                $user = $session->getUser();
                if ( $user->isLoggedIn() ) {
                        $this->loadFromUserObject( $user );
+
+                       // If this user is autoblocked, set a cookie to track the Block. This has to be done on
+                       // every session load, because an autoblocked editor might not edit again from the same
+                       // IP address after being blocked.
+                       $config = RequestContext::getMain()->getConfig();
+                       if ( $config->get( 'CookieSetOnAutoblock' ) === true ) {
+                               $block = $this->getBlock();
+                               $shouldSetCookie = $this->getRequest()->getCookie( 'BlockID' ) === null
+                                       && $block
+                                       && $block->getType() === Block::TYPE_USER
+                                       && $block->isAutoblocking();
+                               if ( $shouldSetCookie ) {
+                                       wfDebug( __METHOD__ . ': User is autoblocked, setting cookie to track' );
+                                       $block->setCookie( $this->getRequest()->response() );
+                               }
+                       }
+
                        // Other code expects these to be set in the session, so set them.
                        $session->set( 'wsUserID', $this->getId() );
                        $session->set( 'wsUserName', $this->getName() );
                        $session->set( 'wsToken', $this->getToken() );
                        return true;
                }
-
                return false;
        }
 
@@ -1608,6 +1630,31 @@ class User implements IDBAccessObject {
                // User/IP blocking
                $block = Block::newFromTarget( $this, $ip, !$bFromSlave );
 
+               // If no block has been found, check for a cookie indicating that the user is blocked.
+               $blockCookieVal = (int)$this->getRequest()->getCookie( 'BlockID' );
+               if ( !$block instanceof Block && $blockCookieVal > 0 ) {
+                       // Load the Block from the ID in the cookie.
+                       $tmpBlock = Block::newFromID( $blockCookieVal );
+                       if ( $tmpBlock instanceof Block ) {
+                               // Check the validity of the block.
+                               $blockIsValid = $tmpBlock->getType() == Block::TYPE_USER
+                                       && !$tmpBlock->isExpired()
+                                       && $tmpBlock->isAutoblocking();
+                               $config = RequestContext::getMain()->getConfig();
+                               $useBlockCookie = ( $config->get( 'CookieSetOnAutoblock' ) === true );
+                               if ( $blockIsValid && $useBlockCookie ) {
+                                       // Use the block.
+                                       $block = $tmpBlock;
+                                       $this->blockTrigger = 'cookie-block';
+                               } else {
+                                       // If the block is not valid, clear the block cookie (but don't delete it,
+                                       // because it needs to be cleared from LocalStorage as well and an empty string
+                                       // value is checked for in the mediawiki.user.blockcookie module).
+                                       $block->setCookie( $this->getRequest()->response(), true );
+                               }
+                       }
+               }
+
                // Proxy blocking
                if ( !$block instanceof Block && $ip !== null && !in_array( $ip, $wgProxyWhitelist ) ) {
                        // Local list
@@ -1616,11 +1663,13 @@ class User implements IDBAccessObject {
                                $block->setBlocker( wfMessage( 'proxyblocker' )->text() );
                                $block->mReason = wfMessage( 'proxyblockreason' )->text();
                                $block->setTarget( $ip );
+                               $this->blockTrigger = 'proxy-block';
                        } elseif ( $this->isAnon() && $this->isDnsBlacklisted( $ip ) ) {
                                $block = new Block;
                                $block->setBlocker( wfMessage( 'sorbs' )->text() );
                                $block->mReason = wfMessage( 'sorbsreason' )->text();
                                $block->setTarget( $ip );
+                               $this->blockTrigger = 'openproxy-block';
                        }
                }
 
@@ -1639,6 +1688,7 @@ class User implements IDBAccessObject {
                                # Mangle the reason to alert the user that the block
                                # originated from matching the X-Forwarded-For header.
                                $block->mReason = wfMessage( 'xffblockreason', $block->mReason )->text();
+                               $this->blockTrigger = 'xff-block';
                        }
                }
 
@@ -1653,11 +1703,11 @@ class User implements IDBAccessObject {
                        $this->mBlockedby = '';
                        $this->mHideName = 0;
                        $this->mAllowUsertalk = false;
+                       $this->blockTrigger = false;
                }
 
                // Extensions
                Hooks::run( 'GetBlockedStatus', [ &$this ] );
-
        }
 
        /**
@@ -1689,9 +1739,8 @@ class User implements IDBAccessObject {
         * @return bool True if blacklisted.
         */
        public function inDnsBlacklist( $ip, $bases ) {
-
                $found = false;
-               // @todo FIXME: IPv6 ???  (http://bugs.php.net/bug.php?id=33170)
+               // @todo FIXME: IPv6 ???  (https://bugs.php.net/bug.php?id=33170)
                if ( IP::isIPv4( $ip ) ) {
                        // Reverse IP, bug 21255
                        $ipReversed = implode( '.', array_reverse( explode( '.', $ip ) ) );
@@ -1802,12 +1851,16 @@ class User implements IDBAccessObject {
                        return false;
                }
 
+               $limits = array_merge(
+                       [ '&can-bypass' => true ],
+                       $wgRateLimits[$action]
+               );
+
                // Some groups shouldn't trigger the ping limiter, ever
-               if ( !$this->isPingLimitable() ) {
+               if ( $limits['&can-bypass'] && !$this->isPingLimitable() ) {
                        return false;
                }
 
-               $limits = $wgRateLimits[$action];
                $keys = [];
                $id = $this->getId();
                $userLimit = false;
index 395ce37..319b5d4 100644 (file)
@@ -160,6 +160,7 @@ class AutoloadGenerator {
         *
         * @param {string} $commandName Command name to include in comment
         * @param {string} $filename of PHP file to put autoload information in.
+        * @return string
         */
        protected function generatePHPAutoload( $commandName, $filename ) {
                // No existing JSON file found; update/generate PHP file
@@ -290,6 +291,10 @@ EOD;
                foreach ( glob( $this->basepath . '/*.php' ) as $file ) {
                        $this->readFile( $file );
                }
+
+               // Legacy aliases
+               $this->forceClassPath( 'DatabaseBase',
+                       $this->basepath . '/includes/libs/rdbms/database/Database.php' );
        }
 }
 
index 9fc2431..ef2c14a 100644 (file)
@@ -77,16 +77,21 @@ class BatchRowIterator implements RecursiveIterator {
         */
        private $key;
 
+       /**
+        * @var array Additional query options
+        */
+       protected $options = [];
+
        /**
         * @param IDatabase $db The database to read from
         * @param string|array $table      The name or names of the table to read from
         * @param string|array $primaryKey The name or names of the primary key columns
         * @param integer      $batchSize  The number of rows to fetch per iteration
-        * @throws MWException
+        * @throws InvalidArgumentException
         */
        public function __construct( IDatabase $db, $table, $primaryKey, $batchSize ) {
                if ( $batchSize < 1 ) {
-                       throw new MWException( 'Batch size must be at least 1 row.' );
+                       throw new InvalidArgumentException( 'Batch size must be at least 1 row.' );
                }
                $this->db = $db;
                $this->table = $table;
@@ -97,7 +102,7 @@ class BatchRowIterator implements RecursiveIterator {
        }
 
        /**
-        * @param array $condition Query conditions suitable for use with
+        * @param array $conditions Query conditions suitable for use with
         *  IDatabase::select
         */
        public function addConditions( array $conditions ) {
@@ -105,7 +110,15 @@ class BatchRowIterator implements RecursiveIterator {
        }
 
        /**
-        * @param array $condition Query join conditions suitable for use
+        * @param array $options Query options suitable for use with
+        *  IDatabase::select
+        */
+       public function addOptions( array $options ) {
+               $this->options = array_merge( $this->options, $options );
+       }
+
+       /**
+        * @param array $conditions Query join conditions suitable for use
         *  with IDatabase::select
         */
        public function addJoinConditions( array $conditions ) {
@@ -199,7 +212,7 @@ class BatchRowIterator implements RecursiveIterator {
                        [
                                'LIMIT' => $this->batchSize,
                                'ORDER BY' => $this->orderBy,
-                       ],
+                       ] + $this->options,
                        $this->joinConditions
                );
 
index 1e7eda8..39b65c3 100644 (file)
@@ -112,15 +112,8 @@ class BatchRowUpdate {
         *
         * @param callable $output A callback taking a single string
         *  parameter to output
-        *
-        * @throws MWException
         */
-       public function setOutput( $output ) {
-               if ( !is_callable( $output ) ) {
-                       throw new MWException(
-                               'Provided $output param is required to be callable.'
-                       );
-               }
+       public function setOutput( callable $output ) {
                $this->output = $output;
        }
 
index 1376fa7..3bddd77 100644 (file)
  * @file
  */
 
-class MWCryptHKDF {
-
-       /**
-        * Singleton instance for public use
-        */
-       protected static $singleton = null;
-
-       /**
-        * The persistant cache
-        */
-       protected $cache = null;
-
-       /**
-        * Cache key we'll use for our salt
-        */
-       protected $cacheKey = null;
-
-       /**
-        * The hash algorithm being used
-        */
-       protected $algorithm = null;
-
-       /**
-        * binary string, the salt for the HKDF
-        */
-       protected $salt;
-
-       /**
-        * The pseudorandom key
-        */
-       private $prk;
+use MediaWiki\MediaWikiServices;
 
-       /**
-        * The secret key material. This must be kept secret to preserve
-        * the security properties of this RNG.
-        */
-       private $skm;
-
-       /**
-        * The last block (K(i)) of the most recent expanded key
-        */
-       protected $lastK;
-
-       /**
-        * a "context information" string CTXinfo (which may be null)
-        * See http://eprint.iacr.org/2010/264.pdf Section 4.1
-        */
-       protected $context = [];
-
-       /**
-        * Round count is computed based on the hash'es output length,
-        * which neither php nor openssl seem to provide easily.
-        */
-       public static $hashLength = [
-               'md5' => 16,
-               'sha1' => 20,
-               'sha224' => 28,
-               'sha256' => 32,
-               'sha384' => 48,
-               'sha512' => 64,
-               'ripemd128' => 16,
-               'ripemd160' => 20,
-               'ripemd256' => 32,
-               'ripemd320' => 40,
-               'whirlpool' => 64,
-       ];
-
-       /**
-        * @param string $secretKeyMaterial
-        * @param string $algorithm Name of hashing algorithm
-        * @param BagOStuff $cache
-        * @param string|array $context Context to mix into HKDF context
-        * @throws MWException
-        */
-       public function __construct( $secretKeyMaterial, $algorithm, $cache, $context ) {
-               if ( strlen( $secretKeyMaterial ) < 16 ) {
-                       throw new MWException( "MWCryptHKDF secret was too short." );
-               }
-               $this->skm = $secretKeyMaterial;
-               $this->algorithm = $algorithm;
-               $this->cache = $cache;
-               $this->salt = ''; // Initialize a blank salt, see getSaltUsingCache()
-               $this->prk = '';
-               $this->context = is_array( $context ) ? $context : [ $context ];
-
-               // To prevent every call from hitting the same memcache server, pick
-               // from a set of keys to use. mt_rand is only use to pick a random
-               // server, and does not affect the security of the process.
-               $this->cacheKey = wfMemcKey( 'HKDF', mt_rand( 0, 16 ) );
-       }
-
-       /**
-        * Save the last block generated, so the next user will compute a different PRK
-        * from the same SKM. This should keep things unpredictable even if an attacker
-        * is able to influence CTXinfo.
-        */
-       function __destruct() {
-               if ( $this->lastK ) {
-                       $this->cache->set( $this->cacheKey, $this->lastK );
-               }
-       }
-
-       /**
-        * MW specific salt, cached from last run
-        * @return string Binary string
-        */
-       protected function getSaltUsingCache() {
-               if ( $this->salt == '' ) {
-                       $lastSalt = $this->cache->get( $this->cacheKey );
-                       if ( $lastSalt === false ) {
-                               // If we don't have a previous value to use as our salt, we use
-                               // 16 bytes from MWCryptRand, which will use a small amount of
-                               // entropy from our pool. Note, "XTR may be deterministic or keyed
-                               // via an optional “salt value”  (i.e., a non-secret random
-                               // value)..." - http://eprint.iacr.org/2010/264.pdf. However, we
-                               // use a strongly random value since we can.
-                               $lastSalt = MWCryptRand::generate( 16 );
-                       }
-                       // Get a binary string that is hashLen long
-                       $this->salt = hash( $this->algorithm, $lastSalt, true );
-               }
-               return $this->salt;
-       }
+class MWCryptHKDF {
 
        /**
         * Return a singleton instance, based on the global configs.
-        * @return self
-        * @throws MWException
+        * @return CryptHKDF
         */
        protected static function singleton() {
-               global $wgHKDFAlgorithm, $wgHKDFSecret, $wgSecretKey, $wgMainCacheType;
-
-               $secret = $wgHKDFSecret ?: $wgSecretKey;
-               if ( !$secret ) {
-                       throw new MWException( "Cannot use MWCryptHKDF without a secret." );
-               }
-
-               // In HKDF, the context can be known to the attacker, but this will
-               // keep simultaneous runs from producing the same output.
-               $context = [];
-               $context[] = microtime();
-               $context[] = getmypid();
-               $context[] = gethostname();
-
-               // Setup salt cache. Use APC, or fallback to the main cache if it isn't setup
-               $cache = ObjectCache::getLocalServerInstance( $wgMainCacheType );
-
-               if ( is_null( self::$singleton ) ) {
-                       self::$singleton = new self( $secret, $wgHKDFAlgorithm, $cache, $context );
-               }
-
-               return self::$singleton;
-       }
-
-       /**
-        * Produce $bytes of secure random data. As a side-effect,
-        * $this->lastK is set to the last hashLen block of key material.
-        * @param int $bytes Number of bytes of data
-        * @param string $context Context to mix into CTXinfo
-        * @return string Binary string of length $bytes
-        */
-       protected function realGenerate( $bytes, $context = '' ) {
-
-               if ( $this->prk === '' ) {
-                       $salt = $this->getSaltUsingCache();
-                       $this->prk = self::HKDFExtract(
-                               $this->algorithm,
-                               $salt,
-                               $this->skm
-                       );
-               }
-
-               $CTXinfo = implode( ':', array_merge( $this->context, [ $context ] ) );
-
-               return self::HKDFExpand(
-                       $this->algorithm,
-                       $this->prk,
-                       $CTXinfo,
-                       $bytes,
-                       $this->lastK
-               );
+               return MediaWikiServices::getInstance()->getCryptHKDF();
        }
 
        /**
@@ -243,62 +72,7 @@ class MWCryptHKDF {
         * @return string Cryptographically secure pseudorandom binary string
         */
        public static function HKDF( $hash, $ikm, $salt, $info, $L ) {
-               $prk = self::HKDFExtract( $hash, $salt, $ikm );
-               $okm = self::HKDFExpand( $hash, $prk, $info, $L );
-               return $okm;
-       }
-
-       /**
-        * Extract the PRK, PRK = HMAC(XTS, SKM)
-        * Note that the hmac is keyed with XTS (the salt),
-        * and the SKM (source key material) is the "data".
-        *
-        * @param string $hash The hashing function to use (e.g., sha256)
-        * @param string $salt The salt to add to the ikm, to get the prk
-        * @param string $ikm The input keying material
-        * @return string Binary string (pseudorandm key) used as input to HKDFExpand
-        */
-       private static function HKDFExtract( $hash, $salt, $ikm ) {
-               return hash_hmac( $hash, $ikm, $salt, true );
-       }
-
-       /**
-        * Expand the key with the given context
-        *
-        * @param string $hash Hashing Algorithm
-        * @param string $prk A pseudorandom key of at least HashLen octets
-        *    (usually, the output from the extract step)
-        * @param string $info Optional context and application specific information
-        *    (can be a zero-length string)
-        * @param int $bytes Length of output keying material in bytes
-        *    (<= 255*HashLen)
-        * @param string &$lastK Set by this function to the last block of the expansion.
-        *    In MediaWiki, this is used to seed future Extractions.
-        * @return string Cryptographically secure random string $bytes long
-        * @throws MWException
-        */
-       private static function HKDFExpand( $hash, $prk, $info, $bytes, &$lastK = '' ) {
-               $hashLen = MWCryptHKDF::$hashLength[$hash];
-               $rounds = ceil( $bytes / $hashLen );
-               $output = '';
-
-               if ( $bytes > 255 * $hashLen ) {
-                       throw new MWException( "Too many bytes requested from HDKFExpand" );
-               }
-
-               // K(1) = HMAC(PRK, CTXinfo || 1);
-               // K(i) = HMAC(PRK, K(i-1) || CTXinfo || i); 1 < i <= t;
-               for ( $counter = 1; $counter <= $rounds; ++$counter ) {
-                       $lastK = hash_hmac(
-                               $hash,
-                               $lastK . $info . chr( $counter ),
-                               $prk,
-                               true
-                       );
-                       $output .= $lastK;
-               }
-
-               return substr( $output, 0, $bytes );
+               return CryptHKDF::HKDF( $hash, $ikm, $salt, $info, $L );
        }
 
        /**
@@ -309,7 +83,7 @@ class MWCryptHKDF {
         * @return string Binary string of length $bytes
         */
        public static function generate( $bytes, $context ) {
-               return self::singleton()->realGenerate( $bytes, $context );
+               return self::singleton()->generate( $bytes, $context );
        }
 
        /**
@@ -322,7 +96,7 @@ class MWCryptHKDF {
         */
        public static function generateHex( $chars, $context = '' ) {
                $bytes = ceil( $chars / 2 );
-               $hex = bin2hex( self::singleton()->realGenerate( $bytes, $context ) );
+               $hex = bin2hex( self::singleton()->generate( $bytes, $context ) );
                return substr( $hex, 0, $chars );
        }
 
diff --git a/includes/utils/MWCryptHash.php b/includes/utils/MWCryptHash.php
deleted file mode 100644 (file)
index 1117357..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-<?php
-/**
- * Utility functions for generating hashes
- *
- * This is based in part on Drupal code as well as what we used in our own code
- * prior to introduction of this class, by way of MWCryptRand.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-class MWCryptHash {
-       /**
-        * The hash algorithm being used
-        */
-       protected static $algo = null;
-
-       /**
-        * The number of bytes outputted by the hash algorithm
-        */
-       protected static $hashLength = [
-               true => null,
-               false => null,
-       ];
-
-       /**
-        * Decide on the best acceptable hash algorithm we have available for hash()
-        * @return string A hash algorithm
-        */
-       public static function hashAlgo() {
-               if ( !is_null( self::$algo ) ) {
-                       return self::$algo;
-               }
-
-               $algos = hash_algos();
-               $preference = [ 'whirlpool', 'sha256', 'sha1', 'md5' ];
-
-               foreach ( $preference as $algorithm ) {
-                       if ( in_array( $algorithm, $algos ) ) {
-                               self::$algo = $algorithm;
-                               wfDebug( __METHOD__ . ': Using the ' . self::$algo . " hash algorithm.\n" );
-
-                               return self::$algo;
-                       }
-               }
-
-               // We only reach here if no acceptable hash is found in the list, this should
-               // be a technical impossibility since most of php's hash list is fixed and
-               // some of the ones we list are available as their own native functions
-               // But since we already require at least 5.2 and hash() was default in
-               // 5.1.2 we don't bother falling back to methods like sha1 and md5.
-               throw new DomainException( "Could not find an acceptable hashing function in hash_algos()" );
-       }
-
-       /**
-        * Return the byte-length output of the hash algorithm we are
-        * using in self::hash and self::hmac.
-        *
-        * @param bool $raw True to return the length for binary data, false to
-        *   return for hex-encoded
-        * @return int Number of bytes the hash outputs
-        */
-       public static function hashLength( $raw = true ) {
-               $raw = (bool)$raw;
-               if ( is_null( self::$hashLength[$raw] ) ) {
-                       self::$hashLength[$raw] = strlen( self::hash( '', $raw ) );
-               }
-
-               return self::$hashLength[$raw];
-       }
-
-       /**
-        * Generate an acceptably unstable one-way-hash of some text
-        * making use of the best hash algorithm that we have available.
-        *
-        * @param string $data
-        * @param bool $raw True to return binary data, false to return it hex-encoded
-        * @return string A hash of the data
-        */
-       public static function hash( $data, $raw = true ) {
-               return hash( self::hashAlgo(), $data, $raw );
-       }
-
-       /**
-        * Generate an acceptably unstable one-way-hmac of some text
-        * making use of the best hash algorithm that we have available.
-        *
-        * @param string $data
-        * @param string $key
-        * @param bool $raw True to return binary data, false to return it hex-encoded
-        * @return string An hmac hash of the data + key
-        */
-       public static function hmac( $data, $key, $raw = true ) {
-               if ( !is_string( $key ) ) {
-                       // a fatal error in HHVM; an exception will at least give us a stack trace
-                       throw new InvalidArgumentException( 'Invalid key type: ' . gettype( $key ) );
-               }
-               return hash_hmac( self::hashAlgo(), $data, $key, $raw );
-       }
-
-}
index dd3ea1b..5818958 100644 (file)
  * @file
  */
 
-class MWCryptRand {
-       /**
-        * Minimum number of iterations we want to make in our drift calculations.
-        */
-       const MIN_ITERATIONS = 1000;
-
-       /**
-        * Number of milliseconds we want to spend generating each separate byte
-        * of the final generated bytes.
-        * This is used in combination with the hash length to determine the duration
-        * we should spend doing drift calculations.
-        */
-       const MSEC_PER_BYTE = 0.5;
-
-       /**
-        * Singleton instance for public use
-        */
-       protected static $singleton = null;
-
-       /**
-        * A boolean indicating whether the previous random generation was done using
-        * cryptographically strong random number generator or not.
-        */
-       protected $strong = null;
-
-       /**
-        * Initialize an initial random state based off of whatever we can find
-        * @return string
-        */
-       protected function initialRandomState() {
-               // $_SERVER contains a variety of unstable user and system specific information
-               // It'll vary a little with each page, and vary even more with separate users
-               // It'll also vary slightly across different machines
-               $state = serialize( $_SERVER );
-
-               // To try vary the system information of the state a bit more
-               // by including the system's hostname into the state
-               $state .= wfHostname();
-
-               // Try to gather a little entropy from the different php rand sources
-               $state .= rand() . uniqid( mt_rand(), true );
-
-               // Include some information about the filesystem's current state in the random state
-               $files = [];
-
-               // We know this file is here so grab some info about ourselves
-               $files[] = __FILE__;
-
-               // We must also have a parent folder, and with the usual file structure, a grandparent
-               $files[] = __DIR__;
-               $files[] = dirname( __DIR__ );
-
-               // The config file is likely the most often edited file we know should
-               // be around so include its stat info into the state.
-               // The constant with its location will almost always be defined, as
-               // WebStart.php defines MW_CONFIG_FILE to $IP/LocalSettings.php unless
-               // being configured with MW_CONFIG_CALLBACK (e.g. the installer).
-               if ( defined( 'MW_CONFIG_FILE' ) ) {
-                       $files[] = MW_CONFIG_FILE;
-               }
-
-               foreach ( $files as $file ) {
-                       MediaWiki\suppressWarnings();
-                       $stat = stat( $file );
-                       MediaWiki\restoreWarnings();
-                       if ( $stat ) {
-                               // stat() duplicates data into numeric and string keys so kill off all the numeric ones
-                               foreach ( $stat as $k => $v ) {
-                                       if ( is_numeric( $k ) ) {
-                                               unset( $k );
-                                       }
-                               }
-                               // The absolute filename itself will differ from install to install so don't leave it out
-                               $path = realpath( $file );
-                               if ( $path !== false ) {
-                                       $state .= $path;
-                               } else {
-                                       $state .= $file;
-                               }
-                               $state .= implode( '', $stat );
-                       } else {
-                               // The fact that the file isn't there is worth at least a
-                               // minuscule amount of entropy.
-                               $state .= '0';
-                       }
-               }
-
-               // Try and make this a little more unstable by including the varying process
-               // id of the php process we are running inside of if we are able to access it
-               if ( function_exists( 'getmypid' ) ) {
-                       $state .= getmypid();
-               }
-
-               // If available try to increase the instability of the data by throwing in
-               // the precise amount of memory that we happen to be using at the moment.
-               if ( function_exists( 'memory_get_usage' ) ) {
-                       $state .= memory_get_usage( true );
-               }
-
-               // It's mostly worthless but throw the wiki's id into the data for a little more variance
-               $state .= wfWikiID();
-
-               // If we have a secret key set then throw it into the state as well
-               global $wgSecretKey;
-               if ( $wgSecretKey ) {
-                       $state .= $wgSecretKey;
-               }
-
-               return $state;
-       }
-
-       /**
-        * Randomly hash data while mixing in clock drift data for randomness
-        *
-        * @param string $data The data to randomly hash.
-        * @return string The hashed bytes
-        * @author Tim Starling
-        */
-       protected function driftHash( $data ) {
-               // Minimum number of iterations (to avoid slow operations causing the
-               // loop to gather little entropy)
-               $minIterations = self::MIN_ITERATIONS;
-               // Duration of time to spend doing calculations (in seconds)
-               $duration = ( self::MSEC_PER_BYTE / 1000 ) * MWCryptHash::hashLength();
-               // Create a buffer to use to trigger memory operations
-               $bufLength = 10000000;
-               $buffer = str_repeat( ' ', $bufLength );
-               $bufPos = 0;
-
-               // Iterate for $duration seconds or at least $minIterations number of iterations
-               $iterations = 0;
-               $startTime = microtime( true );
-               $currentTime = $startTime;
-               while ( $iterations < $minIterations || $currentTime - $startTime < $duration ) {
-                       // Trigger some memory writing to trigger some bus activity
-                       // This may create variance in the time between iterations
-                       $bufPos = ( $bufPos + 13 ) % $bufLength;
-                       $buffer[$bufPos] = ' ';
-                       // Add the drift between this iteration and the last in as entropy
-                       $nextTime = microtime( true );
-                       $delta = (int)( ( $nextTime - $currentTime ) * 1000000 );
-                       $data .= $delta;
-                       // Every 100 iterations hash the data and entropy
-                       if ( $iterations % 100 === 0 ) {
-                               $data = sha1( $data );
-                       }
-                       $currentTime = $nextTime;
-                       $iterations++;
-               }
-               $timeTaken = $currentTime - $startTime;
-               $data = MWCryptHash::hash( $data );
-
-               wfDebug( __METHOD__ . ": Clock drift calculation " .
-                       "(time-taken=" . ( $timeTaken * 1000 ) . "ms, " .
-                       "iterations=$iterations, " .
-                       "time-per-iteration=" . ( $timeTaken / $iterations * 1e6 ) . "us)\n" );
-
-               return $data;
-       }
-
-       /**
-        * Return a rolling random state initially build using data from unstable sources
-        * @return string A new weak random state
-        */
-       protected function randomState() {
-               static $state = null;
-               if ( is_null( $state ) ) {
-                       // Initialize the state with whatever unstable data we can find
-                       // It's important that this data is hashed right afterwards to prevent
-                       // it from being leaked into the output stream
-                       $state = MWCryptHash::hash( $this->initialRandomState() );
-               }
-               // Generate a new random state based on the initial random state or previous
-               // random state by combining it with clock drift
-               $state = $this->driftHash( $state );
-
-               return $state;
-       }
-
-       /**
-        * @see self::wasStrong()
-        */
-       public function realWasStrong() {
-               if ( is_null( $this->strong ) ) {
-                       throw new MWException( __METHOD__ . ' called before generation of random data' );
-               }
-
-               return $this->strong;
-       }
-
-       /**
-        * @see self::generate()
-        */
-       public function realGenerate( $bytes, $forceStrong = false ) {
-
-               wfDebug( __METHOD__ . ": Generating cryptographic random bytes for " .
-                       wfGetAllCallers( 5 ) . "\n" );
-
-               $bytes = floor( $bytes );
-               static $buffer = '';
-               if ( is_null( $this->strong ) ) {
-                       // Set strength to false initially until we know what source data is coming from
-                       $this->strong = true;
-               }
-
-               if ( strlen( $buffer ) < $bytes ) {
-                       // If available make use of mcrypt_create_iv URANDOM source to generate randomness
-                       // On unix-like systems this reads from /dev/urandom but does it without any buffering
-                       // and bypasses openbasedir restrictions, so it's preferable to reading directly
-                       // On Windows starting in PHP 5.3.0 Windows' native CryptGenRandom is used to generate
-                       // entropy so this is also preferable to just trying to read urandom because it may work
-                       // on Windows systems as well.
-                       if ( function_exists( 'mcrypt_create_iv' ) ) {
-                               $rem = $bytes - strlen( $buffer );
-                               $iv = mcrypt_create_iv( $rem, MCRYPT_DEV_URANDOM );
-                               if ( $iv === false ) {
-                                       wfDebug( __METHOD__ . ": mcrypt_create_iv returned false.\n" );
-                               } else {
-                                       $buffer .= $iv;
-                                       wfDebug( __METHOD__ . ": mcrypt_create_iv generated " . strlen( $iv ) .
-                                               " bytes of randomness.\n" );
-                               }
-                       }
-               }
-
-               if ( strlen( $buffer ) < $bytes ) {
-                       if ( function_exists( 'openssl_random_pseudo_bytes' ) ) {
-                               $rem = $bytes - strlen( $buffer );
-                               $openssl_bytes = openssl_random_pseudo_bytes( $rem, $openssl_strong );
-                               if ( $openssl_bytes === false ) {
-                                       wfDebug( __METHOD__ . ": openssl_random_pseudo_bytes returned false.\n" );
-                               } else {
-                                       $buffer .= $openssl_bytes;
-                                       wfDebug( __METHOD__ . ": openssl_random_pseudo_bytes generated " .
-                                               strlen( $openssl_bytes ) . " bytes of " .
-                                               ( $openssl_strong ? "strong" : "weak" ) . " randomness.\n" );
-                               }
-                               if ( strlen( $buffer ) >= $bytes ) {
-                                       // openssl tells us if the random source was strong, if some of our data was generated
-                                       // using it use it's say on whether the randomness is strong
-                                       $this->strong = !!$openssl_strong;
-                               }
-                       }
-               }
-
-               // Only read from urandom if we can control the buffer size or were passed forceStrong
-               if ( strlen( $buffer ) < $bytes &&
-                       ( function_exists( 'stream_set_read_buffer' ) || $forceStrong )
-               ) {
-                       $rem = $bytes - strlen( $buffer );
-                       if ( !function_exists( 'stream_set_read_buffer' ) && $forceStrong ) {
-                               wfDebug( __METHOD__ . ": Was forced to read from /dev/urandom " .
-                                       "without control over the buffer size.\n" );
-                       }
-                       // /dev/urandom is generally considered the best possible commonly
-                       // available random source, and is available on most *nix systems.
-                       MediaWiki\suppressWarnings();
-                       $urandom = fopen( "/dev/urandom", "rb" );
-                       MediaWiki\restoreWarnings();
-
-                       // Attempt to read all our random data from urandom
-                       // php's fread always does buffered reads based on the stream's chunk_size
-                       // so in reality it will usually read more than the amount of data we're
-                       // asked for and not storing that risks depleting the system's random pool.
-                       // If stream_set_read_buffer is available set the chunk_size to the amount
-                       // of data we need. Otherwise read 8k, php's default chunk_size.
-                       if ( $urandom ) {
-                               // php's default chunk_size is 8k
-                               $chunk_size = 1024 * 8;
-                               if ( function_exists( 'stream_set_read_buffer' ) ) {
-                                       // If possible set the chunk_size to the amount of data we need
-                                       stream_set_read_buffer( $urandom, $rem );
-                                       $chunk_size = $rem;
-                               }
-                               $random_bytes = fread( $urandom, max( $chunk_size, $rem ) );
-                               $buffer .= $random_bytes;
-                               fclose( $urandom );
-                               wfDebug( __METHOD__ . ": /dev/urandom generated " . strlen( $random_bytes ) .
-                                       " bytes of randomness.\n" );
-
-                               if ( strlen( $buffer ) >= $bytes ) {
-                                       // urandom is always strong, set to true if all our data was generated using it
-                                       $this->strong = true;
-                               }
-                       } else {
-                               wfDebug( __METHOD__ . ": /dev/urandom could not be opened.\n" );
-                       }
-               }
-
-               // If we cannot use or generate enough data from a secure source
-               // use this loop to generate a good set of pseudo random data.
-               // This works by initializing a random state using a pile of unstable data
-               // and continually shoving it through a hash along with a variable salt.
-               // We hash the random state with more salt to avoid the state from leaking
-               // out and being used to predict the /randomness/ that follows.
-               if ( strlen( $buffer ) < $bytes ) {
-                       wfDebug( __METHOD__ .
-                               ": Falling back to using a pseudo random state to generate randomness.\n" );
-               }
-               while ( strlen( $buffer ) < $bytes ) {
-                       $buffer .= MWCryptHash::hmac( $this->randomState(), strval( mt_rand() ) );
-                       // This code is never really cryptographically strong, if we use it
-                       // at all, then set strong to false.
-                       $this->strong = false;
-               }
-
-               // Once the buffer has been filled up with enough random data to fulfill
-               // the request shift off enough data to handle the request and leave the
-               // unused portion left inside the buffer for the next request for random data
-               $generated = substr( $buffer, 0, $bytes );
-               $buffer = substr( $buffer, $bytes );
-
-               wfDebug( __METHOD__ . ": " . strlen( $buffer ) .
-                       " bytes of randomness leftover in the buffer.\n" );
-
-               return $generated;
-       }
-
-       /**
-        * @see self::generateHex()
-        */
-       public function realGenerateHex( $chars, $forceStrong = false ) {
-               // hex strings are 2x the length of raw binary so we divide the length in half
-               // odd numbers will result in a .5 that leads the generate() being 1 character
-               // short, so we use ceil() to ensure that we always have enough bytes
-               $bytes = ceil( $chars / 2 );
-               // Generate the data and then convert it to a hex string
-               $hex = bin2hex( $this->generate( $bytes, $forceStrong ) );
-
-               // A bit of paranoia here, the caller asked for a specific length of string
-               // here, and it's possible (eg when given an odd number) that we may actually
-               // have at least 1 char more than they asked for. Just in case they made this
-               // call intending to insert it into a database that does truncation we don't
-               // want to give them too much and end up with their database and their live
-               // code having two different values because part of what we gave them is truncated
-               // hence, we strip out any run of characters longer than what we were asked for.
-               return substr( $hex, 0, $chars );
-       }
-
-       /** Publicly exposed static methods **/
+use MediaWiki\MediaWikiServices;
 
+class MWCryptRand {
        /**
-        * Return a singleton instance of MWCryptRand
-        * @return MWCryptRand
+        * @return CryptRand
         */
        protected static function singleton() {
-               if ( is_null( self::$singleton ) ) {
-                       self::$singleton = new self;
-               }
-
-               return self::$singleton;
+               return MediaWikiServices::getInstance()->getCryptRand();
        }
 
        /**
@@ -385,7 +42,7 @@ class MWCryptRand {
         * @return bool Returns true if the source was strong, false if not.
         */
        public static function wasStrong() {
-               return self::singleton()->realWasStrong();
+               return self::singleton()->wasStrong();
        }
 
        /**
@@ -401,7 +58,7 @@ class MWCryptRand {
         * @return string Raw binary random data
         */
        public static function generate( $bytes, $forceStrong = false ) {
-               return self::singleton()->realGenerate( $bytes, $forceStrong );
+               return self::singleton()->generate( $bytes, $forceStrong );
        }
 
        /**
@@ -417,6 +74,6 @@ class MWCryptRand {
         * @return string Hexadecimal random data
         */
        public static function generateHex( $chars, $forceStrong = false ) {
-               return self::singleton()->realGenerateHex( $chars, $forceStrong );
+               return self::singleton()->generateHex( $chars, $forceStrong );
        }
 }
diff --git a/includes/utils/MWGrants.php b/includes/utils/MWGrants.php
deleted file mode 100644 (file)
index 58efdc7..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-<?php
-/**
- * Functions and constants to deal with grants
- *
- * 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
- */
-
-/**
- * A collection of public static functions to deal with grants.
- */
-class MWGrants {
-
-       /**
-        * List all known grants.
-        * @return array
-        */
-       public static function getValidGrants() {
-               global $wgGrantPermissions;
-
-               return array_keys( $wgGrantPermissions );
-       }
-
-       /**
-        * Map all grants to corresponding user rights.
-        * @return array grant => array of rights
-        */
-       public static function getRightsByGrant() {
-               global $wgGrantPermissions;
-
-               $res = [];
-               foreach ( $wgGrantPermissions as $grant => $rights ) {
-                       $res[$grant] = array_keys( array_filter( $rights ) );
-               }
-               return $res;
-       }
-
-       /**
-        * Fetch the display name of the grant
-        * @param string $grant
-        * @param Language|string|null $lang
-        * @return string Grant description
-        */
-       public static function grantName( $grant, $lang = null ) {
-               // Give grep a chance to find the usages:
-               // grant-blockusers, grant-createeditmovepage, grant-delete,
-               // grant-editinterface, grant-editmycssjs, grant-editmywatchlist,
-               // grant-editpage, grant-editprotected, grant-highvolume,
-               // grant-oversight, grant-patrol, grant-protect, grant-rollback,
-               // grant-sendemail, grant-uploadeditmovefile, grant-uploadfile,
-               // grant-basic, grant-viewdeleted, grant-viewmywatchlist,
-               // grant-createaccount
-               $msg = wfMessage( "grant-$grant" );
-               if ( $lang !== null ) {
-                       if ( is_string( $lang ) ) {
-                               $lang = Language::factory( $lang );
-                       }
-                       $msg->inLanguage( $lang );
-               }
-               if ( !$msg->exists() ) {
-                       $msg = wfMessage( 'grant-generic', $grant );
-                       if ( $lang ) {
-                               $msg->inLanguage( $lang );
-                       }
-               }
-               return $msg->text();
-       }
-
-       /**
-        * Fetch the display names for the grants.
-        * @param string[] $grants
-        * @param Language|string|null $lang
-        * @return string[] Corresponding grant descriptions
-        */
-       public static function grantNames( array $grants, $lang = null ) {
-               if ( $lang !== null ) {
-                       if ( is_string( $lang ) ) {
-                               $lang = Language::factory( $lang );
-                       }
-               }
-
-               $ret = [];
-               foreach ( $grants as $grant ) {
-                       $ret[] = self::grantName( $grant, $lang );
-               }
-               return $ret;
-       }
-
-       /**
-        * Fetch the rights allowed by a set of grants.
-        * @param string[]|string $grants
-        * @return string[]
-        */
-       public static function getGrantRights( $grants ) {
-               global $wgGrantPermissions;
-
-               $rights = [];
-               foreach ( (array)$grants as $grant ) {
-                       if ( isset( $wgGrantPermissions[$grant] ) ) {
-                               $rights = array_merge( $rights, array_keys( array_filter( $wgGrantPermissions[$grant] ) ) );
-                       }
-               }
-               return array_unique( $rights );
-       }
-
-       /**
-        * Test that all grants in the list are known.
-        * @param string[] $grants
-        * @return bool
-        */
-       public static function grantsAreValid( array $grants ) {
-               return array_diff( $grants, self::getValidGrants() ) === [];
-       }
-
-       /**
-        * Divide the grants into groups.
-        * @param string[]|null $grantsFilter
-        * @return array Map of (group => (grant list))
-        */
-       public static function getGrantGroups( $grantsFilter = null ) {
-               global $wgGrantPermissions, $wgGrantPermissionGroups;
-
-               if ( is_array( $grantsFilter ) ) {
-                       $grantsFilter = array_flip( $grantsFilter );
-               }
-
-               $groups = [];
-               foreach ( $wgGrantPermissions as $grant => $rights ) {
-                       if ( $grantsFilter !== null && !isset( $grantsFilter[$grant] ) ) {
-                               continue;
-                       }
-                       if ( isset( $wgGrantPermissionGroups[$grant] ) ) {
-                               $groups[$wgGrantPermissionGroups[$grant]][] = $grant;
-                       } else {
-                               $groups['other'][] = $grant;
-                       }
-               }
-
-               return $groups;
-       }
-
-       /**
-        * Get the list of grants that are hidden and should always be granted
-        * @return string[]
-        */
-       public static function getHiddenGrants() {
-               global $wgGrantPermissionGroups;
-
-               $grants = [];
-               foreach ( $wgGrantPermissionGroups as $grant => $group ) {
-                       if ( $group === 'hidden' ) {
-                               $grants[] = $grant;
-                       }
-               }
-               return $grants;
-       }
-
-       /**
-        * Generate a link to Special:ListGrants for a particular grant name.
-        *
-        * This should be used to link end users to a full description of what
-        * rights they are giving when they authorize a grant.
-        *
-        * @param string $grant the grant name
-        * @param Language|string|null $lang
-        * @return string (proto-relative) HTML link
-        */
-       public static function getGrantsLink( $grant, $lang = null ) {
-               return \Linker::linkKnown(
-                       \SpecialPage::getTitleFor( 'Listgrants', false, $grant ),
-                       htmlspecialchars( self::grantName( $grant, $lang ) )
-               );
-       }
-
-       /**
-        * Generate wikitext to display a list of grants
-        * @param string[]|null $grantsFilter If non-null, only display these grants.
-        * @param Language|string|null $lang
-        * @return string Wikitext
-        */
-       public static function getGrantsWikiText( $grantsFilter, $lang = null ) {
-               global $wgContLang;
-
-               if ( is_string( $lang ) ) {
-                       $lang = Language::factory( $lang );
-               } elseif ( $lang === null ) {
-                       $lang = $wgContLang;
-               }
-
-               $s = '';
-               foreach ( self::getGrantGroups( $grantsFilter ) as $group => $grants ) {
-                       if ( $group === 'hidden' ) {
-                               continue; // implicitly granted
-                       }
-                       $s .= "*<span class=\"mw-grantgroup\">" .
-                               wfMessage( "grant-group-$group" )->inLanguage( $lang )->text() . "</span>\n";
-                       $s .= ":" . $lang->semicolonList( self::grantNames( $grants, $lang ) ) . "\n";
-               }
-               return "$s\n";
-       }
-
-}
index abba5a1..c6d1a54 100644 (file)
@@ -21,6 +21,7 @@
  * @author Aaron Schulz
  */
 use Wikimedia\Assert\Assert;
+use MediaWiki\MediaWikiServices;
 
 /**
  * Class for getting statistically unique IDs
@@ -55,13 +56,13 @@ class UIDGenerator {
                if ( !preg_match( '/^[0-9a-f]{12}$/i', $nodeId ) ) {
                        MediaWiki\suppressWarnings();
                        if ( wfIsWindows() ) {
-                               // http://technet.microsoft.com/en-us/library/bb490913.aspx
+                               // https://technet.microsoft.com/en-us/library/bb490913.aspx
                                $csv = trim( wfShellExec( 'getmac /NH /FO CSV' ) );
                                $line = substr( $csv, 0, strcspn( $csv, "\n" ) );
                                $info = str_getcsv( $line );
                                $nodeId = isset( $info[0] ) ? str_replace( '-', '', $info[0] ) : '';
                        } elseif ( is_executable( '/sbin/ifconfig' ) ) { // Linux/BSD/Solaris/OS X
-                               // See http://linux.die.net/man/8/ifconfig
+                               // See https://linux.die.net/man/8/ifconfig
                                $m = [];
                                preg_match( '/\s([0-9a-f]{2}(:[0-9a-f]{2}){5})\s/',
                                        wfShellExec( '/sbin/ifconfig -a' ), $m );
@@ -368,7 +369,7 @@ class UIDGenerator {
                // Counter values would not survive accross script instances in CLI mode.
                $cache = null;
                if ( ( $flags & self::QUICK_VOLATILE ) && PHP_SAPI !== 'cli' ) {
-                       $cache = ObjectCache::getLocalServerInstance();
+                       $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
                }
                if ( $cache ) {
                        $counter = $cache->incrWithInit( $bucket, $cache::TTL_INDEFINITE, $count, $count );
@@ -516,7 +517,7 @@ class UIDGenerator {
        protected function timeWaitUntil( array $time ) {
                do {
                        $ct = self::millitime();
-                       if ( $ct >= $time ) { // http://php.net/manual/en/language.operators.comparison.php
+                       if ( $ct >= $time ) { // https://secure.php.net/manual/en/language.operators.comparison.php
                                return $ct; // current timestamp is higher than $time
                        }
                } while ( ( ( $time[0] - $ct[0] ) * 1000 + ( $time[1] - $ct[1] ) ) <= 10 );
@@ -553,9 +554,9 @@ class UIDGenerator {
                        $ts = ( 1000 * $sec + $msec ) * 10000 + (int)$offset + $delta;
                        $id_bin = str_pad( decbin( $ts % pow( 2, 60 ) ), 60, '0', STR_PAD_LEFT );
                } elseif ( extension_loaded( 'gmp' ) ) {
-                       $ts = gmp_add( gmp_mul( (string) $sec, '1000' ), (string) $msec ); // ms
+                       $ts = gmp_add( gmp_mul( (string)$sec, '1000' ), (string)$msec ); // ms
                        $ts = gmp_add( gmp_mul( $ts, '10000' ), $offset ); // 100ns intervals
-                       $ts = gmp_add( $ts, (string) $delta );
+                       $ts = gmp_add( $ts, (string)$delta );
                        $ts = gmp_mod( $ts, gmp_pow( '2', '60' ) ); // wrap around
                        $id_bin = str_pad( gmp_strval( $ts, 2 ), 60, '0', STR_PAD_LEFT );
                } elseif ( extension_loaded( 'bcmath' ) ) {
diff --git a/includes/utils/iterators/IteratorDecorator.php b/includes/utils/iterators/IteratorDecorator.php
deleted file mode 100644 (file)
index c1b5020..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-/**
- * Allows extending classes to decorate an Iterator with
- * reduced boilerplate.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Maintenance
- */
-abstract class IteratorDecorator implements Iterator {
-       protected $iterator;
-
-       public function __construct( Iterator $iterator ) {
-               $this->iterator = $iterator;
-       }
-
-       public function current() {
-               return $this->iterator->current();
-       }
-
-       public function key() {
-               return $this->iterator->key();
-       }
-
-       public function next() {
-               $this->iterator->next();
-       }
-
-       public function rewind() {
-               $this->iterator->rewind();
-       }
-
-       public function valid() {
-               return $this->iterator->valid();
-       }
-}
diff --git a/includes/utils/iterators/NotRecursiveIterator.php b/includes/utils/iterators/NotRecursiveIterator.php
deleted file mode 100644 (file)
index 52ca61b..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/**
- * Wraps a non-recursive iterator with methods to be recursive
- * without children.
- *
- * Alternatively wraps a recursive iterator to prevent recursing deeper
- * than the wrapped iterator.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Maintenance
- */
-class NotRecursiveIterator extends IteratorDecorator implements RecursiveIterator {
-       public function hasChildren() {
-               return false;
-       }
-
-       public function getChildren() {
-               return null;
-       }
-}
index ca188ba..2490b9d 100644 (file)
@@ -5,6 +5,7 @@ Bartosz Dziewoński <bdziewonski@wikimedia.org>
 Brad Jorsch <bjorsch@wikimedia.org>
 Ed Sanders <esanders@wikimedia.org>
 Florian Schmidt <florian.schmidt.welzow@t-online.de>
+Geoffrey Mon <geofbot@gmail.com>
 James D. Forrester <jforrester@wikimedia.org>
 Roan Kattouw <roan@wikimedia.org>
 Sucheta Ghoshal <sghoshal@wikimedia.org>
diff --git a/includes/widget/DateInputWidget.php b/includes/widget/DateInputWidget.php
new file mode 100644 (file)
index 0000000..f011f0b
--- /dev/null
@@ -0,0 +1,165 @@
+<?php
+/**
+ * MediaWiki Widgets – DateInputWidget class.
+ *
+ * @copyright 2016 MediaWiki Widgets Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+namespace MediaWiki\Widget;
+
+use DateTime;
+
+/**
+ * Date input widget.
+ *
+ * @since 1.29
+ */
+class DateInputWidget extends \OOUI\TextInputWidget {
+
+       protected $inputFormat = null;
+       protected $displayFormat = null;
+       protected $placeholderLabel = null;
+       protected $placeholderDateFormat = null;
+       protected $precision = null;
+       protected $mustBeAfter = null;
+       protected $mustBeBefore = null;
+       protected $overlay = null;
+
+       /**
+        * @param array $config Configuration options
+        * @param string $config['inputFormat'] Date format string to use for the textual input field.
+        *   Displayed while the widget is active, and the user can type in a date in this format.
+        *   Should be short and easy to type. (default: 'YYYY-MM-DD' or 'YYYY-MM', depending on
+        *   `precision`)
+        * @param string $config['displayFormat'] Date format string to use for the clickable label.
+        *   while the widget is inactive. Should be as unambiguous as possible (for example, prefer
+        *   to spell out the month, rather than rely on the order), even if that makes it longer.
+        *   Applicable only if the widget is infused. (default: language-specific)
+        * @param string $config['placeholderLabel'] Placeholder text shown when the widget is not
+        *   selected. Applicable only if the widget is infused. (default: taken from message
+        *   `mw-widgets-dateinput-no-date`)
+        * @param string $config['placeholderDateFormat'] User-visible date format string displayed
+        *   in the textual input field when it's empty. Should be the same as `inputFormat`, but
+        *   translated to the user's language. (default: 'YYYY-MM-DD' or 'YYYY-MM', depending on
+        *   `precision`)
+        * @param string $config['precision'] Date precision to use, 'day' or 'month' (default: 'day')
+        * @param string $config['mustBeAfter'] Validates the date to be after this.
+        *   In the 'YYYY-MM-DD' or 'YYYY-MM' format, depending on `precision`.
+        * @param string $config['mustBeBefore'] Validates the date to be before this.
+        *   In the 'YYYY-MM-DD' or 'YYYY-MM' format, depending on `precision`.
+        * @param string $config['overlay'] The jQuery selector for the overlay layer on which to render
+        *   the calendar. This configuration is useful in cases where the expanded calendar is larger
+        *   than its container. The specified overlay layer is usually on top of the container and has
+        *   a larger area. Applicable only if the widget is infused. By default, the calendar uses
+        *   relative positioning.
+        */
+       public function __construct( array $config = [] ) {
+               $config = array_merge( [
+                       // Default config values
+                       'precision' => 'day',
+               ], $config );
+
+               // Properties
+               if ( isset( $config['inputFormat'] ) ) {
+                       $this->inputFormat = $config['inputFormat'];
+               }
+               if ( isset( $config['placeholderDateFormat'] ) ) {
+                       $this->placeholderDateFormat = $config['placeholderDateFormat'];
+               }
+               $this->precision = $config['precision'];
+               if ( isset( $config['mustBeAfter'] ) ) {
+                       $this->mustBeAfter = $config['mustBeAfter'];
+               }
+               if ( isset( $config['mustBeBefore'] ) ) {
+                       $this->mustBeBefore = $config['mustBeBefore'];
+               }
+
+               // Properties stored for the infused JS widget
+               if ( isset( $config['displayFormat'] ) ) {
+                       $this->displayFormat = $config['displayFormat'];
+               }
+               if ( isset( $config['placeholderLabel'] ) ) {
+                       $this->placeholderLabel = $config['placeholderLabel'];
+               }
+               if ( isset( $config['overlay'] ) ) {
+                       $this->overlay = $config['overlay'];
+               }
+
+               // Set up placeholder text visible if the browser doesn't override it (logic taken from JS)
+               if ( $this->placeholderDateFormat !== null ) {
+                       $placeholder = $this->placeholderDateFormat;
+               } elseif ( $this->inputFormat !== null ) {
+                       // We have no way to display a translated placeholder for custom formats
+                       $placeholder = '';
+               } else {
+                       $placeholder = wfMessage( "mw-widgets-dateinput-placeholder-$this->precision" )->text();
+               }
+
+               $config = array_merge( [
+                       // Processed config values
+                       'placeholder' => $placeholder,
+               ], $config );
+
+               // Parent constructor
+               parent::__construct( $config );
+
+               // Calculate min/max attributes (which are skipped by TextInputWidget) and add to <input>
+               // min/max attributes are inclusive, but mustBeAfter/Before are exclusive
+               if ( $this->mustBeAfter !== null ) {
+                       $min = new DateTime( $this->mustBeAfter );
+                       $min = $min->modify( '+1 day' );
+                       $min = $min->format( 'Y-m-d' );
+                       $this->input->setAttributes( [ 'min' => $min ] );
+               }
+               if ( $this->mustBeBefore !== null ) {
+                       $max = new DateTime( $this->mustBeBefore );
+                       $max = $max->modify( '-1 day' );
+                       $max = $max->format( 'Y-m-d' );
+                       $this->input->setAttributes( [ 'max' => $max ] );
+               }
+
+               // Initialization
+               $this->addClasses( [ 'mw-widget-dateInputWidget' ] );
+       }
+
+       protected function getJavaScriptClassName() {
+               return 'mw.widgets.DateInputWidget';
+       }
+
+       public function getConfig( &$config ) {
+               if ( $this->inputFormat !== null ) {
+                       $config['inputFormat'] = $this->inputFormat;
+               }
+               if ( $this->displayFormat !== null ) {
+                       $config['displayFormat'] = $this->displayFormat;
+               }
+               if ( $this->placeholderLabel !== null ) {
+                       $config['placeholderLabel'] = $this->placeholderLabel;
+               }
+               if ( $this->placeholderDateFormat !== null ) {
+                       $config['placeholderDateFormat'] = $this->placeholderDateFormat;
+               }
+               if ( $this->precision !== null ) {
+                       $config['precision'] = $this->precision;
+               }
+               if ( $this->mustBeAfter !== null ) {
+                       $config['mustBeAfter'] = $this->mustBeAfter;
+               }
+               if ( $this->mustBeBefore !== null ) {
+                       $config['mustBeBefore'] = $this->mustBeBefore;
+               }
+               if ( $this->overlay !== null ) {
+                       $config['overlay'] = $this->overlay;
+               }
+               return parent::getConfig( $config );
+       }
+
+       public function getInputElement( $config ) {
+               // Inserts date/month type attribute
+               return parent::getInputElement( $config )
+                       ->setAttributes( [
+                               'type' => ( $config['precision'] === 'month' ) ? 'month' : 'date'
+                       ] );
+       }
+}
index 3e28759..2e4ef89 100644 (file)
@@ -137,6 +137,12 @@ class Language {
         */
        static private $fallbackLanguageCache = [];
 
+       /**
+        * Cache for grammar rules data
+        * @var MapCacheLRU|null
+        */
+       static private $grammarTransformations;
+
        /**
         * Cache for language names
         * @var HashBagOStuff|null
@@ -291,7 +297,7 @@ class Language {
                # Since these are limited, this is safe even later changes to the registry --
                # the only oddity is that it might change the type of the tag, and thus
                # the results from the capturing groups.
-               # http://www.iana.org/assignments/language-subtag-registry
+               # https://www.iana.org/assignments/language-subtag-registry
 
                $grandfathered = "en{$s}GB{$s}oed"
                        . "|i{$s}(?:ami|bnn|default|enochian|hak|klingon|lux|mingo|navajo|pwn|tao|tay|tsu)"
@@ -332,7 +338,7 @@ class Language {
                        // People think language codes are html safe, so enforce it.
                        // Ideally we should only allow a-zA-Z0-9-
                        // but, .+ and other chars are often used for {{int:}} hacks
-                       // see bugs 37564, 37587, 36938
+                       // see bugs T39564, T39587, T38938
                        $cache[$code] =
                                // Protect against path traversal
                                strcspn( $code, ":/\\\000&<>'\"" ) === strlen( $code )
@@ -1623,7 +1629,7 @@ class Language {
         *
         * Based on a PHP-Nuke block by Sharjeel which is released under GNU/GPL license
         *
-        * @see http://phpnuke.org/modules.php?name=News&file=article&sid=8234&mode=thread&order=0&thold=0
+        * @see https://phpnuke.org/modules.php?name=News&file=article&sid=8234&mode=thread&order=0&thold=0
         *
         * @param string $ts
         *
@@ -1852,9 +1858,9 @@ class Language {
         * Algorithm to convert Gregorian dates to Thai solar dates,
         * Minguo dates or Minguo dates.
         *
-        * Link: http://en.wikipedia.org/wiki/Thai_solar_calendar
-        *       http://en.wikipedia.org/wiki/Minguo_calendar
-        *       http://en.wikipedia.org/wiki/Japanese_era_name
+        * Link: https://en.wikipedia.org/wiki/Thai_solar_calendar
+        *       https://en.wikipedia.org/wiki/Minguo_calendar
+        *       https://en.wikipedia.org/wiki/Japanese_era_name
         *
         * @param string $ts 14-character timestamp
         * @param string $cName Calender name
@@ -2593,7 +2599,7 @@ class Language {
        public function iconv( $in, $out, $string ) {
                # Even with //IGNORE iconv can whine about illegal characters in
                # *input* string. We just ignore those too.
-               # REF: http://bugs.php.net/bug.php?id=37166
+               # REF: https://bugs.php.net/bug.php?id=37166
                # REF: https://phabricator.wikimedia.org/T18885
                MediaWiki\suppressWarnings();
                $text = iconv( $in, $out . '//IGNORE', $string );
@@ -3730,6 +3736,7 @@ class Language {
 
                return $word;
        }
+
        /**
         * Get the grammar forms for the content language
         * @return array Array of grammar forms
@@ -3745,6 +3752,46 @@ class Language {
 
                return [];
        }
+
+       /**
+        * Get the grammar transformations data for the language.
+        * Used like grammar forms, with {{GRAMMAR}} and cases,
+        * but uses pairs of regexes and replacements instead of code.
+        *
+        * @return array[] Array of grammar transformations.
+        * @throws MWException
+        * @since 1.28
+        */
+       public function getGrammarTransformations() {
+               $languageCode = $this->getCode();
+
+               if ( self::$grammarTransformations === null ) {
+                       self::$grammarTransformations = new MapCacheLRU( 10 );
+               }
+
+               if ( self::$grammarTransformations->has( $languageCode ) ) {
+                       return self::$grammarTransformations->get( $languageCode );
+               }
+
+               $data = [];
+
+               $grammarDataFile = __DIR__ . "/data/grammarTransformations/$languageCode.json";
+               if ( is_readable( $grammarDataFile ) ) {
+                       $data = FormatJson::decode(
+                               file_get_contents( $grammarDataFile ),
+                               true
+                       );
+
+                       if ( $data === null ) {
+                               throw new MWException( "Invalid grammar data for \"$languageCode\"." );
+                       }
+
+                       self::$grammarTransformations->set( $languageCode, $data );
+               }
+
+               return $data;
+       }
+
        /**
         * Provides an alternative text depending on specified gender.
         * Usage {{gender:username|masculine|feminine|unknown}}.
@@ -4461,14 +4508,15 @@ class Language {
        }
 
        /**
-        * @todo Document
+        * Formats a time given in seconds into a string representation of that time.
+        *
         * @param int|float $seconds
-        * @param array $format Optional
-        *   If $format['avoid'] === 'avoidseconds': don't mention seconds if $seconds >= 1 hour.
-        *   If $format['avoid'] === 'avoidminutes': don't mention seconds/minutes if $seconds > 48 hours.
+        * @param array $format An optional argument that formats the returned string in different ways:
+        *   If $format['avoid'] === 'avoidseconds': don't show seconds if $seconds >= 1 hour,
+        *   If $format['avoid'] === 'avoidminutes': don't show seconds/minutes if $seconds > 48 hours,
         *   If $format['noabbrevs'] is true: use 'seconds' and friends instead of 'seconds-abbrev'
         *     and friends.
-        *   For backwards compatibility, $format may also be one of the strings 'avoidseconds'
+        * @note For backwards compatibility, $format may also be one of the strings 'avoidseconds'
         *     or 'avoidminutes'.
         * @return string
         */
index 13ba7e8..5a9f652 100644 (file)
@@ -18,6 +18,7 @@
  * @file
  * @ingroup Language
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * Base class for language conversion.
@@ -47,7 +48,9 @@ class LanguageConverter {
        ];
 
        public $mMainLanguageCode;
-       public $mVariants, $mVariantFallbacks, $mVariantNames;
+       public $mVariants;
+       public $mVariantFallbacks;
+       public $mVariantNames;
        public $mTablesLoaded = false;
        public $mTables;
        // 'bidirectional' 'unidirectional' 'disable' for each variant
@@ -550,8 +553,8 @@ class LanguageConverter {
                        $variant = $this->getPreferredVariant();
                }
 
-               $cache = ObjectCache::newAccelerator( CACHE_NONE );
-               $key = wfMemcKey( 'languageconverter', 'namespace-text', $index, $variant );
+               $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
+               $key = $cache->makeKey( 'languageconverter', 'namespace-text', $index, $variant );
                $nsVariantText = $cache->get( $key );
                if ( $nsVariantText !== false ) {
                        return $nsVariantText;
index 4003bdd..a2288d0 100644 (file)
@@ -28,7 +28,7 @@
  *
  *
  * Based on:
- *   - http://commons.wikimedia.org/wiki/Image:Inuktitut.png
+ *   - https://commons.wikimedia.org/wiki/Image:Inuktitut.png
  *   - LanguageSr.php
  *
  * @ingroup Language
index 60384a8..62de390 100644 (file)
@@ -31,7 +31,6 @@
  * @ingroup Language
  */
 class LanguageRu extends Language {
-
        /**
         * Convert from the nominative form of a noun to some other case
         * Invoked with {{grammar:case|word}}
@@ -46,19 +45,22 @@ class LanguageRu extends Language {
                        return $wgGrammarForms['ru'][$case][$word];
                }
 
-               $grammarDataFile = __DIR__ . '/data/grammar.ru.json';
-               $grammarData = FormatJson::decode( file_get_contents( $grammarDataFile ), true );
+               $grammarTransformations = $this->getGrammarTransformations();
+
+               if ( isset( $grammarTransformations[$case] ) ) {
+                       foreach ( array_values( $grammarTransformations[$case] ) as $rule ) {
+                               $form = $rule[0];
 
-               if ( array_key_exists( $case, $grammarData ) ) {
-                       foreach ( array_keys( $grammarData[$case] ) as $form ) {
                                if ( $form === '@metadata' ) {
                                        continue;
                                }
 
+                               $replacement = $rule[1];
+
                                $regex = "/$form/";
 
                                if ( preg_match( $regex, $word ) ) {
-                                       $word = preg_replace( $regex, $grammarData[$case][$form], $word );
+                                       $word = preg_replace( $regex, $replacement, $word );
 
                                        break;
                                }
@@ -70,7 +72,7 @@ class LanguageRu extends Language {
 
        /**
         * Four-digit number should be without group commas (spaces)
-        * See manual of style at http://ru.wikipedia.org/wiki/Википедия:Оформление_статей
+        * See manual of style at https://ru.wikipedia.org/wiki/Википедия:Оформление_статей
         * So "1 234 567", "12 345" but "1234"
         *
         * @param string $_
index 61aba70..0de396d 100644 (file)
@@ -28,7 +28,7 @@
  *
  *
  * Based on:
- *   - http://en.wikipedia.org/wiki/Shilha_language
+ *   - https://en.wikipedia.org/wiki/Shilha_language
  *   - LanguageSr.php
  *
  * @ingroup Language
index fc91443..886ee94 100644 (file)
@@ -186,7 +186,6 @@ class SrConverter extends LanguageConverter {
                } else {
                        return false;
                }
-
        }
 
 }
index c947341..42ee44d 100644 (file)
@@ -27,7 +27,7 @@
  * Turkish has two different i, one with a dot and another without a dot. They
  * are totally different letters in this language, so we have to override the
  * ucfirst and lcfirst methods.
- * See http://en.wikipedia.org/wiki/Dotted_and_dotless_I
+ * See https://en.wikipedia.org/wiki/Dotted_and_dotless_I
  * and @bug 28040
  * @ingroup Language
  */
index d9111a6..e1099f8 100644 (file)
@@ -174,7 +174,6 @@ class LanguageZh extends LanguageZh_hans {
         * @return string
         */
        function normalizeForSearch( $string, $autoVariant = 'zh-hans' ) {
-
                // always convert to zh-hans before indexing. it should be
                // better to use zh-hans for search, since conversion from
                // Traditional to Simplified is less ambiguous than the
@@ -183,7 +182,6 @@ class LanguageZh extends LanguageZh_hans {
                // LanguageZh_hans::normalizeForSearch
                $s = parent::normalizeForSearch( $s );
                return $s;
-
        }
 
        /**
diff --git a/languages/classes/data/grammar.ru.json b/languages/classes/data/grammar.ru.json
deleted file mode 100644 (file)
index 446163b..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-       "@metadata": {
-               "authors": [
-                       "Alexander Sigachov (alexander.sigachov at Googgle Mail)",
-                       "Amir E. Aharoni (amir.aharoni@mail.huji.ac.il)"
-               ],
-               "comment": "These rules don't cover the whole grammar of the language, and are intended only for names of languages and Wikimedia projects."
-       },
-       "genitive": {
-               "(.+)ь$": "$1я",
-               "(.+)ия$": "$1ии",
-               "(.+)ка$": "$1ки",
-               "(.+)ти$": "$1тей",
-               "(.+)ды$": "$1дов",
-               "(.+)д$": "$1да",
-               "(.+)ник$": "$1ника",
-               "(.+)ные$": "$1ных"
-       },
-       "prepositional": {
-               "(.+)ь$": "$1е",
-               "(.+)ия$": "$1ии",
-               "(.+)ка$": "$1ке",
-               "(.+)ти$": "$1тях",
-               "(.+)ды$": "$1дах",
-               "(.+)д$": "$1де",
-               "(.+)ник$": "$1нике",
-               "(.+)ные$": "$1ных"
-       },
-       "languagegen": {
-               "@metadata": "язык в родительном падеже: '(с) русского'",
-               "(.+)кий$": "$1кого",
-               "иврит$": "иврита",
-               "идиш$": "идиша",
-               "(.+)$": "$1"
-       },
-       "languageprep": {
-               "@metadata": "язык в предложном падеже: '(на) русском'",
-               "(.+)кий$": "$1ком",
-               "иврит$": "иврите",
-               "идиш$": "идише",
-               "(.+)$": "$1"
-       },
-       "languageadverb": {
-               "@metadata": "наречие с названием языка: 'по-русски'",
-               "(.+)кий$": "по-$1ки",
-               "иврит$": "на иврите",
-               "идиш$": "на идише",
-               "(идо|урду|хинди|эсперанто)$": "на $1",
-               "(.+)$": "на языке $1"
-       }
-}
index 836fb86..0557455 100644 (file)
@@ -174,6 +174,7 @@ class Names {
                'gom' => 'गोंयची कोंकणी / Gõychi Konknni', # Goan Konkani
                'gom-deva' => 'गोंयची कोंकणी', # Goan Konkani (Devanagari script)
                'gom-latn' => 'Gõychi Konknni', # Goan Konkani (Latin script)
+               'gor' => 'Bahasa Hulontalo', # Gorontalo
                'got' => '𐌲𐌿𐍄𐌹𐍃𐌺', # Gothic
                'grc' => 'Ἀρχαία ἑλληνικὴ', # Ancient Greek
                'gsw' => 'Alemannisch', # Alemannic
@@ -241,6 +242,7 @@ class Names {
                'krc' => 'къарачай-малкъар', # Karachay-Balkar
                'kri' => 'Krio', # Krio
                'krj' => 'Kinaray-a', # Kinaray-a
+               'krl' => 'karjal', # Karelian
                'ks' => 'कॉशुर / کٲشُر', # Kashmiri (multiple scripts - defaults to Perso-Arabic)
                'ks-arab' => 'کٲشُر', # Kashmiri (Perso-Arabic script)
                'ks-deva' => 'कॉशुर', # Kashmiri (Devanagari script)
@@ -316,7 +318,7 @@ class Names {
                'nv' => 'Diné bizaad', # Navajo
                'ny' => 'Chi-Chewa', # Chichewa
                'oc' => 'occitan', # Occitan
-               'olo' => 'Livvinкarjala', # Livvi-Karelian
+               'olo' => 'Livvinkarjala', # Livvi-Karelian
                'om' => 'Oromoo', # Oromo
                'or' => 'ଓଡ଼ିଆ', # Oriya
                'os' => 'Ирон', # Ossetic, bug 29091
diff --git a/languages/data/grammarTransformations/ru.json b/languages/data/grammarTransformations/ru.json
new file mode 100644 (file)
index 0000000..deb58b7
--- /dev/null
@@ -0,0 +1,57 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Alexander Sigachov (alexander.sigachov at Googgle Mail)",
+                       "Amir E. Aharoni (amir.aharoni@mail.huji.ac.il)"
+               ],
+               "comment": "These rules don't cover the whole grammar of the language, and are intended only for names of languages and Wikimedia projects."
+       },
+       "genitive": [
+               [ "(.+)ь$", "$1я" ],
+               [ "(.+)ия$", "$1ии" ],
+               [ "(.+)ка$", "$1ки" ],
+               [ "(.+)ти$", "$1тей" ],
+               [ "(.+)ды$", "$1дов" ],
+               [ "(.+)д$", "$1да" ],
+               [ "(.+)ник$", "$1ника" ],
+               [ "(.+)ные$", "$1ных" ]
+       ],
+       "prepositional": [
+               [ "(.+)ь$", "$1е" ],
+               [ "(.+)ия$", "$1ии" ],
+               [ "(.+)ка$", "$1ке" ],
+               [ "(.+)ти$", "$1тях" ],
+               [ "(.+)ды$", "$1дах" ],
+               [ "(.+)д$", "$1де" ],
+               [ "(.+)ник$", "$1нике" ],
+               [ "(.+)ные$", "$1ных" ]
+       ],
+       "languagegen": [
+               [ "@metadata", [
+                       "comment", "язык в родительном падеже: '(с) русского'"
+               ] ],
+               [ "(.+)кий$", "$1кого" ],
+               [ "иврит$", "иврита" ],
+               [ "идиш$", "идиша" ],
+               [ "(.+)$", "$1" ]
+       ],
+       "languageprep": [
+               [ "@metadata", [
+                       "comment", "язык в предложном падеже: '(на) русском'"
+               ] ],
+               [ "(.+)кий$", "$1ком" ],
+               [ "иврит$", "иврите" ],
+               [ "идиш$", "идише" ],
+               [ "(.+)$", "$1" ]
+       ],
+       "languageadverb": [
+               [ "@metadata", [
+                       "comment", "наречие с названием языка: 'по-русски'"
+               ] ],
+               [ "(.+)кий$", "по-$1ки" ],
+               [ "иврит$", "на иврите" ],
+               [ "идиш$", "на идише" ],
+               [ "(идо|урду|хинди|эсперанто)$", "на $1" ],
+               [ "(.+)$", "на языке $1" ]
+       ]
+}
index 88eb4bf..4f0b535 100644 (file)
        "preview": "Eu dilèë",
        "showpreview": "Peuleumah hasé",
        "showdiff": "Peuleumah neuubah",
-       "anoneditwarning": "Droëneuh   hana teudapeuta tamong. Alamat IP Droëneuh   teucatat lam tarèh (riwayat away) ôn nyoë.",
+       "anoneditwarning": "<strong>Peuneugah:</strong> Droëneuh hana lom neutamong. Alamat IP-neuh jeuët deuh bak ureuëng la'én meunyö neumeuandam. Meunyö Droëneuh <strong>[$1 neutamong]</strong> atawa <strong>[$2 neudapeuta]</strong>, neuandamneuh jeuët teutuléh ateuëh nan Droëneuh ngön na lom meunapha'at nyang la'én.",
        "missingcommenttext": "Neupasoë beunalah di yup.",
        "summary-preview": "Eu dilèë neuringkaih:",
        "blockedtitle": "Ureueng ngui geutheun",
        "activeusers-intro": "Nyoë nakeuh dapeuta ureuëng ngui nyang na geuteumuléh lam $1 {{PLURAL:$1|uroë}} nyoë.",
        "activeusers-count": "$1 {{PLURAL:$1|buet}} lam {{PLURAL:$3|uroë|$3 uroë}} nyoë",
        "activeusers-from": "Peuleumah ureueng ngui nyang neuawai ngön:",
-       "activeusers-hidebots": "Peusom bot",
-       "activeusers-hidesysops": "Peusom ureueng urôh",
        "activeusers-noresult": "Hana ureueng ngui nyang meutumèe.",
        "listgrouprights": "Dapeuta khut ureueng ngui",
        "listgrouprights-key": "Teuneurang:\n* <span class=\"listgrouprights-granted\">Khut nyang geubri</span>\n* <span class=\"listgrouprights-revoked\">Khut nyang hana geubri</span>",
        "tooltip-t-recentchangeslinked": "Neuubah barô lam laman nyang meupawôt nibak laman nyoë",
        "tooltip-feed-rss": "Umpeuën RSS keu laman nyoë",
        "tooltip-feed-atom": "Umpeuën Atom keu miëng nyoë",
-       "tooltip-t-contributions": "Dapeuta beuneuri ureuëng ngui nyoë",
+       "tooltip-t-contributions": "Dapeuta beuneuri {{GENDER:$1|ureuëng ngui nyoë}}",
        "tooltip-t-emailuser": "Peu'ét surat-e keu ureuëng ngui nyoë",
        "tooltip-t-upload": "Peutamong beureukaih",
        "tooltip-t-specialpages": "Dapeuta ban dum miëng kusuih",
        "exif-xresolution": "Resolusi linteuëng",
        "exif-yresolution": "Rèsolusi buju",
        "exif-datetime": "Uroë buleuën ngön watèë neuubah beureukaih",
+       "exif-make": "Pabrék kamèra",
+       "exif-model": "Moden kamèra",
        "exif-software": "Software geungui",
        "exif-exifversion": "Versi Exif",
        "exif-colorspace": "Ruweuëng wareuna",
        "tag-filter": "Saréng [[Special:Tags|tag]]:",
        "tag-filter-submit": "Saréng",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag}}]]: $2)",
+       "logentry-delete-delete": "$1 {{GENDER:$2|geusampôh}} miëng $3",
        "logentry-newusers-create": "$1 {{GENDER:$2|geupeugöt}} akun ureuëng ngui",
        "searchsuggest-search": "Mita",
        "duration-seconds": "{{PLURAL:$1|deutik}}",
index eb15a0e..a5c7dd0 100644 (file)
        "passwordreset-emailtitle": "Аккаунт и гъэпсыкIэхэр, мий щыI {{SITENAME}}",
        "passwordreset-emailelement": "НэбгырацIэ: \n$1\n\nTemporary password: \n$2",
        "passwordreset-emailsentemail": "Мыр регистрыгъэ емэйлэу щытмэ уи аккаунтым пае, шъэфгущыIэм и зэтедз емэйл къыпфагъэхьыщт.",
-       "passwordreset-emailsent-capture": "ШъэфгущыIэм изэтедз фэгъэхьыгъэ емэйлыр гъахьыгъэ, ычIэгъкIэ ар олъэгъу.",
        "changeemail": "Зэблэхъу е тегъэкI емэйл адресыр",
        "changeemail-no-info": "Мы нэкIубгъом занкIэу укIонэу уфаемэ, системэм ухэхьэгъэн фае.",
        "changeemail-oldemail": "Джырэ емэйл адрес:",
        "content-model-javascript": "JavaScript",
        "content-json-empty-object": "Объект нэкI",
        "content-json-empty-array": "Массив нэкI",
-       "cantcreateaccounttitle": "Аккаунт ублэн лъэкIыгъэп",
        "viewpagelogs": "Мы нэкӏубгъом и логхэр къэгъэлъагъу",
        "nohistory": "Мы нэкIубгъом и еIэзэнмэ я тарихъ щыIэп.",
        "currentrev": "Ыужрэ версие",
        "linksearch-ok": "Лъыхъу",
        "listusers-submit": "Къэгъэлъагъу",
        "listusers-noresult": "Нэбгырэ пари гъотыгъэп.",
-       "activeusers-hidebots": "Ботхэр гъэбылъ",
-       "activeusers-hidesysops": "Администраторхэр гъэбылъ",
        "activeusers-noresult": "Нэбгырэ пари гъотыгъэп.",
        "listgrouprights": "Нэбгырэмэ якупмэ яфитыныгъэхэр",
        "listgrouprights-group": "Куп",
index cb869d0..794eae2 100644 (file)
        "yourname": "اسم المستخدم:",
        "yourpassword": "كلمة السر:",
        "yourpasswordagain": "أعد كتابة كلمة السر:",
-       "remembermypassword": "تذكر دخولي على هذا الحاسوب (إلى {{PLURAL:$1||يوم واحد|يومين|$1 أيام|$1 يومًا|$1 يوم}} كحد أقصى)",
        "yourdomainname": "نطاقك:",
        "externaldberror": "هناك إما خطأ في دخول قاعدة البيانات الخارجية أو أنه غير مسموح لك بتحديث حسابك الخارجي.",
        "login": "ادخل",
index d6534b6..a905b3c 100644 (file)
        "yourpasswordagain": "Herhaal wagwoord",
        "createacct-yourpasswordagain": "Bevestig wagwoord",
        "createacct-yourpasswordagain-ph": "Sleutel weer u wagwoord in",
-       "remembermypassword": "Onthou dat ek op hierdie rekenaar ingeteken het (vir 'n maksimum van $1 {{PLURAL:$1|dag|dae}})",
        "userlogin-remembermypassword": "Hou my aangemeld",
        "userlogin-signwithsecure": "Gebruik veilige verbinding",
        "yourdomainname": "U domein:",
        "upload-copy-upload-invalid-domain": "Gekopieerde oplaaie word nie vanuit die domein toegelaat nie.",
        "upload-dialog-title": "Laai lêer op",
        "upload-dialog-button-cancel": "Kanselleer",
+       "upload-dialog-button-back": "Terug",
        "upload-dialog-button-done": "Gedoen",
        "upload-dialog-button-save": "Stoor",
        "upload-dialog-button-upload": "Oplaai",
        "usereditcount": "$1 {{PLURAL:$1|wysiging|wysigings}}",
        "usercreated": "{{GENDER:$3|Geregistreer}} op $1 om $2",
        "newpages": "Nuwe bladsye",
+       "newpages-submit": "Wys",
        "newpages-username": "Gebruikersnaam:",
        "ancientpages": "Oudste bladsye",
        "move": "Skuif",
        "activeusers-intro": "Hierdie is 'n lys van gebruikers wat die laaste {{PLURAL:$1|dag|$1 dae}} enige aktiwiteit getoon het.",
        "activeusers-count": "$1 onlangse {{PLURAL:$1|wysiging|wysigings}} in die {{PLURAL:$3|afgelope dag|laaste $3 dae}}",
        "activeusers-from": "Wys gebruikers, beginnende by:",
-       "activeusers-hidebots": "Versteek bots",
-       "activeusers-hidesysops": "Versteek administrateurs",
        "activeusers-noresult": "Geen gebruikers gevind nie.",
        "activeusers-submit": "Wys",
        "listgrouprights": "Gebruikersgroepregte",
        "pageinfo-length": "Bladsylengte (in grepe)",
        "pageinfo-article-id": "Bladsy-ID",
        "pageinfo-language": "Taal vir die bladsy",
+       "pageinfo-content-model-change": "wysig",
        "pageinfo-robot-policy": "Status vir soekenjins",
        "pageinfo-robot-index": "Toegestaan",
        "pageinfo-robot-noindex": "Nie toegestaan",
        "patrol-log-page": "Kontroleringslogboek",
        "patrol-log-header": "Die logboek wys weergawes wat as gekontroleer gemerk is.",
        "log-show-hide-patrol": "Nasienlogboek $1",
+       "confirm-markpatrolled-button": "OK",
        "deletedrevision": "Ou weergawe $1 geskrap",
        "filedeleteerror-short": "Fout met verwydering van lêer: $1",
        "filedeleteerror-long": "Foute het voorgekom by die skraping van die lêer:\n\n$1",
        "htmlform-cloner-create": "Meer meer by",
        "htmlform-cloner-delete": "Verwyder",
        "htmlform-cloner-required": "Ten minste één waarde verwag.",
+       "htmlform-date-placeholder": "JJJJ-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "JJJJ-MM-DD HH:MM:SS",
        "htmlform-title-badnamespace": "[[:$1]] is nie in die \"{{ns:$2}}\" naamspasie nie.",
        "htmlform-title-not-creatable": "\"$1\" is nie 'n aanvaarbare blad titel nie",
        "htmlform-title-not-exists": "$1 bestaan nie.",
-       "sqlite-has-fts": "Weergawe $1 met ondersteuning vir vol-teks soektogte (\"full-text search\")",
-       "sqlite-no-fts": "Weergawe $1 sonder ondersteuning vir vol-teks soektogte (\"full-text search\")",
+       "htmlform-user-not-exists": "<strong>$1</strong> bestaan nie.",
+       "htmlform-user-not-valid": "<strong>$1</strong> is nie 'n geldige gebruikersnaam nie.",
        "logentry-delete-delete": "$1 {{GENDER:$2|het}} bladsy $3 verwyder",
        "logentry-delete-restore": "$1 {{GENDER:$2|het}} bladsy $3 teruggeplaas",
        "logentry-delete-event": "$1 {{GENDER:$2|het}} die sigbaarheid van {{PLURAL:$5|'n logboekreël|$5 logboekreëls}} van $3 gewysig: $4",
        "feedback-bugornote": "As u reg is om 'n tegniese probleem in detail te beskryf, [$1 rapporteer 'n fout].\nAnders kan u die eenvoudige vorm hieronder gebruik. U kommentaar sal by die bladsy \"[$3 $2]\", saam met u gebruikersnaam en die webblaaier wat u gebruik gevoeg word.",
        "feedback-cancel": "Kanselleer",
        "feedback-close": "Gedoen",
-       "feedback-error-title": "Fout",
        "feedback-error1": "Fout: onbekende resultaat van die API",
        "feedback-error2": "Fout: Wysiging het gefaal",
        "feedback-error3": "Fout: Geen reaksie van API",
        "mw-widgets-dateinput-placeholder-month": "JJJJ-MM",
        "mw-widgets-titleinput-description-new-page": "bladsy bestaan nog nie",
        "mw-widgets-titleinput-description-redirect": "aanstuur na $1",
+       "sessionprovider-generic": "$1-sessies",
        "log-action-filter-all": "Alle",
-       "authprovider-resetpass-skip-label": "Slaan oor"
+       "authmanager-email-label": "E-pos",
+       "authmanager-email-help": "E-posadres",
+       "authmanager-realname-label": "Regte naam",
+       "authmanager-realname-help": "Die gebruiker se regte naam",
+       "authprovider-resetpass-skip-label": "Slaan oor",
+       "specialpage-securitylevel-not-allowed-title": "Nie toegestaan",
+       "cannotauth-not-allowed-title": "Geen toegang",
+       "cannotauth-not-allowed": "U word nie toegelaat om die bladsy te gebruik nie",
+       "credentialsform-account": "Gebruikersnaam:",
+       "edit-error-short": "Fout: $1",
+       "edit-error-long": "Foute:\n\n$1"
 }
index 23da0fa..5f9ab04 100644 (file)
        "yourname": "Nofka:",
        "yourpassword": "Fjalëkalimi:",
        "yourpasswordagain": "Fjalëkalimi përsëdyti:",
-       "remembermypassword": "Mbaj mend fjalëkalimin tem në këtë shfletues (për $1 {{PLURAL:$1|ditë|ditë}})",
        "yourdomainname": "Domena juej:",
        "externaldberror": "Ose pat gabim në databazën e autentifikimit, ose nuk lejoheni me ndryshue llogarinë tuej të jashtme.",
        "login": "Kyçu",
        "undo-failure": "Redaktimi nuk mund të kthehej për shkak të përplasjeve të ndërmjetshme.",
        "undo-norev": "S'mund të zhbëja këtë redaktim pasi nuk ekziston ose është grisur.",
        "undo-summary": "U kthye versioni $1 i bërë nga [[Special:Contributions/$2]] ([[User talk:$2]])",
-       "cantcreateaccounttitle": "Nuk mundet të krijohet llogaria",
        "cantcreateaccount-text": "Hapja e llogarive nga kjo adresë IP ('''$1''') është bllokuar nga [[User:$3|$3]].\n\nArsyeja e dhënë nga $3 është ''$2''.",
        "viewpagelogs": "Shih regjistrat për këtë faqe",
        "nohistory": "Nuk ka histori redaktimesh për këtë faqe.",
index 712dc1f..0033e3e 100644 (file)
        "yourpasswordagain": "መግቢያ ቃልዎን ዳግመኛ ይስጡ",
        "createacct-yourpasswordagain": "የመግቢያ ቃሉን ይድገሙ",
        "createacct-yourpasswordagain-ph": "የመግቢያ ቃሉን ይድገሙ",
-       "remembermypassword": "ለሚቀጥለው ጊዜ በዚ ኮምፒውተር ላይ በአባልነት ስሜ መግባቴን ( ቢባዛ ለ $1 {{PLURAL:$1|ቀን|ቀናት}}) አስታውስ።",
        "yourdomainname": "የእርስዎ ከባቢ (domain)፦",
        "password-change-forbidden": "በዚሁ ዊኪ መግቢያ ቃልን መቀይር አልተፈቀደም።",
        "externaldberror": "ወይም አፍአዊ የማረጋገጫ መረጃ-ቤት ስኅተት ነበረ፣ ወይም አፍአዊ አባልነትዎን ማሳደስ አልተፈቀዱም።",
        "passwordreset-email": "የኢ-ሜል አድራሻ:",
        "passwordreset-emailelement": "የአባል ስም፦ \n$1\n\nጊዜያዊ መግቢያ ቃል፦ \n$2",
        "passwordreset-emailsentemail": "የማስታወሻ ኢ-ሜል ተልኳል።",
-       "passwordreset-emailsent-capture": "የማስታወሻ ኢ-ሜል ተልኳል፤ ከዚህም ታች ይታያል።",
-       "passwordreset-emailerror-capture": "የማስታወሻ ኢ-ሜል ተልኳል፤ ከዚህም ታች ይታያል፤ ነገር ግን ወደ ተጠቃሚው ለመላክ ስንል አልተከናወነም፡",
        "changeemail": "ኢ-ሜል አድራሻዎን ለመቀይር",
        "changeemail-header": "የአባልነትዎን ኢ-ሜል አድራሻ ለመቀይር",
        "changeemail-no-info": "ይህንን ገጽ በቀጥታ ለማግኘት አስቀድሞ መግባት ያስፈልጋል።",
        "undo-failure": "ከዚሁ ለውጥ በኋላ ቅራኔ ለውጦች ስለ ገቡ ሊገለበጥ አይቻልም።",
        "undo-norev": "ለውጡ አይኖርም ወይም ጠፍቷልና ሊገለበጥ አልተቻለም።",
        "undo-summary": "አንድ ለውጥ $1 ከ[[Special:Contributions/$2|$2]] ([[User talk:$2|ውይይት]]) ገለበጠ",
-       "cantcreateaccounttitle": "ብዕር ስም ለመፍጠር አይቻልም",
        "cantcreateaccount-text": "ከዚሁ የቁጥር አድራሻ ('''$1''') የብዕር ስም መፍጠር በ[[User:$3|$3]] ታግዷል።\n\nበ$3 የተሰጠው ምክንያት ''$2'' ነው።",
        "viewpagelogs": "መዝገቦች ለዚሁ ገጽ",
        "nohistory": "ለዚሁ ገጽ የዕትሞች ታሪክ የለም።",
        "activeusers": "ተግባራዊ አባላት ዝርዝር",
        "activeusers-intro": "እነዚህ አባላት ባለፈው $1 ቀን ውስጥ ማናቸውንም አይነት ተግባር ፈጸሙ።",
        "activeusers-count": "$1 {{PLURAL:$1|ለውጥ|ለውጦች}} ባለፈው $3 ቀን ውስጥ",
-       "activeusers-hidebots": "ሎሌዎች ይደበቁ",
-       "activeusers-hidesysops": "መጋቢዎች ይደበቁ",
        "activeusers-noresult": "ማንም ተጠቃሚ አልተገኘም።",
        "listgrouprights": "የተጠቃሚ ስብስባ መብቶች",
        "listgrouprights-group": "ስብስባ",
index 092ecc4..e7e53b7 100644 (file)
        "minoredit": "He feito una edición menor",
        "watchthis": "Cosirar ista pachina",
        "savearticle": "Alzar pachina",
+       "publishpage": "Publicar a pachina",
        "publishchanges": "Publicar os cambeos",
        "preview": "Previsualización",
        "showpreview": "Amostrar previsualización",
        "activeusers-intro": "Ista ye una lista d'usuarios que han teniu bella actividat en os zaguers $1 {{PLURAL:$1|diya|diyas}}.",
        "activeusers-count": "$1 {{PLURAL:$1|edición|edicions}} en os zaguers {{PLURAL:$3|diya|$3 diyas}}",
        "activeusers-from": "Amostrar nombres d'usuario que prencipien por:",
-       "activeusers-hidebots": "Amagar robots",
-       "activeusers-hidesysops": "Amagar administradors",
        "activeusers-noresult": "No s'han trobato usuarios.",
        "listgrouprights": "Dreitos d'a colla d'usuarios",
        "listgrouprights-summary": "Contino trobará a lista de collas d'usuario definitas en iste wiki, con os suyos dreitos d'acceso asociatos. Tamién puet trobar aquí [[{{MediaWiki:Listgrouprights-helppage}}|información adicional]] sobre os dreitos individuals.",
index 6bc5553..e7415f5 100644 (file)
@@ -43,7 +43,7 @@
        "tog-enotifminoredits": "Sendan mē spearcǣrend þǣr trametas oþþe ymelan sīen efne lyt andwended.",
        "tog-enotifrevealaddr": "Īwan mīnne spearcǣrenda naman on gecȳðendum spearcǣrendum",
        "tog-shownumberswatching": "Īwan þæt rīm behealdendra brūcenda",
-       "tog-oldsig": "Genge selfmearc:",
+       "tog-oldsig": "Þin genge handseten:",
        "tog-fancysig": "Dōn selfmearce tō wikitexte (lēas ǣr gedōnes hlencan)",
        "tog-uselivepreview": "Notian rihte īwedre forebysene",
        "tog-forceeditsummary": "Cȳðan mē þǣr ic ne wrīte adihtunge sceortnesse",
@@ -53,6 +53,7 @@
        "tog-watchlisthideliu": "Hȳdan adihtunga fram inmeldodum brūcendum wiþ þæt behealdungtæl",
        "tog-watchlisthideanons": "Hȳdan adihtunga fram uncūðum brūcendum wiþ þæt behealdungtæl",
        "tog-watchlisthidepatrolled": "Hȳdan weardoda adihtunga wiþ þæt behealdungtæl",
+       "tog-watchlisthidecategorization": "Ahȳd trameta floccnaman",
        "tog-ccmeonemails": "Sendan mē gelīcnessa þāra spearcǣrenda þe ic ōðrum brūcendum sende",
        "tog-diffonly": "Nā īwan trametes innunge under scādungum",
        "tog-showhiddencats": "Īwan gehȳdede floccas",
        "newwindow": "(openaþ in nīwum ēagþyrele)",
        "cancel": "Undōn",
        "moredotdotdot": "Mā...",
-       "morenotlisted": "Þis getæl nis fulfyled.",
+       "morenotlisted": "Þis getæl meaht bēon unfulfyled.",
        "mypage": "Mīn tramet",
        "mytalk": "Mīn mōtung",
        "anontalk": "Þisses IP naman mōtung",
        "wrongpasswordempty": "Þū ne write nǣnig þafungword. \nSēc þū eft lā.",
        "passwordtooshort": "Þafungword sculon habban læst {{PLURAL:$1|1 stafan|$1 stafena}}.",
        "passwordtoolong": "Þafungword ne cunnon wesan lengran þonne {{PLURAL:$1|1 stafa|$1 stafena}}.",
+       "passwordtoopopular": "Swiðe gewunelice gelēafnesword ne mæg man brūcan. Cies anliepe gelēafnesword.",
        "password-name-match": "Þīn þafungword sceal wesan ungelīc þīnum brūcendes naman.",
        "password-login-forbidden": "Sēo nytt þisses brūcendes naman and þafungwordes nis gelīfed.",
        "mailmypassword": "Settan þafungword eft",
        "passwordremindertitle": "Nīwe hwīlendlic þafungword for {{SITENAME}}",
        "noemail": "Þær nis nǣnig spearcǣrenda nama gewriten for \"$1\" brūcende.",
        "noemailcreate": "Þū þearft wrītan gengne spearcǣrenda naman.",
-       "blocked-mailpassword": "Þīn IP nama is fortȳned and ne cann adihtan; þæs ne cann  hit brūcan þone þafungworda eftgemyndgunge tōl swā þæt man ne miswende hine.",
+       "passwordsent": "Niw gelēafnesword habbaþ we gesended þæm ærendgewrites hamsteall in ūr nambrede for \"$1\".",
+       "blocked-mailpassword": "Þīn IP nama is fortȳned and ne mæg adihtan. To þam þæt man ne mæg miswendan, man ne mōt brūcan gelēafneswordforfang fram þissum IP stede.",
        "acct_creation_throttle_hit": "Nēosiende tō þissum wici, þe þīnne IP-Stōwe brȳcþ, hæfþ gesett {{PLURAL:$1|1 hordcleofan|$1 hordcleofan}} in þǣm læsten dæge. Þu ne canst settan ǣnige māran. Þǣrfram ne cunnon Nēosiende, þe þisne IP-Stōwe brȳcþ, settan ǣnige hordcleofan māran on þisse handhwīle.",
        "accountcreated": "Scōp reccinge",
        "loginlanguagelabel": "Sprǣc: $1",
index 5a3781b..56bbdfe 100644 (file)
        "createacct-yourpassword-ph": "कूटशब्द दर्ज करऽ",
        "createacct-yourpasswordagain": "कूटशब्द केरऽ पुष्टि करऽ",
        "createacct-yourpasswordagain-ph": "कूटशब्द पुनः लिखऽ",
-       "remembermypassword": "इ कंप्यूटर पर हमरॊ लॉग-इन सूचना याद रखॊ (अधिकतम $1 {{PLURAL:$1|दिन|दिन}} लेली)",
        "userlogin-remembermypassword": "हमरा लॉगिन रखऽ",
        "login": "लॉग इन",
        "nav-login-createaccount": "सत्रारंभ / खाता खोलॊ",
index 380a919..6b042e4 100644 (file)
@@ -67,7 +67,9 @@
                        "Hhaboh162002",
                        "بدارين",
                        "باسم",
-                       "Moud hosny"
+                       "Moud hosny",
+                       "ديفيد",
+                       "Super ninja2"
                ]
        },
        "tog-underline": "سطر تحت الوصلات:",
        "faq": "الأسئلة المتكررة",
        "faqpage": "Project:أسئلة متكررة",
        "actions": "أفعال",
-       "namespaces": "Ù\81ضاءات Ø§Ù\84تسÙ\85Ù\8aØ©",
+       "namespaces": "Ù\86طاÙ\82ات",
        "variants": "المتغيرات",
        "navigation-heading": "قائمة التصفح",
        "errorpagetitle": "خطأ",
        "history": "تاريخ الصفحة",
        "history_short": "تاريخ",
        "updatedmarker": "عدلت منذ زيارتي الأخيرة",
-       "printableversion": "بتنسق للطباعة",
+       "printableversion": "نسخة للطباعة",
        "permalink": "رابط دائم",
        "print": "اطبع",
        "view": "مطالعة",
        "passwordreset-nocaller": "يجب أن يتم توفير مستدعي",
        "passwordreset-nosuchcaller": "المستدعي غير موجود: $1",
        "passwordreset-ignored": "إعادة ضبط كلمة السر لم تتم التعامل معها. ربما لا موفر تم ضبطه؟",
-       "passwordreset-invalideamil": "عنوان بريد إلكتروني غير صالح",
+       "passwordreset-invalidemail": "عنوان بريد إلكتروني غير صالح",
        "passwordreset-nodata": "لا اسم مستخدم ولا عنوان بريد الإلكتروي تم توفيره",
        "changeemail": "تغيير أو إزالة عنوان البريد الإلكتروني",
        "changeemail-header": "إكمال هذا النموذج لتغيير عنوان البريد الإلكتروني الخاص بك. إذا كنت ترغب في إزالة جمعية أي عنوان البريد الإلكتروني من حسابك، وترك الفراغ عنوان البريد الإلكتروني الجديد عند تقديم النموذج",
        "mergehistory-from": "الصفحة المصدر:",
        "mergehistory-into": "الصفحة الهدف:",
        "mergehistory-list": "تاريخ التعديل القابل للدمج",
-       "mergehistory-merge": "المراجعات التالية من [[:$1]] يمكن دمجها إلى [[:$2]].\nاستخدم عامود الصناديق لدمج المراجعات التي تم إنشاؤها في وقبل الوقت المحدد.\nلاحظ أن استخدام وصلات التصفح سيعيد ضبط هذا العامود.",
+       "mergehistory-merge": "المراجعات التالية من [[:$1]] يمكن دمجها إلى [[:$2]].\nاستخدم عمود الصناديق لدمج المراجعات التي تم إنشاؤها في وقبل الوقت المحدد.\nلاحظ أن استخدام وصلات التصفح سيعيد ضبط هذا العمود.",
        "mergehistory-go": "عرض التعديلات القابلة للدمج",
        "mergehistory-submit": "دمج المراجعات",
        "mergehistory-empty": "لا مراجعات يمكن دمجها.",
        "searchprofile-advanced-tooltip": "ابحث في النطاقات المخصصة",
        "search-result-size": "$1 ({{PLURAL:$2|لا كلمات|كلمة واحدة|كلمتان|$2 كلمات|$2 كلمة}})",
        "search-result-category-size": "{{PLURAL:$1|لا أعضاء|عضو واحد|عضوان|$1 أعضاء|$1 عضوًا|$1 عضو}} ({{PLURAL:$2|لا تصانيف فرعية|تصنيف فرعي واحد|تصنيفان فرعيان|$2 تصنيفات فرعية|$2 تصنيفًا فرعيًا|$2 تصنيف فرعي}} و{{PLURAL:$3|لا ملفات|ملف واحد|ملفان|$3 ملفات|$3 ملفًا|$3 ملف}})",
-       "search-redirect": "(تحويلة $1)",
+       "search-redirect": "(تحويلة من $1)",
        "search-section": "(قسم $1)",
        "search-category": "(التصنيف $1)",
        "search-file-match": "(يطابق محتوى الملف)",
        "prefs-watchlist": "قائمة المراقبة",
        "prefs-editwatchlist": "تعديل قائمة المراقبة",
        "prefs-editwatchlist-label": "عدل قائمة مراقبتك:",
-       "prefs-editwatchlist-edit": "أعرض Ù\88Ø£حذف عناوين من قائمة مراقبتك",
+       "prefs-editwatchlist-edit": "اعرض Ù\88احذف عناوين من قائمة مراقبتك",
        "prefs-editwatchlist-raw": "عدل قائمة المراقبة الخام",
        "prefs-editwatchlist-clear": "امسح قائمة المراقبة",
        "prefs-watchlist-days": "عدد الأيام للعرض في قائمة المراقبة:",
        "grant-basic": "الصلاحيات الأساسية",
        "grant-viewdeleted": "عرض الملفات والصفحات المحذوفة",
        "grant-viewmywatchlist": "عرض قائمة مراقبتك",
+       "grant-viewrestrictedlogs": "عرض مدخلات السجل المحظورة",
        "newuserlogpage": "سجل إنشاء المستخدمين",
        "newuserlogpagetext": "هذا سجل بعمليات إنشاء المستخدمين.",
        "rightslog": "سجل صلاحيات المستخدمين",
        "upload-dialog-disabled": "رفع الملفات باستخدام هذا الحوار معطلة على هذه الويكي.",
        "upload-dialog-title": "رفع الملف",
        "upload-dialog-button-cancel": "إلغاء",
+       "upload-dialog-button-back": "رجوع",
        "upload-dialog-button-done": "تم",
        "upload-dialog-button-save": "احفظ",
        "upload-dialog-button-upload": "رفع",
        "apisandbox-results-fixtoken-fail": "فشل جلب توكين \"$1\"",
        "apisandbox-alert-page": "هناك حقول غير صالحة في هذه الصفحة.",
        "apisandbox-alert-field": "قيمة هذا الحقل غير صالحة.",
+       "apisandbox-continue": "استمرار",
+       "apisandbox-continue-clear": "إفراغ",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} س [https://www.mediawiki.org/wiki/API:Query#Continuing_queries يستمر] في الطلب الأخير؛ {{int:apisandbox-continue-clear}} سيفرغ المعاملات المرتبطة بالاستمرار.",
+       "apisandbox-param-limit": "أدخل <kbd>max</kbd> لاستخدام الحد الأقصى.",
        "booksources": "مصادر كتاب",
        "booksources-search-legend": "البحث عن مصادر الكتب",
        "booksources-isbn": "ردمك:",
        "booksources-search": "بحث",
        "booksources-text": "توجد أدناه قائمة بوصلات لمواقع أخرى تبيع الكتب الجديدة والمستعملة، أيضا يمكنك أن تحصل على معلومات إضافية عن الكتب التي تبحث عنها من هناك:",
        "booksources-invalid-isbn": "رقم ISBN المعطى لا يبدو صحيحا؛ تحقق من أخطاء النسخ من المصدر الأصلي.",
+       "magiclink-tracking-rfc": "الصفحات التي تستخدم الوصلات السحرية لRFC",
+       "magiclink-tracking-rfc-desc": "هذه الصفحة تستخدم الوصلات السحرية لRFC. انظر [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] حول كيفية التغيير.",
+       "magiclink-tracking-pmid": "الصفحات التي تستخدم الوصلات السحرية لPMID",
+       "magiclink-tracking-pmid-desc": "هذه الصفحة تستخدم الوصلات السحرية لPMID. انظر [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] حول كيفية التغيير.",
+       "magiclink-tracking-isbn": "الصفحات التي تستخدم الوصلات السحرية لISBN",
+       "magiclink-tracking-isbn-desc": "هذه الصفحة تستخدم الوصلات السحرية لISBN. انظر [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] حول كيفية التغيير.",
        "specialloguserlabel": "المؤدي:",
        "speciallogtitlelabel": "الهدف (عنوان أو {{ns:user}}:اسم المستخدم للمستخدم):",
        "log": "سجلات",
        "activeusers-intro": "هذه قائمة بالمستخدمين الذين مارسوا نوعا من النشاط خلال {{PLURAL:$1||اليوم الماضي|اليومين الماضيين|ال$1 أيام الماضية|ال$1 يوما ماضيا|ال$1 يوم ماضي}}.",
        "activeusers-count": "{{PLURAL:$1|لا أفعال|فعل واحد|فعلان اثنان|$1 أفعال|$1 فعلا|$1 فعل}} منذ {{PLURAL:$3||يوم|يومين|$3 أيام|$3 يوما|$1 يوم}}",
        "activeusers-from": "اعرض المستخدمين ابتداء من:",
-       "activeusers-hidebots": "أخف البوتات",
-       "activeusers-hidesysops": "أخف الإداريين",
+       "activeusers-groups": "عرض المستخدمين المنتمين للمجموعات:",
        "activeusers-noresult": "لم يعثر على أي مستخدمين",
        "activeusers-submit": "عرض المستخدمين النشطين",
        "listgrouprights": "صلاحيات مجموعات المستخدمين",
        "mailnologin": "لا يوجد عنوان للإرسال",
        "mailnologintext": "يجب أن تقوم [[Special:UserLogin|بتسجيل الدخول]] وإدخال بريد إلكتروني صالح في صفحة [[Special:Preferences|التفضيلات]] لتتمكن من إرسال الرسائل لمستخدمين آخرين.",
        "emailuser": "مراسلة المستخدم",
-       "emailuser-title-target": "راسل بالبريد الإلكتروني هذا  {{GENDER:$1| المستخدم}}",
+       "emailuser-title-target": "راسل هذا  {{GENDER:$1| المستخدم}} بالبريد الإلكتروني",
        "emailuser-title-notarget": "مراسلة المستخدم",
        "emailpagetext": "يمكنك استخدام الاستمارة بالأسفل لإرسال رسالة بريد إلكتروني إلى {{GENDER:$1|هذا المستخدم|هذه المستخدمة}}.\n'''يمكن أن يرى المرسل إليه عنوان بريدك الإلكتروني''' الذي أدخلته في [[Special:Preferences|تفضيلاتك]] كعنوان المرسل في البريد الإلكتروني، كي يستطيع المتلقي الرد عليك مباشرة.",
        "defemailsubject": "رسالة {{SITENAME}} من المستخدم \"$1\"",
        "modifiedarticleprotection": "غير مستوى حماية \"[[$1]]\"",
        "unprotectedarticle": "أزال الحماية من \"[[$1]]\"",
        "movedarticleprotection": "نقل إعدادات الحماية من \"[[$2]]\" إلى \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|محمي}} \"[[$1]]\"",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|غير مستوى الحماية|غيرت مستوى الحماية}} ل\"[[$1]]\"",
+       "unprotectedarticle-comment": "{{GENDER:$2|أزال الحماية|أزالت الحماية}} من \"[[$1]]\"",
        "protect-title": "ضبط حماية \"$1\"",
        "protect-title-notallowed": "عرض مستوى حماية \"$1\"",
        "prot_1movedto2": "نُقلت [[$1]] إلى [[$2]]",
        "sp-contributions-blocked-notice-anon": "عنوان الأيبي هذا ممنوع حاليا.\nآخر مدخلة لسجل المنع معروضة هنا كمرجع:",
        "sp-contributions-search": "بحث عن مساهمات",
        "sp-contributions-username": "عنوان أيبي أو اسم مستخدم:",
-       "sp-contributions-toponly": "أظÙ\87ر Ø£Ø¹Ù\84Ù\89 Ø§Ù\84Ù\85راجعات فقط",
+       "sp-contributions-toponly": "أظÙ\87ر Ø§Ù\84Ù\86سخ Ø§Ù\84حاÙ\84Ù\8aØ© فقط",
        "sp-contributions-newonly": "أظهر إنشاء الصفحات فقط",
        "sp-contributions-hideminor": "أخف التعديلات الطفيفة",
        "sp-contributions-submit": "بحث",
        "movelogpagetext": "بالأسفل قائمة بالصفحات التي تم نقلها.",
        "movesubpage": "{{PLURAL:$1||الصفحة الفرعية|الصفحتان الفرعيتان|الصفحات الفرعية}}",
        "movesubpagetext": "لهذه الصفحة {{PLURAL:$1||صفحة فرعية واحدة معروضة|صفحتان فرعيتان معروضتان|$1 صفحات فرعية معروضة|$1 صفحة فرعية معروضة}} بالأسفل.",
+       "movesubpagetalktext": "صفحة النقاش المكافئة لديها $1 {{PLURAL:$1|صفحة فرعية|صفحات فرعية}} معروضة بالأسفل.",
        "movenosubpage": "ليس لهذه الصفحة صفحات فرعية.",
        "movereason": "السبب:",
        "revertmove": "استرجع",
        "allmessagesname": "الاسم",
        "allmessagesdefault": "النص الافتراضي",
        "allmessagescurrent": "النص الحالي",
-       "allmessagestext": "Ù\87Ø°Ù\87 Ù\82ائÙ\85Ø© Ø¨Ø±Ø³Ø§Ø¦Ù\84 Ø§Ù\84Ù\86ظاÙ\85 Ø§Ù\84Ù\85تÙ\88Ù\81رة Ù\81Ù\8a Ù\86طاÙ\82 Ù\85Ù\8aدÙ\8aاÙ\88Ù\8aÙ\83Ù\8a.\nÙ\8aرجÙ\89 Ø²Ù\8aارة :\n[https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki Localisation] Ù\88 [https://translatewiki.net translatewiki.net]\nإازا Ù\83Ù\86ت ØªØ±ØºØ¨ Ù\81Ù\8a Ø§Ù\84Ù\85ساÙ\87Ù\85Ø© Ø¨ØªØ¹Ø±Ù\8aب Ù\85Ù\8aدÙ\8aا Ù\88Ù\8aÙ\83Ù\8a",
+       "allmessagestext": "Ù\87Ø°Ù\87 Ù\82ائÙ\85Ø© Ø¨Ø±Ø³Ø§Ø¦Ù\84 Ø§Ù\84Ù\86ظاÙ\85 Ø§Ù\84Ù\85تÙ\88Ù\81رة Ù\81Ù\8a Ù\86طاÙ\82 Ù\85Ù\8aدÙ\8aاÙ\88Ù\8aÙ\83Ù\8a.\nÙ\85Ù\86 Ù\81ضÙ\84Ù\83 Ø²Ø± [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation ØªØ±Ø¬Ù\85Ø© Ù\85Ù\8aدÙ\8aاÙ\88Ù\8aÙ\83Ù\8a] Ù\88 [https://translatewiki.net ØªØ±Ø§Ù\86سÙ\84Ù\8aت Ù\88Ù\8aÙ\83Ù\8a Ø¯Ù\88ت Ù\86ت] Ù\84Ù\88 Ù\83Ù\86ت ØªØ±ØºØ¨ Ù\81Ù\8a Ø§Ù\84Ù\85ساÙ\87Ù\85Ø© Ù\81Ù\8a ØªØ±Ø¬Ù\85Ø© Ù\85Ù\8aدÙ\8aاÙ\88Ù\8aÙ\83Ù\8a Ø§Ù\84أساسÙ\8aØ©.",
        "allmessagesnotsupportedDB": "هذه الصفحة لا يمكن استخدامها لأن '''$wgUseDatabaseMessages''' تم تعطيله.",
        "allmessages-filter-legend": "المرشح",
        "allmessages-filter": "رشح حسب حالة التخصيص:",
        "pageinfo-category-pages": "عدد الصفحات",
        "pageinfo-category-subcats": "عدد التصنيفات الفرعية",
        "pageinfo-category-files": "عدد الملفات",
+       "pageinfo-user-id": "مُعرِّف المستخدم",
        "markaspatrolleddiff": "علم بعلامة المراجعة",
        "markaspatrolledtext": "علم هذه الصفحة بعلامة المراجعة",
        "markaspatrolledtext-file": "علم نسخة الملف هذه بعلامة المراجعة",
        "patrol-log-header": "هذا سجل بالمراجعات المراجعة.",
        "log-show-hide-patrol": "$1 سجل الخفر",
        "log-show-hide-tag": "$1 سجل الوسوم",
+       "confirm-markpatrolled-button": "موافق",
+       "confirm-markpatrolled-top": "علم على المراجعة $3 من $2 كمراجعة؟",
        "deletedrevision": "حذف المراجعة القديمة $1",
        "filedeleteerror-short": "خطأ حذف الملف: $1",
        "filedeleteerror-long": "حدثت أخطاء أثناء حذف الملف:\n\n$1",
        "newimages-showbots": "أظهر التحميلات بواسطة البوتات",
        "newimages-hidepatrolled": "أخف المرفوعات المنظورة",
        "noimages": "لا شيء للعرض.",
+       "gallery-slideshow-toggle": "تغيير الصور المصغرة",
        "ilsubmit": "بحث",
        "bydate": "حسب التاريخ",
        "sp-newimages-showfrom": "أظهر الملفات الجديدة بدءا من $2، $1",
        "tags-deactivate": "تعطيل",
        "tags-hitcount": "{{PLURAL:$1|لا تغييرات|تغيير واحد|تغييران|$1 تغييرات|$1 تغييرا|$1 تغيير}}",
        "tags-manage-no-permission": "ليس لديك صلاحية إدارة وسوم التغيير.",
-       "tags-manage-blocked": "لا يمكنك إدارة علامات التغيير في حين منعت.",
+       "tags-manage-blocked": "لا يمكنك إدارة وسوم التغيير أثناء {{GENDER:$1|منعك}}.",
        "tags-create-heading": "إنشاء وسم جديد",
        "tags-create-explanation": "في الوضع الافتراضي، الوسوم الجديدة المنشأة سيتاح استخدامها للبوتات والمستخدمين.",
        "tags-create-tag-name": "اسم الوسم:",
        "tags-deactivate-not-allowed": "من غير الممكن تعطيل الوسم \"$1\".",
        "tags-deactivate-submit": "عطل",
        "tags-apply-no-permission": "ليس لديك إذن لتطبيق علامات التغيير جنبا إلى جنب مع التغييرات.",
-       "tags-apply-blocked": "لا يمكنك تطبيق علامات التغيير جنبا إلى جنب مع التغييرات في حين منعت.",
+       "tags-apply-blocked": "لا يمكنك تطبيق وسوم التغيير جنبا إلى جنب مع تغييراتك أثناء {{GENDER:$1|منعك}}.",
        "tags-apply-not-allowed-one": "الوسم \"$1\" غير مسموح أن يتم تطبيقه يدويا.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|الوسم|الوسوم}} التالية غير مسموح أن يتم تطبيقها يدويا: $1",
        "tags-update-no-permission": "أنت لا تمتلك السماح لإضافة أو إزالة وسوم التغيير من المراجعات أو مدخلات السجل الفردية.",
-       "tags-update-blocked": "لا يمكنك إضافة أو إزالة العلامات التغيير بينماهي محظورة.",
+       "tags-update-blocked": "لا يمكنك إضافة أو إزالة وسوم التغيير أثناء {{GENDER:$1|منعك}}.",
        "tags-update-add-not-allowed-one": "الوسم \"$1\" غير مسموح أن تتم إضافته يدويا.",
        "tags-update-add-not-allowed-multi": "The following {{PLURAL:$2|الوسم|الوسوم}} التالية غير مسموح أن تتم إضافتها يدويا: $1",
        "tags-update-remove-not-allowed-one": "من غير المسموح بإزالة وسم \"$1\".",
        "htmlform-cloner-create": "إضافة المزيد",
        "htmlform-cloner-delete": "إزالة",
        "htmlform-cloner-required": "مطلوب قيمة واحدة على الأقل.",
+       "htmlform-date-placeholder": "YYYY-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "YYYY-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "القيمة التي حددتها ليست تاريخا متعرف عليه. جرب استخدام صيغة YYYY-MM-DD.",
+       "htmlform-time-invalid": "القيمة التي حددتها ليست وقتا متعرف عليه. جرب استخدام صيغة HH:MM:SS.",
+       "htmlform-datetime-invalid": "القيمة التي حددتها ليست وقتا وتاريخا متعرف عليه. جرب استخدام صيغة YYYY-MM-DD HH:MM:SS.",
+       "htmlform-date-toolow": "القيمة التي حددتها هي قبل أول تاريخ مسموح به $1.",
+       "htmlform-date-toohigh": "القيمة التي حددتها هي بعد آخر تاريخ مسموح به $1.",
+       "htmlform-time-toolow": "القيمة التي حددتها هي قبل أول وقت مسموح به $1.",
+       "htmlform-time-toohigh": "القيمة التي حددتها هي بعد آخر وقت مسموح به $1.",
+       "htmlform-datetime-toolow": "القيمة التي حددتها هي قبل أول تاريخ ووقت مسموح بهما $1.",
+       "htmlform-datetime-toohigh": "القيمة التي حددتها هي بعد آخر تاريخ ووقت مسموح بهما $1.",
        "htmlform-title-badnamespace": "[[:$1]] ليس في نطاق \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" ليس عنوان صفحة يمكن إنشاؤه",
        "htmlform-title-not-exists": "$1 غير موجود.",
        "htmlform-user-not-exists": "<strong>$1</strong> غير موجود",
        "htmlform-user-not-valid": "اسم المستخدم <strong>$1</strong> غير صالح.",
        "logentry-delete-delete": "{{GENDER:$2|حذف|حذفت}} $1 صفحة $3",
-       "logentry-delete-restore": "{{GENDER:$2|استعاد|استعادت}} $1 صفحة $3",
+       "logentry-delete-restore": "{{GENDER:$2|استرجع|استرجعت}} $1 صفحة $3",
        "logentry-delete-event": "{{GENDER:$2|غيّر|غيّرت}} $1 إمكانية مشاهدة {{PLURAL:$5||حدث|حدثين|$5 أحداث|$5 حدثًا|$5 حدث}} في سجل $3: $4",
        "logentry-delete-revision": "غيّر{{GENDER:$2||ت}} $1 إمكانية مشاهدة {{PLURAL:$5||مراجعة واحدة|مراجعتين|$5 مراجعات|$5 مراجعة}} في صفحة $3: $4",
        "logentry-delete-event-legacy": "{{GENDER:$2|غيّر|غيّرت}} $1 إمكانية رؤية أحداث في سجل $3",
        "feedback-external-bug-report-button": "أرسل تقرير علة تقنية",
        "feedback-dialog-title": "أرسل تغذية راجعة",
        "feedback-dialog-intro": "أنت يمكنك استخدام الاستمارة السهلة بالأسفل لإرسال تعليقك. تعليقك ستتم إضافته للصفحة \"$1\"، مع اسم المستخدم الخاص بك.",
-       "feedback-error-title": "خطأ",
        "feedback-error1": "خطأ: لا يمكن التعرف عليها من API",
        "feedback-error2": "خطأ: فشل في تحرير",
        "feedback-error3": "خطأ : لا توجد استجابة من API",
        "feedback-thanks": "شكرا! أُرسلت ملاحظاتك لصفحة \"[$2 $1]\".",
        "feedback-thanks-title": "شكرا لك!",
        "feedback-useragent": "وكيل المستخدم:",
-       "searchsuggest-search": "بحث",
+       "searchsuggest-search": "ابحث Ù\81Ù\8a {{SITENAME}}",
        "searchsuggest-containing": "يحتوي...",
        "api-error-autoblocked": "عنوان الأيبي الخاص بك تم منعه تلقائيا، لأنه تم استخدامه بواسطة مستخدم ممنوع",
        "api-error-badaccess-groups": "لا يسمح لك بتحميل الملفات إلى هذه الويكي.",
        "usercssispublic": "من فضل لاحظ: صفحات الCSS الفرعية لا ينبغي أن تحتوي على بيانات سرية بما أنها يمكن رؤيتها بواسطة المستخدمين الآخرين.",
        "restrictionsfield-badip": "عنوان أيبي أو نطاق غير صحيح: $1",
        "restrictionsfield-label": "نطاقات الأيبي المسموح بها:",
-       "restrictionsfield-help": "عنوان أيبي أو نطاق CIDR واحد لكل سطر. لتفعيل كل شيء، استخدم<br><code>0.0.0.0/0</code><br><code>::/0</code>"
+       "restrictionsfield-help": "عنوان أيبي أو نطاق CIDR واحد لكل سطر. لتفعيل كل شيء، استخدم<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "خطأ: $1",
+       "edit-error-long": "الأخطاء:\n\n$1"
 }
index 3907c46..8d20e95 100644 (file)
        "yourpasswordagain": "ܟܬܘܒ ܡܠܬܐ ܕܥܠܠܐ ܙܒܢܬܐ ܐܚܪܬܐ:",
        "createacct-yourpasswordagain": "ܫܪܪ ܡܠܬܐ ܕܥܠܠܐ",
        "createacct-yourpasswordagain-ph": "ܐܥܠ ܡܠܬܐ ܕܥܠܠܐ ܙܒܢ ܐܚܪܝܢ",
-       "remembermypassword": "ܕܟܘܪ ܥܠܠܬܝ ܥܠ ܡܦܐܬܢܐ ܗܢܐ (ܠܡܬܚܐ ܥܠܝܐ ܕ $1 {{PLURAL:$1|ܝܘܡܐ|ܝܘܡܬ̈ܐ}})",
        "userlogin-remembermypassword": "ܫܒܘܩ ܠܝ ܥܠܝܠܐ ܒܚܘܫܒܢܝ",
        "userlogin-signwithsecure": "ܐܚܫܚ ܕܒܝܩܘܬܐ ܡܫܝܢܢܬܐ",
        "login": "ܥܘܠ",
        "edit-already-exists": "ܒܪܝܐ ܕܦܐܬܐ ܚܕܬܐ ܠܐ ܡܬܡܨܝܢܐ.\nܗܕܐ ܦܐܬܐ ܐܝܬ ܡܢ ܟܕܘ.",
        "editwarning-warning": "ܐܢ ܫܒܩܬ ܦܐܬܐ ܗܕܐ ܡܬܡܨܝܢܬܐ ܐܝܬܝܗ ܕܚܣܪܬ ܟܠ ܫܘܚܠܦ̈ܐ ܕܥܒܝܕܬ ܗܪܟܐ.\nܡܨܬ ܕܬܒܛܠ ܙܘܗܪܐ ܗܢܐ ܐܢ ܥܠܝܠܐ ܐܝܬܝܟ ܒܡܢܬܐ ܕ\"ܫܚܠܦܬܐ\" ܒܨܒܝܢܝܘܬ̈ܐ.",
        "undo-summary": "ܠܐ ܬܥܒܕ $1 ܒܝܕ [[Special:Contributions/$2|$2]] ([[User talk:$2|ܡܡܠܠܐ]])",
-       "cantcreateaccounttitle": "ܒܪܝܐ ܕܚܘܫܒܢܐ ܠܐ ܡܬܡܨܝܢܐ",
        "viewpagelogs": "ܚܙܝ ܣܓܠ̈ܐ ܕܦܐܬܐ ܗܕܐ",
        "nohistory": "ܠܝܬ ܬܫܥܝܬܐ ܕܫܘܚܠܦ̈ܐ ܠܦܐܬܐ ܗܕܐ",
        "currentrev": "ܬܢܝܬܐ ܗܫܝܬܐ",
        "activeusers": "ܡܟܬܒܘܬܐ ܕܗܕ̈ܡܐ ܙܪ̄ܝܙܐ",
        "activeusers-count": "$1 {{PLURAL:$1|ܥܒܕܐ|ܥܒܕ̈ܐ}} ܒ {{PLURAL:$3|ܝܘܡܐ ܐܚܪܝܐ|$3 ܝܘܡܬ̈ܐ ܐܚܪ̈ܝܐ}}",
        "activeusers-from": "ܚܘܝ ܡܦܠܚܢ̈ܐ ܕܫܪܐ ܥܡ:",
-       "activeusers-hidebots": "ܛܫܝ ܒܘܬ̈ܐ (bots)",
-       "activeusers-hidesysops": "ܛܫܝ ܡܕܒܪ̈ܢܐ",
        "activeusers-noresult": "ܠܐ ܐܫܬܟܚ ܡܦܠܚܢ̈ܐ ܐܢܫ̈ܝܢ.",
        "listgrouprights": "ܙܕ̈ܩܐ ܕܟܢܘܫܬܐ ܕܡܦܠܚܢ̈ܐ",
        "listgrouprights-group": "ܟܢܘܫܬܐ",
index 6893166..dd96161 100644 (file)
        "articlepage": "Adkintun trokiñdungu wülngiñ",
        "talk": "Nütramkawün",
        "views": "Adngelün",
-       "toolbox": "Küdzawpeyüm",
+       "toolbox": "Küdawpeyüm",
        "userpage": "Adkintun kellufe ñi wülngiñ",
        "projectpage": "Adkintun zeumanzugu wülngiñ",
        "imagepage": "Adkintun ad wülngiñ",
        "yourname": "Tami üy",
        "yourpassword": "Tami kondungu",
        "yourpasswordagain": "Rüf feypinge nülawe:",
-       "remembermypassword": "Amulen tañi nülküwküleael tüfa mew (alürumechi $1 {{PLURAL:$1 antü}})",
        "login": "Konkülen",
        "nav-login-createaccount": "konkülen/dewman konün",
        "userlogin": "Konkülen/dewman konün",
index 3dfb6ab..79fc096 100644 (file)
        "yourpasswordagain": "عاود كتبت كلمت السر:",
        "createacct-yourpasswordagain": "أكّد كلمت` السرّ",
        "createacct-yourpasswordagain-ph": "عاود دخّل كلمت` السرّ",
-       "remembermypassword": "اتفكر الدخول تاعي ب هاذ النافيكاتور (ب مدّة حدها{{PLURAL:$1||يوم واحد|يومين|$1 إيّام|$1 يوم}})",
        "userlogin-remembermypassword": "خلّيني مسجّل داخل",
        "userlogin-signwithsecure": "استعمل التوصال المأمون.",
        "yourdomainname": "الدومان تاعك:",
        "passwordreset-emailtext-user": "المستعملي $1 ف {{SITENAME}} راه طلب تبدال ف كلمت` السرّ تاعك ف {{SITENAME}}\n($4). {{PLURAL:$3|الحساب|الحسايات}} تاع المستعملي {{PLURAL:$3|راه مربوط|راهم مربوطين}} ب لادريسة تاع ليمال هادي:\n\n$2\n\n{{PLURAL:$3|هاد كلمت` السرّ المأقّتة|هادي كلمات` السرّ المأقّتة}} غادي يكمل صلوحها منّا على {{PLURAL:$5|نهار واحد|$5 إيّام}}.\nمادابيك تسجّل داخل ضركا و تختار كلمت` سرّ جديدة. يلا كان وحداخُر دار هاد المطلب، ولا راك ضركا تفكّرت كلمت` السرّ تاعك القديمة و ما بقيتش باغي تبدّلها، تنجم برك تتنسّا هاد الميساج و تدخُل ب كلمت` السرّ تاعك تاع مضاري.",
        "passwordreset-emailelement": "سميّت` المستعملي: \n$1\n\nكلمت` السرّ المأقّتة: \n$2",
        "passwordreset-emailsentemail": "راه نبعَت إيمال تاع تبدال كلمت` السرّ.",
-       "passwordreset-emailsent-capture": "راه اترسل إيمال تاع تبدال كلمت` السرّ، و راه محطوط هنا لتحت.",
-       "passwordreset-emailerror-capture": "راه اترسل الإيمال تاع تبدال كلمت` السرّ، الّي راح محطوط هنا لتحت، بصّح البعيت تاعهُ لل {{GENDER:$2|مستعملي}} ما نجحش: $1",
        "changeemail": "بدّل لادريسة تاع الإيمال",
        "changeemail-header": "كمّل الكتبة ف` الجدوال هادا باش تبدّل لادريسة تاع الإيمال تاعك. يلزم لك تدخّل كلمت` السرّ تاعك باش تأكّد هاد التبدال.",
        "changeemail-no-info": "لازم لك تكون مسجّل داخل باش توصَل ل هاد الپاجة بسّراح.",
index 74c6dec..dcab5ec 100644 (file)
        "yourname": "smiṫ l-mosṫĥdim:",
        "yourpassword": "Saroṫ:",
        "yourpasswordagain": "aaawd ktb lmot de passe dyalk",
-       "remembermypassword": "Ĝqel ĝla smiyṫ l-ḫsab dyali fe had l-ordinaṫør (ġir limoddaṫ {{PLURAL:$1|yom waḫed|$1 iyyam}})",
        "yourdomainname": "domain dyalk",
        "externaldberror": "kayn imma ċi ĥata' f-doĥol qaĝidaṫ l-bayanaṫ wlla rah ma msmoḫ-likċ baċ ṫḫddṫ l-ḫisab l-ĥariji taĝk.",
        "login": "Dĥel",
        "undo-failure": "ma ṣlaḫ-ċ ṫredd ṫ-ṫĝdil ḫiṫ tra ċi ṫĝdil mn morah.",
        "undo-norev": "ma ṣlaḫ-ċ ṫredd ṫ-ṫĝdil ḫiṫ ma kayn-ċ wlla ṫhyyed.",
        "undo-summary": "reḍḍ l-morajaĝa $1 d-[[Special:Contributions/$2|$2]] ([[User talk:$2|niqaċ]])",
-       "cantcreateaccounttitle": "lcont maymknch tnchaa",
        "viewpagelogs": "Ċof l-ĝamaliyaṫ dyal had ṣ-ṣefḫa",
        "nohistory": "ma kayn ḫṫṫa istorik d-ṫĝdilaṫ l-had ṣfḫa.",
        "currentrev": "Ċof l-versyon l-leĥĥra",
        "listusers-blocked": "(mbloki)",
        "activeusers": "lista dyal lmostkhdimin nachtin",
        "activeusers-from": "wrri l-mosṫĥdimin lli badyin mn:",
-       "activeusers-hidebots": "khbbi lbotat",
-       "activeusers-hidesysops": "Khbbi lidariyin",
        "activeusers-noresult": "ta mostakhdim matlgach.",
        "listgrouprights": "salahiyat mjmoat lmostkhdimin",
        "listgrouprights-key": "* <span class=\"listgrouprights-granted\">ḫoqoq mĝtiyya</span>\n* <span class=\"listgrouprights-revoked\">ḫoqoq mḫeyyda</span>",
        "htmlform-submit": "ṣift",
        "htmlform-reset": "rojoa an taadilat",
        "htmlform-selectorother-other": "okhra",
-       "sqlite-has-fts": "$1 maa imkaniyat lbaht f nass kaml",
-       "sqlite-no-fts": "$1 imkaniyat lbaht f nass kaml",
        "revdelete-restricted": "tḅḅq ḍ-ḍawaḅit ll-idariyyin",
        "revdelete-unrestricted": "ḫyyd ḍ-ḍawaḅit ll-idariyyin",
        "rightsnone": "(walo)",
index 0e51642..947d17d 100644 (file)
        "userlogin-yourpassword": "الباسورد:",
        "yourpasswordagain": "اكتب الباسورد تاني:",
        "createacct-yourpasswordagain": "أكد كلمه السر",
-       "remembermypassword": " (لمدة   $1 {{PLURAL:$1|يوم|يوم}})خليك فاكر دخولى على الكمبيوتر دا",
        "yourdomainname": "النطاق بتاعك:",
        "externaldberror": "يا إما فى حاجة غلط فى الدخول على قاعدة البيانات الخارجية أو انت مش مسموح لك تعمل تحديث لحسابك الخارجي.",
        "login": "دخول",
        "activeusers-intro": "دى قايمه اليوزرات اللى عملوا نشاط فى آخر $1 {{PLURAL:$1|يوم|يوم}}.",
        "activeusers-count": "$1 {{PLURAL:$1|تعديل|تعديل}} فى آخر {{PLURAL:$3|يوم|$3 يوم}}",
        "activeusers-from": "عرض اليوزرات بداية من:",
-       "activeusers-hidebots": "خبى البوتات",
-       "activeusers-hidesysops": "خبى السيسوبات",
        "activeusers-noresult": "مالقيناش اى يوزر",
        "listgrouprights": "حقوق مجموعات اليوزرز",
        "listgrouprights-summary": "دى لستة بمجموعات اليوزرز المتعرفة فى الويكى دا، بالحقوق اللى معاهم.\nممكن تلاقى معلومات زيادة عن الحقوق بتاعة كل واحد  [[{{MediaWiki:Listgrouprights-helppage}}|هنا]].",
index 941b518..70a1442 100644 (file)
@@ -19,7 +19,8 @@
                        "Macofe",
                        "IKHazarika",
                        "Dibya Dutta",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "চাণক্য কুমাৰ দাস"
                ]
        },
        "tog-underline": "সংযোগসমূহ অধোৰেখিত কৰক:",
@@ -37,6 +38,7 @@
        "tog-watchdefault": "মই সম্পাদনা কৰা সকলো পৃষ্ঠা মোৰ লক্ষ্য-তালিকাত যোগ কৰক",
        "tog-watchmoves": "মই স্থানান্তৰ কৰা সকলো পৃষ্ঠা আৰু ফাইল মোৰ লক্ষ্য-তালিকাত যোগ কৰক",
        "tog-watchdeletion": "মই বিলোপ কৰা সকলো পৃষ্ঠা মোৰ লক্ষ্য-তালিকাত যোগ কৰক",
+       "tog-watchuploads": "মই আপল'ড কৰা নতুন ফাইলসমূহ মোৰ লক্ষ্যপৃষ্ঠাত যোগ কৰক",
        "tog-watchrollback": "মই পূৰ্ববত কৰা পৃষ্ঠা মোৰ লক্ষ্য-তালিকাত যোগ কৰা হওক",
        "tog-minordefault": "সকলো সম্পাদনা অগুৰুত্বপূৰ্ণ বুলি নিজে নিজে চিহ্নিত কৰক",
        "tog-previewontop": "সম্পাদনা বাকছৰ ওপৰত খচৰা দেখুৱাওক",
@@ -46,7 +48,7 @@
        "tog-enotifminoredits": "অগুৰুত্বপূৰ্ণ সম্পাদনা হ'লেও মোলৈ ই-মেইল পঠাব",
        "tog-enotifrevealaddr": "জাননী ই-মেইল বোৰত মোৰ ই-মেইল ঠিকনা দেখুৱাব",
        "tog-shownumberswatching": "লক্ষ্য কৰি থকা সদস্য সমূহৰ সংখ্যা দেখুৱাওক",
-       "tog-oldsig": "বৰ্তমানৰ স্বাক্ষৰ:",
+       "tog-oldsig": "à¦\86পà§\8bনাৰ à¦¬à§°à§\8dতমানৰ à¦¸à§\8dবাà¦\95à§\8dষৰ:",
        "tog-fancysig": "স্বাক্ষৰ ৱিকিটেক্সট হিচাপে ব্যৱহাৰ কৰক (স্বয়ংক্ৰিয় সংযোগ অবিহনে)",
        "tog-uselivepreview": "তাৎক্ষণিক প্ৰাক্‌দৰ্শন ব্যৱহাৰ কৰক",
        "tog-forceeditsummary": "সম্পাদনাৰ সাৰাংশ নিদিলে মোক জনাব",
@@ -54,6 +56,7 @@
        "tog-watchlisthidebots": "মোৰ লক্ষ্য-তালিকাত ব'টে কৰা সম্পাদনা নেদেখুৱাব",
        "tog-watchlisthideminor": "মোৰ লক্ষ্য-তালিকাত অগুৰুত্বপূৰ্ণ সম্পাদনা নেদেখুৱাব",
        "tog-watchlisthideliu": "প্ৰবেশ কৰা সদস্যৰ সম্পাদনাসমূহ আঁতৰাই অনুসৰণ-তালিকা দেখুৱাওক",
+       "tog-watchlistreloadautomatically": "পৰিশোধক সলনি হ'লেই লক্ষ্যপৃষ্ঠা স্বয়ংক্ৰিয়ভাৱে ৰিল'ড কৰক (জাভাস্ক্ৰিপ্টৰ প্ৰয়োজন)",
        "tog-watchlisthideanons": "বেনামী সদস্যৰ সম্পাদনাসমূহ আঁতৰাই অনুসৰণ-তালিকা দেখুৱাওক",
        "tog-watchlisthidepatrolled": "পৰীক্ষিত সম্পাদনাসমূহ লক্ষ্য-তালিকাৰ পৰা লুকুৱাই ৰাখক",
        "tog-watchlisthidecategorization": "পৃষ্ঠাবোৰৰ শ্ৰেণীকৰণ লুকুৱাওক",
@@ -62,7 +65,7 @@
        "tog-showhiddencats": "নিহিত শ্ৰেণীসমূহ দেখুৱাওক",
        "tog-norollbackdiff": "পূৰ্বৱত কৰা পাছত পাৰ্থক্য নেদেখুৱাব",
        "tog-useeditwarning": "সালসলনি সংৰক্ষণ নকৰাকৈ সম্পাদনা পৃষ্ঠা ত্যাগৰ সময়ত মোক সাৱধান কৰক",
-       "tog-prefershttps": "পà§\8dৰৱà§\87শ à¦\95ৰà§\8bà¦\81তà§\87 à¦¸à¦¦à¦¾à¦¯à¦¼ সুৰক্ষিত সংযোগ ব্যৱহাৰ কৰক",
+       "tog-prefershttps": "পà§\8dৰৱà§\87শ à¦\95ৰাৰ à¦¸à¦®à¦¯à¦¼à¦¤ সুৰক্ষিত সংযোগ ব্যৱহাৰ কৰক",
        "underline-always": "সদায়",
        "underline-never": "কেতিয়াও নহয়",
        "underline-default": "ব্ৰাউজাৰ ডিফল্ট",
        "october-date": "অক্টোবৰ $1",
        "november-date": "নৱেম্বৰ $1",
        "december-date": "ডিচেম্বৰ $1",
+       "period-am": "পূৰ্বাহ্ন",
+       "period-pm": "অপৰাহ্ন",
        "pagecategories": "{{PLURAL:$1|শ্ৰেণী|শ্ৰেণীসমূহ}}",
        "category_header": "\"$1\" শ্ৰেণীৰ পৃষ্ঠাসমূহ",
        "subcategories": "উপশ্ৰেণীসমূহ",
        "newwindow": "(নতুন ৱিণ্ড'ত খোল খায়)",
        "cancel": "বাতিল কৰক",
        "moredotdotdot": "অধিক...",
-       "morenotlisted": "এই তালিকা সম্পূৰ্ণ নহয়।",
+       "morenotlisted": "এই তালিকা সম্পূৰ্ণ নহ'ব পাৰে।",
        "mypage": "পৃষ্ঠা",
        "mytalk": "বাৰ্তালাপ",
-       "anontalk": "à¦\8fà¦\87 IP-ত à¦¯à§\8bà¦\97াযà§\8bà¦\97 à¦\95ৰক",
+       "anontalk": "বাৰà§\8dতা à¦¦à¦¿à¦¯à¦¼ক",
        "navigation": "দিকদৰ্শন",
        "and": "&#32;আৰু",
        "qbfind": "বিচৰা হওক",
        "talk": "আলোচনা",
        "views": "দৰ্শন",
        "toolbox": "সঁজুলিসমূহ",
+       "tool-link-userrights": "{{GENDER:$1|সদস্য}} গোটসমূহ সলাওক",
+       "tool-link-emailuser": "এই {{GENDER:$1|সদস্যজনক}} ইমেইল কৰক",
        "userpage": "সদস্য পৃষ্ঠা চাওক",
        "projectpage": "প্ৰকল্প পৃষ্ঠা চাওক",
        "imagepage": "নথি পৃষ্ঠা চাওক",
        "laggedslavemode": "সাৱধানবাণী: ইয়াত সাম্প্ৰতিক সাল-সলনি নাথাকিব পাৰে",
        "readonly": "তথ্যকোষ বন্ধ কৰা আছে",
        "enterlockreason": "বন্ধ কৰাৰ কাৰণ দিয়ক, লগতে কেতিয়ামানে খোলা হব তাকো জনাব।",
-       "readonlytext": "হয়তো নিয়মীয়া পৰিচৰ্যাৰ বাবে তথ্যকোষত নতুন সম্পাদনা আৰু আন সাল-সলনি বন্ধ কৰা হৈছে। কিছু সময় পিছত এয়া সাধাৰণ অৱস্থালৈ আহিব।\n\nযিজন প্ৰশাসকে বন্ধ কৰিছে তেওঁ এই কাৰণ দিছে: $1",
+       "readonlytext": "হয়তà§\8b à¦¨à¦¿à¦¯à¦¼à¦®à§\80য়া à¦ªà§°à¦¿à¦\9aৰà§\8dযাৰ à¦¬à¦¾à¦¬à§\87 à¦¤à¦¥à§\8dযà¦\95à§\8bষত à¦¨à¦¤à§\81ন à¦¸à¦®à§\8dপাদনা à¦\86ৰà§\81 à¦\86ন à¦¸à¦¾à¦²-সলনি à¦¬à¦¨à§\8dধ à¦\95ৰা à¦¹à§\88à¦\9bà§\87। à¦\95িà¦\9bà§\81 à¦¸à¦®à¦¯à¦¼ à¦ªà¦¿à¦\9bত à¦\8fয়া à¦¸à¦¾à¦§à¦¾à§°à¦£ à¦\85ৱসà§\8dথালà§\88 à¦\86হিব।\n\nযিà¦\9cন à¦ªà§\8dৰণালà§\80 à¦ªà§\8dৰশাসà¦\95à§\87 à¦¬à¦¨à§\8dধ à¦\95ৰিà¦\9bà§\87 à¦¤à§\87à¦\93à¦\81 à¦\8fà¦\87 à¦\95াৰণ à¦¦à¦¿à¦\9bà§\87: $1",
        "missing-article": "\"$1\" $2 লেখাটো তথ্যকোষত পোৱা নগ’ল ।\n\nবিলোপ কৰা কোনো পৃষ্ঠাৰ সংযোগৰ বাবে সাধাৰণতে এনে ঘটে ।\n\nযদি এনে হোৱা নাই তেন্তে আপুনি ছফ্টৱেৰত কিবা সমস্যা পাইছে ।\nঅনুগ্ৰহ কৰি এই সম্পৰ্কে ইউ.আৰ.এল. সহ কোনো [[Special:ListUsers/sysop|প্ৰশাসক]]ক জনাওক ।",
        "missingarticle-rev": "(সংস্কৰণ#: $1)",
        "missingarticle-diff": "(তফাৎ: $1, $2)",
        "title-invalid-talk-namespace": "অনুৰোধ কৰা পৃষ্ঠাৰ শিৰোনামে এটা আলোচনা পৃষ্ঠা সূচাইছে যিটো থাকিব নোৱাৰে।",
        "title-invalid-characters": "অনুৰোধ কৰা পৃষ্ঠাৰ শিৰোনামত অবৈধ চিহ্ন আছে: \"$1\"।",
        "title-invalid-magic-tilde": "অনুৰোধ কৰা পৃষ্ঠাৰ শিৰোনামত অবৈধ যাদুকৰী টাইল্ড শৃংখল আছে (<nowiki>~~~</nowiki>)।",
-       "title-invalid-too-long": "অনুৰোধ কৰা পৃষ্ঠাৰ শিৰোনাম অতি দীঘল। UTF-8 এন্‌ক'ডিঙত ই {PLURAL:$1|বাইট}}তকৈ দীঘল হ'ব নালাগে।",
+       "title-invalid-too-long": "অনুৰোধ কৰা পৃষ্ঠাৰ শিৰোনাম অতি দীঘল। UTF-8 এন্‌ক'ডিঙত ই $1 {{PLURAL:$1|বাইটতকৈ}} দীঘল হ'ব নালাগে।",
        "title-invalid-leading-colon": "অনুৰোধ কৰা পৃষ্ঠাৰ শিৰোনামৰ আৰম্ভণিত এটা অবৈধ ক'ল'ন আছে।",
        "perfcached": "তলত দিয়া তথ্যখিনি আগতে জমা কৰি থোৱা (cached) আৰু সাম্প্ৰতিক নহ'ব পাৰে। এই তথ্যখিনিত সৰ্বোচ্চ {{PLURAL:$1|এটা ফলাফল|$1টা ফলাফল}} উপলব্ধ।",
        "perfcachedts": "তলত দিয়া তথ্য খিনি আগতে জমা কৰি থোৱা (cached) আৰু শেষবাৰৰ কাৰণে $1 ত নবীকৰণ কৰা হৈছিল। সৰ্বাধিক {{PLURAL:$4|এটা ফলাফল|$4 টা ফলাফল}} এই কেশ্বত পাব।",
        "viewsource": "উৎস চাওক",
        "viewsource-title": "$1ৰ উৎস চাওক",
        "actionthrottled": "কাৰ্য লেহেম কৰা হৈছে",
-       "actionthrottledtext": "সà§\8dপাম à§°à§\8bধ à¦\95ৰিবলà§\88 à¦\8fà¦\87 à¦\95à§\8dৰিয়াতà§\8b à¦\95ম à¦¸à¦®à¦¯à¦¼à§° à¦­à¦¿à¦¤à§°à¦¤ à¦¬à¦¹à§\81 à¦¬à§\87à¦\9bি à¦¬à¦¾à§° à¦\95ৰাতà§\8b à§°à§\8bধ à¦\95ৰা à¦¹à§\88à¦\9bà§\87, আৰু আপুনি ইতিমধ্যে সেই সীমা অতিক্ৰম কৰিলে।\nঅনুগ্ৰহ কৰি কিছু সময় পাছত চেষ্টা কৰক।",
+       "actionthrottledtext": "দà§\81ৰà§\8dবাà¦\95à§\8dয à§°à§\8bধ à¦\95ৰিবলà§\88 à¦\8fà¦\87 à¦\95à§\8dৰিয়াতà§\8b à¦\95ম à¦¸à¦®à¦¯à¦¼à§° à¦­à¦¿à¦¤à§°à¦¤ à¦¬à¦¹à§\81 à¦¬à§\87à¦\9bি à¦¬à¦¾à§° à¦\95ৰাà¦\9fà§\8b à¦¨à¦¿à¦·à§\87ধ আৰু আপুনি ইতিমধ্যে সেই সীমা অতিক্ৰম কৰিলে।\nঅনুগ্ৰহ কৰি কিছু সময় পাছত চেষ্টা কৰক।",
        "protectedpagetext": "সম্পাদনা ৰোধ কৰিবলৈ এই পৃষ্ঠাটো সুৰক্ষিত কৰা হৈছে।",
        "viewsourcetext": "আপুনি এই পৃষ্ঠাটোৰ উৎস চাব আৰু প্ৰতিলিপি কৰিব পাৰে।",
        "viewyourtext": "আপুনি <strong>আপোনাৰ সম্পাদনাসমূহ</strong>ৰ উৎস চাব আৰু এই পৃষ্ঠালৈ প্ৰতিলিপি কৰিব পাৰে।",
        "virus-scanfailed": "স্কেন অসফল (কোড $1)",
        "virus-unknownscanner": "অজ্ঞাত এন্টিভাইৰাচ:",
        "logouttext": "'''আপুনি প্ৰস্থান কৰিলে।'''\n\nমন কৰিব যে যেতিয়ালৈকে আপোনাৰ ব্ৰাউজাৰৰ অস্থায়ী-স্মৃতি (cache) খালী নকৰে, তেতিয়ালৈকে কিছুমান পৃষ্ঠাত আপুনি প্ৰৱেশ কৰা বুলি দেখুৱাই থাকিব পাৰে।",
+       "cannotlogoutnow-title": "এতিয়া প্ৰস্থান কৰিব নোৱাৰি",
+       "cannotlogoutnow-text": "$1 ব্যৱহাৰ কৰাৰ সময়ত প্ৰস্থান কৰিব নোৱাৰি।",
        "welcomeuser": "আদৰিছোঁ, $1!",
        "welcomecreation-msg": "== আদৰিছোঁ, $1! ==\nআপোনাৰ সদস্যভুক্তি হৈ গ’ল ।\n[[Special:Preferences|{{SITENAME}}ৰ পছন্দসমূহ]]ত আপোনাৰ পছন্দমতে ব্যক্তিগতকৰণ কৰি ল’বলৈ নাপাহৰে যেন ।",
        "yourname": "সদস্যনাম:",
        "yourpasswordagain": "গুপ্তশব্দ আকৌ এবাৰ লিখক",
        "createacct-yourpasswordagain": "গুপ্তশব্দ নিশ্চিত কৰক",
        "createacct-yourpasswordagain-ph": "গুপ্তশব্দ আকৌ লিখক",
-       "remembermypassword": "মোৰ প্ৰৱেশ এই কম্পিউটাৰত মনত ৰাখিব (সৰ্বাধিক $1 {{PLURAL:$1|দিনলৈ|দিনলৈ}})",
        "userlogin-remembermypassword": "মোক লগ্‌-ইন কৰাই ৰাখক",
        "userlogin-signwithsecure": "নিৰাপদ সংযোগ ব্যৱহাৰ কৰক",
+       "cannotlogin-title": "প্ৰৱেশ কৰিব নোৱাৰি",
+       "cannotlogin-text": "প্ৰৱেশ কৰা সম্ভৱ নহয়",
+       "cannotloginnow-title": "এতিয়া প্ৰৱেশ কৰিব নোৱাৰি",
+       "cannotloginnow-text": "$1 ব্যৱহাৰ কৰাৰ সময়ত প্ৰৱেশ কৰিব নোৱাৰি।",
        "yourdomainname": "আপোনাৰ ডমেইন:",
        "password-change-forbidden": "আপুনি এই ৱিকিত গুপ্তশব্দ সলাব নোৱাৰে।",
        "externaldberror": "কোনো প্ৰামাণ্যকৰণ তথ্যকোষৰ ত্ৰুটি ঘটিছে নতুবা আপোনাৰ বৰ্হি-একাউণ্ট নৱীকৰণ কৰাৰ অনুমতি নাই ।",
        "passwordreset-emailtext-user": "{{SITENAME}}ত $1 ব্যৱহাৰকাৰীয়ে {{SITENAME}} ($4)ৰ বাবে আপোনাৰ গুপ্তশব্দ ন-কৈ বহুৱাবলৈ অনুৰোধ জনাইছিল। ই-পত্ৰ ঠিকনাটোৰ লগত এই সদস্যৰ {{PLURAL:$3|একাউণ্ট|একাউণ্টসমূহ}} জড়িত হৈ আছে।\n \n$2\n \n{{PLURAL:$3|এই অস্থায়ী গুপ্তশব্দ|এই অস্থায়ী গুপ্তশব্দবোৰ}} {{PLURAL:$5|এদিনত|$5 দিনত }} নাইকীয়া হ’ব । আপুনি লগ-ইন কৰি এটা নতুন গুপ্তশব্দ দিয়া উচিত। যদি আন কোনোবাই এই অনুৰোধ কৰিছিল, বা আপুনি নিজৰ পূৰ্বৰ গুপ্তশব্দ মনত পেলাইছে আৰু ইয়াক সলাব খোজা নাই, তেন্তে আপুনি এই বাৰ্তাক অগ্ৰাহ্য কৰি নিজৰ পূৰ্বৰ গুপ্তশব্দ ব্যৱহাৰ কৰি থাকিব পাৰে।",
        "passwordreset-emailelement": "সদস্যনাম: \n$1\n\nঅস্থায়ী গুপ্তশব্দ: \n$2",
        "passwordreset-emailsentemail": "এইটো আপোনাৰ একাউণ্টৰ পঞ্জীকৃত ই-মেইল ঠিকনা হয়নে, হয় যদি এটা গুপ্তশব্দ উদ্ধাৰ ই-মেইল পঠিওৱা হ'ব।",
-       "passwordreset-emailsent-capture": "এখন গুপ্তশব্দ উদ্ধাৰ ইমেইল পঠিওৱা হৈছে, এইখন তলত দেখা পাব।",
-       "passwordreset-emailerror-capture": "এখন গুপ্তশব্দ উদ্ধাৰ ইমেইল সৃষ্টি কৰা হ'ল, কিন্তু {{GENDER:$2|সদস্যজনলৈ}} পঠিয়াব পৰা নগ'ল। সেইখন তলত দেখুওৱা হৈছে: $1",
        "changeemail": "ই-মেইল ঠিকনা সলনি নাইবা বিলোপ কৰক",
        "changeemail-header": "একাউণ্টৰ ই-মেইল ঠিকনা সলনি কৰক",
        "changeemail-no-info": "এই পৃষ্ঠাটোত প্ৰৱেশাধিকাৰ পাবলৈ আপুনি লগ্‌ ইন কৰিব লাগিব।",
        "minoredit": "এইটো এটা অগুৰুত্বপূৰ্ণ সম্পাদনা",
        "watchthis": "এই পৃষ্ঠাটো লক্ষ্য কৰক",
        "savearticle": "পৃষ্ঠা সাঁচক",
+       "savechanges": "সাঁচি থওক",
        "preview": "খচৰা",
        "showpreview": "খচৰা চাওক",
        "showdiff": "সালসলনিবোৰ দেখুৱাওক",
        "newarticle": "(নতুন)",
        "newarticletext": "আপুনি বিচৰা প্ৰবন্ধটো বিচাৰি পোৱা নগ'ল।\n\nইচ্ছা কৰিলে আপুনিয়েই এই প্ৰবন্ধটো লিখা আৰম্ভ কৰিব পাৰে। [$1 ইয়াত] সহায় পাব।\n\nআপুনি যদি ইয়ালৈ ভুলতে আহিছে, তেনেহলে আপোনাৰ ব্ৰাওজাৰৰ '''BACK''' বুটামত টিপা মাৰক।",
        "anontalkpagetext": "----''এইখন আলোচনা পৃষ্ঠা বেনামী সদস্যৰ বাবে, যিয়ে নিজা একাউণ্ট  সৃষ্টি কৰা নাই বা যিয়ে সেই একাউণ্ট ব্যৱহাৰ নকৰে।\nএতেকে আমি তেখেতসকলক আই-পি ঠিকনাৰে চিনাক্ত কৰিবলৈ বাধ্য।\nসেই একেই আই-পি ঠিকনা অনেকেই ব্যৱহাৰ কৰিব পাৰে।\nআপুনি যদি এজন বেনামী সদস্য আৰু যদি আপুনি অনুভৱ কৰে যে আপোনাৰ প্ৰতি অপ্ৰাসঙ্গিক মন্তব্য কৰা হৈছে, তেনেহলে আন বেনামী সদস্যৰ পৰা পৃথক কৰিবলৈ \n[[Special:CreateAccount|একাউন্ট সৃষ্টি কৰক]] বা [[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}}|এই শিৰোনামা সন্ধান কৰিব পাৰে]],\nবা <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} সম্পৰ্কীয় অভিলেখ সন্ধান কৰিব পাৰে]</span>, কিন্তু এই পৃষ্ঠা সৃষ্টি কৰিবলৈ আপোনাৰ অনুমতি নাই।",
        "missing-revision": "\"{{FULLPAGENAME}}\" নামৰ পৃষ্ঠাৰ #$1 সংশোধনৰ অস্তিত্ব নাই।\n\nসাধাৰণতে বিলোপ কৰা এখন পৃষ্ঠাৰ পুৰণা ইতিহাস লিংক অনুসৰণ কৰিলে এনে হয়।\n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} বিলোপন ল'গ]ত অধিক তথ্য পাব।",
        "userpage-userdoesnotexist": "\"<nowiki>$1</nowiki>\" নামৰ সদস্য একাউন্ট নিবন্ধিত নহয় ।\nঅনুগ্ৰহ কৰি চাওক আপুনি এই পৃষ্ঠা সৃষ্টি/সম্পাদনা কৰিব বিচাৰিছে নেকি ।",
        "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$3 য়ে আগবঢ়োৱা ইয়াৰ কাৰণ হৈছে ''$2''",
        "cantcreateaccount-range-text": "[[User:$3|$3]]য়ে <strong>$1</strong> পৰিসীমাৰ আই পি ঠিকনাৰ পৰা একাউণ্ট সৃষ্টি বাৰণ কৰিছে যাৰ ভিতৰত আপোনাৰ আই ই ঠিকনাও (<strong>$4</strong>) আছে।\n\n $3য়ে <em>$2</em> বুলি কাৰণ দৰ্শাইছে",
        "viewpagelogs": "এই পৃষ্ঠাৰ অভিলেখ চাওক ।",
        "suppress": "অমনোযোগ",
        "querypage-disabled": "কাৰ্য্যগত কাৰণত এই বিশেষ পৃষ্ঠাটো নিষ্ক্ৰিয় কৰা হৈছে।",
        "apisandbox-results": "ফলাফল",
+       "apisandbox-continue": "অব্যাহত ৰাখক",
        "booksources": "গ্ৰন্থৰ উৎস সমূহ",
        "booksources-search-legend": "গ্ৰন্থ উৎস সন্ধান",
        "booksources-search": "সন্ধান",
        "activeusers-intro": "যোৱা  {{PLURAL:$1|দিন|দিন}}ৰ ভিতৰত অৱদান আগবঢ়োৱা ব্যৱহাৰকাৰীৰ তালিকা",
        "activeusers-count": "যোৱা {{PLURAL:$3|দিনত|$3 দিনত}} সৰ্বমুঠ $1 {{PLURAL:$1|টা কাম}}",
        "activeusers-from": "ইয়াৰে আৰম্ভ হোৱা ব্যৱহাৰকাৰী সকল দেখুৱাওক:",
-       "activeusers-hidebots": "বট নেদেখুৱাব",
-       "activeusers-hidesysops": "প্ৰশাসক নেদেখুৱাব",
        "activeusers-noresult": "কোনো সদস্য পোৱা নগ'ল।",
        "listgrouprights": "ব্যৱহাৰকাৰী গোটৰ অধিকাৰ",
        "listgrouprights-summary": "এই ৱিকিত থকা গোটসমূহৰ তালিকা সেইবোৰৰ প্ৰৱেশাধিকাৰসহ তলত দিয়া হ’ল ।\nসুকীয়া অধিকাৰ সম্পৰ্কে [[{{MediaWiki:Listgrouprights-helppage}}|অধিক তথ্য]] থাকিব পাৰে ।",
        "contributions": "{{GENDER:$1|সদস্যৰ}} বৰঙণিসমূহ",
        "contributions-title": "$1ৰ বৰঙণিসমূহ",
        "mycontris": "বৰঙণিসমূহ",
+       "anoncontribs": "বৰঙণি",
        "contribsub2": "{{GENDER:$3|$1}} ($2)ৰ কাৰণে",
        "nocontribs": "এই গুণসমূহৰ লগত মিল থকা কোনো সালসলনি পোৱা নগ’ল ।",
        "uctop": "(বৰ্তমান)",
        "javascripttest": "জাভাস্ক্ৰিপ্ট পৰীক্ষা।",
        "javascripttest-pagetext-unknownaction": "অজ্ঞাত কাৰ্য \"$1\"।",
        "javascripttest-qunit-intro": "mediawiki.org-ত [$1 পৰীক্ষা নথিকৰণ] চাওক।",
-       "tooltip-pt-userpage": "আপোনাৰ সদস্য পৃষ্ঠা",
+       "tooltip-pt-userpage": "{{GENDER:|আপোনাৰ সদস্য}} পৃষ্ঠা",
        "tooltip-pt-anonuserpage": "যি আই.পি. ঠিকনাৰ পৰা আপুনি সম্পাদনা কৰিছে তাৰ সদস্য পৃষ্ঠা",
-       "tooltip-pt-mytalk": "আপোনাৰ আলোচনা পৃষ্ঠা",
+       "tooltip-pt-mytalk": "{{GENDER:|আপোনাৰ}} আলোচনা পৃষ্ঠা",
        "tooltip-pt-anontalk": "এই আই.পি. ঠিকনাৰ পৰা কৰা সম্পাদনাসমূহৰ আলোচনা",
-       "tooltip-pt-preferences": "আপোনাৰ পছন্দসমূহ",
+       "tooltip-pt-preferences": "{{GENDER:|আপোনাৰ}} পছন্দসমূহ",
        "tooltip-pt-watchlist": "আপুনি সালসলনিৰ গতিবিধি লক্ষ্য কৰি থকা পৃষ্ঠাসমূহৰ সুচী",
-       "tooltip-pt-mycontris": "আপোনাৰ বৰঙণিৰ তালিকা",
+       "tooltip-pt-mycontris": "{{GENDER:|আপোনাৰ}} বৰঙণিসমূহ",
        "tooltip-pt-login": "বাধ্যতামূলক নহ'লেও প্ৰৱেশ কৰাটো বাঞ্চনীয়",
        "tooltip-pt-logout": "প্ৰস্থান",
        "tooltip-pt-createaccount": "আপোনাক এটা একাউণ্ট সৃষ্টি কৰি প্ৰৱেশ কৰিবলৈ অনুৰোধ জনোৱা হৈছে, কিন্তু এয়া বাধ্যতামূলক নহয়",
        "tooltip-t-recentchangeslinked": "সংযুক্ত পৃষ্ঠাসমূহৰ শেহতীয়া সালসলনিসমূহ",
        "tooltip-feed-rss": "এই পৃষ্ঠাৰ বাবে আৰ-এচ-এচ ভুক্তি",
        "tooltip-feed-atom": "এই পৃষ্ঠাৰ বাবে এটম ভুক্তি",
-       "tooltip-t-contributions": "এই সদস্যজনৰ অৰিহনাসমূহৰ সূচী চাওক",
+       "tooltip-t-contributions": "{{GENDER:$1|এই সদস্যজনৰ}} বৰঙণিসমূহৰ তালিকা চাওক",
        "tooltip-t-emailuser": "এই সদস্যজনলৈ ই-মেইল পঠাওক",
        "tooltip-t-info": "এই পৃষ্ঠাৰ বিষয়ে অধিক তথ্য",
        "tooltip-t-upload": "ফাইল আপল'ডৰ বাবে",
        "htmlform-chosen-placeholder": "এটা বিকল্প বাছনি কৰক",
        "htmlform-cloner-create": "আৰু যোগ কৰক",
        "htmlform-cloner-delete": "আঁতৰাওক",
-       "sqlite-has-fts": "$1 সম্পূৰ্ণ-পাঠ অনুসন্ধান সমৰ্থন সহ",
-       "sqlite-no-fts": "$1 সম্পূৰ্ণ-পাঠ সন্ধান সমৰ্থন অবিহনে",
        "logentry-delete-delete": "$3 পৃষ্ঠাটো $1ৰদ্বাৰা {{GENDER:$2|বিলোপ কৰা হ'ল}}",
        "logentry-delete-restore": "$1-এ $3 পৃষ্ঠাটো {{GENDER:$2|পুনৰ্সংৰক্ষণ কৰিলে}}",
        "logentry-delete-event": "$3: $4 -ত {{PLURAL:$5|এটা লগ ঘটনা|$5 লগ ঘটনাসমূহ}} -ৰ $1 পৰিৱৰ্তন কৰা দৃশ্যমানতা",
        "special-characters-group-khmer": "খেমাৰ",
        "special-characters-title-endash": "en দেছ্‌",
        "special-characters-title-emdash": "em দেছ‌",
-       "special-characters-title-minus": "বিয়োগ চিন",
-       "api-error-blacklisted": "অনুগ্ৰহ কৰি অন্য এটা বৰ্ণনামূলক শিৰোনাম নিৰ্বাচন কৰক"
+       "special-characters-title-minus": "বিয়োগ চিন"
 }
index dde90d0..48ab3ee 100644 (file)
        "yourpasswordagain": "M535x523S14c50508x492S14c58469x492S22520503x477S22520465x477 M518x531S33b00482x483S1f711482x509 M516x515S10018484x485S1f010487x485 M528x514S15a39472x487S28802506x486S18250481x499 S38a00464x490",
        "createacct-yourpasswordagain": "M535x523S14c50508x492S14c58469x492S22520503x477S22520465x477 M518x531S33b00482x483S1f711482x509 M516x515S10018484x485S1f010487x485 M528x514S15a39472x487S28802506x486S18250481x499",
        "createacct-yourpasswordagain-ph": "M535x523S14c50508x492S14c58469x492S22520503x477S22520465x477 M518x531S33b00482x483S1f711482x509 M516x515S10018484x485S1f010487x485 M528x514S15a39472x487S28802506x486S18250481x499",
-       "remembermypassword": "M538x567S1f548504x543S1f520513x534S1f520513x481S22b04522x499S2ff00482x483 M514x514S15a01491x487S20500487x503 M538x521S2a200497x480S20b00462x508S11530523x482S15a37462x483S11551470x493 M536x521S2ff00482x483S10011515x491S28108515x461 M508x525S10004493x475S22a04494x510 M523x528S14011492x504S15a00477x495S2b800483x473 S38b00470x493 M536x521S2ff00482x483S10011515x491S28108515x461 M519x530S18210496x475S18218482x471S20b00496x483S22b00495x500 $1 {{PLURAL:$1|M526x534S15a1a499x522S10010507x467S28903478x486S37706474x522S37700520x495}} S38b04470x493",
        "userlogin-remembermypassword": "M521x526S1f750501x511S1f758480x511S26620493x474 M521x517S10043491x483S20500479x506 M538x521S2a200497x480S20b00462x508S11530523x482S15a37462x483S11551470x493",
        "password-change-forbidden": "M518x584S10004492x534S22a04493x569S30a00482x483 M518x633S19220493x614S14020479x583S19220493x561S18620491x530S30a00482x483 S38700463x496 M508x523S10040493x493S26500493x477 M527x521S10059473x479S10051497x479S20e00494x491S22a04493x506 M521x532S10609498x496S10621487x512S21100500x483S2df20479x468 M518x531S33b00482x483S1f711482x509 M516x515S10018484x485S1f010487x485 S38800464x496",
        "login": "M538x521S2a200497x480S20b00462x508S11530523x482S15a37462x483S11551470x493",
        "permissionserrorstext": "M508x523S10040493x493S26500493x477 M534x542S2ff00482x483S26500520x505S20e00521x526S1f540493x518 M531x528S15a40511x472S15a48478x472S2d200505x505S2d211470x505 {{PLURAL:$1|M547x518S30a00482x483S22124511x473S1c517522x483}} S38900464x493",
        "permissionserrorstext-withaction": "M508x523S10040493x493S26500493x477 M534x542S2ff00482x483S26500520x505S20e00521x526S1f540493x518 M531x528S15a40511x472S15a48478x472S2d200505x505S2d211470x505 $2 {{PLURAL:$1|M547x518S30a00482x483S22124511x473S1c517522x483}} S38900464x493",
        "log-fulllog": "M525x524S2ff00482x483S10e00507x494S26500511x474 M520x529S20e00493x504S20348493x486S15a51497x471S26503480x516 M518x536S15a37483x465S18550493x476S15a37483x509S15a51486x513",
-       "cantcreateaccounttitle": "M527x521S10059473x479S10051497x479S20e00494x491S22a04493x506 M532x519S20302493x485S2030a489x502S21100509x504S26900516x482S26910468x501 M518x517S15a30482x489S1f750484x484S20500496x506S22a04505x495",
        "viewpagelogs": "M525x524S2ff00482x483S10e00507x494S26500511x474 M531x512S15a37501x488S1f550507x495S20e00487x499S26502469x498 M518x536S15a37483x465S18550493x476S15a37483x509S15a51486x513",
        "currentrev-asof": "M521x524S1f740501x509S1f748479x498S20e00503x494S22a00502x476 M536x534S35610482x483S10601513x506S21600525x501 M521x532S10609498x496S10621487x512S21100500x483S2df20479x468 M557x536S36d00479x503S10001536x498S10009510x506S2b711518x476S2b700531x465 $1",
        "revisionasof": "M513x542S1ce50491x458S22a00492x492S14c50487x511 M519x539S14402488x485S1440a481x461S22b04503x509 M536x521S2ff00482x483S10011515x491S28108515x461 $1",
        "logentry-newusers-autocreate": "M526x522S15a56499x510S11520503x479S20e00489x496S26a02474x489 M518x517S15a30482x489S1f750484x484S20500496x506S22a04505x495 $1 M531x531S14c30506x469S2a204508x503S2a21c470x503S14c38470x469 {{GENDER:$2|M532x519S20302493x485S2030a489x502S21100509x504S26900516x482S26910468x501}} M520x525S15a18480x490S10a02483x476S23100494x508S20e00500x494",
        "log-name-managetags": "M519x514S15a28482x487S11502489x498 M530x529S10640507x503S10648479x489S26c08503x484S26c18470x471 M518x536S15a37483x465S18550493x476S15a37483x509S15a51486x513",
        "log-name-tag": "M519x514S15a28482x487S11502489x498 M518x536S15a37483x465S18550493x476S15a37483x509S15a51486x513",
-       "feedback-error-title": "M518x526S2ff00482x483S19a00487x506",
        "searchsuggest-search": "M546x525S2ff00482x483S16d10492x505S2e502519x502",
        "api-error-mustbeloggedin": "M539x579S10e27506x534S10e09480x534S22a07495x565S22a17469x564S21b00531x528S21b00504x528S30a00482x483 M520x576S14c19480x549S15a01497x550S20710483x530S30a00482x483 S38700463x496 M516x519S10651485x482S22a04493x504 M538x521S2a200497x480S20b00462x508S11530523x482S15a37462x483S11551470x493 S38800464x496",
        "api-error-unclassified": "M536x518S2ff00482x483S15a11513x486S28108513x453 M518x526S2ff00482x483S19a00487x506 M528x529S10030509x499S10038477x499S2a200505x472S2a218473x472",
index aab16b4..df7652d 100644 (file)
        "botpasswords-label-delete": "Desaniciar",
        "botpasswords-label-resetpassword": "Reestablecer la contraseña",
        "botpasswords-label-grants": "Permisos aplicables:",
-       "botpasswords-help-grants": "Cada permisu da accesu a los permisos de usuario llistaos que yá tenga la cuenta. Mira la [[Special:ListGrants|tabla de permisos]] pa más información.",
+       "botpasswords-help-grants": "Los permisos dan accesu a los permisos d'usuariu que yá tenga la cuenta. Activar un permisu equí nun da accesu a nengún permisu que la to cuenta nun tenga d'otra miente. Mira la [[Special:ListGrants|tabla de permisos]] pa más información.",
        "botpasswords-label-grants-column": "Permitío",
        "botpasswords-bad-appid": "El nome del bot \"$1\" nun ye válidu.",
        "botpasswords-insert-failed": "Nun pudo amestase'l nome de bot «$1». ¿Taba añadíu yá?",
        "passwordreset-nocaller": "Tien d'apurrise un llamador",
        "passwordreset-nosuchcaller": "El llamador nun esiste: $1",
        "passwordreset-ignored": "Nun se llogró'l reaniciu de la contraseña. ¿Seique nun se configuró un proveedor?",
-       "passwordreset-invalideamil": "Direición de corréu inválida",
+       "passwordreset-invalidemail": "Direición de corréu inválida",
        "passwordreset-nodata": "Nun s'apurrió nin un nome d'usuariu nin una dirección de corréu electrónicu",
        "changeemail": "Camudar o desaniciar la dirección de corréu electrónicu",
        "changeemail-header": "Completa esti formulariu pa camudar la dirección de corréu electrónicu. Si quies desaniciar l'asociación de cualquier dirección de corréu electrónicu de la to cuenta, dexa en blancu la nueva dirección de corréu electrónicu cuando unvies el formulariu.",
        "searchprofile-advanced-tooltip": "Buscar nos espacios de nomes personalizaos",
        "search-result-size": "$1 ({{PLURAL:$2|1 pallabra|$2 pallabres}})",
        "search-result-category-size": "{{PLURAL:$1|1 miembru|$1 miembros}} ({{PLURAL:$2|1 subcategoría|$2 subcategories}}, {{PLURAL:$3|1 ficheru|$3 ficheros}})",
-       "search-redirect": "(redireición de $1)",
+       "search-redirect": "(redireición dende $1)",
        "search-section": "(seición $1)",
        "search-category": "(categoría $1)",
        "search-file-match": "(casa col conteníu del ficheru)",
        "prefs-watchlist-edits-max": "Númberu máximu: 1000",
        "prefs-watchlist-token": "Pase de la llista de siguimientu:",
        "prefs-misc": "Varios",
-       "prefs-resetpass": "Camudar la conseña",
+       "prefs-resetpass": "Camudar la contraseña",
        "prefs-changeemail": "Camudar o desaniciar la dirección de corréu electrónicu",
        "prefs-setemail": "Conseñar una direición de corréu electrónicu",
        "prefs-email": "Opciones de corréu",
        "prefs-help-gender": "Configurar esta preferencia ye opcional. El software usa esti valor pa dirixise a ti y pa mentate a terceros col xéneru gramatical correchu.\nEsta información sedrá pública.",
        "email": "Corréu",
        "prefs-help-realname": "El nome real ye opcional.\nSi se da, pue usase pa date reconocimientu pol to trabayu.",
-       "prefs-help-email": "La direición de corréu ye opcional, pero ye necesaria pa unviate una conseña nueva si escaeces la tuya.",
+       "prefs-help-email": "La direición de corréu ye opcional, pero ye necesaria pa unviate una contraseña nueva si escaeces la tuya.",
        "prefs-help-email-others": "Tamién pues escoyer permitir qu'otres persones contauten contigo pela to páxina d'usuariu o la d'alderique ensin necesidá de revelar la to identidá.",
        "prefs-help-email-required": "Necesítase una direición de corréu electrónicu.",
        "prefs-info": "Información básica",
        "right-siteadmin": "Candar y descandar la base de datos",
        "right-override-export-depth": "Esportar páxines, incluyendo páxines enllazaes fasta una fondura de 5",
        "right-sendemail": "Unviar corréu a otros usuarios",
-       "right-passwordreset": "Ver los correos de reestablecimientu de conseña",
+       "right-passwordreset": "Ver los correos de reestablecimientu de contraseña",
        "right-managechangetags": "Crear y (des)activar [[Special:Tags|etiquetes]]",
        "right-applychangetags": "Aplicar [[Special:Tags|etiquetes]] xunto colos cambios propios",
        "right-changetags": "Amestar y desaniciar [[Special:Tags|etiquetes]] arbitraries en revisiones individuales y entraes del rexistru",
        "grant-basic": "Permisos básicos",
        "grant-viewdeleted": "Ver los ficheros y páxines desaniciaos",
        "grant-viewmywatchlist": "Ver la to llista de siguimientu",
+       "grant-viewrestrictedlogs": "Ver entraes acutaes del rexistru",
        "newuserlogpage": "Rexistru de creación d'usuarios",
        "newuserlogpagetext": "Esti ye un rexistru de creación d'usuarios.",
        "rightslog": "Rexistru de permisos d'usuariu",
        "upload-dialog-disabled": "Nesta wiki tán desactivaes les xubíes de ficheros por aciu d'esti diálogu.",
        "upload-dialog-title": "Xubir ficheru",
        "upload-dialog-button-cancel": "Encaboxar",
+       "upload-dialog-button-back": "Anterior",
        "upload-dialog-button-done": "Fecho",
        "upload-dialog-button-save": "Guardar",
        "upload-dialog-button-upload": "Xubir",
        "apisandbox-results-fixtoken-fail": "Nun pudo recuperase'l token «$1».",
        "apisandbox-alert-page": "Los campos d'esta páxina nun son válidos.",
        "apisandbox-alert-field": "El valor d'esti campu nun ye válidu.",
+       "apisandbox-continue": "Siguir",
+       "apisandbox-continue-clear": "Llimpiar",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries siguirá] cola última solicitú; {{int:apisandbox-continue-clear}} llimpiará los parámetros rellacionaos con siguir.",
+       "apisandbox-param-limit": "Escribe <kbd>max</kbd> pa usar la llende máxima.",
        "booksources": "Fontes de llibros",
        "booksources-search-legend": "Busca de fontes de llibros",
        "booksources-search": "Buscar",
        "booksources-text": "Esta ye una llista d'enllaces a otros sitios que vienden llibros nuevos y usaos, y que puen tener más información sobre los llibros que ta buscando:",
        "booksources-invalid-isbn": "El códigu ISBN que puxisti nun paez que valga; mira que te vien copiáu de la fonte orixinal.",
+       "magiclink-tracking-rfc": "Páxines que usen enllaces máxicos RFC",
+       "magiclink-tracking-rfc-desc": "Esta páxina utiliza enllaces máxicos RFC. Consulta [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] pa saber como facer la migración.",
+       "magiclink-tracking-pmid": "Páxines qu'usen enllaces máxicos PMID",
+       "magiclink-tracking-pmid-desc": "Esta páxina utiliza enllaces máxicos PMID. Consulta [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] pa saber como facer la migración.",
+       "magiclink-tracking-isbn": "Páxines que usen enllaces máxicos ISBN",
+       "magiclink-tracking-isbn-desc": "Esta páxina utiliza enllaces máxicos ISBN. Consulta [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] pa saber como facer la migración.",
        "specialloguserlabel": "Fecho por:",
        "speciallogtitlelabel": "Oxetivu (títulu o {{ns:user}}:nome d'usuariu):",
        "log": "Rexistros",
        "activeusers-intro": "Esta ye una llista d'usuarios que tuvieron alguna mena d'actividá hai menos de $1 {{PLURAL:$1|día|díes}}.",
        "activeusers-count": "$1 {{PLURAL:$1|edición|ediciones}} {{PLURAL:$3|nel caberu día|nos caberos $3 díes}}",
        "activeusers-from": "Amosar usuarios principiando dende:",
-       "activeusers-hidebots": "Anubrir bots",
-       "activeusers-hidesysops": "Anubrir alministradores",
+       "activeusers-groups": "Amosar los usuarios que pertenecen a los grupos:",
        "activeusers-noresult": "Nun s'alcontraron usuarios.",
        "activeusers-submit": "Amosar los usuarios activos",
        "listgrouprights": "Drechos de los grupos d'usuariu",
        "modifiedarticleprotection": "camudó’l nivel de proteición de «[[$1]]»",
        "unprotectedarticle": "quitó-y la protección a \"[[$1]]\"",
        "movedarticleprotection": "treslladó los parámetros de proteición dende «[[$2]]» a «[[$1]]»",
+       "protectedarticle-comment": "{{GENDER:$2|Protexó}} «[[$1]]»",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Cambió'l nivel de protección}} pa «[[$1]]»",
+       "unprotectedarticle-comment": "{{GENDER:$2|Quitó la protección}} de «[[$1]]»",
        "protect-title": "Protexendo \"$1\"",
        "protect-title-notallowed": "Ver el nivel de proteición de «$1»",
        "prot_1movedto2": "[[$1]] treslladáu a [[$2]]",
        "movelogpagetext": "Esta ye la llista de páxines treslladaes.",
        "movesubpage": "{{PLURAL:$1|Subpáxina|Subpáxines}}",
        "movesubpagetext": "Esta páxina tien $1 {{PLURAL:$1|subpáxina|subpáxines}} que s'amuesen darréu.",
+       "movesubpagetalktext": "La páxina d'alderique correspondiente tien $1 {{PLURAL:$1|subpáxina|subpáxines}} que {{PLURAL:$1|s'amuesa|s'amuesen}} darréu.",
        "movenosubpage": "Esta páxina nun tien subpáxines.",
        "movereason": "Motivu:",
        "revertmove": "revertir",
        "pageinfo-category-pages": "Númberu de páxines",
        "pageinfo-category-subcats": "Númberu de subcategoríes",
        "pageinfo-category-files": "Númberu de ficheros",
+       "pageinfo-user-id": "ID d'usuariu",
        "markaspatrolleddiff": "Marcar como supervisada",
        "markaspatrolledtext": "Marcar esta páxina como supervisada",
        "markaspatrolledtext-file": "Marcar esta versión del ficheru como patrullada",
        "patrol-log-header": "Esti ye un rexistru de les revisiones supervisaes.",
        "log-show-hide-patrol": "$1 rexistru de supervisión",
        "log-show-hide-tag": "$1 rexistru d'etiquetes",
+       "confirm-markpatrolled-button": "Aceutar",
+       "confirm-markpatrolled-top": "¿Marcar la revisión $3 de $2 como patrullada?",
        "deletedrevision": "Esborrada la reversión vieya $1",
        "filedeleteerror-short": "Error al esborrar l'archivu: $1",
        "filedeleteerror-long": "Atopáronse errores al esborrar l'archivu:\n\n$1",
        "newimages-showbots": "Ver les xubíes de los bots",
        "newimages-hidepatrolled": "Despintar les entraes patrullaes",
        "noimages": "Nun hai nada que ver.",
+       "gallery-slideshow-toggle": "Intercambiar les miniatures",
        "ilsubmit": "Guetar",
        "bydate": "por fecha",
        "sp-newimages-showfrom": "Amosar los archivos nuevos emprimando dende'l $1 a les $2",
        "tags-deactivate": "desactivar",
        "tags-hitcount": "$1 {{PLURAL:$1|cambiu|cambios}}",
        "tags-manage-no-permission": "Nun tienes permisu p'alministrar etiquetes de cambiu.",
-       "tags-manage-blocked": "Nun puedes xestionar etiquetes de cambiu mentanto teas bloquiáu.",
+       "tags-manage-blocked": "Nun puedes xestionar etiquetes de cambiu mentanto teas {{GENDER:$1|bloquiáu|bloquiada}}.",
        "tags-create-heading": "Crear una etiqueta nueva",
        "tags-create-explanation": "De mou predetermináu, les etiquetes nueves que se creen tarán disponibles pa que les usen los usuarios y bots.",
        "tags-create-tag-name": "Nome de la etiqueta:",
        "tags-deactivate-not-allowed": "Nun ye posible desactivar la etiqueta «$1».",
        "tags-deactivate-submit": "Desactivar",
        "tags-apply-no-permission": "Nun tienes permisu p'aplicar etiquetes de cambios xunto colos cambios.",
-       "tags-apply-blocked": "Nun puedes aplicar etiquetes de cambiu xunto colos cambios mentanto teas bloquiáu.",
+       "tags-apply-blocked": "Nun puedes aplicar etiquetes de cambiu xunto colos cambios mentanto teas {{GENDER:$1|bloquiáu|bloquiada}}.",
        "tags-apply-not-allowed-one": "Nun se permite aplicar manualmente la etiqueta «$1».",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|La siguiente etiqueta nun pue|Les siguientes etiquetes nun puen}} aplicase manualmente: $1",
        "tags-update-no-permission": "Nun tienes permisu p'amestar o desaniciar etiquetes de cambiu nes revisiones individuales o entraes del rexistru.",
-       "tags-update-blocked": "Nun puedes amestar o desaniciar etiquetes de cambiu mentanto teas bloquiáu.",
+       "tags-update-blocked": "Nun puedes amestar o desaniciar etiquetes de cambiu mentanto teas {{GENDER:$1|bloquiáu|bloquiada}}.",
        "tags-update-add-not-allowed-one": "Nun se permite amestar manualmente la etiqueta «$1».",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|La siguiente etiqueta nun pue|Les siguientes etiquetes nun puen}} amestase manualmente: $1",
        "tags-update-remove-not-allowed-one": "Nun se permite desaniciar la etiqueta «$1».",
        "htmlform-cloner-create": "Amestar más",
        "htmlform-cloner-delete": "Desaniciar",
        "htmlform-cloner-required": "Necesítase polo menos un valor.",
+       "htmlform-date-placeholder": "AAAA-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "AAAA-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "El valor que disti nun ye una data reconocible. Prueba usando'l formatu AAAA-MM-DD.",
+       "htmlform-time-invalid": "El valor que disti nun ye una hora reconocible. Prueba usando'l formatu HH:MM:SS.",
+       "htmlform-datetime-invalid": "Nun se reconoció la fecha y hora nel formatu proporcionáu. Prueba a usar el formatu AAAA-MM-DD HH:MM:SS.",
+       "htmlform-date-toolow": "El valor que disti ye anterior a la fecha más antigua permitida, $1.",
+       "htmlform-date-toohigh": "El valor especificáu ye posterior a la mayor data permitida, $1.",
+       "htmlform-time-toolow": "El valor qu'especificasti ye anterior a la hora más antigua permitida, $1.",
+       "htmlform-time-toohigh": "El valor qu'especificasti ye posterior a la hora más nueva permitida, $1.",
+       "htmlform-datetime-toolow": "El valor qu'especificasti ye anterior a la fecha y hora más antigua permitida, $1.",
+       "htmlform-datetime-toohigh": "El valor qu'especificasti ye posterior a la fecha y hora más nueva permitida, $1.",
        "htmlform-title-badnamespace": "[[:$1]] nun ta nel espaciu de nomes \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "«$1» nun ye un títulu de páxina que pueda crease",
        "htmlform-title-not-exists": "$1 nun esiste.",
        "feedback-external-bug-report-button": "Rexistrar una xera técnica",
        "feedback-dialog-title": "Unviar opinión",
        "feedback-dialog-intro": "Puedes usar el formulariu fácil de más abaxo pa unviar comentarios. Estos amestaránse a la páxina «$1», xunto col to nome d'usuariu.",
-       "feedback-error-title": "Error",
        "feedback-error1": "Fallu: Resultáu de la API non reconocíu",
        "feedback-error2": "Fallu: Falló la edición",
        "feedback-error3": "Fallu: Ensin respuesta de la API",
        "feedback-thanks": "¡Gracies! La to opinión s'espublizó na páxina «[$2  $1]».",
        "feedback-thanks-title": "¡Gracies!",
        "feedback-useragent": "Axente d'usuariu:",
-       "searchsuggest-search": "Buscar",
+       "searchsuggest-search": "Buscar en {{SITENAME}}",
        "searchsuggest-containing": "que contien...",
        "api-error-autoblocked": "La to dirección IP bloquióse automáticamente porque la usó un usuariu bloquiáu.",
        "api-error-badaccess-groups": "Nun tienes permisu pa xubir ficheros a esta wiki.",
        "authmanager-authn-autocreate-failed": "Falló la creación automática d'una cuenta local: $1",
        "authmanager-change-not-supported": "Les credenciales apurríes nun pueden camudase porque nun hai nada que les use.",
        "authmanager-create-disabled": "Ta desactivada la creación de cuentes.",
-       "authmanager-create-from-login": "Pa crear la cuenta, rellena los campos de más abaxo.",
+       "authmanager-create-from-login": "Pa crear la cuenta, rellena los campos.",
        "authmanager-create-not-in-progress": "La creación de la cuenta nun ta progresando, o perdiéronse los datos de la sesión. Por favor, vuelve de nueves al principiu.",
        "authmanager-create-no-primary": "Les credenciales apurríes nun pueden usase pa crear cuentes.",
        "authmanager-link-no-primary": "Les credenciales apurríes nun pueden usase pa enllazar cuentes.",
        "unlinkaccounts-success": "Desenllazóse la cuenta.",
        "authenticationdatachange-ignored": "Nun se xestionó'l cambéu de los datos d'autentificacion. ¿Seique, nun se configuró un fornidor?",
        "userjsispublic": "Atención: les subpáxines JavaScript nun tendríen de contener datos acutaos porque son visibles pa otros usuarios.",
-       "usercssispublic": "Atención: les subpáxines CSS nun tendríen de contener datos acutaos porque son visibles pa otros usuarios."
+       "usercssispublic": "Atención: les subpáxines CSS nun tendríen de contener datos acutaos porque son visibles pa otros usuarios.",
+       "restrictionsfield-badip": "Direición o rangu IP inválidu: $1",
+       "restrictionsfield-label": "Rangos d'IP permitíos:",
+       "restrictionsfield-help": "Una única direición IP o rangu CIDR per llinia. P'activar toos, utiliza<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Error: $1",
+       "edit-error-long": "Errores:\n\n$1"
 }
index dca9dfe..e2ea9aa 100644 (file)
        "yourpasswordagain": "Пароль такрар гьабе:",
        "createacct-yourpasswordagain": "Пароль ритIухъ гьабе",
        "createacct-yourpasswordagain-ph": "Пароль цоги нухалъ хъвай",
-       "remembermypassword": "Дир цIарги парольги гьаб компьютералда цIунизе (гIицIго $1 {{PLURAL:$1|къоялъ}})",
        "userlogin-remembermypassword": "Системаялда чӀезе",
        "yourdomainname": "Дур домен:",
        "password-change-forbidden": "Гьаб викиялда пароль хисизабун бажаруларо дуда.",
index 0081c7e..b8ca12d 100644 (file)
        "yourname": "Rinaf favesikyolt",
        "yourpassword": "Rinaf remravlem",
        "yourpasswordagain": "Va rinaf remravlem tolon bazel",
-       "remembermypassword": "Setikera va jinaf remravlem koe bati nedisiki (kali cugon $1 {{PLURAL:$1|viel|viel}})",
        "yourdomainname": "Rinaf ind",
        "externaldberror": "Ont divefa origakrokla va pilkomodara ont va rinafa divefa pata me ronuskel.",
        "login": "Pilkomodá",
        "undo-failure": "Betaks me zo rodimaskir golde kobodas walif betaks yo.",
        "undo-norev": "Dimbetara tir merotisa golde metira ok sulara.",
        "undo-summary": "Dimaskira va $1 betaks ke [[Special:Contributions/$2|$2]] ([[User talk:$2|Prilara]])",
-       "cantcreateaccounttitle": "Pataredura me tir",
        "cantcreateaccount-text": "Pataredura male bate IP ('''$1''') mane gan [[User:$3|$3]] zo elekayar.\n\nBazeyena lazava ke $3 tir ''$2''.",
        "viewpagelogs": "Wira va \"logs\" ke batu bu",
        "nohistory": "Nedoy izvot va batu bu.",
index 1a6b71d..96529ac 100644 (file)
        "yourpasswordagain": "गुप्त कुंजी एक दाँइ अउर लिखो:",
        "createacct-yourpasswordagain": "गुप्त कुंजी कय पुष्टि करो",
        "createacct-yourpasswordagain-ph": "गुप्त कुंजी फिर से लिखो",
-       "remembermypassword": "इ ब्राउज़र पे हमार लॉगिन याद रखो (अधिकतम $1 {{PLURAL:$1|दिन|दिन}} कय लिए)",
        "userlogin-remembermypassword": "हम्मै लॉग्ड इन रखो",
        "userlogin-signwithsecure": "सुरक्षित कनेक्शन कय प्रयोग करो",
        "yourdomainname": "आप कय डोमेन:",
        "passwordreset-emailtext-user": "{{SITENAME}} ($4) पे सदस्य $1 आपकय {{PLURAL:$3|खाता}} कय गुप्तकुंजी कय रीसेट करेक अनुरोध करे हैं। इ ई-मेल ठहर से इ {{PLURAL:$3|खाता जोडान है}}:\n\n$2\n\n{{PLURAL:$3|ई}} अस्थायी गुप्तकुंजी {{PLURAL:$5|दिन}} कय बाद काम नाइ करि।\nआप लॉग इन कइकै एकठु नँवा गुप्त कुंजी अभीन लै लेक चाहि। यदि इ अनुरोध केहु दुसर करे है, या फिर आप कय आपन गुप्त कुंजी याद आई गा है, अव आप {{PLURAL:$3|आपन}} गुप्तकुंजी नाई बदलेक चाहा जात है, आप इ संदेश कय अनदेखा कई कय आपन पुरान गुप्तकुंजी कय प्रयोग कइ सका जात है।",
        "passwordreset-emailelement": "सदस्यनाँव: \n$1\n\nअस्थायी गुप्तकुंजी: \n$2",
        "passwordreset-emailsentemail": "एक गुप्तकुंजी रीसेट ई-मेल भेज दिहा गा है।",
-       "passwordreset-emailsent-capture": "नीचे जवन देखावा है ओकर गुप्तकुंजी रीसेट ई-मेल भेज दिहा गा है।",
-       "passwordreset-emailerror-capture": "नीचे दिहा गुप्त कुंजी रीसेट ई-मेल पैदा भा रहा, लेकिन ओका {{GENDER:$2|सदस्य}} कय भेजब असफल रहा।\nत्रुटि: $1",
        "changeemail": "ईमेल ठाँव बदला जाय",
        "changeemail-header": "अपना ई-मेल पता परिवर्तित करने के लिए इस फ़ॉर्म को पूरा करें। इस बदलाव की पुष्टि करने के लिये आपको अपना कूटशब्द पुनः लिखना पड़ेगा।",
        "changeemail-no-info": "इ पन्ना कय सीधय प्रयोग करेक लिए आप कय लॉग इन करेक परि।",
        "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एकरे लिये $3 ''$2'' कारण दिहे हैं।",
        "cantcreateaccount-range-text": "<strong>$1</strong> कय श्रेणी में आवे वाला आई॰पी ठहर से, जवनेमें आप कय आई॰पी ठहर (<strong>$4</strong>) शामिल है, नँवा खाता बनावे कय लिए [[User:$3|$3]] अवरोधित कई गा है। \n\n$3 द्वारा दिया गया कारण है: \"$2\"",
        "viewpagelogs": "इस पन्ना कय लॉग देखा जाय",
        "activeusers-intro": "इ सक्रिय सदस्यन् कय सूची होय जे पिछला $1 {{PLURAL:$1|दिन}} में कुछ काम करें है।",
        "activeusers-count": "$1 {{PLURAL:$1|काम}} पिछला $3 {{PLURAL:$3|दिन}} में",
        "activeusers-from": "इ अक्षर से शुरु होय वाले सदस्य देखावा जाय:",
-       "activeusers-hidebots": "बॉट लुकुआवा जाय",
-       "activeusers-hidesysops": "प्रबंधक लुकुआवा जाय",
        "activeusers-noresult": "कवनो सदस्य नाइ मिलें ।",
        "listgrouprights": "सदस्य समूह अधिकार",
        "listgrouprights-summary": "नीचे इ विकि खर्तीन परिभाषित सदस्य समूहन् कय सूची होय, सथवे में हर समूह से जोड़ान अधिकारो है।\nहर अधिकार कय बारे में [[{{MediaWiki:Listgrouprights-helppage}}|ढेर जानकरीओ]] उपलब्ध है।",
        "htmlform-chosen-placeholder": "एक्ठु विकल्प चुना जाय",
        "htmlform-cloner-create": "अउर जोडा जाय",
        "htmlform-cloner-delete": "हटावा जाय",
-       "sqlite-has-fts": "$1 पूर्ण पाठ खोज समर्थन कय साथ",
-       "sqlite-no-fts": "$1पूर्ण-पाठ खोज समर्थन कय बिना",
        "logentry-delete-delete": "$1 ने पृष्ठ $3 {{GENDER:$2|हटा}} दिहा गय",
        "logentry-delete-restore": "$1 ने पृष्ठ $3 कय {{GENDER:$2|पुनर्स्थापित}} कै गय",
        "logentry-delete-event": "$1 ने $3 पृष्ठ की लॉग {{PLURAL:$5|प्रविष्टि|प्रविष्टियों}} की दृश्यता {{GENDER:$2|बदली}}: $4",
        "feedback-cancel": "रद्द करा जाय",
        "feedback-close": "होइ गवा",
        "feedback-dialog-title": "प्रतिक्रिया भेजा जाय",
-       "feedback-error-title": "त्रुटि",
        "feedback-error1": "त्रुटि: न पहचाना गया परिणाम एपीआई से",
        "feedback-error2": "त्रुटि: संपादन विफल रहा है",
        "feedback-error3": "त्रुटि: एपीआई से कोई प्रतिक्रिया नहीं",
index add8bea..d16eafd 100644 (file)
        "yourpasswordagain": "Parolu təkrar daxil edin:",
        "createacct-yourpasswordagain": "Parolu təsdiqlə",
        "createacct-yourpasswordagain-ph": "Parolu təkrar daxil edin",
-       "remembermypassword": "Məni bu kompyuterdə xatırla (maksimum $1 {{PLURAL:$1|gün|gün}})",
        "userlogin-remembermypassword": "Sistemdə qal",
        "userlogin-signwithsecure": "Etibarlı bağlantıdan istifadə edin",
        "yourdomainname": "Sizin domeniniz:",
        "booksources-isbn": "ISBN:",
        "booksources-search": "Axtar",
        "booksources-text": "Aşağıda yeni və işlənmiş kitablar satan xarici keçidlərdə siz axtardığınız kitab haqqında əlavə məlumat ala bilərsiz:",
+       "magiclink-tracking-isbn": "ISBN sehrli keçidlərinin istifadə olunduğu səhifələr",
        "specialloguserlabel": "İcraçı:",
        "speciallogtitlelabel": "Məqsəd (başlıq və ya istifadəçi):",
        "log": "Qeydlər",
        "listusers-blocked": "(bloklanıb)",
        "activeusers": "Aktiv istifadəçilərin siyahısı",
        "activeusers-count": "Son {{PLURAL:$3|gündə|$3 gündə}} $1 {{PLURAL:$1|redaktə|redaktə}}",
-       "activeusers-hidebots": "Botları gizlə",
-       "activeusers-hidesysops": "İdarəçiləri gizlə",
        "activeusers-noresult": "İstifadəçi tapılmadı.",
        "listgrouprights": "İstifadəçi qruplarının hüquqları",
        "listgrouprights-summary": "Bu vikidə olan istifadəçi siyahıları və onların hüquqları aşağıda göstərilmişdir.\nFərdi hüquqlar haqqında əlavə məlumatı [[{{MediaWiki:Listgrouprights-helppage}}]] səhifəsində tapa bilərsiniz",
        "listgrouprights-addgroup-self-all": "Bütün qrupları öz hesabına əlavə edə bilər",
        "listgrouprights-removegroup-self-all": "Bütün qrupları öz hesabından çıxara bilər",
        "listgrouprights-namespaceprotection-namespace": "Adlar fəzası",
+       "restricted-displaytitle-ignored": "İmtina edilmiş görüntü başlıqlarına malik səhifələr",
        "mailnologin": "Ünvan yoxdur",
        "emailuser": "İstifadəçiyə e-məktub göndər",
        "defemailsubject": "\"$1\" adlı istifadəçidən {{SITENAME}} e-məktubu",
        "htmlform-selectorother-other": "Digər",
        "htmlform-no": "Xeyr",
        "htmlform-yes": "Bəli",
-       "sqlite-has-fts": "$1 tam mətn axtarma ilə",
-       "sqlite-no-fts": "$1 tam mətn axtarma olmadan",
        "logentry-delete-delete": "$1 $3 səhifəsini {{GENDER:$2|sildi}}",
        "logentry-suppress-delete": "$1 $3 səhifəsini {{GENDER:$2|gizlətdi}}",
        "revdelete-content-hid": "gizli mətn",
        "feedback-bugnew": "Mən yoxladım. Yeni xəta barədə xəbər ver",
        "feedback-cancel": "İmtina",
        "feedback-close": "Oldu",
-       "feedback-error-title": "Xəta",
        "feedback-error2": "Xəta: Redaktə qeydə alınmadı",
        "feedback-message": "Mesaj:",
        "feedback-subject": "Mövzu:",
index 76c2859..62514e7 100644 (file)
        "title-invalid-utf8": "ایسته‌نیلن صفحه‌نین آدیندا بیر یانلیش UTF-8 کاراکتِری وار.",
        "title-invalid-interwiki": "آختاردیٛغیٛنیٛز صفحه‌ آدیٛیٛندا بیر ایستیفاده‌ اوْلۇنا بیلمه‌‌ین اینتئر ویکی باغلانتیٛسیٛ وار.",
        "title-invalid-characters": "ایسته‌نیلن صفحه‌نین آدیندا، یانلیش کاراکتِرلر وار: «$1»",
-       "perfcached": "بÙ\88 Ø¨Û\8cÙ\84Ú¯Û\8cØ\8c Ú©Ù\8eØ´ Ø§Ù\88Ù\84Ù\88بâ\80\8cدÙ\88ر Ù\88 Ø§Ù\88Ù\84ا Ø¨Û\8cÙ\84ر Ú¯Ù\88Ù\86جÙ\84 اولماسین. چوخو {{PLURAL:$1|بیر نتیجه|$1 نتیجه}} کَش‌ده‌دیر.",
-       "perfcachedts": "بÙ\88 Ø¨Û\8cÙ\84Ú¯Û\8c Ú©Ù\8eØ´ Ø§Ù\88Ù\84Ù\88بâ\80\8cدÙ\88رØ\8c Ø³Ù\88Ù\86 Ø¯Ù\81عÙ\87 $1 Ù\88اختÛ\8cÙ\86دا Ú¯Ù\88Ù\86جÙ\84Û\8cبâ\80\8cدÛ\8cر. چوخو {{PLURAL:$4|بیر نتیجه|$4 نتیجه}} کَش‌ده‌دیر.",
-       "querypage-no-updates": "بو یارپاق‌دا گونجل‌له‌مک ایندی باغلانیب‌دیر.\nبورداکی بیلگیلر یئنی‌لشمیه‌جکلر.",
+       "perfcached": "بÙ\88 Ø¯Ø¦Û\8cتاØ\8c Ú©Ù\8eØ´ Ø§Ù\88Ù\84Ù\88بâ\80\8cدÙ\88ر Ù\88 Ø§Ù\88Ù\84ا Ø¨Û\8cÙ\84ر Ø¢Ù¾Ø¯Û\8cت اولماسین. چوخو {{PLURAL:$1|بیر نتیجه|$1 نتیجه}} کَش‌ده‌دیر.",
+       "perfcachedts": "بÙ\88 Ø¯Ø¦Û\8cتا Ú©Ù\8eØ´ Ø§Ù\88Ù\84Ù\88بâ\80\8cدÙ\88رØ\8c Ø³Ù\88Ù\86 Ø¯Ù\81عÙ\87 $1 Ù\88اختÛ\8cÙ\86دا Ø¢Ù¾Ø¯Û\8cÙ\86 Ø§Ù\88Ù\84Ù\88Ù\86Ù\88بدÙ\88ر. چوخو {{PLURAL:$4|بیر نتیجه|$4 نتیجه}} کَش‌ده‌دیر.",
+       "querypage-no-updates": "بو صفحه ده آپدیت ائتمک ایندی باغلانیب‌دیر.\nبورداکی دئیتا یئنی‌لشمیه‌جکلر.",
        "viewsource": "قایناغا باخ",
        "viewsource-title": "$1 اوچون قایناغا باخین",
        "actionthrottled": "سیزین چالیشمانیزین قاباغی آلیندی",
        "yourpasswordagain": "رمزی یئنی‌دن یازین:",
        "createacct-yourpasswordagain": "رمزی دوغرولایین",
        "createacct-yourpasswordagain-ph": "رمزی یئنی‌دن یازین",
-       "remembermypassword": "بو بیلگی‌سایاردا منیم گیریشیمی (چوخو $1 {{PLURAL:$1|گون}}ه قدر) یاددا ساخلا",
        "userlogin-remembermypassword": "منی ایچری‌ده ساخلا",
        "userlogin-signwithsecure": "آرخایین باغلانتی ایشلدین",
        "cannotloginnow-title": "ایندی گیریش اوْلونمازدیر",
        "undo-summary-username-hidden": "گیزلی ایستیفاده‌چی ایله ائدیلمیش $1 نوسخه‌سینی قایتارماق",
        "cantcreateaccount-text": "بو ای پی عنوانین‌دان ('$1) ایستیفاده‌چی حسابی یارادیلماسی [[User:$3|$3]] طرفین‌دن انگللنمیش‌دیر.\n\n$3 طرفین‌دن وئریلن سبب '$2",
        "cantcreateaccount-range-text": "<strong>$1</strong> آی‌پی آدرس آرالیغیندان حساب یارانماق، [[User:$3|$3]] ایشلدنی طرفیندن یاساقلانیب‌دیر. سیزین‌ده آی‌پی آدرسیز (<strong>$4</strong>) بو آرادادیر.\n\n$3 طرفین‌دن وئریلن سبب بودور: «$2»",
-       "viewpagelogs": "بۇ صفحه‌نین قئیدلرینه باخ",
+       "viewpagelogs": "بۇ صفحه‌نین ژورناللارینا باخ",
        "nohistory": "بو صحیفه اوچون دَییشدیرمه گئچمیشی یوخدور.",
        "currentrev": "سون نوسخه",
        "currentrev-asof": "$1 تاریخینه کیمی سون حال",
        "revisionasof": "$1 نوسخه‌سی",
        "revision-info": "$1- یارادیلمیش نوسخه{{GENDER:$6|$2}}$7 الیله",
-       "previousrevision": "قاباق‌کی سۆروم",
+       "previousrevision": "قاباقکی نوسخه",
        "nextrevision": "داها یئنی نوسخه ←",
        "currentrevisionlink": "سون نوسخه",
        "cur": "ایندی",
        "difference-title-multipage": "«$1» و «$2» صحیفه‌لرین آراسینداکی فرقلر",
        "difference-multipage": "(صفحه‌لر آراسینداکی فرق‌لر)",
        "lineno": "خط $1:",
-       "compareselectedversions": "سئÚ\86Û\8cÙ\84Ù\85Û\8cØ´ Ù\86Ù\88سخÙ\87â\80\8cÙ\84رÛ\8c Ù\82ارشÛ\8cÙ\84اشدÛ\8cر",
+       "compareselectedversions": "سئÚ\86Û\8cÙ\84Ù\85Û\8cØ´ Ù\86Ù\88سخÙ\87â\80\8cÙ\84رÛ\8c Ù\85Ù\88Ù\82اÛ\8cسÙ\87 Ø§Ø¦Øª",
        "showhideselectedversions": "سئچیلمیش نوسخه‌لری گؤستر/گیزلد",
        "editundo": "قایتار",
        "diff-empty": "فرقیسیز",
        "searchprofile-advanced-tooltip": "تاپشیریلان آدفضالاریندا آختار",
        "search-result-size": "$1 ({{PLURAL:$2|۱ سؤزجوک|$2 سؤزجوک}})",
        "search-result-category-size": "{{PLURAL:$1|بیر|$1}} عوضو ({{PLURAL:$2|بیر|$}} آلت‌بؤلمه، {{PLURAL:$3|بیر|$3}} فایل)",
-       "search-redirect": "یول‌لاندیرما $1",
+       "search-redirect": "($1-دن يوْل‌لاندیریلمیش)",
        "search-section": "(بؤلوم $1)",
        "search-category": "(رده  $1)",
        "search-file-match": "(فایلین ایچری اوخشاری)",
        "action-edit": "بو صحیفه‌نی دَییشدیر",
        "action-createpage": "صفحه یارات",
        "action-createtalk": "دانیشیق صفحه‌سی یارات",
-       "action-createaccount": "بÙ\88 Ø§Û\8cستÛ\8cÙ\81ادÙ\87â\80\8cÚ\86Û\8c Ø­Ø³Ø§Ø¨Û\8cÙ\86Û\8c Û\8cاراد",
+       "action-createaccount": "بÙ\88 Ø§Û\8cØ´Ù\84دÙ\86 Ø­Ø³Ø§Ø¨Û\8cÙ\86Û\8c Û\8cارات",
        "action-history": "بو صفحه نین گئچمیشین گور",
        "action-minoredit": "بو دَییشیکلیگی، کیچیک اولاراق نیشانلا",
        "action-move": "بو صحیفه‌‌نین آدینی ديَیشدیر",
        "listduplicatedfiles-summary": "بۇرا، سوْن نۆسخه‌لری آیری بیر فایلین سوْن نۆسخه‌سی‌نین کوْپی‌سی اوْلان فایل‌لارین لیستیدیر. یالنیز یئرلی فایل‌لار گؤز آلتینا آلینیبلار.",
        "listduplicatedfiles-entry": "[[:File:$1|$1]]-ین [[$3|{{PLURAL:$2|بیر کوْپی‌سی|$2 کوْپی‌سی}}]] واردیر.",
        "unusedtemplates": "ایشلدیلمه‌میش شابلونلار",
-       "unusedtemplatestext": "بو صحیفه بوتون، {{ns:template}} آدفضاسیندا اولان و باشقا صحیفه‌لرده اولمایان صحیفه‌لری لیست ائدیر.\nشابلونلاری سیلمک‌دن اؤنجه، لوطفاً اونلارا اولان باشقا باغلانتیلاری یوخلایین.",
+       "unusedtemplatestext": "بو صفحه بوتون، {{ns:template}} آدفضاسیندا اولان و آیری صفحه‌لرده ایشلدیلمه‌میش صفحه‌لری لیست ائدیر.\nشابلونلاری سیلمک‌دن قاباق، لوطفاً اونلارا اولان آیری باغلانتیلاری یوخلایین.",
        "unusedtemplateswlh": "باشقا باغلانتیلار",
        "randompage": "تصادوفی صفحه",
        "randompage-nopages": "بو {{PLURAL:$2|آدفضاسیندا|آدفضالاریندا}} هئچ صحیفه یوخدور: $1.",
        "nrevisions": "{{PLURAL:$1|بیر|$1}} نوسخه",
        "nimagelinks": "$1 ده{{PLURAL:$1|صحیفه‌ده}}ایستیفاده اولونمور",
        "ntransclusions": "$1 ده{{PLURAL:$1|صحیفه‌ده}}ایستیفاده اولونور",
-       "specialpage-empty": "بو صحیفه بوشدور",
+       "specialpage-empty": "بو صفحه بوشدور.",
        "lonelypages": "يئتیم صفحه‌‌لر",
        "lonelypagestext": "آشاغی‌داکی صحیفه‌لره {{SITENAME}} سایتین‌داکی دیگر صحیفه‌لردن علاقه وئریلممیش یا دا چارپاز داخیل ائدیلممیش.",
        "uncategorizedpages": "بؤلمه‌سیز صفحه‌لر",
        "wantedpages": "ایسته‌نیلن صفحه‌لر",
        "wantedpages-badtitle": "مراجعت زامانتی يانلیش باشلیق: $1",
        "wantedfiles": "ایسته‌نیلن فایللار",
-       "wantedfiletext-cat": "آشاغیداکی فایل‌لار ایشله‌نیبلر اما یوخدورلار. ائشیک آنباردا اولان فایل‌لار دا اولدوقلارینا باخمایاراق، لیست‌ده گلیبلر. ائله یانلیش باخیشلار <del>خطلنه‌جکلر</del>. هم‌ده، اولمایان فایل‌لاری ایشلدن صحیفه‌لر ده [[:$1]]-ده لیست اولونوبلار.",
+       "wantedfiletext-cat": "آشاغیداکی فایل‌لار ایشله‌نیبلر اما یوخدورلار. ائشیک آنباردا اولان فایل‌لار دا اولدوقلارینا باخمایاراق، لیست‌ده گلیبلر. ائله خطالی باخیشلار <del>خطلنه‌جکلر</del>. هم‌ده، اولمایان فایل‌لاری ایشلدن صفحه‌لر ده [[:$1]]-ده لیست اولونوبلار.",
        "wantedfiletext-cat-noforeign": "آشاغی دا کی اولان فایل لار ایستفاده اولونور سانکی یوخدولار. بوندان اونجه فایل لاری اولموش صفحه لر [[:$1]] ده لیست اولوب لار.",
        "wantedfiletext-nocat": "اشاغی داکی فایل لار ایستفاده اولور سانکی یوخدولار.حتی مومکین دیر خارجی حویض مخزن لریندن اولماق  ایله بو ردا فهرست اولا . وهر مثب رتبه سی یانلیش <del> خط یئمیش اولاجاق.</del>",
        "wantedfiletext-nocat-noforeign": "آشاغی داکی فایل لار ایشلنیلیر سانکی یوخدورلار.",
        "longpages": "اۇزون صفحه‌‌لر",
        "deadendpages": "کئچید وئرمه‌ين صحیفه‌‌لر",
        "deadendpagestext": "آشاغیداکی صحیفه‌‌لردن بو ویکیپئدیياداکی دیگر صحیفه‌‌لره هئچ بیر کئچید يوخدور.",
-       "protectedpages": "Ù\85حاÙ\81ظÙ\87â\80\8câ\80\8cÙ\84Û\8c ØµØ­Û\8cÙ\81ه‌‌لر",
+       "protectedpages": "Ù\82Ù\88Ù\92رÙ\88Ù\86اÙ\86 ØµÙ\81Ø­ه‌‌لر",
        "protectedpages-indef": "يالنیز مدتسیز محافظه‌‌لر",
        "protectedpages-summary": "بۇ صحیفه، ایندیکی قوْرونان موْجود اوْلان صحیفه‌لری لیست ائدیر. یارانماق‌دان قوْرونان باشلیقلارین لیستینی گؤرمک اۆچون [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]]-ه باخین.",
        "protectedpages-cascade": "یالنیز کاسکاد محافظه‌لر",
        "protectedpages-noredirect": "یوْل‌لاندیرمالاری گیزلت",
        "protectedpagesempty": "حال-حاضردا بو پارامئتره اویغون هئچ بیر محافظه‌لی صحیفه یوخ‌دور",
-       "protectedpages-timestamp": "واخت دامغاسی",
+       "protectedpages-timestamp": "چاغ اتیکتی",
        "protectedpages-page": "صفحه",
-       "protectedpages-expiry": "بیتمک تاریخی",
-       "protectedpages-performer": "Ù\82Ù\88Ù\92رÙ\88Û\8cاÙ\86 Ø§Û\8cستÛ\8cÙ\81ادÙ\87â\80\8cÚ\86Û\8c",
+       "protectedpages-expiry": "قورتارماق تاریخی",
+       "protectedpages-performer": "Ù\82Ù\88Ù\92رÙ\88Û\8cاÙ\86 Ø§Û\8cØ´Ù\84دÙ\86",
        "protectedpages-params": "قوْروماق پارامئترلری",
        "protectedpages-reason": "نَدَن‌لیگی",
        "protectedpages-unknown-timestamp": "بیلینمه‌ین",
        "usercreated": "$1 تاریخینده، ساعات $2-ده {{GENDER:$3|یارانیب‌دیر}}",
        "newpages": "يئنی صفحه‌لر",
        "newpages-username": "ایشلدن آدی:",
-       "ancientpages": "ان اسکی صفحه‌لر",
+       "ancientpages": "ان کؤهنه صفحه‌لر",
        "move": "آدینی دَییشدیر",
        "movethispage": "بو صحیفه‌‌نین آدینی ديَیشدیر",
-       "unusedimagestext": "آشاغی‌داکی فایل‌لار وار آنجاق هر هانسی بیر صحیفه‌ده باسدیریلمیش دئییل.\nخاهیش ائدیریک اونوتمایین کی، دیگر web سایت‌لاری بیر فایلا بیرباشا بیر اورل ایله علاقه وئره بیلر، و بونا گؤره ائففئکتیو ایستیفاده‌ده اولماسا بئله هله بورادا لیستنبیلیر.",
-       "unusedcategoriestext": "آشاغیدا اولان بولمه لر مؤوجود اولدوغو حالدا، هئچ بیر مادده یا دا بولمه لر طرفین‌دن ایستیفاده ائدیلمیر.",
+       "unusedimagestext": "آشاغی‌داکی فایل‌لار وار آنجاق هر هانسی بیر صفحه‌ده باسدیریلمیش دئییل.\nلوطفا یاددا ساخلایین کی، آیری وب سایت‌لاری بیر فایلا بیرباشا بیر اورل ایله باغلایا بیلر، و بونا گؤره چالیشقان ایشلتمه ده اولمازسا بئله هله بورادا لیستله نبیلیر.",
+       "unusedcategoriestext": "آشاغیدا اولان بولمه لر مؤوجود اولدوغو حالدا، هئچ بیر مقاله یوخسا بولمه لر طرفین‌دن ایشلدیلمیر.",
        "notargettitle": "وئریلمه‌يیب",
        "notargettext": "بو صحیفه یا یا کاربر حیاتا کئچیرمک اوچون بیر هدف صحیفه‌سی یا دا ایستیفاده‌چی‌سی بئلیرتمئدینیز.",
        "nopagetitle": "بئله هدف صحیفه‌سی یوخ‌دور",
        "activeusers-intro": "بۇرادا سوْن {{PLURAL:$1|بیر|$1}} گۆن‌ده دَییشدیرمه ائدن ایشلدن‌لرین لیستی گؤروشور.",
        "activeusers-count": "سون {{PLURAL:$3|گون|$3 گون}}‌ده، {{PLURAL:$1|$1}} چالیشما",
        "activeusers-from": "بۇندان باشلایان ایشلدن‌لری گؤستر:",
-       "activeusers-hidebots": "روْبات‌لاری گیزلت",
-       "activeusers-hidesysops": "ایداره‌چیلری گیزلت",
        "activeusers-noresult": "هئچ ایشلدن تاپیلمادی.",
        "activeusers-submit": "چالیشقان ایشلدن‌لری گؤستر",
        "listgrouprights": "ایستیفاده‌چی قروپ حاقلاری",
        "sp-contributions-suppresslog": "باسدیریلمیش ایشلدن فعالیت‌لری",
        "sp-contributions-deleted": "سیلینمیش ایشلدن چالیشمالاری",
        "sp-contributions-uploads": "یوکله‌نَنلر",
-       "sp-contributions-logs": "قئیدلر",
+       "sp-contributions-logs": "ژورناللار",
        "sp-contributions-talk": "دانیشیق",
        "sp-contributions-userrights": "ایستیفاده‌چی حاقلارین ایداره‌ ائتمه‌سی",
        "sp-contributions-blocked-notice": "بو ایستیفاده‌چی حال-حاضردا بلوکلانمیش‌دیر.\nبلوکلاما قئیدلری‌نین سونونجوسو آشاغیدا گؤستریلمیش‌دیر:",
        "version-ext-license": "لیسانس",
        "version-ext-colheader-name": "اوزانتی",
        "version-skin-colheader-name": "قابیق",
-       "version-ext-colheader-version": "سۆروم",
+       "version-ext-colheader-version": "نوسخه",
        "version-ext-colheader-license": "لیسانس",
        "version-ext-colheader-description": "آچیقلاما",
        "version-ext-colheader-credits": "یازیچی‌لار",
        "intentionallyblankpage": "بو صحیفه خصوصیله بوش‌دور.",
        "external_image_whitelist": " #بو سطری اولدوغو کیمی بوراخین <pre>\n#دوزگون ایفاده (رِقولار اِکسپرِشِن) پارچالارینی (یالنیز // آراسیندا اولان قیسمی) آشاغی‌يا قویون\n#بونلار ائشیک‌ده‌کی عکسلرین آدرسلریله تطبیق اولاجاقلار\n#تطبیق اولانلار، عکس کیمی گؤستریله‌جکلر، اولمایانلارا یالنیز بیر باغلانتی گؤستریله‌جکدیر\n#بو # نیشانی ایله باشلایان سطرلر، شرح کیمی نظرده توتولاجاقلار\n#بو حرفلرین کیچیک/بؤیوک اولماغینا حساس دئییل\n\n#بوتون دوزگون ایفاده پارچالارینی، بو سطرین اوستونه قویون. بو سطری اولدوغو کیمی بوراخین</pre>",
        "tags": "مومکون دییشیک‌لیک ائتیکئت‌لری",
-       "tag-filter": "[[Special:Tags|اِتیکِت]] سۆزگُجی:",
+       "tag-filter": "[[Special:Tags|اِتیکِت]] فیلتری:",
        "tag-filter-submit": "سۆزگَج",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|اِتیکِت|اِتیکِتلر}}]]: $2)",
        "tags-title": "اِتیکتلر",
        "htmlform-title-not-exists": "$1 یوخدور.",
        "htmlform-user-not-exists": "<strong>$1</strong> یوخدور.",
        "htmlform-user-not-valid": "<strong>$1</strong> بیر دوزگون ایشلدن آدی دئییل.",
-       "sqlite-has-fts": "$1 بوتون یازی آختارما دستگی‌له",
-       "sqlite-no-fts": "$1 بوتون یازی آختارماماق‌لا",
        "logentry-delete-delete": "$1، $3 صفحه‌سینی {{GENDER:$2|سیلدی}}",
        "logentry-delete-restore": "$1، $3 صفحه‌سینی {{GENDER:$2|قایتاردی}}",
        "logentry-delete-event": "$1، $3-ده $5 سیاهی اولایینین {{PLURAL:$5|گؤرونوشونو|گؤرونوشلرینی}} {{GENDER:$2|دَییشدیردی}}: $4",
        "feedback-bugornote": "بیر تکنیکی خطانی شرح وئرمگه آماده اولساز، لوطفاً [$1 بیر باگ بیلدیرین].\nاو اولماسا، بو آشاغیداکی ساده فورم‌دان ایستیفاده ائده بیلرسینیز. سیزین باخیشینیز، ایستیفاده‌چی آدینیزلا، «[$3 $2]» صحیفه‌سینه آرتیریلاجاق‌دیر.",
        "feedback-cancel": "وازگئچ",
        "feedback-close": "اولدو",
-       "feedback-error-title": "خطا",
        "feedback-error1": "خطا: API-دان تانینمامیش نتیجه",
        "feedback-error2": "خطا: دَییشدیرمه باشاری‌سیز اولدو",
        "feedback-error3": "خطا: API-دان جاواب گلمه‌دی",
        "feedback-submit": "گؤندر",
        "feedback-thanks": "تشکورلر! سیزین گئری-بیلدیریمینیز «[$2 $1]» صحیفه‌سینه گؤندریلدی.",
        "feedback-thanks-title": "تشکورلر!",
-       "searchsuggest-search": "آختار",
+       "searchsuggest-search": "{{SITENAME}}-دا آختار",
        "searchsuggest-containing": "ساخلانیلیر...",
        "api-error-badaccess-groups": "سیزین بو ویکی‌یه فایل یوکله‌مک ایجازه‌نیز یوخدور.",
        "api-error-badtoken": "ایچری خطاسی: پیس کود.",
index 7a4ccf1..b4699c2 100644 (file)
@@ -26,7 +26,8 @@
                        "Lizalizaufa",
                        "Кутлубаева Кунсулу Закиевна",
                        "Вильданова Гюзель",
-                       "Ilmira"
+                       "Ilmira",
+                       "Irus"
                ]
        },
        "tog-underline": "Һылтанмалар аҫтына һыҙыу:",
        "passwordreset-emailelement": "Ҡулланыусы исеме: \n$1\n\nВаҡытлыса серһүҙ: \n$2",
        "passwordreset-emailsentemail": "Серһүҙҙе ташлау тураһындағы мәғлүмәт менән электрон почта аша хат ебәрелде.",
        "passwordreset-emailsentusername": "Әгәр был ҡатнашыусының исеменә бәйле  электрон почтаһының адресы булһа, ул саҡта  серһүҙҙе тергеҙеү өсөн  хат ебәреләсәк.",
-       "passwordreset-invalideamil": "Электрон почта адресы ҡабул ителмәй",
+       "passwordreset-invalidemail": "Электрон почта адресы ҡабул ителмәй",
        "changeemail": "Электрон почта адресын үҙгәртергә",
        "changeemail-header": "Электрон почта адресын үҙгәртеү",
        "changeemail-no-info": "Был биткә туранан ирешеү өсөн һеҙгә системала танылыу кәрәк.",
        "upload-form-label-infoform-categories": "Категориялар",
        "upload-form-label-infoform-date": "Дата",
        "upload-form-label-own-work-message-generic-local": "Тейәлгән файл  {{SITENAME}} лицензия сәйәсәтенә ярашлы икәнен раҫлайым.",
-       "upload-form-label-not-own-work-message-generic-local": "{{SITENAME}} ҡағиҙәләренә ярашлы файлды тейәй алмаһағыҙ, диалог теҙерәһен ябығыҙ ҙа тейәү !с!н башҡа ысулды һайлағыҙ.",
+       "upload-form-label-not-own-work-message-generic-local": "{{SITENAME}} ҡағиҙәләренә ярашлы файлды тейәй алмаһағыҙ, диалог тәҙрәһен ябығыҙ ҙа тейәү өсөн башҡа ысулды һайлағыҙ.",
        "upload-form-label-not-own-work-local-generic-local": "Ошонда эшләп ҡарағыҙ[[Special:Upload|килешеү буйынса тейәү бите]].",
        "upload-form-label-own-work-message-generic-foreign": "Был файлды дөйөм репозиторийға күсереүемде аңлайым. Быны ҡулланыусы килешеүе һәм лицензия сәйәсәтенә ярашлы эшләүемде раҫлайым.",
        "upload-form-label-not-own-work-message-generic-foreign": "{{SITENAME}} ҡағиҙәләренә ярашлы файлды тейәй алмаһағыҙ, диалог теҙерәһен ябығыҙ ҙа тейәү өсөн башҡа ысулды һайлағыҙ.",
        "upload-curl-error28": "Көтөү ваҡыты үтте",
        "upload-curl-error28-text": "\nСайт бигерәк оҙаҡ яуап бирмәй.\nЗинһар, сайттың эшләүен тикшерегеҙ һәм, бер аҙ көткәндән һуң, яңынан ҡабатлап ҡарағыҙ.\nБәлки, һеҙгә сайт бушыраҡ саҡта ҡабатлап ҡарарға кәрәктер.",
        "license": "Рөхсәтнамә:",
-       "license-header": "Рөхсәтнәмә",
+       "license-header": "Рөхсәтнамә",
        "nolicense": "Бер нимә лә һайланмаған",
        "licenses-edit": "Лицензия параметрҙарын үҙгәртергә",
        "license-nopreview": "(Ҡарап сығыу мөмкин түгел)",
        "activeusers-intro": "Был — һуңғы $1 {{PLURAL:$1|көн}} эсендә ниҙер башҡарған ҡатнашыусылар исемлеге.",
        "activeusers-count": "һуңғы $3 {{PLURAL:$3|1=көн}} эсендәге һуңғы көндә $1 {{PLURAL:$1|үҙгәртеү}}",
        "activeusers-from": "Ошондай хәрефтәрҙән башланған ҡатнашыусыларҙы күрһәтергә:",
-       "activeusers-hidebots": "Боттарҙы йәшерергә",
-       "activeusers-hidesysops": "Хакимдәрҙе йәшерергә",
        "activeusers-noresult": "Ҡатнашыусылар табылманы",
        "activeusers-submit": "Әүҙем ҡулланыусыларҙы күрһәтергә",
        "listgrouprights": "Ҡатнашыусылар төркөмө хоҡуҡтары",
        "tags-deactivate-not-allowed": "«$1» тамғаһын һүндереп булмай.",
        "tags-deactivate-submit": "һүндерергә",
        "tags-apply-no-permission": "Һеҙҙең үҙгәртеү тамғаһы ҡуйыу хоҡуғы юҡ.",
-       "tags-apply-blocked": "Үҙгәртеүҙәргә тамға ҡуфырға һеҙҙең хоҡуҡ юҡ, һеҙ бикләнгән.",
+       "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-blocked": "Блок алынғансы, үҙгәртеү тамғалары менән идара итә алмайһығыҙ.",
        "tags-update-add-not-allowed-one": " «$1» тамғаһын ҡулдан файҙаланып булмай",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|түбәндәге тег}} ҡулдан өҫтәлмәй: $1",
        "tags-update-remove-not-allowed-one": " «$1» тамғаһын юйып булмай",
        "feedback-external-bug-report-button": "Техник эш еберергә",
        "feedback-dialog-title": "Баһалама ебәрергә",
        "feedback-dialog-intro": "Баһалама ебәреү өсөн түбәндәге форманы файҙаланығыҙ. Һеҙҙең исем менән комментарий «$1» битендә буласаҡ.",
-       "feedback-error-title": "Хата",
        "feedback-error1": "Хата: API-нан беленмәгән хата",
        "feedback-error2": "Хата: Мөхәррирләү хатаһы",
        "feedback-error3": "Хата: API-нан яуап юҡ",
        "changecredentials-submit": "Иҫәп мәғлүмәттәрен үҙгәртеү",
        "removecredentials": "Иҫәп мәғлүмәттәрен юйырға",
        "removecredentials-submit": "Иҫәп мәғлүмәттәрен юйырға",
-       "credentialsform-account": "Иҫәп яҙмаһы исеме:"
+       "credentialsform-account": "Иҫәп яҙмаһы исеме:",
+       "edit-error-short": "Хата: $1"
 }
index 76dcb87..585cb1e 100644 (file)
        "yourname": "pesengan penganggen",
        "yourpassword": "kruna sandi",
        "yourpasswordagain": "jumunin kruna sandi",
-       "remembermypassword": "elingang kruna sandi padewekan ring computer niki ( suwennyane $1{{PLURAL:$1|dina}})",
        "login": "malebu ring log",
        "nav-login-createaccount": "malebu log / ngawe pepalihan",
        "userlogin": "malebu log / ngawe pepalihan",
index fceddbc..3808477 100644 (file)
        "yourname": "Nutzanama:",
        "yourpassword": "Passwort:",
        "yourpasswordagain": "Es Passwort no amoi eigebm",
-       "remembermypassword": "Mitm Brausa dauahoft ogmejd bleibm (maximoi $1 {{PLURAL:$1|Dog|Dog}})",
        "yourdomainname": "Dei Domain:",
        "externaldberror": "Entweder es ligt a Feeler bai da externen Authentifiziarung vur oder du derfst dai externs Benytzerkonto ned aktualisirn.",
        "login": "Eilogga",
index c54c9eb..23b877e 100644 (file)
        "yourpasswordagain": "کلمه رمز دگه نویس",
        "createacct-yourpasswordagain": "چه دوبارگ پسوردء بلک ات",
        "createacct-yourpasswordagain-ph": "چه دوبارگ پسوردء بلک ات",
-       "remembermypassword": "می ورودءَ ته ای کامپیوتر بدار (په $1 {{PLURAL:$1|روچ|روچ}})",
        "userlogin-remembermypassword": "منء همک وهد برجاه بدار",
        "userlogin-signwithsecure": "چه ایمنین کنکشنء کارمرز بکن ات",
        "yourdomainname": "شمی دامین",
        "passwordreset-emailtext-user": "کاربر $1 چه {{SITENAME}} شمئی پسوردء واترء لوٹ مان {{SITENAME}} ($4) کتگ انت. {{PLURAL:$3|اکانت|اکانتان}} چیریگین کاربر گون ائ ایمیل ادرس همگرنچ انت:\n\n$2\n\n{{PLURAL:$3|ائ موکتین پسورد|ائ موکتین پسوردان}} رند چه {{PLURAL:$5|یک روچ|$5 روچ}} باطل بیت انت.\nشما ضرور انت انیگء لاگین کن ات ءُ نوکین پسوردء بزیر ات. اگان ادگر شهسء ائ لوٹء راهیگ کتگ انت، یانکه وتی اصلیگین پسوردء هیال کت ات ءُ رندء نلوٹ ات آئرا ٹگل دئیت، بیت که ائ پیگامء نگند بزان ات ءُ وتی پیسریگین پسوردء کارمرز کن ات.",
        "passwordreset-emailelement": "یوزرنام: \n$1\n\nموکتین پسورد: \n$2",
        "passwordreset-emailsentemail": "یک ایمیلء گون پسوردء واترء راهیگ بوت.",
-       "passwordreset-emailsent-capture": "یک ایمیلء پر پسورد واترء واسته که جهلیگء پیش دارگ بیت، راهیگ بیتگ انت.",
-       "passwordreset-emailerror-capture": "واترین ایمیل، که جهلیگء پیش دارگ بیت، اڈ بوت، بلئی آئی راهیگ پر {{GENDER:$2|کاربر}} پکا نبوت: $1",
        "changeemail": "ایمیل ادرسء ٹگل بدئ",
        "changeemail-header": "وتی اکانتء ایمیل ادرسء ٹگل بدئ",
        "changeemail-no-info": "پر یکپارگین دزرسی مان ائ تاکء پیکن لاگین کن ات.",
        "undo-nochange": "چوش که پیداگ انت ویرایش مان انیگء باطل بوتگ انت.",
        "undo-summary": "بازبینی برگردین $1 گون [[Special:مشارکتان/$2|$2]] ([[User talk:$2|گپ]] | [[Special:Contributions/$2|{{MediaWiki:Contribslink}}]])",
        "undo-summary-username-hidden": "بی اثر کتن نسخهٔ $1 گون یک نامالومین کاربرء واسته",
-       "cantcreateaccounttitle": "نه نونیت حساب شرکنت",
        "cantcreateaccount-text": "شرکتن حساب چی ای آدرس آی پی ('''$1''') محدود بوتت توسط [[User:$3|$3]].\n\nدلیلی داتگین توسط $3  شی انت ''$2''",
        "cantcreateaccount-range-text": "اکانتء اڈ کتن چه آی پی ادرسء مان ائ هوار <strong>$1</strong>، که شمئی آی پی (<strong>$4</strong>) مان آئی توکاانت، گون [[User:$3|$3]] متوقف بیتگ انت.\nدرشان کتگین دلیل گون $3، $2 انت.",
        "viewpagelogs": "آمار ای صفحه بچار",
index abacb5a..2fc4b3c 100644 (file)
        "yourpasswordagain": "Pakilaog giraray kan sekretong panlaog:",
        "createacct-yourpasswordagain": "Kumpirmaron an sekretong panlaog",
        "createacct-yourpasswordagain-ph": "Pakikaag otro an sekretong panlaog",
-       "remembermypassword": "Giromdoma an sakong paglaog sa kilyaw (browser) na ini (para sa maksimum na $1 {{PLURAL:$1|aldaw|mga aldaw}})",
        "userlogin-remembermypassword": "Dagos mo akong giromdomon na nakalaog",
        "userlogin-signwithsecure": "Gamiton an seguradong koneksyon",
        "yourdomainname": "An saimong kasakupan:",
        "activeusers-intro": "Iyo in an listahan kan mga paragamit na nagkaigwa nin mga ginibo sa laog kan nakaaging $1 {{PLURAL:$1|aldaw|mga aldaw}}.",
        "activeusers-count": "$1 {{PLURAL:$1|aksyon|mga aksyon}} sa nakaaging {{PLURAL:$3|aldaw|$3 mga aldaw}}",
        "activeusers-from": "Ipahiling an mga paragamit magpoon sa:",
-       "activeusers-hidebots": "Itago an mga panalnga",
-       "activeusers-hidesysops": "Itago an mga administrador",
        "activeusers-noresult": "Mayong mga paragamit na nanagboan.",
        "listgrouprights": "Mga karapatan kan grupo nin paragamit",
        "listgrouprights-summary": "An minasunod iyo an listahan kan mga grupo nin paragamit na pinaghunsay kaining wiki, kaiba an saindang asosyadong mga karapatan nin paggamit.\nPuwedeng magkakaigwa nin [[{{MediaWiki:Listgrouprights-helppage}}|kadagdagang impormasyon]] mapanungod sa indibidwal na mga karapatan.",
        "htmlform-chosen-placeholder": "Magpili nin sarong opsyon",
        "htmlform-title-not-creatable": "\"$1\" bako sarong maimumuknang titulo kan pahina",
        "htmlform-title-not-exists": "$1 bakong eksistido.",
-       "sqlite-has-fts": "$1 na igwang suporta sa kabilogang-teksto nin paghahanap",
-       "sqlite-no-fts": "$1 na mayong suporta sa kabilogang-teksto nin paghahanap",
        "logentry-delete-delete": "$1 {{GENDER:$2|pinagpura na}} pahina $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|pinagbalik}} na pahina $3",
        "logentry-delete-event": "$1 {{GENDER:$2|pinagliwat}}an bisibilidad kan {{PLURAL:$5|sarong talaan nin pangyayari|$5 talaan nin mga pangyayari}} kan $3: $4",
index 894c727..03282b0 100644 (file)
@@ -15,7 +15,8 @@
                        "Тест",
                        "아라",
                        "Liashko",
-                       "Macofe"
+                       "Macofe",
+                       "Kareyac"
                ]
        },
        "tog-underline": "Падкрэсьліваць спасылкі:",
        "botpasswords-label-delete": "Выдаліць",
        "botpasswords-label-resetpassword": "Скінуць пароль",
        "botpasswords-label-grants": "Прыдатныя дазволы:",
-       "botpasswords-help-grants": "Ð\9aожнÑ\8b Ð´Ð°Ð·Ð²Ð¾Ð» Ð´Ð°Ðµ Ð´Ð¾Ñ\81Ñ\82Ñ\83п Ð´Ð° Ð¿Ñ\80авоÑ\9e Ñ\83дзелÑ\8cнÑ\96ка, Ñ\8fкÑ\96Ñ\8f Ñ\9eжо Ð¼Ð°Ðµ Ñ\80аÑ\85Ñ\83нак Ñ\83дзелÑ\8cнÑ\96ка. Глядзіце [[Special:ListGrants|табліцу дазволаў]] дзеля дадатковых зьвестак.",
+       "botpasswords-help-grants": "Ð\94азволÑ\8b Ð´Ð°Ñ\8eÑ\86Ñ\8c Ð´Ð¾Ñ\81Ñ\82Ñ\83п Ð´Ð° Ð¿Ñ\80авоÑ\9e Ñ\83дзелÑ\8cнÑ\96ка, Ñ\8fкÑ\96Ñ\8f Ñ\9eжо Ð¼Ð°Ðµ Ð²Ð°Ñ\88 Ñ\80аÑ\85Ñ\83нак Ñ\83дзелÑ\8cнÑ\96ка. Ð\9dаданÑ\8cне Ð´Ð°Ð·Ð²Ð¾Ð»Ñ\83 Ñ\82Ñ\83Ñ\82 Ð½Ðµ Ð´Ð°Ðµ Ð´Ð¾Ñ\81Ñ\82Ñ\83пÑ\83 Ð´Ð° Ð¿Ñ\80авоÑ\9e, Ñ\8fкÑ\96Ñ\85 Ð½Ñ\8fма Ñ\9e Ð²Ð°Ñ\88ага Ñ\80аÑ\85Ñ\83нкÑ\83. Глядзіце [[Special:ListGrants|табліцу дазволаў]] дзеля дадатковых зьвестак.",
        "botpasswords-label-grants-column": "Дазволена",
        "botpasswords-bad-appid": "Назва робата «$1» зьяўляецца няслушнай.",
        "botpasswords-insert-failed": "Не атрымалася дадаць робата зь імем «$1». Магчыма, ён ужо быў дададзены?",
        "passwordreset-nocaller": "Мусіць быць пададзены той, хто робіць выклік",
        "passwordreset-nosuchcaller": "Аўтар выкліку не існуе: $1",
        "passwordreset-ignored": "Скіданьне паролю не адбылося. Магчыма, ня быў наладжаны пастаўшчык?",
-       "passwordreset-invalideamil": "Няслушны адрас электроннай пошты",
+       "passwordreset-invalidemail": "Няслушны адрас электроннай пошты",
        "passwordreset-nodata": "Не былі пададзеныя ні імя ўдзельніка, ні адрас электроннай пошты",
        "changeemail": "Зьмяніць або выдаліць адрас электроннай пошты",
        "changeemail-header": "Запоўніце гэтую форму, каб зьмяніць ваш адрас электроннай пошты. Калі вы жадаеце выдаліць адрас электроннай пошты, далучаны да вашага рахунку, пакіньце поле новага адрасу электроннай пошты пустым пры запаўненьні формы.",
        "subject-preview": "Папярэдні прагляд загалоўку:",
        "previewerrortext": "Адбылася памылка пры спробе папярэдняга прагляду вашых зьменаў.",
        "blockedtitle": "Удзельнік заблякаваны",
-       "blockedtext": "'''Ваш рахунак ўдзельніка ці IP-адрас быў заблякаваны.'''\n\nБлякаваньне выканаў $1.\nПрычына гэтага: ''$2''.\n\n* Пачатак блякаваньня: $8\n* Сканчэньне блякаваньня: $6\n* Быў заблякаваны: $7\n\nВы можаце скантактавацца з $1 ці адным зь іншых [[{{MediaWiki:Grouppage-sysop}}|адміністратараў]], каб абмеркаваць блякаваньне. Заўважце, што Вы ня зможаце ўжыць магчымасьць «даслаць ліст па электроннай пошце», пакуль не пазначыце сапраўдны адрас электроннай пошты ў Вашых [[Special:Preferences|наладах]], і калі гэта Вам не было забаронена.\nВаш IP-адрас — $3, ідэнтыфікатар блякаваньня — #$5.\nКалі ласка, улучайце ўсю вышэйпададзеную інфармацыю ва ўсе запыты, што Вы будзеце рабіць.",
-       "autoblockedtext": "Ваш IP-адрас быў аўтаматычна заблякаваны, таму што ён ужываўся іншым удзельнікам, які быў заблякаваны $1.\nПрычына гэтага:\n\n:''$2''\n\n* Блякаваньне пачалося: $8\n* Блякаваньне скончыцца: $6\n* Быў заблякаваны: $7\n\nВы можаце скантактавацца з $1 ці з адным зь іншых [[{{MediaWiki:Grouppage-sysop}}|адміністратараў]], каб абмеркаваць блякаваньне.\n\nЗаўважце, што Вы ня зможаце ужываць магчымасьць «даслаць ліст праз электронную пошту», пакуль ня будзе пазначаны дзейны адрас электроннай пошты ў Вашых [[Special:Preferences|наладах удзельніка]], і калі гэта Вам не было забаронена.\n\nВаш цяперашні IP-адрас — $3, ідэнтыфікатар блякаваньня — #$5.\nКалі ласка, улучайце ўсю вышэйпададзеную інфармацыю ва ўсе запыты, што Вы будзеце рабіць.",
+       "blockedtext": "<strong>Ваш рахунак удзельніка ці IP-адрас быў заблякаваны.</strong>\n\nБлякаваньне выканаў $1.\nПрычына гэтага: <em>$2</em>.\n\n* Пачатак блякаваньня: $8\n* Сканчэньне блякаваньня: $6\n* Быў заблякаваны: $7\n\nВы можаце скантактавацца з $1 ці адным зь іншых [[{{MediaWiki:Grouppage-sysop}}|адміністратараў]], каб абмеркаваць блякаваньне. Заўважце, што Вы ня зможаце ўжыць магчымасьць «даслаць ліст па электроннай пошце», пакуль не пазначыце сапраўдны адрас электроннай пошты ў Вашых [[Special:Preferences|наладах]], і калі гэта Вам не было забаронена.\nВаш IP-адрас — $3, ідэнтыфікатар блякаваньня — #$5.\nКалі ласка, улучайце ўсю вышэйпададзеную інфармацыю ва ўсе запыты, што Вы будзеце рабіць.",
+       "autoblockedtext": "Ваш IP-адрас быў аўтаматычна заблякаваны, таму што ён ужываўся іншым удзельнікам, які быў заблякаваны $1.\nПрычына гэтага:\n\n:<em>$2</em>\n\n* Блякаваньне пачалося: $8\n* Блякаваньне скончыцца: $6\n* Быў заблякаваны: $7\n\nВы можаце скантактавацца з $1 ці з адным зь іншых [[{{MediaWiki:Grouppage-sysop}}|адміністратараў]], каб абмеркаваць блякаваньне.\n\nЗаўважце, што Вы ня зможаце ўжываць магчымасьць «даслаць ліст праз электронную пошту», пакуль ня будзе пазначаны дзейны адрас электроннай пошты ў Вашых [[Special:Preferences|наладах удзельніка]], і калі гэта Вам не было забаронена.\n\nВаш цяперашні IP-адрас — $3, ідэнтыфікатар блякаваньня — #$5.\nКалі ласка, улучайце ўсю вышэйпададзеную інфармацыю ва ўсе запыты, што Вы будзеце рабіць.",
        "blockednoreason": "прычына не пазначана",
        "whitelistedittext": "Вам трэба $1, каб рэдагаваць старонкі.",
        "confirmedittext": "Вы мусіце пацьвердзіць Ваш адрас электроннай пошты перад рэдагаваньнем старонак. Калі ласка, пазначце і пацьвердзіце адрас электроннай пошты праз Вашы [[Special:Preferences|налады]].",
        "nosuchsectiontitle": "Немагчыма знайсьці сэкцыю",
-       "nosuchsectiontext": "Вы спрабуеце рэдагаваць сэкцыю, якой не існуе.\nЯна магла быць перанесена, альбо выдалена пад час Вашага прагляду старонкі.",
+       "nosuchsectiontext": "Вы спрабавалі рэдагаваць сэкцыю, якой не існуе.\nЯна магла быць перанесеная альбо выдаленая, пакуль вы праглядалі старонку.",
        "loginreqtitle": "Патрабуецца ўваход у сыстэму",
        "loginreqlink": "ўвайсьці",
        "loginreqpagetext": "Вы мусіце $1, каб праглядаць іншыя старонкі.",
-       "accmailtitle": "Пароль адасланы.",
-       "accmailtext": "СÑ\82воÑ\80анÑ\8b Ð°Ð´Ð²Ð¾Ð»Ñ\8cнÑ\8b Ð¿Ð°Ñ\80олÑ\8c Ð´Ð»Ñ\8f [[User talk:$1|$1]] Ð±Ñ\8bÑ\9e Ð°Ð´Ð°Ñ\81ланÑ\8b Ð¿Ð° Ð°Ð´Ñ\80аÑ\81е $2. Ð¯Ð³Ð¾ Ð¼Ð¾Ð¶Ð½Ð° Ð·Ñ\8cмÑ\8fнÑ\96Ñ\86Ñ\8c Ð½Ð° Ñ\81Ñ\82аÑ\80онÑ\86Ñ\8b ''[[Special:ChangePassword|зÑ\8cменÑ\8b Ð¿Ð°Ñ\80олÑ\8e]]'' пасьля ўваходу.",
+       "accmailtitle": "Пароль адасланы",
+       "accmailtext": "Ð\92Ñ\8bпадковÑ\8b Ð¿Ð°Ñ\80олÑ\8c Ð´Ð»Ñ\8f [[User talk:$1|$1]] Ð±Ñ\8bÑ\9e Ð°Ð´Ð°Ñ\81ланÑ\8b Ð¿Ð° Ð°Ð´Ñ\80аÑ\81е $2. Ð¯Ð³Ð¾ Ð¼Ð¾Ð¶Ð½Ð° Ð·Ñ\8cмÑ\8fнÑ\96Ñ\86Ñ\8c Ð½Ð° Ñ\81Ñ\82аÑ\80онÑ\86Ñ\8b <em>[[Special:ChangePassword|зÑ\8cменÑ\8b Ð¿Ð°Ñ\80олÑ\8e]]</em> пасьля ўваходу.",
        "newarticle": "(Новая)",
        "newarticletext": "Вы прыйшлі па спасылцы на старонку, якая яшчэ не існуе.\nКаб стварыць яе, напішыце тэкст у полі ніжэй (глядзіце [$1 старонку дапамогі] для дадатковай інфармацыі).\nКалі Вы трапілі сюды памылкова, націсьніце кнопку «<strong>назад</strong>» у вашым браўзэры.",
        "anontalkpagetext": "----\n<em>Гэта старонка гутарак ананімнага ўдзельніка, які яшчэ не стварыў сабе рахунак альбо не ўжывае яго.</em>\nТаму мы вымушаныя ўжываць лічбавы IP-адрас дзеля ягонай ідэнтыфікацыі. Адзін IP-адрас можа выкарыстоўвацца некалькімі ўдзельнікамі. Калі Вы — ананімны ўдзельнік і лічыце, што атрымалі не прызначаныя Вам камэнтары, калі ласка, [[Special:CreateAccount|стварыце рахунак]] альбо [[Special:UserLogin|ўвайдзіце ў сыстэму]], каб у будучыні пазьбегнуць магчымай блытаніны зь іншымі ананімнымі ўдзельнікамі.",
        "noarticletext": "Цяпер тэкст на гэтай старонцы адсутнічае.\nВы можаце [[Special:Search/{{PAGENAME}}|пашукаць гэтую назву]] сярод іншых старонак, <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>» не зарэгістраваны. Калі ласка, удакладніце, ці жадаеце Вы стварыць/рэдагаваць гэтую старонку.",
+       "missing-revision": "Вэрсія старонкі №$1 з назвай «{{FULLPAGENAME}}» не існуе.\n\nЗвычайна гэта здараецца з-за пераходу па састарэлай спасылцы на старонку, якая была выдаленая.\nПадрабязнасьці можна знайсьці ў [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале выдаленьняў].",
+       "userpage-userdoesnotexist": "Рахунак удзельніка «$1» не зарэгістраваны. Калі ласка, удакладніце, ці жадаеце Вы стварыць/рэдагаваць гэтую старонку.",
        "userpage-userdoesnotexist-view": "Рахунак «$1» ня створаны.",
-       "blocked-notice-logextract": "Гэты ўдзельнік у дадзены момант заблякаваны.\nАпошні запіс з журналу блякаваньняў пададзены ніжэй для даведкі:",
+       "blocked-notice-logextract": "Гэты ўдзельнік у цяперашні момант заблякаваны.\nАпошні запіс з журналу блякаваньняў пададзены ніжэй для даведкі:",
        "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. Ён яшчэ не запісаны!'''",
-       "userjspreview": "'''Памятайце, што гэта толькі папярэдні прагляд Вашага JavaScript, ён яшчэ не запісаны!'''",
-       "sitecsspreview": "'''Памятайце, што гэта толькі папярэдні прагляд гэтага CSS.'''\n'''Ён яшчэ не захаваны!'''",
-       "sitejspreview": "'''Памятайце, што гэта толькі папярэдні прагляд гэтага коду JavaScript.'''\n'''Ён яшчэ не захаваны!'''",
-       "userinvalidcssjstitle": "'''Папярэджаньне:''' няма тэмы афармленьня «$1».\nПамятайце, што ўласныя старонкі .css і .js павінны мець назву, якая складаецца з малых літараў, напрыклад, {{ns:user}}:Хтосьці/vector.css, а не {{ns:user}}:Хтосьці/Vector.css.",
+       "usercssyoucanpreview": "<strong>Падказка:</strong> выкарыстоўвайце кнопку «{{int:showpreview}}», каб паспрабаваць новы CSS-код перад яго захаваньнем.",
+       "userjsyoucanpreview": "<strong>Падказка:</strong> выкарыстоўвайце кнопку «{{int:showpreview}}», каб паспрабаваць новы код JavaScript перад тым, як яго захаваць.",
+       "usercsspreview": "<strong>Памятайце, што гэта толькі папярэдні прагляд вашага CSS. Ён яшчэ не запісаны!</strong>",
+       "userjspreview": "<strong>Памятайце, што гэта толькі папярэдні прагляд Вашага JavaScript. Ён яшчэ не запісаны!</strong>",
+       "sitecsspreview": "<strong>Памятайце, што гэта толькі папярэдні прагляд гэтага CSS.\nЁн яшчэ не захаваны!</strong>",
+       "sitejspreview": "<strong>Памятайце, што гэта толькі папярэдні прагляд гэтага коду JavaScript.\nЁн яшчэ не захаваны!</strong>",
+       "userinvalidcssjstitle": "<strong>Папярэджаньне:</strong> няма тэмы афармленьня «$1».\nПамятайце, што ўласныя старонкі .css і .js павінны мець назву, якая складаецца з малых літараў, напрыклад, {{ns:user}}:Хтосьці/vector.css, а не {{ns:user}}:Хтосьці/Vector.css.",
        "updated": "(Абноўлена)",
        "note": "'''Заўвага: '''",
        "previewnote": "'''Гэта толькі папярэдні прагляд.'''\nВашыя зьмены яшчэ не былі захаваныя!",
        "grant-basic": "Асноўныя правы",
        "grant-viewdeleted": "Прагляд выдаленых файлаў і старонак",
        "grant-viewmywatchlist": "Прагляд вашага сьпісу назіраньня",
+       "grant-viewrestrictedlogs": "Прагляд запісаў журнала з абмежаваным доступам",
        "newuserlogpage": "Журнал стварэньня рахункаў",
        "newuserlogpagetext": "Гэта журнал стварэньня рахункаў удзельнікаў і ўдзельніц.",
        "rightslog": "Журнал правоў удзельнікаў",
        "upload-dialog-disabled": "Загрузка файлаў з дапамогай гэтага дыялёгу адключаная ў гэтай вікі.",
        "upload-dialog-title": "Загрузка файла",
        "upload-dialog-button-cancel": "Адмяніць",
+       "upload-dialog-button-back": "Назад",
        "upload-dialog-button-done": "Зроблена",
        "upload-dialog-button-save": "Захаваць",
        "upload-dialog-button-upload": "Загрузіць",
        "apisandbox-results-fixtoken-fail": "Памылка пры атрыманьні токену «$1».",
        "apisandbox-alert-page": "Палі на гэтай старонцы няслушныя.",
        "apisandbox-alert-field": "Значэньне гэтага поля зьяўляецца няслушным.",
+       "apisandbox-continue": "Працягнуць",
+       "apisandbox-continue-clear": "Ачысьціць",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries працягне] апошні запыт; {{int:apisandbox-continue-clear}} ачысьціць парамэтры, зьвязаныя з працягам.",
+       "apisandbox-param-limit": "Увядзіце <kbd>max</kbd>, каб выкарыстаць максымальны ліміт.",
        "booksources": "Крыніцы кніг",
        "booksources-search-legend": "Пошук кніг",
        "booksources-isbn": "ISBN:",
        "booksources-search": "Шукаць",
        "booksources-text": "Ніжэй знаходзіцца сьпіс спасылак на іншыя сайты, якія прадаюць новыя і патрыманыя кнігі, і могуць таксама мець інфармацыю пра кнігі, якія Вы шукаеце:",
        "booksources-invalid-isbn": "Пададзены няслушны ISBN; праверце, магчыма ўзьніклі памылкі пры пераносе нумару з арыгінальнай крыніцы.",
+       "magiclink-tracking-rfc": "Старонкі, на якіх ужытыя магічныя спасылкі RFC",
+       "magiclink-tracking-rfc-desc": "На гэтай старонцы ўжываюцца магічныя спасылкі RFC. Глядзіце [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] пра тое, як зладзіць міграцыю.",
+       "magiclink-tracking-pmid": "Старонкі, на якіх ужытыя магічныя спасылкі PMID",
+       "magiclink-tracking-pmid-desc": "На гэтай старонцы ўжываюцца магічныя спасылкі PMID. Глядзіце [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] пра тое, як зладзіць міграцыю.",
+       "magiclink-tracking-isbn": "Старонкі, на якіх ужытыя магічныя спасылкі ISBN",
+       "magiclink-tracking-isbn-desc": "На гэтай старонцы ўжываюцца магічныя спасылкі ISBN. Глядзіце [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] пра тое, як зладзіць міграцыю.",
        "specialloguserlabel": "Выканаўца:",
        "speciallogtitlelabel": "Мэта (назва ці {{ns:user}}:імя_ўдзельніка для ўдзельніка):",
        "log": "Журналы падзеяў",
        "activeusers-intro": "Гэта сьпіс удзельнікаў, якія былі актыўнымі на працягу $1 {{PLURAL:$1|апошняга дня|апошніх дзён|апошніх дзён}}.",
        "activeusers-count": "$1 {{PLURAL:$1|дзеяньне|дзеяньні|дзеяньняў}} за $3 {{PLURAL:$3|апошні дзень|апошнія дні|апошніх дзён}}",
        "activeusers-from": "Паказваць ўдзельнікаў, пачынаючы з:",
-       "activeusers-hidebots": "Схаваць робатаў",
-       "activeusers-hidesysops": "Схаваць адміністратараў",
+       "activeusers-groups": "Паказаць удзельнікаў, якія належаць да групаў:",
        "activeusers-noresult": "Удзельнікі ня знойдзеныя.",
        "activeusers-submit": "Паказаць актыўных удзельнікаў",
        "listgrouprights": "Правы групаў удзельнікаў",
        "modifiedarticleprotection": "зьменены ўзровень абароны старонкі «[[$1]]»",
        "unprotectedarticle": "зьнятая абарона з «[[$1]]»",
        "movedarticleprotection": "перанесеныя налады абароны з «[[$2]]» на «[[$1]]»",
+       "protectedarticle-comment": "{{GENDER:$2|Абараніў|Абараніла}} «[[$1]]»",
        "protect-title": "Абарона «$1»",
        "protect-title-notallowed": "Прагляд узроўню абароны «$1»",
        "prot_1movedto2": "[[$1]] перанесеная ў [[$2]]",
        "patrol-log-header": "Гэта журнал патруляваных вэрсіяў.",
        "log-show-hide-patrol": "$1 журнал патруляваньняў",
        "log-show-hide-tag": "$1 журнал метак",
+       "confirm-markpatrolled-button": "Добра",
        "deletedrevision": "Выдаленая старая вэрсія $1",
        "filedeleteerror-short": "Памылка выдаленьня файла: $1",
        "filedeleteerror-long": "У часе выдаленьня файла ўзьніклі наступныя памылкі:\n\n$1",
        "newimages-showbots": "Паказаць загружаныя робатамі",
        "newimages-hidepatrolled": "Схаваць патруляваныя загрузкі",
        "noimages": "Выявы адсутнічаюць.",
+       "gallery-slideshow-toggle": "Пераключыць мініятуры",
        "ilsubmit": "Шукаць",
        "bydate": "па даце",
        "sp-newimages-showfrom": "Паказаць новыя файлы, загружаныя пазьней за $2, $1",
        "tags-deactivate": "адключыць",
        "tags-hitcount": "$1 {{PLURAL:$1|зьмена|зьмены|зьменаў}}",
        "tags-manage-no-permission": "Вы ня маеце правоў на зьмену метак.",
-       "tags-manage-blocked": "Вы ня можаце мяняць меткі, калі заблякаваныя.",
+       "tags-manage-blocked": "Вы ня можаце мяняць меткі, калі {{GENDER:$1|вы}} заблякаваныя.",
        "tags-create-heading": "Стварэньне новай меткі",
        "tags-create-explanation": "Па змоўчаньні, наваствораныя меткі будуць даступныя для выкарыстаньня ўдзельнікамі і робатамі.",
        "tags-create-tag-name": "Назва меткі:",
        "tags-deactivate-not-allowed": "Немагчыма дэактываваць метку «$1».",
        "tags-deactivate-submit": "Адключыць",
        "tags-apply-no-permission": "Вы ня маеце права прымяняць меткі да вашых рэдагаваньняў.",
-       "tags-apply-blocked": "Вы ня можаце мяняць меткі да вашых зьменаў, калі заблякаваныя.",
+       "tags-apply-blocked": "Ð\92Ñ\8b Ð½Ñ\8f Ð¼Ð¾Ð¶Ð°Ñ\86е Ð¼Ñ\8fнÑ\8fÑ\86Ñ\8c Ð¼ÐµÑ\82кÑ\96 Ð´Ð° Ð²Ð°Ñ\88Ñ\8bÑ\85 Ð·Ñ\8cменаÑ\9e, ÐºÐ°Ð»Ñ\96 Ð²Ñ\8b Ð·Ð°Ð±Ð»Ñ\8fкаванÑ\8bÑ\8f.",
        "tags-apply-not-allowed-one": "Метка «$1» ня можа быць прызначаная ўручную.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|Наступную метку|Наступныя меткі}} нельга дадаваць уручную: $1",
        "tags-update-no-permission": "Вы ня маеце права на дадаваньне ці выдаленьне метак зьменаў для асобных вэрсіяў ці запісаў журналаў.",
        "htmlform-cloner-create": "Дадаць больш",
        "htmlform-cloner-delete": "Выдаліць",
        "htmlform-cloner-required": "Патрабуецца як мінімум яшчэ адно значэньне.",
+       "htmlform-date-placeholder": "ГГГГ-ММ-ДД",
+       "htmlform-time-placeholder": "ГГ:ХХ:СС",
+       "htmlform-datetime-placeholder": "ГГГГ-ММ-ДД ГГ:ХХ:СС",
+       "htmlform-date-invalid": "Уведзенае вамі значэньне не зьяўляецца датай. Паспрабуйце ўжыць фармат ГГГГ-ММ-ДД.",
+       "htmlform-time-invalid": "Уведзенае вамі значэньне не зьяўляецца часам. Паспрабуйце ўжыць фармат ГГ:ХХ:СС.",
+       "htmlform-datetime-invalid": "Уведзенае вамі значэньне не зьяўляецца датай і часам. Паспрабуйце ўжыць фармат ГГГГ-ММ-ДД ГГ:ХХ:СС.",
+       "htmlform-date-toolow": "Уведзенае вамі значэньне меней за самую раньнюю дазволеную дату $1.",
+       "htmlform-date-toohigh": "Значэньне, якое вы выбралі, болей за самую позьнюю дазволеную дату $1.",
+       "htmlform-time-toolow": "Значэньне, якое вы выбралі, меней за самы раньні дазволены час $1.",
+       "htmlform-time-toohigh": "Значэньне, якое вы выбралі, болей за самы позьні дазволены час $1.",
+       "htmlform-datetime-toolow": "Значэньне, якое вы выбралі, меней за самую раньнюю дазволеную дату і час $1.",
+       "htmlform-datetime-toohigh": "Значэньне, якое вы выбралі, болей за найпазьнейшую дазволеную дату і час $1.",
        "htmlform-title-badnamespace": "[[:$1]] знаходзіцца не ў прасторы назваў «{{ns:$2}}».",
        "htmlform-title-not-creatable": "«$1» — немагчымы загаловак для старонкі",
        "htmlform-title-not-exists": "$1 не існуе.",
        "feedback-external-bug-report-button": "Аформіць тэхнічную задачу",
        "feedback-dialog-title": "Адаслаць водгук",
        "feedback-dialog-intro": "Свой водгук Вы можаце адаслаць праз простую форму зьнізу. Ваш камэнтар будзе дададзены на старонку «$1» разам з Вашым іменем.",
-       "feedback-error-title": "Памылка",
        "feedback-error1": "Памылка: невядомы вынік з API",
        "feedback-error2": "Памылка рэдагаваньня",
        "feedback-error3": "Памылка: няма адказу ад API",
        "feedback-thanks": "Дзякуй! Ваш водгук быў разьмешчаны на старонцы «[$2 $1]».",
        "feedback-thanks-title": "Дзякуй!",
        "feedback-useragent": "Агент удзельніка:",
-       "searchsuggest-search": "Пошук",
+       "searchsuggest-search": "Пошук у {{GRAMMAR:месны|{{SITENAME}}}}",
        "searchsuggest-containing": "утрымлівае...",
        "api-error-autoblocked": "Ваш IP-адрас быў аўтаматычна заблякаваны, бо ён быў выкарыстаны заблякаваным удзельнікам.",
        "api-error-badaccess-groups": "У Вас няма дазволу загружаць файлы ў гэтую вікі.",
        "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-unprotect": "Зьняцьце абароны",
index 7ce602c..d6cd8e0 100644 (file)
@@ -28,7 +28,8 @@
                        "Goshaproject",
                        "Nemo bis",
                        "SamGold",
-                       "Liashko"
+                       "Liashko",
+                       "Mechanizatar"
                ]
        },
        "tog-underline": "Падкрэсліваць спасылкі:",
        "views": "Віды",
        "toolbox": "Прылады",
        "tool-link-userrights": "Змяніць групы {{GENDER:$1|ўдзельніка|ўдзельніцы}}",
+       "tool-link-emailuser": "Напісаць ліст {{GENDER:$1|удзельніку|удзельніцы}}",
        "userpage": "Паказаць старонку ўдзельніка",
        "projectpage": "Паказаць старонку праекта",
        "imagepage": "Гл. старонку файла",
        "botpasswords-label-delete": "Сцерці",
        "botpasswords-label-resetpassword": "Скінуць пароль",
        "botpasswords-label-grants": "Прыдатныя дазволы:",
-       "botpasswords-help-grants": "Ð\9aожнÑ\8b Ð´Ð°Ð·Ð²Ð¾Ð» Ð´Ð°Ðµ Ð´Ð¾Ñ\81Ñ\82Ñ\83п Ð´Ð° Ð¿Ñ\80авоÑ\9e Ñ\83дзелÑ\8cнÑ\96ка, Ñ\8fкÑ\96Ñ\8f Ñ\9eжо Ð¿Ñ\80Ñ\8bзнаÑ\87анÑ\8b Ñ\9eлÑ\96ковамÑ\83 Ð·Ð°Ð¿Ñ\96Ñ\81Ñ\83 Ñ\83дзелÑ\8cнÑ\96ка. Ð\93лÑ\8fдзÑ\96Ñ\86е [[Special:ListGrants|Ñ\82аблÑ\96Ñ\86Ñ\83 Ð´Ð°Ð·Ð²Ð¾Ð»Ð°Ñ\9e]] Ð´Ð»Ñ\8f Ð°Ñ\82Ñ\80Ñ\8bманнÑ\8f Ð´Ð°Ð´Ð°Ñ\82ковÑ\8bÑ\85 Ð·Ñ\8cвестак.",
+       "botpasswords-help-grants": "Ð\94азволÑ\8b Ð´Ð°Ñ\8eÑ\86Ñ\8c Ð´Ð¾Ñ\81Ñ\82Ñ\83п Ð´Ð° Ð¿Ñ\80авоÑ\9e, Ñ\8fкÑ\96Ñ\8f Ñ\9eжо Ð¼Ð°Ðµ Ð\92аÑ\88 Ñ\83лÑ\96ковÑ\8b Ð·Ð°Ð¿Ñ\96Ñ\81. Ð\9dаданне Ð´Ð°Ð·Ð²Ð¾Ð»Ñ\83 Ñ\82Ñ\83Ñ\82 Ð½Ðµ Ð´Ð°Ðµ Ð´Ð¾Ñ\81Ñ\82Ñ\83пÑ\83 Ð´Ð° Ð¿Ñ\80авоÑ\9e, Ñ\8fкÑ\96Ñ\85 Ð½Ñ\8fма Ñ\9e Ð\92аÑ\88ага Ñ\9eлÑ\96ковага Ð·Ð°Ð¿Ñ\96Ñ\81Ñ\83. Ð\93лÑ\8fдзÑ\96Ñ\86е [[Special:ListGrants|Ñ\82аблÑ\96Ñ\86Ñ\83 Ð´Ð°Ð·Ð²Ð¾Ð»Ð°Ñ\9e]] Ð´Ð»Ñ\8f Ð°Ñ\82Ñ\80Ñ\8bманнÑ\8f Ð´Ð°Ð´Ð°Ñ\82ковÑ\8bÑ\85 Ð·вестак.",
        "botpasswords-label-grants-column": "Дазволена",
        "botpasswords-bad-appid": "Назва робата \"$1\" недапушчальная.",
        "botpasswords-insert-failed": "Не ўдалося дадаць робату назву \"$1\". Магчыма, яна ўжо дададзена?",
        "passwordreset-nocaller": "Мусіць быць указана, хто выклікае",
        "passwordreset-nosuchcaller": "Аўтар выкліку не існуе: $1",
        "passwordreset-ignored": "Скід пароля не быў апрацаваны. Магчыма, не настроены пастаўшчык?",
-       "passwordreset-invalideamil": "Няслушны адрас электроннай пошты",
+       "passwordreset-invalidemail": "Няслушны адрас электроннай пошты",
        "passwordreset-nodata": "Не былі пададзены ні імя ўдзельніка, ні адрас электроннай пошты",
        "changeemail": "Змяніць або выдаліць адрас электроннай пошты",
        "changeemail-header": "Запоўніце гэтую форму, каб змяніць свой адрас электроннай пошты. Калі хочаце выдаліць адрас электроннай пошты, злучаны з вашым уліковым запісам, пакіньце поле новага адраса электроннай пошты пустым пры адпраўцы формы.",
        "missing-revision": "Няма версіі #$1 у старонкі з назвай \"{{FULLPAGENAME}}\".\n\nЗвычайна такое здараецца, калі прайсці па састарэлай спасылцы з гісторыі на старонку, якая была сцёрта.\nПадрабязнасці можна пабачыць у [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} журнале сціранняў].",
        "userpage-userdoesnotexist": "Рахунак удзельніка \"<nowiki>$1</nowiki>\" не зарэгістраваны. Праверце, ці вы жадаеце стварыць або паправіць гэтую старонку.",
        "userpage-userdoesnotexist-view": "Уліковы запіс удзельніка \" $1 \"не зарэгістраваны.",
-       "blocked-notice-logextract": "Гэты карыстальнік у дадзены момант заблакаваны. \n Апошні запіс журнала блакіровак прыводзіцца ніжэй для даведкі:",
+       "blocked-notice-logextract": "Гэты карыстальнік у дадзены момант заблакаваны. \nАпошні запіс журнала блакіровак прыводзіцца ніжэй для даведкі:",
        "clearyourcache": "<strong>Заўвага:</strong> Пасля замацоўвання, вам можа спатрэбіцца ачыстка кэшу браўзера, каб убачыць унесеныя змяненні. \n*<strong>Firefox / Safari:</strong> націсніце <em>Reload</em>, утрымліваючы <em>Shift</em>, або націсніце <em>Ctrl-F5</em> ці <em>Ctrl-R</em> (<em>⌘-R</em> на Макінтошах)\n* <strong>Google Chrome</strong>: Націсніце <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> на Mac)\n* <strong>Internet Explorer</strong>: націсніце <em>Refresh</em>, утрымліваючы <em>Ctrl</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}}''\" для выпрабоўвання новага коду JS ''перад тым'', як яго запісваць.",
+       "usercssyoucanpreview": "<strong>Парада:</strong> Карыстайцеся кнопкай \"''{{int:showpreview}}''\", каб паспрабаваць новы код CSS перад тым, як яго запісваць.",
+       "userjsyoucanpreview": "<strong>Парада:</strong> Карыстайцеся кнопкай \"''{{int:showpreview}}''\", каб паспрабаваць новы код JavaScript перад тым, як яго запісваць.",
        "usercsspreview": "'''Памятайце, што гэта толькі папярэдні паказ вашага ўласнага CSS. Праўкі яшчэ не замацаваныя!'''",
-       "userjspreview": "'''Памятайце, што гэта выпрабаванне/папярэдні паказ вашага ўласнага Яваскрыпту, які яшчэ не быў замацаваны!'''",
-       "sitecsspreview": "'''Памятайце, што гэта толькі папярэдні паказ вашага CSS.'''\n'''Праўкі яшчэ не замацаваныя!'''",
-       "sitejspreview": "'''Памятайце, што гэта толькі папярэдні паказ вашага JavaScript.'''\n'''Праўкі яшчэ не замацаваныя!'''",
+       "userjspreview": "<strong>Памятайце, што гэта толькі выпрабаванне/папярэдні паказ вашага JavaScript. Праўкі яшчэ не замацаваныя!</strong>",
+       "sitecsspreview": "<strong>Памятайце, што гэта толькі папярэдні паказ вашага CSS.\nПраўкі яшчэ не замацаваныя!</strong>",
+       "sitejspreview": "<strong>Памятайце, што гэта толькі папярэдні паказ вашага JavaScript.\nПраўкі яшчэ не замацаваныя!</strong>",
        "userinvalidcssjstitle": "'''Увага:''' Няма вокладкі з назвай \"$1\". Памятайце, што свае старонкі .css і .js называюцца толькі малымі літарамі, такім чынам, напр., {{ns:user}}:Foo/vector.css, а не {{ns:user}}:Foo/Vector.css.",
        "updated": "(Абноўлена)",
        "note": "<strong>Заўвага:</strong>",
        "searchprofile-advanced-tooltip": "Шукаць у дадатковых прасторах назваў",
        "search-result-size": "$1 ({{PLURAL:$2|1 слова|$2 словы|$2 словаў}})",
        "search-result-category-size": "{{PLURAL:$1|$1 элемент|$1 элемента|$1 элементаў}} ({{PLURAL:$2|$2 падкатэгорыя|$2 падкатэгорыі|$2 падкатэгорый}}, {{PLURAL:$3|$3 файл|$3 файла|$3 файлаў}})",
-       "search-redirect": "(перасылка $1)",
+       "search-redirect": "(перанакіраванне з $1)",
        "search-section": "(падраздзел $1)",
        "search-category": "(катэгорыя $1)",
        "search-file-match": "(адпавядае змесціву файла)",
        "grant-basic": "Асноўныя правы",
        "grant-viewdeleted": "Праглядаць сцёртыя файлы і старонкі",
        "grant-viewmywatchlist": "Бачыць ваш спіс назірання",
+       "grant-viewrestrictedlogs": "Прагляд запісаў журнала з абмежаваным доступам",
        "newuserlogpage": "Журнал рэгістрацыі ўдзельнікаў",
        "newuserlogpagetext": "Гэта журнал рэгістрацыі новых удзельнікаў.",
        "rightslog": "Журнал правоў удзельнікаў",
        "upload-foreign-cant-upload": "Гэта вікі не настроена для ўкладання файлаў у запытанае старонняе сховішча файлаў.",
        "upload-dialog-title": "Укласці файл",
        "upload-dialog-button-cancel": "Нічога",
+       "upload-dialog-button-back": "Назад",
        "upload-dialog-button-done": "Гатова",
        "upload-dialog-button-save": "Запісаць",
        "upload-dialog-button-upload": "Укласці",
        "apisandbox-results-fixtoken": "Папраўце токен і паўтарыце адпраўку",
        "apisandbox-alert-page": "Палі на гэтай старонцы недапушчальныя.",
        "apisandbox-alert-field": "Значэнне гэтага поля недапушчальнае.",
+       "apisandbox-continue": "Працягнуць",
+       "apisandbox-continue-clear": "Ачысціць",
+       "apisandbox-param-limit": "Увядзіце <kbd>max</kbd>, каб выкарыстаць максімальны ліміт.",
        "booksources": "Кнігі",
        "booksources-search-legend": "Знайсці, дзе купіць кнігі",
        "booksources-search": "Пошук",
        "booksources-text": "Ніжэй паказаны пералік спасылак на іншыя сеціўныя пляцоўкі, якія прадаюць новыя і б/у кнігі, і, магчыма, маюць больш звестак пра кнігі, якіх вы шукаеце:",
        "booksources-invalid-isbn": "Гэты ISBN не выглядае правільным; праверце правільнасць капіравання з арыгіналу.",
+       "magiclink-tracking-rfc": "Старонкі, на якіх ужытыя чароўныя спасылкі RFC",
+       "magiclink-tracking-rfc-desc": "На гэтай старонцы ўжываюцца чароўныя спасылкі RFC. Глядзіце [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] аб тым, як перанесці.",
+       "magiclink-tracking-pmid": "Старонкі, на якіх ужытыя чароўныя спасылкі PMID",
+       "magiclink-tracking-pmid-desc": "На гэтай старонцы ўжываюцца чароўныя спасылкі PMID. Глядзіце [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] пра тое, як перанесці.",
+       "magiclink-tracking-isbn": "Старонкі, на якіх ужытыя чароўныя спасылкі ISBN",
+       "magiclink-tracking-isbn-desc": "На гэтай старонцы ўжываюцца чароўныя спасылкі ISBN. Глядзіце [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] пра тое, як перанесці.",
        "specialloguserlabel": "Выканаўца:",
        "speciallogtitlelabel": "Мэта (назва ці {{ns:user}}:імя_ўдзельніка для ўдзельніка):",
        "log": "Журналы",
        "activeusers-intro": "Гэта пералік удзельнікаў, якія нешта рабілі за апошнія $1 {{PLURAL:$1|дзень|дзён}}.",
        "activeusers-count": "$1 {{PLURAL:$1|дзеянне|дзеянні|дзеянняў}} за апошні{{PLURAL:$3| дзень|я $3 дні|я $3 дзён}}",
        "activeusers-from": "Паказ, пачынаючы з:",
-       "activeusers-hidebots": "Без робатаў",
-       "activeusers-hidesysops": "Без адміністратараў",
        "activeusers-noresult": "Няма такіх удзельнікаў.",
        "activeusers-submit": "Паказаць актыўных удзельнікаў",
        "listgrouprights": "Дазволы для груп удзельнікаў",
        "export-download": "Прапанаваць запісаць у файл",
        "export-templates": "Разам з шаблонамі",
        "export-pagelinks": "Разам са старонкамі, на якія ёсць спасылкі (макс. кольк. крокаў):",
+       "export-manual": "Дадаць старонкі ўручную:",
        "allmessages": "Сістэмныя паведамленні",
        "allmessagesname": "Назва",
        "allmessagesdefault": "Прадвызначаны тэкст",
        "thumbnail-temp-create": "Не ўдаецца стварыць часовы файл эскіза",
        "thumbnail-dest-create": "Не ўдаецца захаваць эскіз па месцы прызначэння",
        "thumbnail_invalid_params": "Няправільныя параметры драбніцы",
+       "thumbnail_toobigimagearea": "Файл з памерамі большымі, чым $1",
        "thumbnail_dest_directory": "Немагчыма стварыць мэтавую тэчку",
        "thumbnail_image-type": "Дадзены тып выявы не падтрымліваецца",
        "thumbnail_gd-library": "Няпоўная канфігурацыя бібліятэкі GD, адсутнічае функцыя $1",
        "patrol-log-header": "Журнал ухваленых версій",
        "log-show-hide-patrol": "$1 журнал ухваленняў",
        "log-show-hide-tag": "$1 журнал бірак",
+       "confirm-markpatrolled-button": "Добра",
        "deletedrevision": "Сцёрта старая версія $1",
        "filedeleteerror-short": "Памылка пры сціранні файла: $1",
        "filedeleteerror-long": "Памылкі пры спробе сцірання файла:\n\n$1",
        "confirm-watch-top": "Дабавіць старонку ў спіс назірання",
        "confirm-unwatch-button": "ОК",
        "confirm-unwatch-top": "Выняць гэту старонку з вашага спіса назірання?",
+       "confirm-rollback-button": "Добра",
        "confirm-rollback-top": "Адкаціць праўкі гэтай старонкі?",
        "quotation-marks": "«$1»",
        "imgmultipageprev": "← папярэдняя старонка",
        "tag-filter": "Фільтр [[Special:Tags|бірак]]:",
        "tag-filter-submit": "Фільтр",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Тэг|Тэгі}}]]: $2)",
+       "tag-mw-contentmodelchange": "змена мадэлі змесціва",
        "tags-title": "Біркі",
        "tags-intro": "Тут пералічаныя біркі, якімі праграмы могуць пазначыць праўку, а таксама іх значэнні.",
        "tags-tag": "Назва біркі",
        "tags-activate": "актываваць",
        "tags-deactivate": "адключыць",
        "tags-hitcount": "$1 {{PLURAL:$1|змена|змены|змен}}",
+       "tags-manage-blocked": "Вы не можаце мяняць меткі, калі вы заблакаваныя.",
        "tags-create-heading": "Стварыць новую бірку",
        "tags-create-explanation": "Калі не ўказана іншае, новыя біркі будуць даступны для выкарыстання ўдзельнікам і робатам.",
        "tags-create-tag-name": "Назва біркі:",
        "tags-deactivate-reason": "Прычына:",
        "tags-deactivate-not-allowed": "Немагчыма дэактываваць бірку \"$1\".",
        "tags-deactivate-submit": "Дэактываваць",
+       "tags-apply-blocked": "Вы не можаце мяняць меткі да Вашых зменаў, калі вы заблакаваныя.",
        "tags-update-add-not-allowed-one": "Бірку \"$1\" нельга дадаваць уручную.",
        "tags-update-remove-not-allowed-one": "Бірку \"$1\" нельга выдаляць.",
        "tags-update-remove-not-allowed-multi": "{{PLURAL:$2|Наступную бірку|Наступныя біркі}} нельга выдаляць уручную: $1",
        "feedback-cancel": "Адмена",
        "feedback-close": "Зроблена.",
        "feedback-dialog-title": "Даслаць водгук",
-       "feedback-error-title": "Памылка",
        "feedback-error1": "Памылка. Невядомы вынік з API",
        "feedback-error2": "Памылка. Збой праўкі",
        "feedback-error3": "Памылка. Няма адказу ад API",
        "feedback-submit": "Даслаць",
        "feedback-thanks": "Дзякуй! Ваш водгук размешчаны на старонцы «[$2 $1]».",
        "feedback-thanks-title": "Дзякуем!",
-       "searchsuggest-search": "Ð\97найÑ\81Ñ\86Ñ\96",
+       "searchsuggest-search": "ШÑ\83каÑ\86Ñ\8c Ñ\83 {{SITENAME}}",
        "searchsuggest-containing": "змяшчае...",
        "api-error-badaccess-groups": "У Вас няма дазволу загружаць файлы ў гэтую вікі.",
        "api-error-badtoken": "Унутраная памылка: няслушны ключ.",
index b357dea..75266e8 100644 (file)
                        "Ket",
                        "Ricordo.tenerissimo",
                        "Plamen",
-                       "Iliev"
+                       "Iliev",
+                       "Spas.Z.Spasov",
+                       "АдмиралАнимЕ",
+                       "Irus",
+                       "Kareyac"
                ]
        },
        "tog-underline": "Подчертаване на препратките:",
@@ -88,8 +92,8 @@
        "editfont-style": "Стил на шрифта в кутията за редактиране:",
        "editfont-default": "По подразбиране за браузъра",
        "editfont-monospace": "Равноширок шрифт",
-       "editfont-sansserif": "Ð\91езÑ\81еÑ\80иÑ\84ен Ñ\88Ñ\80иÑ\84Ñ\82",
-       "editfont-serif": "СеÑ\80иÑ\84ен Ñ\88Ñ\80иÑ\84Ñ\82",
+       "editfont-sansserif": "ШÑ\80иÑ\84Ñ\82 Ð±ÐµÐ· Ð¸Ð·Ð²Ð¸Ð²ÐºÐ¸",
+       "editfont-serif": "ШÑ\80иÑ\84Ñ\82 Ñ\81 Ð¸Ð·Ð²Ð¸Ð²ÐºÐ¸",
        "sunday": "неделя",
        "monday": "понеделник",
        "tuesday": "вторник",
        "october-date": "$1 октомври",
        "november-date": "$1 ноември",
        "december-date": "$1 декември",
+       "period-am": "Преди обед",
+       "period-pm": "След обед",
        "pagecategories": "{{PLURAL:$1|Категория|Категории}}",
        "category_header": "Страници в категория „$1“",
        "subcategories": "Подкатегории",
        "qbpageoptions": "Тази страница",
        "qbmyoptions": "Моите страници",
        "faq": "ЧЗВ",
-       "faqpage": "Project:ЧЗВ",
+       "faqpage": "Проект:ЧЗВ",
        "actions": "Действия",
        "namespaces": "Именни пространства",
        "variants": "Варианти",
        "talk": "Беседа",
        "views": "Прегледи",
        "toolbox": "Инструменти",
+       "tool-link-emailuser": "Писмо до {{GENDER:$1|потребителя}}",
        "userpage": "Потребителска страница",
        "projectpage": "Проектна страница",
        "imagepage": "Преглед на файла",
        "title-invalid-interwiki": "Желаното заглавие на страница съдържа препратка към друго уики, което не може да бъде ползвано в заглавия.",
        "title-invalid-talk-namespace": "Желаното заглавие на страница се отнася към беседа, която не съществува",
        "title-invalid-characters": "Желаното заглавие на статия съдържа невалидни знаци: „$1“",
-       "title-invalid-relative": "Заглавието съдържа относителен път. Относителни заглавия на статии (./,../) са невалидни, защото често ще са недостижимо, когато биват извиквани от браузъра на потребителя.",
+       "title-invalid-relative": "Заглавието съдържа относителен път. Относителните заглавия на статии (./,../) са невалидни, защото често са недостижими, когато биват обработвани от браузъра на потребителя.",
        "title-invalid-magic-tilde": "Желаното заглавие на статия съдържа невалидна поредица от тилди (<nowiki>~~~</nowiki>).",
        "title-invalid-too-long": "Желаното заглавие на статия е твърде дълго. Трябва да е не по-дълго от $1 {{PLURAL:$1|байт|байта}} в кодиране UTF-8.",
        "title-invalid-leading-colon": "Желаното заглавие на статия съдържа невалидно двоеточие в началото.",
        "virus-scanfailed": "сканирането не сполучи (код $1)",
        "virus-unknownscanner": "непознат антивирус:",
        "logouttext": "'''Излязохте от системата.'''\n\nОбърнете внимание, че някои страници все още ще се показват така, сякаш сте влезли, докато не изтриете кеша на браузъра.",
+       "cannotlogoutnow-title": "Не може да излезете сега.",
        "welcomeuser": "Здравейте, $1!",
        "welcomecreation-msg": "Вашата сметка беше създадена.\nМожете да промените [[Special:Preferences|настройките на {{SITENAME}}]] според предпочитанията си.",
        "yourname": "Потребителско име:",
        "createacct-yourpasswordagain-ph": "Въвежда се паролата (повторно)",
        "userlogin-remembermypassword": "Запомняне",
        "userlogin-signwithsecure": "Използване на защитена връзка",
+       "cannotlogin-title": "Не може да влезете в",
+       "cannotlogin-text": "Влизането в системата не е възможно.",
+       "cannotloginnow-title": "Не може да влезете сега",
+       "cannotcreateaccount-title": "Невъзможно е да бъде създадена потребителска сметка",
        "yourdomainname": "Домейн:",
        "password-change-forbidden": "Не можете да променяте пароли в това уики.",
        "externaldberror": "Или е станала грешка в базата от данни при външното удостоверяване, или не ви е позволено да обновявате външната си сметка.",
        "createacct-reason-ph": "Защо създавате друга сметка",
        "createacct-submit": "Създаване на сметката",
        "createacct-another-submit": "Създаване на сметка",
-       "createacct-continue-submit": "Продължаване създаването на акаунт",
-       "createacct-another-continue-submit": "Продължаване създаването на акаунт",
+       "createacct-continue-submit": "Продължаване създаването на сметка",
+       "createacct-another-continue-submit": "Продължаване създаването на сметка",
        "createacct-benefit-heading": "{{SITENAME}} се създава от хора като вас.",
        "createacct-benefit-body1": "{{PLURAL:$1|редакция|редакции}}",
        "createacct-benefit-body2": "{{PLURAL:$1|страница|страници}}",
        "passwordremindertitle": "Напомняне за парола от {{SITENAME}}",
        "passwordremindertext": "Някой (най-вероятно вие, от IP-адрес $1) е пожелал нова парола за влизане в {{SITENAME}} ($4).\nЗа потребител „$2“ е създадена временната парола „$3“.\nСега би трябвало да влезете в системата и да си изберете нова парола.\nНовата временна парола ще бъде активна {{PLURAL:$5|един ден|$5 дни}}.\n\nАко заявката е направена от друг или пък сте си спомнили паролата и не искате да я променяте, можете да пренебрегнете това съобщение и да продължите да използвате старата си парола.",
        "noemail": "Няма записана електронна поща за потребителя „$1“.",
-       "noemailcreate": "Необходимо е да въведете валиден адрес за е-поща",
+       "noemailcreate": "Необходимо е да въведете валиден адрес за ел. поща",
        "passwordsent": "Нова парола беше изпратена на електронната поща на „$1“.\nСлед като я получите, влезте отново.",
        "blocked-mailpassword": "Редактирането от Вашия IP-адрес е забранено, затова не Ви се позволява да използвате възможността за възстановяване на парола.",
        "eauthentsent": "Писмото за потвърждение е изпратено на посочения адрес. В него са описани действията, които трябва да се извършат, за да потвърдите, че този адрес за електронна поща действително е ваш.",
        "throttled-mailpassword": "Функцията за напомняне на паролата е използвана през {{PLURAL:$1|последния един час|последните $1 часа}}.\nЗа предотвратяване на злоупотреби е разрешено да се изпраща не повече от едно напомняне в рамките на {{PLURAL:$1|един час|$1 часа}}.",
        "mailerror": "Грешка при изпращане на писмо: $1",
-       "acct_creation_throttle_hit": "Ð\9fÑ\80ез Ð¿Ð¾Ñ\81ледноÑ\82о Ð´ÐµÐ½Ð¾Ð½Ð¾Ñ\89ие, през този IP-адрес посетители на това уики са създали {{PLURAL:$1|1 сметка |$1 сметки}}, което е максималният допустим брой за този период.\nВ резултат, към момента не могат да създават повече потребителски сметки през този IP-адрес.",
+       "acct_creation_throttle_hit": "Ð\9fÑ\80ез Ð¿Ð¾Ñ\81ледниÑ\82е $2, през този IP-адрес посетители на това уики са създали {{PLURAL:$1|1 сметка |$1 сметки}}, което е максималният допустим брой за този период.\nВ резултат, към момента не могат да създават повече потребителски сметки през този IP-адрес.",
        "emailauthenticated": "Адресът на електронната ви поща беше потвърден на $2 в $3.",
        "emailnotauthenticated": "Адресът на електронната ви поща все още не е потвърден.\nНяма да получавате писма за никоя от следните възможности.",
        "noemailprefs": "За да работят тези функционалности, трябва да посочите адрес на електронна поща в своите настройки.",
        "passwordreset-emailelement": "Потребителско име: \n$1\n\nВременна парола: \n$2",
        "passwordreset-emailsentemail": "Ако електронната Ви поща е свързана със сметката Ви, на нея е изпратено писмо за възстановяване на паролата.",
        "passwordreset-emailsentusername": "Ако това потребителско име е свързано с електронна поща, е изпратено писмо за възстановяване на паролата.",
-       "passwordreset-invalideamil": "Неправилен email адрес",
+       "passwordreset-invalidemail": "Неправилен email адрес",
        "changeemail": "Промяна или премахване на адреса за е-поща",
-       "changeemail-header": "Промяна на адреса за е-поща на сметката",
+       "changeemail-header": "Попълнете формуляра, за да промените адреса на електронната си поща. Ако искате да премахнете адреса на електронната си поща, при попълване на формуляра оставете полето за новия адрес празно.",
        "changeemail-no-info": "За да достъпвате тази страница директно, необходимо е да влезете в системата.",
        "changeemail-oldemail": "Текущ адрес за е-поща:",
        "changeemail-newemail": "Нов адрес за е-поща:",
        "resettokens-resetbutton": "Изчистване на избраните маркери",
        "bold_sample": "Получер текст",
        "bold_tip": "Получер (удебелен) текст",
-       "italic_sample": "Ð\9aÑ\83Ñ\80Ñ\81ивен текст",
-       "italic_tip": "Ð\9aÑ\83Ñ\80Ñ\81ивен (наклонен) текст",
+       "italic_sample": "Ð\9dаклонен текст",
+       "italic_tip": "Ð\9dаклонен текст",
        "link_sample": "Име на препратка",
        "link_tip": "Вътрешна препратка",
        "extlink_sample": "http://www.example.com Текст на външната препратка",
        "previewnote": "<strong>Обърнете внимание, че това е само предварителен преглед.</strong>\nПромените все още не са съхранени!",
        "continue-editing": "Продължаване към полето за редактиране",
        "previewconflict": "Този предварителен преглед отразява текста в горната текстова кутия така, както би се показал, ако съхраните.",
-       "session_fail_preview": "'''За съжаление редакцията ви не успя да бъде обработена поради загуба на данните за текущата сесия. Опитайте отново. Ако все още не работи, опитайте да [[Special:UserLogout|излезете]] и да влезете отново.'''",
+       "session_fail_preview": "За съжаление редакцията ви не успя да бъде обработена поради загуба на данните за текущата сесия.\n\nМоже би сте излезли от системата. <strong>Моля, уверете се, че сте влезли в профила си и опитайте отново. \nАко все още не работи, опитайте да [[Special:UserLogout|излезете]] и да влезете отново, също така проверете дали браузърът ви позволява бисквитки от този сайт.",
        "session_fail_preview_html": "'''За съжаление редакцията ви не беше записана поради изтичането на сесията ви.'''\n\n''Тъй като {{SITENAME}} приема обикновен HTML, предварителният преглед е скрит като предпазна мярка срещу атаки чрез Джаваскрипт.''\n\n'''Опитайте отново. Ако все още не сработва, пробвайте да [[Special:UserLogout|излезете]] и влезете отново.'''",
        "token_suffix_mismatch": "'''Редакцията ви беше отхвърлена, защото браузърът ви е развалил пунктуационните знаци в редакционната отметка. Евентуалното съхранение би унищожило съдържанието на страницата. Понякога това се случва при използването на грешно работещи анонимни междинни сървъри.'''",
        "edit_form_incomplete": "'''Някои части от формуляра за редактиране не достигнаха до сървъра; проверете дали редакциите ви са непокътнати и опитайте отново.'''",
        "undo-success": "Редакцията може да бъде върната. Прегледайте долното сравнение и се уверете, че наистина искате да го направите. След това съхранете страницата, за да извършите връщането.",
        "undo-failure": "Редакцията не може да бъде върната поради конфликтни междинни редакции.",
        "undo-norev": "Редакцията не може да бъде върната, тъй като не съществува или е била изтрита.",
+       "undo-nochange": "Тази редакция изглежда вече е отменена.",
        "undo-summary": "Премахната редакция $1 на [[Special:Contributions/$2|$2]] ([[User talk:$2|беседа]])",
        "undo-summary-username-hidden": "Отмяна на редакция $1 от скрит потребител",
        "cantcreateaccount-text": "[[User:$3|Потребител:$3]] е блокирал(а) създаването на сметки от този IP-адрес ('''$1''').\n\nПричината, изложена от $3, е ''$2''",
        "rev-showdeleted": "показване",
        "revisiondelete": "Изтриване/възстановяване на версии",
        "revdelete-nooldid-title": "Не е зададена версия",
-       "revdelete-nooldid-text": "Не сте задали версия или версии за изпълнението на тази функция.",
+       "revdelete-nooldid-text": "Не сте задали целева версия за изпълнението на тази функция или определената версия не съществува, или се опитвате да скриете настоящата версия.",
        "revdelete-no-file": "Посоченият файл не съществува.",
        "revdelete-show-file-confirm": "Необходимо е потвърждение, че желаете да прегледате изтритата версия на файла „<nowiki>$1</nowiki>“ от $2 $3.",
        "revdelete-show-file-submit": "Да",
        "revdelete-selected-text": "{{PLURAL:$1|Избрана версия|Избрани версии}} от [[:$2]]:",
        "logdelete-selected": "{{PLURAL:$1|Избрано събитие|Избрани събития}}:",
        "revdelete-text-text": "Изтритите редакции ще продължат да се виждат в историята на страницата, но части от съдържанието ще бъдат публично недостъпни.",
+       "revdelete-text-file": "Изтритите файлови редакции ще продължат да се виждат в историята на страницата, но части от съдържанието им ще бъдат публично недостъпни.",
+       "logdelete-text": "Изтриват записи в дневника ще продължат да се виждат в дневниците, но част от тяхното съдържание ще бъде недостъпно за обществеността.",
        "revdelete-text-others": "Другите администратори ще продължат да имат достъп до скритото съдържание и могат да го възстановят, освен ако не бъдат наложени допълнителни ограничения.",
        "revdelete-confirm": "Необходимо е да потвърдите, че желаете да извършите действието, разбирате последствията и го правите според [[{{MediaWiki:Policy-url}}|политиката]].",
        "revdelete-suppress-text": "Премахването трябва да се използва '''само''' при следните случаи:\n* Потенциално уязвима в правно отношение информация\n* Неподходяща лична информация\n*: ''домашни адреси и телефонни номера, номера за социално осигуряване и др.''",
        "searchprofile-advanced-tooltip": "Търсене в избрани именни пространства",
        "search-result-size": "$1 ({{PLURAL:$2|една дума|$2 думи}})",
        "search-result-category-size": "{{PLURAL:$1|1 член|$1 члена}} ({{PLURAL:$2|1 подкатегория|$2 подкатегории}}, {{PLURAL:$3|1 файл|$3 файла}})",
-       "search-redirect": "(пренасочване $1)",
+       "search-redirect": "(пренасочване от $1)",
        "search-section": "(раздел $1)",
        "search-category": "(категория $1)",
        "search-suggest": "Вероятно имахте предвид: $1",
        "badsig": "Избраният подпис не е валиден. Проверете HTML-етикетите!",
        "badsiglength": "Вашият подпис е твърде дълъг.\nПодписите не могат да надвишават $1 {{PLURAL:$1|знак|знака}}.",
        "yourgender": "Какво описание Ви подхожда най-много?",
-       "gender-unknown": "Ð\9fÑ\80едпоÑ\87иÑ\82ам Ð´Ð° Ð½Ðµ Ð¿Ð¾Ñ\81оÑ\87а",
+       "gender-unknown": "Ð\9aогаÑ\82о Ð²Ð¸ Ñ\81поменава, Ñ\81оÑ\84Ñ\82Ñ\83еÑ\80Ñ\8aÑ\82 Ñ\89е Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð° Ð½ÐµÑ\83Ñ\82Ñ\80ални Ð´Ñ\83ми Ð·Ð° Ð¿Ð¾Ð», ÐºÐ¾Ð³Ð°Ñ\82о Ðµ Ð²Ñ\8aзможно",
        "gender-male": "Той редактира уики страниците",
        "gender-female": "Тя редактира уики страниците",
        "prefs-help-gender": "По желание: използва се за коректно обръщение по род в системните съобщения на софтуера. Тази информация е публично достъпна.",
        "right-sendemail": "Изпращане на е-писма до другите потребители",
        "right-passwordreset": "Преглеждане на е-писма за възстановяване на парола",
        "grant-group-email": "Изпращане на е-писмо",
+       "grant-blockusers": "Блокиране и отблокиране на потребители",
        "grant-createaccount": "Създаване на сметки",
        "grant-createeditmovepage": "Създаване, редактиране и преместване на страници",
        "grant-delete": "Изтриване на страници, редакции и записи в дневника",
+       "grant-editinterface": "Редактиране на пространството нарича МедияУики и CSS/JavaScript участник",
        "grant-editmycssjs": "Редактиране на личния CSS/JavaScript",
        "grant-editmyoptions": "Редактиране на вашите потребителски настройки",
        "grant-editmywatchlist": "редактиране на списъка ви за наблюдение",
        "grant-editpage": "Редактиране на съществуващи страници",
        "grant-editprotected": "Редактиране на защитени страници",
+       "grant-highvolume": "Голям обем за редактиране",
+       "grant-oversight": "Скриване на участниците и версия страници",
+       "grant-patrol": "Патрулират промени страници",
+       "grant-privateinfo": "Достъп до лични информации",
+       "grant-protect": "Защита на незаштитени страници",
+       "grant-rollback": "Откатывать промени страници",
+       "grant-sendemail": "Изпращане на имейл до други потребители",
        "grant-uploadeditmovefile": "Качване, заменяне и прехвърляне на файлове",
        "grant-uploadfile": "Качване на нови файлове",
        "grant-basic": "Основни права",
        "sourcefilename": "Първоначално име:",
        "sourceurl": "Изходен адрес:",
        "destfilename": "Целево име:",
-       "upload-maxfilesize": "Ð\9cакÑ\81имален допустим размер на файла: $1",
+       "upload-maxfilesize": "Ð\9cакÑ\81имално допустим размер на файла: $1",
        "upload-description": "Описание на файла",
        "upload-options": "Настройки за качване",
        "watchthisupload": "Наблюдаване на файла",
        "upload-http-error": "Възникна HTTP грешка: $1",
        "upload-dialog-title": "Качване на файл",
        "upload-dialog-button-cancel": "Отказване",
+       "upload-dialog-button-back": "Обратно",
        "upload-dialog-button-done": "Готово",
        "upload-dialog-button-save": "Съхраняване",
        "upload-dialog-button-upload": "Качване",
        "apihelp-no-such-module": "Модул \"$1\" не беше намерен.",
        "apisandbox": "Пясъчник за API",
        "apisandbox-fullscreen": "Разшири полето",
+       "apisandbox-unfullscreen": "Показване на страница",
        "apisandbox-submit": "Направи запитване",
        "apisandbox-reset": "Изчистване",
        "apisandbox-retry": "Повторен опит",
        "apisandbox-dynamic-error-exists": "Параметър с име \"$1\" вече съществува.",
        "apisandbox-results": "Резултати",
        "apisandbox-request-url-label": "URL-адрес на заявката:",
+       "apisandbox-continue": "Продължаване",
+       "apisandbox-continue-clear": "Изчистване",
        "booksources": "Източници на книги",
        "booksources-search-legend": "Търсене на информация за книга",
        "booksources-search": "Търсене",
        "activeusers-intro": "Това е списък на потребителите, които са демонстрирали някаква активност през {{PLURAL:$1|последния|последните}} $1 {{PLURAL:$1|ден|дни}}.",
        "activeusers-count": "$1 {{PLURAL:$1|действие|действия}} за {{PLURAL:$3|последния ден|последните $3 дни}}",
        "activeusers-from": "Показване на потребителите, започвайки от:",
-       "activeusers-hidebots": "Скриване на ботовете",
-       "activeusers-hidesysops": "Скриване на администраторите",
        "activeusers-noresult": "Няма намерени потребители.",
        "listgrouprights": "Права по потребителски групи",
        "listgrouprights-summary": "По-долу на тази страница е показан списък на групите потребители в това уики и права им за достъп. Допълнителна информация за отделните права може да бъде намерена [[{{MediaWiki:Listgrouprights-helppage}}|тук]].",
        "mailnologin": "Няма електронна поща",
        "mailnologintext": "Необходимо е да [[Special:UserLogin|влезете]] и да посочите валидна електронна поща в [[Special:Preferences|настройките]] си, за да може да пращате писма на други потребители.",
        "emailuser": "Писмо до потребителя",
-       "emailuser-title-target": "Ð\98зпÑ\80аÑ\89ане Ð½Ð° Ðµ-пиÑ\81мо Ð½Ð° Ñ\82ози {{GENDER:$1|поÑ\82Ñ\80ебиÑ\82ел}}",
+       "emailuser-title-target": "Ð\9fиÑ\81мо Ð´Ð¾ {{GENDER:$1|поÑ\82Ñ\80ебиÑ\82елÑ\8f}}",
        "emailuser-title-notarget": "Изпращане на е-писмо на потребител",
        "emailpagetext": "Можете да използвате формуляра по-долу, за да изпратите електронно писмо на {{GENDER:$1|този потребител}}.\nАдресът, който се въвели в [[Special:Preferences|настройките си]], ще се появи в полето „От“ на писмото, така че получателят ще е в състояние да ви отговори директно.",
        "defemailsubject": "Писмо от потребител $1 в {{SITENAME}}",
        "watchlist-details": "{{PLURAL:$1|Една наблюдавана страница|$1 наблюдавани страници}} от списъка ви за наблюдение (без беседи).",
        "wlheader-enotif": "Известяването по е-поща е включено.",
        "wlheader-showupdated": "Страниците, които са били променени след последния път, когато сте ги посетили, са показани в '''получер'''.",
-       "wlnote": "{{PLURAL:$1|Показана е последната промяна|Показани са последните '''$1''' промени}} през {{PLURAL:$2|последния час|последните '''$2''' часа}}.",
+       "wlnote": "{{PLURAL:$1|Показана е последната промяна|Показани са последните '''$1''' промени}} през {{PLURAL:$2|последния час|последните '''$2''' часа}}, започвайки от от $3, $4.",
        "wlshowlast": "Показване на последните $1 часа $2 дни",
        "watchlist-hide": "Скриване",
        "watchlist-submit": "Показване",
        "wlshowhideanons": "анонимни потребители",
        "wlshowhidepatr": "патрулирани редакции",
        "wlshowhidemine": "моите редакции",
+       "wlshowhidecategorization": "категоризиране на страници",
        "watchlist-options": "Опции на списъка за наблюдение",
        "watching": "Наблюдение…",
        "unwatching": "Спиране на наблюдение…",
        "enotif_subject_changed": "Страницата „$1“ в {{SITENAME}} беше {{GENDER:$2|променена}} от $2",
        "enotif_body_intro_deleted": "Страницата „$1“ в {{SITENAME}} беше {{GENDER:$2|изтрита}} на $PAGEEDITDATE от $2. Вижте $3.",
        "enotif_body_intro_created": "Страницата „$1“ в {{SITENAME}} беше {{GENDER:$2|създадена}} на $PAGEEDITDATE от $2. За текущата версия, вижте $3",
+       "enotif_body_intro_moved": "Страницата „$1“ в {{SITENAME}} бе {{GENDER:$2|преместена}} на $PAGEEDITDATE от $2. За текущата версия, вижте $3.",
+       "enotif_body_intro_restored": "Страницата „$1“ в {{SITENAME}} бе {{GENDER:$2|възстановена}} на $PAGEEDITDATE от $2. За текущата версия, вижте $3.",
+       "enotif_body_intro_changed": "Страницата „$1“ в {{SITENAME}} бе {{GENDER:$2|променена}} на $PAGEEDITDATE от $2. За текущата версия, вижте $3.",
        "enotif_lastvisited": "Преглед на всички промени след последното ви посещение: $1.",
        "enotif_lastdiff": "Преглед на тази промяна: $1.",
        "enotif_anon_editor": "анонимен потребител $1",
        "alreadyrolled": "Редакцията на [[:$1]], направена от [[User:$2|$2]] ([[User talk:$2|Беседа]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]), не може да бъде отменена. Някой друг вече е редактирал страницата или е отменил промените.\n\nПоследната редакция е на [[User:$3|$3]] ([[User talk:$3|Беседа]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Резюмето на редакцията беше: <em>$1</em>.",
        "revertpage": "Премахване на [[Special:Contributions/$2|редакции на $2]] ([[User talk:$2|беседа]]); възвръщане към последната версия на [[User:$1|$1]]",
-       "revertpage-nouser": "Премахнати редакции на (отстранено потребителско име) и връщане към последната версия на [[User:$1|$1]]",
+       "revertpage-nouser": "Премахнати редакции на (скрито потребителско име) и връщане към последната версия на [[User:$1|$1]]",
        "rollback-success": "Отменени редакции на $1; възвръщане към последната версия на $2.",
        "sessionfailure-title": "Прекъсната сесия",
        "sessionfailure": "Изглежда има проблем със сесията ви; действието беше отказано като предпазна мярка срещу крадене на сесията. Натиснете бутона за връщане на браузъра, презаредете страницата, от която сте дошли, и опитайте отново.",
        "changecontentmodel-title-label": "Заглавие на страницата",
        "changecontentmodel-reason-label": "Причина:",
        "changecontentmodel-success-text": "Типът на съдържанието на [[:$1]] е успешно променен.",
+       "log-name-contentmodel": "Дневник на cъдържанието промяна модела",
+       "log-description-contentmodel": "Събития, отнасящи се до модели на съдържанието на страницата",
        "logentry-contentmodel-change-revertlink": "връщане",
        "logentry-contentmodel-change-revert": "връщане",
        "protectlogpage": "Дневник на защитата",
        "sp-contributions-newbies-sub": "на нови потребители",
        "sp-contributions-newbies-title": "Потребителски приноси за нови сметки",
        "sp-contributions-blocklog": "Дневник на блокиранията",
-       "sp-contributions-deleted": "изтрити приноси на потребител",
+       "sp-contributions-deleted": "изтрити приноси на {{GENDER:$1|потребител}}",
        "sp-contributions-uploads": "качвания",
        "sp-contributions-logs": "дневници",
        "sp-contributions-talk": "беседа",
        "whatlinkshere-hideredirs": "$1 пренасочвания",
        "whatlinkshere-hidetrans": "$1 включвания",
        "whatlinkshere-hidelinks": "$1 препратки",
-       "whatlinkshere-hideimages": "$1 Ð½Ð° Ð¿Ñ\80епÑ\80аÑ\82ки ÐºÑ\8aм Ñ\84айла",
+       "whatlinkshere-hideimages": "$1 препратки към файла",
        "whatlinkshere-filters": "Филтри",
        "whatlinkshere-submit": "Отваряне",
        "autoblockid": "Автоматично блокиране #$1",
        "patrol-log-header": "Тази страница съдържа дневник на проверените версии.",
        "log-show-hide-patrol": "$1 на Дневника на патрула",
        "log-show-hide-tag": "$1 на дневника на отбелязванията",
+       "confirm-markpatrolled-button": "Добре",
        "deletedrevision": "Изтрита стара версия $1",
        "filedeleteerror-short": "Грешка при изтриване на файл: $1",
        "filedeleteerror-long": "Възникнаха грешки при изтриването на файла:\n\n$1",
        "scarytranscludefailed": "[Зареждането на шаблона за $1 не сполучи]",
        "scarytranscludetoolong": "[Адресът е твърде дълъг]",
        "deletedwhileediting": "'''Внимание''': Страницата е била изтрита, след като сте започнали да я редактирате!",
-       "confirmrecreate": "Потребител [[Потребител:$1|$1]] ([[Потребител беседа:$1|беседа]]) е {{GENDER:$1|изтрил}} страницата, откакто сте започнали да я редактирате, като е посочил следното обяснение:\n: <em>$2</em>\nПотвърдете, че наистина желаете да създадете страницата отново.",
+       "confirmrecreate": "Потребител [[User:$1|$1]] ([[User talk:$1|беседа]]) е {{GENDER:$1|изтрил}} страницата, след като сте започнали да я редактирате, като е посочил следното обяснение:\n: <em>$2</em>\nПотвърдете, че наистина желаете да създадете страницата отново.",
        "confirmrecreate-noreason": "Потребител [[User:$1|$1]] ([[User talk:$1|беседа]]) {{GENDER:$1|изтри}} тази страница след като сте започнали да я редактирате. Необходимо е потвърждение, че наистина желаете да създадете страницата отново.",
        "recreate": "Ново създаване",
        "confirm_purge_button": "Добре",
        "htmlform-chosen-placeholder": "Избиране",
        "htmlform-cloner-create": "Добавяне на още",
        "htmlform-cloner-delete": "Премахване",
+       "htmlform-cloner-required": "Изисква се поне една стойност.",
+       "htmlform-date-placeholder": "ГГГГ-ММ-ДД",
+       "htmlform-time-placeholder": "ЧЧ:ММ:СС",
+       "htmlform-datetime-placeholder": "ГГГГ-ММ-ДД ЧЧ:ММ:СС",
+       "htmlform-date-invalid": "Избраната от вас стойност за дата не е разпозната. Опитайте да използвате формат ГГГГ-ММ-ДД.",
        "htmlform-title-badnamespace": "[[:$1]] не е в именното пространство \"{{ns:$2}}\".",
        "htmlform-title-not-exists": "$1 не съществува.",
        "htmlform-user-not-exists": "<strong>$1</strong> не съществува.",
        "feedback-bugornote": "Ако сте готови подробно да опишете технически проблем, моля [$1 докладвайте го тук].\nВ противен случай, можете да използвате лесния формуляр по-долу. Коментарът ви ще бъде добавен към страницата \"[$3 $2]\", наред с вашето потребителско име.",
        "feedback-cancel": "Отказване",
        "feedback-close": "Готово",
-       "feedback-error-title": "Грешка",
        "feedback-error1": "Грешка: Неразпознат резултат от API",
        "feedback-error2": "Грешка: Неуспешна редакция",
        "feedback-error3": "Грешка: Няма отговор от API",
        "feedback-submit": "Изпращане",
        "feedback-thanks": "Благодарности! Вашата обратна информация е публикувана на страницата „[$2  $1]“.",
        "feedback-thanks-title": "Благодарим ви!",
-       "searchsuggest-search": "Търсене",
+       "searchsuggest-search": "Търсене в {{SITENAME}}",
        "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|който е бил изтрит|които са били изтрити}}.",
        "mediastatistics-table-totalbytes": "Общ размер",
        "mediastatistics-header-unknown": "Неизвестно",
        "mediastatistics-header-bitmap": "Растерни изображения",
-       "mediastatistics-header-drawing": "РиÑ\81Ñ\83нки (векторни изображения)",
+       "mediastatistics-header-drawing": "ЧеÑ\80Ñ\82ежи (векторни изображения)",
        "mediastatistics-header-audio": "Аудио",
        "mediastatistics-header-video": "Видео",
        "mediastatistics-header-multimedia": "Мултимедия",
        "authmanager-provider-temporarypassword": "Временна парола",
        "authprovider-resetpass-skip-label": "Пропусни",
        "specialpage-securitylevel-not-allowed-title": "Не е позволено",
-       "cannotauth-not-allowed-title": "Достъпът е отказан"
+       "cannotauth-not-allowed-title": "Достъпът е отказан",
+       "edit-error-short": "Грешка: $1",
+       "edit-error-long": "Грешки:\n\n$1"
 }
index a0b6220..db79800 100644 (file)
        "yourpasswordagain": "پاسوردی تکرار کورتین",
        "createacct-yourpasswordagain": "پاسوردا تایید کورتین",
        "createacct-yourpasswordagain-ph": "پاسوردا پدا داخل کورتین دومین وارا",
-       "remembermypassword": "پاسورد یا چیهرگال ئا (تا حداکثر $1 {{PLURAL:$1|روچ|روچ}}) بئ ای بروزیري تا بسات",
        "userlogin-remembermypassword": "نا داخل بوتگ بسات",
        "userlogin-signwithsecure": "شه امنیت ئا استفاده بکنیت",
        "yourdomainname": "شمی دامنهٔ:",
        "passwordreset-emailtitle": "حسابئ مئلومات بی {{SITENAME}}",
        "passwordreset-emailelement": "کار زوروکئ نام: \n$1\n\nموقت ئین چیهرگال: \n$2",
        "passwordreset-emailsentemail": "یک ایمیل په چیهر گالئ  پاک بوتین  خاتیرا دیم داته بوت.",
-       "passwordreset-emailsent-capture": "یک ایمیلئ په بیئرگردینتین ئا پاسوردئ خاتیرا، دیم داته بوت.",
        "changeemail": "ایمیل ادرسئ تغیر داتین یا پاک کورتین",
        "changeemail-no-info": "په ای تاکدیمی دسترسی ئی خاتیرا داخل بئیت.",
        "changeemail-oldemail": "انونین ایمیل ادرس:",
        "summary": "خلاصه:",
        "subject": "موضو/ئنوان:",
        "minoredit": "ای یک گونڈین ایڈیٹئ است",
-       "watchthis": "دÛ\8cستÛ\8cÙ\86 Ø§Û\8c ØªØ§Ú©Ø¯Û\8cÙ\85Û\8c",
+       "watchthis": "اÛ\8c ØªØ§Ú©Ø¯Û\8cÙ\85ئ Ù¾Ø¯ Ú¯Û\8cرÛ\8c Ú©Ù\88رتÛ\8cÙ\86",
        "savearticle": "تاکدیمئ ساتېتین",
        "preview": "دیم دیست",
        "showpreview": "دیم دیست",
        "undo-nochange": "بئ نظر ئه رسیئت که ایڈیٹ بیئرگردینته بوته.",
        "undo-summary": " $1 ئی ایڈیٹ شه [[Special:Contributions/$2|$2]] ([[User talk:$2|حبر و گپ]]) نیمگا شه بَیْن بورته بوت",
        "undo-summary-username-hidden": " $1 نخسه ئی شه بین بورتین بی یک کار زوروکئ دستا چیهر بوته",
-       "cantcreateaccounttitle": "نه توانیت حسابئ پاچ کنیت",
        "cantcreateaccount-text": "کار زوروکئ هیساب ئی جۆڑ کورتین ئی هه ق گۆ ای آی‌پی  ('''$1''') ادرس ئا، شه [[User:$3|$3]] نیمگا گیپته بوته.\n\nشه $3 ئی نیمگا دلیل ایرنگ بیان بوته: $2",
        "viewpagelogs": "ای تاکدیمئ سیاه چال ئی دیستین",
        "nohistory": "ای تاکدیم ایڈیٹ ئی تاریخچه نداریت.",
        "diff-multi-sameuser": "(ای کار زوروکئ {{PLURAL:$1|یک میانی نخسه|$1 میانی نخسه}}ِ نمایش داته بوته)",
        "diff-multi-otherusers": "({{PLURAL:$1|۱ میانین نخسه|$1 میانین نخسه}} دستکاری بوتگ شه {{PLURAL:$2|۱ کارزوروک|$2 کارزوروک}}ئ نیمگاه  نشان داته نه بوته)",
        "diff-multi-manyusers": "({{PLURAL:$1|یک|$1}} میانین دستکاری بوته ئین نخسه گیشتیر شه {{PLURAL:$2|یک|$2}} کارزورکئ نیمگاه نشان داته نه بوته)",
-       "searchresults": "گشتین ئی  نتیجه",
+       "searchresults": "گشتینئی  نتیجه",
        "searchresults-title": "گشتینئ نتایج په «$1»",
        "titlematches": "مقاله ئی ئنوانئ یکی کورتین",
        "textmatches": "مقاله ئی متنئ یکی کورتین",
        "search-category": "(تهر  $1)",
        "search-file-match": "(فایلی محتوایی یکرنگی)",
        "search-suggest": "آیا شمی منظور ایش ات: $1",
-       "search-rewritten": "$1 ئی نتیجه ئانی نمایش. گشتین په $2 جاها.",
+       "search-rewritten": "$1‌ئی نتیجه‌ئانی نشان داتین. گشتین په $2‌ئی جاگا.",
        "search-interwiki-caption": "گوارین پروژه ئان",
        "search-interwiki-default": "نتایج شه $1 :",
        "search-interwiki-more": "(گیشتیر)",
        "rcshowhidecategorization": "$1 تاکدیمئ تهربندی",
        "rcshowhidecategorization-show": "نشان داتین",
        "rcshowhidecategorization-hide": "چیهر داتین",
-       "rclinks": "نشان داتین $1 آخیر ئین تغییر بئ $2 اخیرین روچا<br />$3",
+       "rclinks": "آ آخیرئین $1 تغیرانئ نشان داتین که به $2 اخیرئین روچانئ تا پیش بوته انت<br />$3",
        "diff": "فرق",
        "hist": "تاریخچه",
        "hide": "چیهر داتین",
        "activeusers-intro": "جهلگا یک لڑئ شه کار زوروکان ئه گیندیت که بئ $1 {{PLURAL:$1|روچ|روچ}} دیمتیرا پئالیت داشته انت.",
        "activeusers-count": "$1 {{PLURAL:$1|پئالیت|پئالیت}} بئ {{PLURAL:$3|رۆچ|$3 رۆچ}} اخیرا",
        "activeusers-from": "نمایش داتین کار زوروکان شرو شه:",
-       "activeusers-hidebots": "رباتانی چیهر داتین",
-       "activeusers-hidesysops": "مدیرانئ چیهرداتین",
        "activeusers-noresult": "هیچ کار زوروکئ ودی نه بوت.",
        "listgrouprights": "کار زوروکین گروپانئ اختیاران",
        "listgrouprights-key": "* <span class=\"listgrouprights-granted\">داته بوته ئین اختیاران</span>\n* <span class=\"listgrouprights-revoked\">کیپته بوته ئین اختیاران</span>",
        "removedwatchtext": "«[[:$1]]» دیم شه  [[Special:Watchlist|شمی واچلیستا]] زورته بوت.",
        "removedwatchtext-short": "\"$1\" ئی دیم شه شمی واچلیستا پاک بوته.",
        "watch": "دیستین",
-       "watchthispage": "دÛ\8cستÛ\8cÙ\86 Ø§Û\8c ØªØ§Ú©Ø¯Û\8cÙ\85Û\8c",
+       "watchthispage": "اÛ\8c ØªØ§Ú©Ø¯Û\8cÙ\85ئ Ù¾Ø¯ Ú¯Û\8cرÛ\8c Ú©Ù\88رتÛ\8cÙ\86",
        "unwatch": "اوشتارین تین دیستینی",
        "unwatchthispage": "اوشتارینتین چارگ ئی",
        "notanarticle": "تاکدیم محتوایی نه اینت",
        "actioncomplete": "کار بوت",
        "actionfailed": "کار نه بوت",
        "deletedtext": "«$1» پاک بوت.\nپه آخیرین پاک بوتینین سابقه ئا بئ $2 ئی تا مراجعه بکنیت.",
-       "dellogpage": "سیاه چال ئی پاک کورتین",
-       "dellogpagetext": "جهلگین لڑلیست شه آخیرین پاک بوته ئین ئانی لڑا اینت.\nموچین ئانی نشان داته بته ئین وخت خادم وخت (گرینویچ ئی وخت) انت.",
-       "deletionlog": "سیاه چال ئی پاک کورتین",
+       "dellogpage": "پاک بوته‌ئانی کورم",
+       "dellogpagetext": "جهلگین لڑلیستا که گیندیت په آخیرئین پاک بوته‌ئین فابلاني خاتیرا اینت.\nموچین نشان داته بوته‌ئین وخت گو (گرینویچ‌ئی وختا) مطابق انت.",
+       "deletionlog": "پاک بوته‌ئانی کورم",
        "reverted": "بی دیمتیرین نخسه ئا بیئرگردینته بوت",
        "deletecomment": "دلیل:",
        "deleteotherreason": "دیگرین دلیل/اضافی:",
        "changecontentmodel-success-text": "[[:$1]] ئی محتوائین رقم تغیر کورت",
        "logentry-contentmodel-change-revertlink": "بیرگردینتین",
        "logentry-contentmodel-change-revert": "بیرگردینتین",
-       "protectlogpage": "سیاهگئ قُلپ",
+       "protectlogpage": "قُلپ بوتینئ کورم",
+       "protectlogtext": "به جهلگا یک لڑی شه تاکدیماني قُلپ بوتینئ اندازه‌گی تغیران آته.\n[[Special:ProtectedPages|قُلپ بوته‌ای تاکدیماني لڑا]]  په انونین قُلپ بوتینئ عملیاتان و گیشتیرین مالوماتي خاتیرا بگیندیت.",
        "protectedarticle": "«[[$1]]» ئا قُلپ کورت",
        "modifiedarticleprotection": "«[[$1]]» قُلپ ئی وزيیتا گردینت",
        "unprotectedarticle": "«[[$1]]» ئی تاکدیمئ قُلپ يا پاچ کورت",
        "undeletebtn": "احیا",
        "undeletelink": "نمایش/احیا",
        "undeleteviewlink": "دیستین",
-       "undeleteinvert": "انتخاب سرچپی بیئت",
+       "undeleteinvert": "انتخابئ سرچپي کورتین",
        "undeletecomment": "دلیل:",
        "undeletedrevisions": "$1 ئی نخسه احیا {{PLURAL:$1|بوت}}",
        "undeletedrevisions-files": "$1 نخسه و $2 فایل پداجۆڑ {{PLURAL:$1|بوت|بوتنت}}.",
        "undelete-show-file-confirm": "آیا شما مطمئن وێت که لوٹیت یک پاک بوته ئین نخسه شه فایل \"<nowiki>$1</nowiki>\" مورخ $2 سائت $3 ئا بگیندیت؟",
        "undelete-show-file-submit": "هان",
        "namespace": "نامئ اؤرکجاه:",
-       "invert": "انتخاب سرچپی بیئت",
-       "tooltip-invert": "اÛ\8c Ø¬Ø¦Ø¨Ù\87 Ø¦Ø§ Ø¦Ù\84اÙ\85ت Ø¨Ø¬Ù\86Û\8cت ØªØ§ Ú©Ù\87 Ù¾Ø²Ø§Û\8c Ù\86اÙ\85 ØªØ§ Ø¦Û\8cÙ\86 Ø§Ù\86تخاب Ø¨Ù\88تÙ\87 Ø¦Û\8cÙ\86 ØªØ§Ú©Ø¯Û\8cÙ\85اÙ\86Û\8c ØªØºÛ\8cرات (Ù\88 Ø¯Û\8cگرÛ\8cÙ\86 Ø¦Ù\84اÙ\85ت Ø¬ØªÙ\87 Ø¨Ù\88تÙ\87 Ø¦Û\8cÙ\86 Ù¾Ø²Ø§Û\8c Ù\86اÙ\85 Ø¦Ø§Ù\86) Ú\86Û\8cÙ\87ر Ø¨Ù\87 ینت",
+       "invert": "انتخابا سرچپي کورتین",
+       "tooltip-invert": "اÛ\8c Ø¬Ø¹Ø¨Ù\87 Ø¦Ø§ Ø¹Ù\84اÙ\85ت Ø¨Ø¬Ù\86Û\8cت ØªØ§ Ú©Ù\87 ØªØ§Ú©Ø¯Û\8cÙ\85اÙ\86Ù\8a ØªÙ\87ئ Ø§Ù\86تخاب Ø¨Ù\88تÙ\87â\80\8cاÛ\8cÙ\86 Ù\86اÙ\85ئ Ø§Ù\88رکجاÙ\87â\80\8cاÛ\8c ØªØºÛ\8cر (Ù\88 Ø¯Û\8cگرÛ\8cÙ\86 Ø¹Ù\84اÙ\85ت Ø¬ØªÙ\87 Ø¨Ù\88تÙ\87â\80\8cاÛ\8cÙ\86 Ù\86اÙ\85ئ Ø§Ù\88رکجاÙ\87اÙ\86) Ú\86Û\8cÙ\87ر Ø¨Ù\87â\80\8cینت",
        "namespace_association": "Associated namespace",
        "tooltip-namespace_association": "ای جئبه ئا ئلامت بجنیت تا که مربوتین موزو ئی پزای نامی گپ گۆ\nانتخاب بوته ئین پزای ناما شامل بیت",
        "blanknamespace": "(بُنیادی)",
        "contributions-userdoesnotexist": "«$1» ئی کار زوروکین حساب راجستر نه بوته.",
        "nocontribs": "هیچ تغیری گۆ ای مشخصات ئان ودێ نه بوت",
        "uctop": "(انونین نخسه)",
-       "month": "بی ای ماه ئی تا (و دیمتیر شه آیی):",
-       "year": "بی ای سال ئی تا (و دیمتیر شه آیی):",
+       "month": "به اي ماه‌ای تا (و دیمتیر شه آیی):",
+       "year": "به اي سالئ تا (و دیمتیر شه آیی):",
        "sp-contributions-newbies": "فقط نوکین مشارکتان نشان داته بیئنت",
        "sp-contributions-newbies-sub": "په نوک کاران",
        "sp-contributions-newbies-title": "په نوک کارین حسابانی خاتیرا کار زوروکئ شراکت ئان",
        "change-blocklink": "بلاک ئی تغیرداتین",
        "contribslink": "شراکت‌ئان",
        "emaillink": "ایمیلی دیم داتین",
-       "blocklogpage": "کورمئ بستین",
+       "blocklogpage": "بستینئ کورم",
        "blocklogentry": "«[[$1]]» ئا تا $2 بست $3",
        "unblocklogentry": "$1 ئا پاچ کورت",
        "block-log-flags-anononly": "فقط زیان نامین کار زوروکان",
        "htmlform-cloner-create": "گیشتیر اضافه کورتین",
        "htmlform-cloner-delete": "پاک کورتین",
        "htmlform-cloner-required": "حداقل ضرورت انداره گ.",
-       "sqlite-has-fts": "$1 گۆ پُشتیوانی شه گشتین ئا بئ کامیلین متن ئی تا",
-       "sqlite-no-fts": "$1 بدون پُشتیوانی شه گشتین ئا بئ کاملین متن ئی تا",
        "logentry-delete-delete": "$1 ، $3 تاکدیما {{GENDER:$2|پاک کورت}}",
        "logentry-delete-restore": "$1 ، $3 ئی تاکدیما {{GENDER:$2|پدا جۆڑ کورت}}",
        "logentry-delete-event": "$1 پیدایی {{PLURAL:$5|یک مورد سیاه چال|$5 مورد سیاه چال}} ئا بئ $3 {{GENDER:$2|تا تغیر دات}}: $4",
        "logentry-protect-modify-cascade": "$1 $3 $4 ئ قُلپئ اندازه گا په {{GENDER:$2|تغییر دات}}[آپشاری]",
        "logentry-rights-rights": "$1 ، $3 ئی عضویتا شه $4 ئی گروپا بئ $5 {{GENDER:$2|تغییر دات}}",
        "logentry-rights-rights-legacy": "$1 عضویتئ گروپا بئ $3 ئا {{GENDER:$2|تغییر دات}}",
-       "logentry-rights-autopromote": "$1 بئ اوتوماتیکین رکما وتر شه $4 بئ $5 {{GENDER:$2|ارتقاء دات}}",
+       "logentry-rights-autopromote": "$1 بِه اوتوماتیکین رقما شه $4 بِه $5‌ئا {{GENDER:$2|ارتقاء کورت}}",
        "logentry-upload-upload": "$1 $3 ئا {{GENDER:$2|بُرز کورت}}",
        "logentry-upload-overwrite": "$1 نوکین نخسه ئی شه $3 ئا {{GENDER:$2|بُرز کورت}}",
        "logentry-upload-revert": "$1 {{GENDER:$2|بُرز کورت}} $3 ئا",
        "feedback-close": "کار بوت",
        "feedback-external-bug-report-button": "یک تخنیکی ئین کاری پایل",
        "feedback-dialog-title": "یک پیڈبک ئی دیم داتین",
-       "feedback-error-title": "خطا",
        "feedback-error2": "خطا: پروشت بئ ایڈیٹ ئی تا",
        "feedback-message": "پیام:",
        "feedback-subject": "ئنوان:",
index 5b12678..e137ee9 100644 (file)
        "tog-hideminor": "हाल के बदलाव में से छोट संपादन छिपाईं",
        "tog-hidepatrolled": "हाल के बदलाव में से जाँचल संपादन छिपाईं",
        "tog-newpageshidepatrolled": "नया पन्ना के सूची में से जाँचल पन्ना सभ के छिपाईं",
+       "tog-hidecategorization": "पन्ना श्रेणीकरण छिपाईं",
        "tog-extendwatchlist": "खाली हाले के बदलाव ना बालुक, सगरी बदलाव के देखावे खातिर धियानसूची के बिस्तारित करीं",
        "tog-usenewrc": "तुरंत भइल बदलाव में आ धियानसूची में भइल बदलाव सभ के पन्ना अनुसार झुंड में बांटी",
        "tog-numberheadings": "हेडिंग के ऑटो-नंबरिंग",
-       "tog-showtoolbar": "समà¥\8dपादन औजारपट्टी के देखावल जाव",
+       "tog-showtoolbar": "सà¤\82पादन औजारपट्टी के देखावल जाव",
        "tog-editondblclick": "दुइ क्लिक पर पन्ना सभ के संपादन करीं",
        "tog-editsectiononrightclick": "खंड की हेडिंग पर दायाँ क्लिक कइ के खंड के सम्पादित करीं",
        "tog-watchcreations": "हमार बनावल पन्ना आ हमार अपलोड कइल फाइल सभ के हमरी धियानसूची में जोड़ दिहल जाव",
        "tog-watchdefault": "हम जौना पन्ना आ फाइलन के संपादित करीं उनहन के हमरी धियानसूची में जोड़ दिहल जाव",
        "tog-watchmoves": "हमरा द्वारा स्थानांतरित पन्ना आ फाइलन के हमरा धियानसूची में जोड़ दिहल जाव",
        "tog-watchdeletion": "हमरा द्वारा हटावल पन्ना आ फाइल सभ के हमार धियानसूची में जोड़ दिहल जाव",
+       "tog-watchuploads": "हम नया फाइल अपलोड करीं त उनहना के हमार धियानसूची में जोड़ल जाय",
        "tog-watchrollback": "हमरा द्वारा रोलबैक कइल गइल पन्ना सभ के हमार धियानसूची में जोड़ दिहल जाव",
        "tog-minordefault": "डिफाल्ट रूप से सगरी संपादन कुल के छोट संपादन की रुप में चिन्हित कइल जाव",
-       "tog-previewontop": "नमà¥\82ना (preview) संपादन बक्सा से पहिले देखावल जाय",
-       "tog-previewonfirst": "पहिला à¤¸à¤\82पादन à¤ªà¤° à¤¨à¤®à¥\82ना देखावल जाय",
-       "tog-enotifwatchlistpages": "हमार à¤§à¤¿à¤¯à¤¾à¤¨à¤¸à¥\82à¤\9aà¥\80 à¤®à¥\87à¤\82 à¤¦à¤°à¥\8dà¤\9c à¤\95à¥\8cनà¥\8b à¤­à¥\80 à¤ªà¤¨à¥\8dना à¤¯à¤¾ à¤«à¤¾à¤\87ल à¤®à¥\87à¤\82 à¤¬à¤¦à¤²à¤¾à¤µ à¤¹à¥\8bà¤\96ला à¤ªà¤° à¤¹à¤®à¤\95à¥\87 à¤\88-मà¥\87ल à¤\95रल जाव",
-       "tog-enotifusertalkpages": "यदि à¤¹à¤®à¤¾à¤° à¤µà¤¾à¤°à¥\8dतालाप à¤ªà¤¨à¥\8dना à¤ªà¤° à¤\95à¥\8cनà¥\8b à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤¹à¥\8bà¤\96à¥\87 à¤¤ à¤¹à¤®à¤\95à¥\87 à¤\88-मà¥\87ल à¤\95रल जाव",
-       "tog-enotifminoredits": "पनà¥\8dना à¤\86 à¤«à¤¾à¤\87ल à¤ªà¤° à¤\9bà¥\8bà¤\9fà¥\8b à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤¹à¥\8bà¤\96à¥\87 à¤¤ à¤¹à¤®à¤\95à¥\87 à¤\88-मà¥\87ल à¤\95रल जाव",
-       "tog-enotifrevealaddr": "à¤\85धिसà¥\82à¤\9aना ई-मेल में हमार ई-मेल पता देखावल जाव",
+       "tog-previewontop": "à¤\9dलà¤\95 (पà¥\8dरà¥\80वà¥\8dयà¥\82) संपादन बक्सा से पहिले देखावल जाय",
+       "tog-previewonfirst": "पहिला à¤¸à¤\82पादन à¤ªà¤° à¤\9dलà¤\95 (पà¥\8dरà¥\80वà¥\8dयà¥\82) देखावल जाय",
+       "tog-enotifwatchlistpages": "हमार à¤§à¤¿à¤¯à¤¾à¤¨à¤¸à¥\82à¤\9aà¥\80 à¤®à¥\87à¤\82 à¤¦à¤°à¥\8dà¤\9c à¤\95à¥\8cनà¥\8b à¤­à¥\80 à¤ªà¤¨à¥\8dना à¤¯à¤¾ à¤«à¤¾à¤\87ल à¤®à¥\87à¤\82 à¤¬à¤¦à¤²à¤¾à¤µ à¤¹à¥\8bà¤\96ला à¤ªà¤° à¤¹à¤®à¤\95à¥\87 à¤\88-मà¥\87ल à¤\95à¤\87ल जाव",
+       "tog-enotifusertalkpages": "à¤\85à¤\97र à¤¹à¤®à¤°à¥\87 à¤¬à¤¾à¤¤à¤\9aà¥\80त à¤ªà¤¨à¥\8dना à¤ªà¤° à¤\95à¥\8cनà¥\8b à¤¬à¤¦à¤²à¤¾à¤µ à¤¹à¥\8bà¤\96à¥\87 à¤¤ à¤¹à¤®à¤\95à¥\87 à¤\88-मà¥\87ल à¤\95à¤\87ल जाव",
+       "tog-enotifminoredits": "पनà¥\8dना à¤\86 à¤«à¤¾à¤\87ल à¤ªà¤° à¤\9bà¥\8bà¤\9fà¥\8b à¤¬à¤¦à¤²à¤¾à¤µ à¤¹à¥\8bà¤\96à¥\87 à¤¤ à¤¹à¤®à¤\95à¥\87 à¤\88-मà¥\87ल à¤\95à¤\87ल जाव",
+       "tog-enotifrevealaddr": "नà¥\8bà¤\9fिफिà¤\95à¥\87शन ई-मेल में हमार ई-मेल पता देखावल जाव",
        "tog-shownumberswatching": "धियान रखे वालन सदस्यन के देखावल जाव",
-       "tog-oldsig": "वरà¥\8dतमान à¤¦à¤¸à¤\96त",
+       "tog-oldsig": "राà¤\89र à¤µà¤°à¥\8dतमान à¤¦à¤¸à¤\96त:",
        "tog-fancysig": "दसखत के विकी पाठ के रुप में उपयोग करीं (बिना ऑटोमेटिक कड़ी के)",
-       "tog-uselivepreview": "लà¤\97ातार à¤\9aालà¥\82 à¤¨à¤®à¥\82ना à¤¦à¥\87à¤\96ावल (preview) à¤\95à¥\87 à¤ªà¥\8dरयà¥\8bà¤\97 à¤\95रà¥\80à¤\82",
+       "tog-uselivepreview": "लà¤\97ातार à¤\9dलà¤\95 (लाà¤\87व à¤ªà¥\8dरà¥\80वà¥\8dयà¥\82) à¤\87सà¥\8dतà¥\87माल à¤\95à¤\87ल à¤\9cाव",
        "tog-forceeditsummary": "यदि संपादन सारांश ना दिहल होखे त हमके सूचित कइल जाय",
        "tog-watchlisthideown": "हमरी धियानसूची से हमार खुद के संपादन छिपाईं",
-       "tog-watchlisthidebots": "हमार धियानसूची से बॉट द्वारा करल गइल बदलाव के छिपाईं",
-       "tog-watchlisthideminor": "हमार धियानसूची से छोट बदलाव के छिपावल जाव",
-       "tog-watchlisthideliu": "हमार धियानसूची में लॉग-इन भइल सदस्यन के संपादन छिपावल जाय",
+       "tog-watchlisthidebots": "धियानसूची से बॉट संपादन छिपावल जाय",
+       "tog-watchlisthideminor": "धियानसूची से छोट संपादन छिपावल जाय",
+       "tog-watchlisthideliu": "धियानसूची में लॉग-इन भइल सदस्यन के संपादन छिपावल जाय",
+       "tog-watchlistreloadautomatically": "जब कौनों फिल्टर बदलल जाय तब धियानसूची ऑटोमेटिक दोबारा लोड होखे (जावास्क्रिप्ट जरूरी)",
        "tog-watchlisthideanons": "आइ॰पी॰ सदस्यन द्वारा करल गइल सम्पादन के हमार धियानसूची में से छिपावल जाय",
        "tog-watchlisthidepatrolled": "जाँचल गइल सम्पादन के हमार ध्यानसूची में से छिपावल जाय",
+       "tog-watchlisthidecategorization": "पन्ना श्रेणीकरण छिपावल जाय",
        "tog-ccmeonemails": "हमरा द्वारा अन्य सदस्यन के भेजल गइल ईमेल के कॉपी हमरो के भेजल जाय",
-       "tog-diffonly": "à¤\85नà¥\8dतर à¤¦à¥\87à¤\96ावत à¤¸à¤®à¤¯ à¤\85à¤\82तर à¤\95à¥\80 à¤¨à¥\80à¤\9aà¥\87 à¤ªà¤¨à¥\8dना à¤\95à¥\87 à¤¸à¤¾à¤®à¤\97à¥\8dरà¥\80 à¤®à¤¤ à¤¦à¥\87à¤\96ावल à¤\9cाव।",
+       "tog-diffonly": "à¤\85à¤\82तर à¤¦à¥\87à¤\96ावत à¤¸à¤®à¤¯ à¤¨à¥\80à¤\9aà¥\87 à¤ªà¤¨à¥\8dना à¤\95à¥\87 à¤¸à¤¾à¤®à¤\97à¥\8dरà¥\80 à¤¨ à¤¦à¥\87à¤\96ावल à¤\9cाय",
        "tog-showhiddencats": "छिपल श्रेणियन के भी देखावल जाय",
-       "tog-norollbackdiff": "रà¥\8bलबà¥\88à¤\95 à¤\95à¤\87ला à¤\95à¥\87 à¤¬à¤¾à¤¦ à¤\85à¤\82तर à¤®à¤¤ à¤¦à¥\87à¤\96ावल à¤\9cाव",
-       "tog-useeditwarning": "à¤\9cà¥\8b à¤¹à¤® à¤\95à¥\8cनà¥\8bà¤\82 à¤ªà¤¨à¥\8dना à¤ªà¤° à¤¸à¤\82पादन à¤\95रत à¤\98रà¥\80 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\95à¥\87 à¤¬à¤¿à¤¨à¤¾ à¤¸à¤¹à¥\87à¤\9cलà¥\87 à¤\9bà¥\8bड़ à¤¦à¥\87à¤\88à¤\82 à¤¤ à¤¹à¤®à¤\95à¥\87 à¤\96बर à¤\95à¤\87ल à¤\9cाव",
-       "tog-prefershttps": "à¤\9cब à¤\96ाता à¤®à¥\87à¤\82 à¤²à¥\89à¤\97िन à¤\95रà¥\80à¤\82 à¤¤ हमेशा सुरक्षित कनेक्शन के प्रयोग कइल जाय",
+       "tog-norollbackdiff": "रà¥\8bलबà¥\88à¤\95 à¤\95à¤\87ला à¤\95à¥\87 à¤¬à¤¾à¤¦ à¤\85à¤\82तर à¤¨ à¤¦à¥\87à¤\96ावल à¤\9cाय",
+       "tog-useeditwarning": "à¤\9cà¥\8b à¤¹à¤® à¤\95à¥\8cनà¥\8bà¤\82 à¤ªà¤¨à¥\8dना à¤ªà¤° à¤¸à¤\82पादन à¤\95रत à¤\98रà¥\80 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\95à¥\87 à¤¬à¤¿à¤¨à¤¾ à¤¸à¤¹à¥\87à¤\9cलà¥\87 à¤\9bà¥\8bड़ à¤¦à¥\87à¤\88à¤\82 à¤¤ à¤¹à¤®à¤\95à¥\87 à¤\96बर à¤\95à¤\87ल à¤\9cाय",
+       "tog-prefershttps": "लà¥\89à¤\97िन à¤°à¤¹à¤²à¥\87 à¤ªà¤° हमेशा सुरक्षित कनेक्शन के प्रयोग कइल जाय",
        "underline-always": "हमेशा",
        "underline-never": "कभी ना",
-       "underline-default": "à¤\9cिलà¥\8dद (सà¥\8dà¤\95िन) à¤¯à¤¾ à¤¬à¥\8dराà¤\89सर डिफॉल्ट",
-       "editfont-style": "समà¥\8dपादन क्षेत्र के फॉन्ट स्टाइल:",
+       "underline-default": "à¤\9cिलà¥\8dद (सà¥\8dà¤\95िन) à¤¯à¤¾ à¤¬à¥\8dराà¤\89à¤\9cर डिफॉल्ट",
+       "editfont-style": "सà¤\82पादन क्षेत्र के फॉन्ट स्टाइल:",
        "editfont-default": "ब्राउजर डिफाल्ट",
        "editfont-monospace": "मोनोस्पेस्ड फोंट",
-       "editfont-sansserif": "सनà¥\8dस-सेरिफ फॉन्ट",
+       "editfont-sansserif": "सà¥\88à¤\82स-सेरिफ फॉन्ट",
        "editfont-serif": "सेरिफ फॉन्ट",
        "sunday": "इतवार",
        "monday": "सोमवार",
        "october-date": "अक्टूबर $1",
        "november-date": "नवंबर $1",
        "december-date": "दिसंबर $1",
+       "period-am": "AM",
+       "period-pm": "PM",
        "pagecategories": "{{PLURAL:$1|श्रेणी|श्रेणी}}",
        "category_header": "\"$1\" श्रेणी में पन्ना",
        "subcategories": "उपश्रेणी",
        "category-file-count-limited": "वर्तमान में निम्नलिखित {{PLURAL:$1|पन्ना|$1 पन्नां}} इ श्रेणीं में बाड़े।",
        "listingcontinuesabbrev": "जारी...",
        "index-category": "सूचीबद्ध पन्ना",
-       "noindex-category": "बिना सूचीबद्ध पन्ना",
+       "noindex-category": "बिनासूचीबद्ध पन्ना",
        "broken-file-category": "टूटल फाइल कड़ियन वाला पन्ना",
        "about": "बारे में",
        "article": "सामग्री पन्ना",
        "newwindow": "(नया विंडो में खोलीं)",
        "cancel": "कैंसिल",
        "moredotdotdot": "अउर...",
-       "morenotlisted": "à¤\87 à¤¸à¥\82à¤\9aà¥\80 à¤ªà¥\82रà¥\8dण à¤¨à¤\87खे।",
+       "morenotlisted": "हà¥\8b à¤¸à¤\95à¥\87ला à¤\95ि à¤\88 à¤²à¤¿à¤¸à¥\8dà¤\9f à¤ªà¥\82रा à¤¨ à¤¹à¥\8bखे।",
        "mypage": "पन्ना",
        "mytalk": "हमार बातचीत पन्ना",
        "anontalk": "बातचीत",
        "tagline": "भोजपुरी {{SITENAME}} से",
        "help": "मदद",
        "search": "खोज",
+       "search-ignored-headings": " #<!-- एह लाइन के बिलकुल अइसहीं छोड़ दीं --> <pre>\n# हेडिंग जिनहन पर खोज करत समय धियान ना दिहल जाई।\n# एह हेडिंग वाला पन्ना जइसहीं सूचीबद्ध होखी, बदलाव प्रभावी हो जइहें।\n# आप एगो खाली संपादन (null edit) कइ के दुबारा सूचीकरण के लागू कर सकत बानी।\n# एकर सिंटेक्स अइसे बा कि:\n#   * Everything from a \"#\" character to the end of the line is a comment.\n#   * Every non-blank line is the exact title to ignore, case and everything.\nसंदर्भ\nबाहरी कड़ी\nइहो देखल जाय\n #</pre> <!-- एह लाइन के बिलकुल अइसहीं छोड़ दीं -->",
        "searchbutton": "खोजीं",
        "go": "जाईं",
        "searcharticle": "जाईं",
        "talk": "बात-चीत",
        "views": "कइसन लउकी?",
        "toolbox": "औजार",
+       "tool-link-userrights": "{{GENDER:$1|प्रयोगकर्ता}} के सदस्यसमूह बदलीं",
+       "tool-link-emailuser": "{{GENDER:$1|प्रयोगकर्ता}} के ईमेल करीं",
        "userpage": "प्रयोगकर्ता पन्ना देखीं",
        "projectpage": "परियोजना पन्ना देखीं",
        "imagepage": "फाइल पन्ना देखीं",
        "databaseerror-query": "अनुरोध: $1",
        "databaseerror-function": "फ़ंक्शन: $1",
        "databaseerror-error": "त्रुटि: $1",
+       "transaction-duration-limit-exceeded": "हाई रिप्लिकेशन लैग बनावे से बचे खातिर ई ट्रांजेक्शन निरस्त कर दिहल गइल, काहें से की राइट करे में लागे वाला समय ($1), $2 के सीमा से अधिक रहल।\nअगर आ कई ठो आइटम एकही साथ बदलत होखीं, तब कई टुकड़ा में ई काम करे के कोसिस करीं।",
        "laggedslavemode": "'''चेतावनी:''' इ पन्ना पर हाल के बदलाव ना होखे के आशंका बा।",
        "readonly": "डेटाबेस लॉक बा",
        "enterlockreason": "लॉक करे के कारण दिहीं, साथे लॉक खुले के समय के लगभग आकलन दिहीं।",
        "missingarticle-rev": "(संशोधन#: $1)",
        "missingarticle-diff": "(अंतर: $1, $2)",
        "readonly_lag": "उपमुख्य डाटाबेस सर्वर मुख्य डाटाबेस के बराबर परावर्तित होत समय मुख्य डाटाबेस सर्वर अपने आप लॉक हो गइल।",
+       "nonwrite-api-promise-error": "'Promise-Non-Write-API-Action' ऍचटीटीपी हेडर भेजल गइल रहल बाकी ई रिक्वेस्ट एपीआइ राइट मॉड्यूल खातिर रहल।",
        "internalerror": "आन्तरिक त्रुटि",
        "internalerror_info": "आन्तरिक त्रुटि: $1",
        "internalerror-fatal-exception": "प्रकार के गंभीर अपवाद \"$1\"",
        "viewsource": "स्रोत देखीं",
        "viewsource-title": "$1 के स्रोत देखीं",
        "actionthrottled": "कार्य समाप्त कर दिहल गइल बा",
-       "actionthrottledtext": "सà¥\8dपà¥\88म à¤\95à¥\87 à¤°à¥\8bà¤\95थाम à¤\96ातिर, à¤\87 à¤\95à¥\8dरिया à¤\8fतना à¤\95म à¤¸à¤®à¤¯ à¤®à¥\87à¤\82 à¤\8fà¤\95 à¤¸à¥\80मा à¤¸à¥\87 à¤\85धिà¤\95 à¤¬à¤¾à¤° à¤\95रà¥\87 à¤\95à¥\87 à¤®à¤¨à¤¾ à¤¬à¤¾, à¤\86 à¤°à¤\89à¤\86 à¤\87 à¤¸à¥\80मा à¤\95à¥\87 à¤ªà¤¾à¤° à¤\95र à¤\9aà¥\81à¤\95ल à¤¬à¤¾à¤¨à¥\80।\nà¤\95à¥\83पया à¤\95à¥\81à¤\9b à¤¸à¤®à¤¯ à¤¬à¤¾à¤¦ à¤ªà¥\81न: à¤¯à¤¤à¥\8dन करीं।",
+       "actionthrottledtext": "दà¥\81रà¥\81पयà¥\8bà¤\97 à¤°à¥\8bà¤\95थाम à¤\89पाय à¤\95à¥\87 à¤°à¥\82प à¤®à¥\87à¤\82, à¤\8fह à¤\95ाम à¤\95à¥\87 à¤¬à¤¹à¥\81त à¤\95म à¤¸à¤®à¤¯ à¤®à¥\87à¤\82 à¤\8fà¤\95 à¤¸à¥\80मा à¤¸à¥\87 à¤\85धिà¤\95 à¤¬à¥\87 à¤\95रà¥\87 à¤\95à¥\87 à¤®à¤¨à¤¾ à¤¬à¤¾, à¤\86 à¤°à¤\89à¤\86 à¤\88 à¤¸à¥\80मा à¤\95à¥\87 à¤ªà¤¾à¤° à¤\95र à¤\9aà¥\81à¤\95ल à¤¬à¤¾à¤¨à¥\80।\nà¤\95à¥\83पया à¤\95à¥\81à¤\9b à¤¸à¤®à¤¯ à¤¬à¤¾à¤¦ à¤¦à¥\8bबारा à¤\95à¥\8bसिस करीं।",
        "protectedpagetext": "इ पन्ना संपादन आ अन्य कार्यं से बचाव खातिर सुरक्षित कर दिहल गइल बा।",
        "viewsourcetext": "रउआँ एह पन्ना के स्रोत देख सकत बानी आ एकर नकल उतार सकत बानी:",
        "viewyourtext": "एह पन्ना पर <strong>राउर आपन संपादन सब</strong>के स्रोत देख सकत बानी आ ओकर नकल ले सकत बानी।",
        "mypreferencesprotected": "रउआ लगे आपन वरियतां ‍‍‍‍(पसंद) बदले के अधिकार नइखे।",
        "ns-specialprotected": "विशेष पन्ना के सम्पादन सम्भव नइखे",
        "titleprotected": "सदस्य [[User:$1|$1]] द्वारा इ शीर्षक के पन्ना बनावे से बचाव खातिर इ के सुरक्षित कर दिहल गइल बा।\nइ खातिर निम्न कारण दिहल गइल बा: <em>$2</em>",
-       "filereadonlyerror": "फाइल \"$1\" के बदलल सक्षम नइखे काहे कि संग्रह \"$2\" 'खाली पाठन हेतु' (रिड ऑन्ली) मोड में बा।\n\nजउन प्रबंधक इ प्रबंध लगउले बानी उहाँ के निम्न विवरण प्रदान कइले बानी: \"$3\"।",
+       "filereadonlyerror": "फाइल \"$1\" के बदलल सक्षम नइखे काहें कि संग्रह \"$2\" 'खाली पढ़े हेतु' (रीड ऑनली) मोड में बा।\n\nजे सिस्टम प्रबंधक ई प्रतिबंध लगावल ऊ नीचे दिहल कारण बतवले रहल: \"$3\"।",
        "invalidtitle-knownnamespace": "\"$2\" नामस्थान आ \"$3\" पाठ्य वाला गलत शीर्षक",
        "invalidtitle-unknownnamespace": "अज्ञात नामस्थान संख्या $1 आ नाम \"$2\" वाला गलत शीर्षक",
        "exception-nologin": "खाता में प्रवेश नइखे",
        "virus-scanfailed": "जाँच विफल (कोड $1)",
        "virus-unknownscanner": "अज्ञात ऐंटीवायरस:",
        "logouttext": "'''रउआ अब खाता से बाहर बानी'''\n\nध्यान रहे कि जब तक रउआ आपन ब्राउजर के कैश साफ ना करब, तब तक कुछ पन्नन में हो सकत बा रउआ के खाता में लगातार प्रवेशित दिखावत रही।",
+       "cannotlogoutnow-title": "एह समय लॉगआउट ना हो सकी",
+       "cannotlogoutnow-text": "$1 के इस्तेमाल करत समय लॉगआउट नइखे संभव।",
        "welcomeuser": "राउर स्वागत बा, $1!",
        "welcomecreation-msg": "राउर खाता बना दिहल गईल बा।\nआपन [[Special:Preferences|{{SITENAME}} वरीयतां]] के बदले के ना भूलब।",
        "yourname": "सदस्यनाम:",
        "yourpasswordagain": "गुप्त-शब्द पुन:डालीं:",
        "createacct-yourpasswordagain": "गुप्तशब्द (पासवर्ड) के पुष्टि करीं",
        "createacct-yourpasswordagain-ph": "गुप्तशब्द (पासवर्ड) फेर से प्रवेश करीं",
-       "remembermypassword": "इ ब्राउजर पर हमार प्रवेश याद रखीं (अधिकतम $1 {{PLURAL:$1|दिन|दिनं}} तक)",
        "userlogin-remembermypassword": "हमके लॉग इन रहे दीं",
        "userlogin-signwithsecure": "सुरक्षित कनेक्शन के प्रयोग करीं",
+       "cannotlogin-title": "लॉगइन नइखे हो पावत",
+       "cannotlogin-text": "लॉगइन कइल संभव नइखे।",
+       "cannotloginnow-title": "एह समय लॉगइन नइखे हो सकत",
+       "cannotloginnow-text": "$1 के इस्तेमाल करत समय लॉगइन कइल नइखे संभव।",
+       "cannotcreateaccount-title": "खाता नइखे बनावल जा सकत",
+       "cannotcreateaccount-text": "एह विकि पर सीधे खाता बनावले के सुबिधा सक्षम नइखे।",
        "yourdomainname": "राउर डोमेनः",
        "password-change-forbidden": "रउआ इ विकी पर गुप्तशब्द नइखीं बदल सकत।",
        "externaldberror": "या त प्रमाणिकरण डाटाबेस में भइल बा या फिर रउआ के आपन बाह्य खाता अपडेट करे के अनुमति नइखे।",
        "login": "लॉग इन",
+       "login-security": "आपन पहिचान साबित करीं",
        "nav-login-createaccount": "खाता प्रवेश / खाता बनाईं",
        "userlogin": "खाता प्रवेश / खाता बनाईं",
        "userloginnocreate": "खाता में प्रवेश",
        "userlogin-resetpassword-link": "आपन गुप्तशब्द भूला गईनी का?",
        "userlogin-helplink2": "लॉग इन में मदद",
        "userlogin-loggedin": "रउआ {{GENDER:$1|$1}} के रूप में पहिले से लॉग्ड इन बानीं।\nकौनो अन्य सदस्य के रूप में लॉग इन करे खातिर निम्नलिखित फ़ॉर्म के प्रयोग करीं।",
+       "userlogin-reauth": "आप के ई साबित करे खातिर की आपे {{GENDER:$1|$1}} बानी, दुबारा लॉगिन करे के पड़ी।",
        "userlogin-createanother": "एगो दूसर खाता बनाईं",
        "createacct-emailrequired": "ई-मेल पता",
        "createacct-emailoptional": "ई-मेल पता (वैकल्पिक)",
        "createacct-email-ph": "आपन ई-मेल पता लिखीं",
        "createacct-another-email-ph": "ई-मेल पता लिखीं",
        "createaccountmail": "एगो अस्थायी यादृच्छिक (रैन्डम) गुप्तशब्द के प्रयोग करीं आ निर्दिष्ट ई-मेल पता पर भेजीं",
+       "createaccountmail-help": "एकर इस्तेमाल केहू दुसरा खातिर खाता बनावे में कइल जा सके ला, बिना पासवर्ड जनले।",
        "createacct-realname": "असली नाम (वैकल्पिक)",
        "createaccountreason": "कारण:",
        "createacct-reason": "कारण",
        "createacct-reason-ph": "रउआ एगो अन्य खाता काहे बना रहल बानी",
+       "createacct-reason-help": "खाता बनवले के लॉग में देखाई पड़े वाला संदेस",
        "createacct-submit": "आपन खाता बनाईं",
-       "createacct-another-submit": "एगो दोसर खाता बनाईं",
+       "createacct-another-submit": "खाता बनाईं",
+       "createacct-continue-submit": "खाता बनावल जारी राखीं",
+       "createacct-another-continue-submit": "खाता बनावल जारी राखीं",
        "createacct-benefit-heading": "{{SITENAME}} रउआ जइसन लोगन द्वारा बनावल गईल बा।",
        "createacct-benefit-body1": "{{PLURAL:$1|संपादन}}",
        "createacct-benefit-body2": "{{PLURAL:$1|पन्ना}}",
        "nocookiesnew": "प्रयोगकर्ता खाता त बन गईल, बाँकी रउआ प्रवेश नईखीं भईल।\n{{SITENAME}} प्रयोगकर्ता लोग के खाता में प्रवेश करावे खातिर कुकिज के प्रयोग करेला।\nराउर कुकिज असक्षम बा।\nकृपया उ के सक्षम करीं, उ के बाद राउर नया प्रयोगकर्ता नाम आ गुप्त शब्द के साथ प्रवेश करीं।",
        "nocookieslogin": "{{SITENAME}} प्रयोगकर्ता लोग के खाता में प्रवेश करावे खातिर कुकिज के प्रयोग करेला।\nराउर कुकिज असक्षम बा।\nकृपया उ के सक्षम करीं आ फिर से कोशिश करीं",
        "nocookiesfornew": "स्रोत के पुष्टि ना हो पावे के कारण इ खाता निर्मित ना करल गइल। \nसुनिश्चित करीं कि रउआ कुकीज़ सक्षम कइले बानी, पृष्ठ के पुनः लोड करीं आ पुनः प्रयास करीं।",
+       "createacct-loginerror": "खाता बनावल सफल भइल बाकी रउआँ अपने-आप लॉगिन ना हो पवलीं। [[Special:UserLogin|मैनुअल लॉगिन]] करीं।",
        "noname": "रउआ उपयुक्त प्रयोगकर्ता नाम नईखीं निर्दिष्ट कईले।",
        "loginsuccesstitle": "लॉगिन पूरा",
        "loginsuccess": "''' \"$1\" के रुप में रउआ {{SITENAME}} में अब प्रवेश कर चुकल बानी।'''",
        "noemail": "\"$1\" सदस्य खातिर कउनो भी ई-मेल पता दर्ज नइखे करल गइल।",
        "noemailcreate": "रउआ एगो जायज ई-मेल पता उपलब्ध करावे के पड़ी।",
        "passwordsent": "\"$1\" के ई-मेल पता पर एगो नया गुप्तशब्द भेज दिहल गइल बा।\nई-मेल पावे के बाद कृपया दुबारा खाता में प्रवेश करब।",
-       "blocked-mailpassword": "राà¤\89र à¤\86à¤\87॰पà¥\80 à¤ªà¤¤à¤¾ à¤\95à¥\87 à¤¸à¤®à¥\8dपादन à¤\95रà¥\87 à¤¸à¥\87 à¤µà¤\82à¤\9aित à¤\95र à¤¦à¤¿à¤¹à¤² à¤\97à¤\87ल à¤¬à¤¾, à¤\86 à¤\97लत à¤ªà¥\8dरयà¥\8bà¤\97 à¤°à¥\8bà¤\95à¥\87 à¤\96ातिर à¤\97à¥\81पà¥\8dतशबà¥\8dद à¤ªà¥\81नà¤\83 à¤ªà¥\8dरापà¥\8dति à¤\95à¥\87 à¤¸à¥\81विधा à¤\87 à¤\86à¤\87॰पà¥\80 à¤ªà¤° à¤¬à¤\82द à¤\95र à¤¦à¤¿à¤¹à¤² à¤\97à¤\87ल à¤¬à¤¾।",
+       "blocked-mailpassword": "राà¤\89र à¤\86à¤\87पà¥\80 à¤ªà¤¤à¤¾ à¤\95à¥\87 à¤¸à¤\82पादन à¤\95रà¥\87 à¤¸à¥\87 à¤°à¥\8bà¤\95 à¤¦à¤¿à¤¹à¤² à¤\97à¤\87ल à¤¬à¤¾à¥¤ à¤¦à¥\81रà¥\81पयà¥\8bà¤\97 à¤°à¥\8bà¤\95à¥\87 à¤\96ातिर, à¤\8f à¤\86à¤\87पà¥\80 à¤¸à¥\87 à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤°à¤¿à¤\95वरà¥\80 à¤\95à¥\87 à¤\85नà¥\81मति à¤¨à¤\87à¤\96à¥\87।",
        "eauthentsent": "दर्ज करावल गइल ई-मेल पता पर एगो पुष्टिकरण ई-मेल भेज दिहल गइल बा।\nउ खाता पर कौनो दुसर ईमेल भेजल जाओ उ से पहिले, रउआ भेजल गईल ई-मेल पर दिहल गइल निर्देश के अनुसरण कर के ई-मेल पता के पुष्टिकरण करावे के पड़ी ताकि पता चले की सही में उ राउरे खाता ह।",
        "throttled-mailpassword": "पिछला {{PLURAL:$1|एक घंटा|$1 घंटा}} के अंदर एगो गुप्तशब्द पुनर्स्थापन ई-मेल भेजल जा चुकल बा।\nदुरुपयोग से बचावे खातिर {{PLURAL:$1|एक घंटा|$1 घंटा}} में सिर्फ एगो गुप्तशब्द पुनर्स्थापन ई-मेल भेजल जाई।",
        "mailerror": "ई-मेल भेजे में त्रुटि: $1",
-       "acct_creation_throttle_hit": "राà¤\89र à¤\86à¤\87॰पà¥\80 à¤ªà¤¤à¤¾ à¤¸à¥\87 à¤\86à¤\88ल à¤\86à¤\97à¤\82तà¥\81à¤\95 à¤ªà¤¿à¤\9bला à¤\9aà¥\8cबà¥\80स à¤\98à¤\82à¤\9fा à¤®à¥\87à¤\82 à¤\87 à¤µà¤¿à¤\95ि à¤ªà¤° {{PLURAL:$1|à¤\8fà¤\95 à¤\96ाता|$1 à¤\96ाता}} à¤¬à¤¨à¤¾ à¤\9aà¥\81à¤\95ल à¤¬à¤¾à¤¨à¥\80, à¤\87 à¤¸à¤®à¤¯à¤¾à¤µà¤§à¤¿ à¤®à¥\87à¤\82 à¤\87हà¥\87 à¤\85धिà¤\95तम à¤¸à¥\80मा à¤¬à¤¾à¥¤\nà¤\85तà¤\83 à¤\87 à¤¸à¤®à¤¯ à¤\87 à¤\86à¤\87॰पà¥\80 à¤ªà¤¤à¤¾ à¤\95à¥\87 à¤ªà¥\8dरयà¥\8bà¤\97 à¤\95रà¥\87 à¤µà¤¾à¤²à¤¾ à¤\86à¤\97à¤\82तà¥\81à¤\95 à¤\85à¤\89र à¤\85धिà¤\95 à¤\96ाता à¤¨à¤\87à¤\96न बना सकत।",
+       "acct_creation_throttle_hit": "राà¤\89र à¤\86à¤\87पà¥\80 à¤ªà¤¤à¤¾ à¤¸à¥\87 à¤\86à¤\87ल à¤\86à¤\97à¤\82तà¥\81à¤\95 à¤²à¥\8bà¤\97 à¤ªà¤¿à¤\9bला $2 à¤®à¥\87à¤\82 à¤\8fह à¤µà¤¿à¤\95ि à¤ªà¤° {{PLURAL:$1|à¤\8fà¤\95 à¤ à¥\8b à¤\96ाता|$1 à¤\96ाता}} à¤¬à¤¨à¤¾ à¤\9aà¥\81à¤\95ल à¤¬à¤¾ à¤\9cवन à¤\8fह à¤¸à¤®à¤¯à¤\85वधि à¤®à¥\87à¤\82 à¤\85धिà¤\95तम à¤¸à¥\80मा à¤¬à¤¾à¥¤\nà¤\8fहà¥\80 à¤\95ारण, à¤\8fह à¤\86à¤\87पà¥\80 à¤ªà¤¤à¤¾ à¤\95à¥\87 à¤\87सà¥\8dतà¥\87माल à¤\95रà¥\87 à¤µà¤¾à¤²à¤¾ à¤\86à¤\97à¤\82तà¥\81à¤\95 à¤\85ब à¤\95à¥\8cनà¥\8bà¤\82 à¤\85à¤\89रà¥\80 à¤\96ाता à¤\8fह à¤¸à¤®à¤¯ à¤¨à¤\87à¤\96à¥\87à¤\82 बना सकत।",
        "emailauthenticated": "$2 के $3 पर राउर ई-मेल पता के पुष्टीकरण हो चुकल बा।",
        "emailnotauthenticated": "राउर ई-मेल पता के अभी तक प्रमाणिकरण नइखे भईल।\nनिम्नलिखित कउनो भी सुविधा खातिर रउआ के कौनो भी ई-मेल ना भेजल जाई।",
        "noemailprefs": "इ सुविधा के प्रयोग करे खातिर आपन वरियता में एगो ई-मेल पता दिहीं।",
        "createaccount-title": "{{SITENAME}} खातिर खाता बनाईं",
        "createaccount-text": "राउर ई-मेल पता खातिर {{SITENAME}} ($4) पर \"$2\" सदस्य नाम से \"$3\" गुप्तशब्द (पासवर्ड) सहित खाता खोलले बानी। रउआ खाता में प्रवेश कर के आपन गुप्तशब्द (पासवर्ड) तुरंत बदल लेवे के चाहीं।\n\nयदि इ खाता गलती से खोलल गईल बा, त रउआ इ संदेश के अनदेखा कर सकत बानी।",
        "login-throttled": "रउआ हाले में कईयन बार खाता में प्रवेश करे के कोशिश कर चुकल बानी।\nकृपया $1 प्रतिक्षा करला के बाद फिर से प्रयास करब।",
-       "login-abort-generic": "राà¤\89र à¤\96ाता à¤®à¥\87à¤\82 à¤ªà¥\8dरवà¥\87श à¤\85सफल à¤°à¤¹à¤² - à¤¨à¤¿à¤·à¥\8dफलित",
+       "login-abort-generic": "राà¤\89र à¤²à¥\89à¤\97िन à¤¬à¤¿à¤«à¤² à¤°à¤¹à¤² - à¤°à¤¦à¥\8dद à¤\95à¤\87ल à¤\97à¤\87ल",
        "login-migrated-generic": "आप के खाता माइग्रेट हो चुकल बा अउर आप के सदस्यनाम इ विकी पर अब मौजूद नइखे।",
        "loginlanguagelabel": "भाषा: $1",
        "suspicious-userlogout": "राउर खाता से बाहर जाये के अनुरोध अस्वीकृत कर दिहल गइल बा काहे कि  अइसन लग रहल बा कि इ कउनो खराब ब्राउज़र या कैश करे वाली प्रॉक्सी द्वारा भेजल गईल रहल।",
        "createacct-another-realname-tip": "असली नाम वैकल्पिक बा।\nयदि रउआ इ के उपलब्ध करावे के चुनत बानी त, एकर प्रयोग सदस्य के ओकरा काम के अधिकार देवे खातिर होखी।",
        "pt-login": "खाता में प्रवेश",
        "pt-login-button": "लॉग इन",
+       "pt-login-continue-button": "लॉगिन जारी राखीं",
        "pt-createaccount": "खाता बनाईं",
        "pt-userlogout": "लॉग आउट",
        "php-mail-error-unknown": "PHP के mail() फ़ंक्शन में अज्ञात त्रुटि बा।",
        "newpassword": "नया गुप्त-शब्द:",
        "retypenew": "नया गुप्त-शब्द पुन: डालीं:",
        "resetpass_submit": "गुप्तशब्द बनाईं आ खाता में प्रवेश करीं",
-       "changepassword-success": "राà¤\89र à¤\97à¥\81पà¥\8dतशबà¥\8dद à¤¸à¤«à¤²à¤¤à¤¾à¤ªà¥\81रà¥\8dवà¤\95 à¤¬à¤¦à¤² à¤¦à¤¿à¤¹à¤² à¤\97à¤\88ल बा!",
+       "changepassword-success": "राà¤\89र à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤¬à¤¦à¤² à¤¦à¤¿à¤¹à¤² à¤\97à¤\87ल बा!",
        "changepassword-throttled": "रउआ हाले में कईयन बार खाता में प्रवेश करे के कोशिश कर चुकल बानी।\nकृपया $1 प्रतिक्षा करला के बाद फिर से प्रयास करब।",
+       "botpasswords": "बॉट पासवर्ड",
+       "botpasswords-disabled": "बॉट पासवर्ड अक्षम कइल गइल बा।",
+       "botpasswords-no-central-id": "बॉट पासवर्ड के प्रयोग करे खातिर आपके सेंट्रलाइज्ड खाता से लॉगिन होखल जरूरी बा।",
+       "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-grants": "लागू हो सके वाला अनुमोदन:",
+       "botpasswords-label-grants-column": "मंजूर भइल",
+       "botpasswords-bad-appid": "बॉट नाँव \"$1\" वैध नइखे।",
+       "botpasswords-insert-failed": "बॉट नाँव $1 जोड़ल फेल हो गइल। का ई पहिलहीं जोड़ल जा चुकल बा?",
+       "botpasswords-update-failed": "बॉट नाँव \"$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": "गुप्त शब्द बदलीं",
        "passwordreset-emailtext-user": "{{SITENAME}} ($4) पर सदस्य $1 राउर {{PLURAL:$3|खाता}} के गुप्तशब्द के पुनर्स्थापित करे के अनुरोध कइले बानी। इ ई-मेल पता से निम्न {{PLURAL:$3|खाता जुड़ल बा}}:\n\n$2\n\n{{PLURAL:$3|इ}} अस्थायी गुप्तशब्द {{PLURAL:$5|एक दिन|$5 दिन}} के बाद काम ना करी।\nरउआ खाता में प्रवेश करके एगो नया गुप्तशब्द अभीये चुन लेवे के चाहीं। यदि इ अनुरोध केहु अउर कइले बा, या फिर रउआ आपन मूल गुप्तशब्द याद आ गईल बा, अउर रउआ {{PLURAL:$3|आपन}} गुप्तशब्द नईखीं बदले के चाहत त, रउआ इ संदेश के अनदेखा कर के आपन पुरनका गुप्तशब्द के प्रयोग जारी रख सकत बानीं।",
        "passwordreset-emailelement": "सदस्यनाम: \n$1\n\nअस्थायी गुप्तशब्द: \n$2",
        "passwordreset-emailsentemail": "एगो गुप्तशब्द रिसेट ई-मेल भेजल जा चुकल बा।",
+       "passwordreset-invalidemail": "अवैध ईमेल पता",
        "changeemail": "ई-मेल पता बदलीं",
        "changeemail-header": "खाता के ई-मेल पता बदलीं",
        "changeemail-no-info": "इ पन्ना के सिधे प्रयोग करे खातिर रउआ पहिले खाता में प्रवेश करे के पड़ी।",
        "sig_tip": "समय मोहर की संघे राउर दस्खत",
        "hr_tip": "पड़ी लकीर (कम प्रयोग करीं)",
        "summary": "छोट विवरण (सारांश):",
-       "subject": "विषय/शिरà¥\8dषà¤\95:",
+       "subject": "बिसय:",
        "minoredit": "छोट परिवर्तन",
        "watchthis": "धियानसूची में डालीं",
        "savearticle": "पन्ना सहेजीं",
+       "savechanges": "बदलाव सहेजीं",
+       "publishpage": "पन्ना प्रकाशित करीं",
+       "publishchanges": "बदलाव प्रकाशित करीं",
        "preview": "पूर्वावलोकन",
        "showpreview": "झलक देखीं",
        "showdiff": "बदलाव देखीं",
        "missingsummary": "'''स्मरणपत्र:'''रउआ एगो सारांश के सम्पादन नईखीं प्रदान कईले। अगर रउआ \"फिर से सुरक्षित करीं\" पर क्लिक करेब, त राउर सम्पादन बिना एगो सारांश के सुरक्षित हो जाई।",
        "selfredirect": "<strong>चेतावनी:</strong> आप खुद के इ पन्ना पर पुनः निर्देशित कर रहल बानी।\nआप अनुप्रेषित खातिर गलत लक्ष्य निर्दिष्ट हो सकत बानी, या आप के द्वारा गलत पन्ना के संपादन हो सकत बा।\nआप यदि फेर से \"{{int:savearticle}}\" क्लिक करत बानी त, पुन: निर्देषण ओइसहु बनावल जाई।",
        "missingcommenttext": "कृपया निचे एगो टिप्पणी करीं।",
-       "missingcommentheader": "'''सà¥\8dमरणपतà¥\8dर:''' à¤°à¤\89à¤\86 à¤\88 à¤\9fिपà¥\8dपणà¥\80 à¤\96ातिर à¤\95à¥\8cनà¥\8b à¤µà¤¿à¤·à¤¯/शिरà¥\8dषà¤\95 à¤ªà¥\8dरदान à¤¨à¤\88à¤\96à¥\80à¤\82 à¤\95à¤\88लà¥\87। \"{{int:savearticle}}\" à¤¯à¤¦à¤¿ à¤°à¤\89à¤\86 à¤«à¤¿à¤° à¤¸à¥\87 à¤¸à¥\81रà¤\95à¥\8dषित à¤\95रब à¤¤ à¤°à¤¾à¤\89र à¤¸à¤®à¥\8dपादन à¤¬à¤¿à¤¨à¤¾ à¤\95à¥\8cनà¥\8b à¤¶à¤¿à¤°à¥\8dषà¤\95 à¤\95à¥\87 à¤¸à¥\81रà¤\95à¥\8dषित à¤¹à¥\8b जाई।",
+       "missingcommentheader": "'''याद à¤¦à¤¿à¤¯à¤¾à¤µà¤² à¤\9cात à¤¬à¤¾:''' à¤°à¤\89à¤\86à¤\81 à¤\8fह à¤\95मà¥\87à¤\82à¤\9f à¤\96ातिर à¤\95à¥\8cनà¥\8bà¤\82 à¤¬à¤¿à¤¸à¤¯ à¤¨à¤\87à¤\96à¥\80à¤\82 à¤¦à¤¿à¤¹à¤²à¥\87। à¤\85à¤\97र à¤\86प \"{{int:savearticle}}\" à¤ªà¤° à¤\95à¥\8dलिà¤\95 à¤\95रब à¤¤à¤¬ à¤°à¤¾à¤\89र à¤¸à¤\82पादन à¤\8fà¤\95रà¥\87 à¤¬à¤¿à¤¨à¤¾ à¤¸à¤¹à¥\87à¤\9cा जाई।",
        "summary-preview": "सारांश पूर्वावलोकन:",
-       "subject-preview": "विषय/शिरà¥\8dषà¤\95 à¤ªà¥\82रà¥\8dवावलà¥\8bà¤\95न:",
+       "subject-preview": "बिसय à¤\95à¥\87 à¤\9dलà¤\95:",
        "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आपन कउनो भी प्रश्न में कृपया इ सब जानकारी भी शामिल करब।",
        "previewnote": "'''याद रखीं, इ एगो झलक मात्र हो।'''\nराउर बदलाव अभी तक सुरक्षित नईखे करल गईल!",
        "continue-editing": "संपादन क्षेत्र में जाईं",
        "previewconflict": "ई नमूना ई देखावत बा की अगर रउआँ ए संपादन बक्सा में मौजूद पाठ के सहेजब त ऊ कइसन देखाई पड़ी।",
-       "session_fail_preview": "<strong>माफ करीं! एह सत्र के आँकड़ा के गायब हो गइला की कारण आपके संपादन के प्रॉसेस करे में हमनी के असमर्थ बाणी।</strong>\nदोबारा से कोसिस करीं।\nअगर तबो काम ना होखे तब [[Special:UserLogout|लॉग आउट करीं]] आ दोबारा लॉग इन कइ के कोसिस करी।",
+       "session_fail_preview": "माफ करीं! एह सत्र के आँकड़ा के गायब हो गइला के कारण आपके संपादन के प्रॉसेस करे में हमनी के असमर्थ बानी जा।\nहो सकेला आप लॉगआउट हो गइल होखीं।\n<strong>जाँच लेईं कि आप अभी लॉगिन बानी आ दुबारा कोसिस करीं</strong>।\nअगर तबो काम ना होखे तब [[Special:UserLogout|लॉगआउट कइके]] आ दोबारा लॉग इन कइ के कोसिस करी, आ जाँच करीं कि आपके ब्राउजर एह साइट से कुकीज सभ के मंजूर करत बा।",
        "session_fail_preview_html": "<strong>माफ करीं! सत्र आँकड़ा के गायब होखला की कारन आपके संपादन सहेजल नइखे जा सकत।</strong>\n\n<em>चूँकि, {{SITENAME}} में मूल HTML सक्षम कइल बाटे, जावास्क्रिप्ट हमला से बचाव की खातिर नमूना देखावे के छिपावल गइल बा।</em>\n\n<strong>अगर ई एगो वैध संपादन बाटे तब एक बेर फिर से कोसिस करीं।</strong>\nअगर तबो पर काम नइखे हो पावत त [[Special:UserLogout|लॉग आउट करीं]] आ दुबारा लॉगिन क के कोसिस करीं।",
        "token_suffix_mismatch": "<strong>राउर संपादन रिजेक्ट कइल जात बा काहें से की राउर क्लायंट संपादन टोकन में विराम चीन्हा सब से गड़बड़ क दिहले बा।</strong>\nपन्ना के पाठ के तहस-नहस होखे से बचावे खाती ई संपादन रिजेक्ट कइल गइल बा।\nकबो-कबो अइसन एहू दसा में हो सकेला जब आप खराबी-युक्त वेबआधारित बेनाम प्रॉक्सी सर्वर के इस्तेमाल करत होखीं।",
        "edit_form_incomplete": "<strong>संपादन के कुछ हिस्सा सर्वर ले ना पहुँच पावल ह; दोहरा के चेक करीं की राउर संपादन बदलल न होखे आ एक बेर फिर से सहेजे के कोसिस करीं।</strong>",
        "editing": "$1 संपादन",
        "creating": "$1 बनावे जा रहल बानी",
        "editingsection": "$1 संपादन (खंड)",
-       "editingcomment": "$1 à¤¸à¤®à¥\8dपादन (नया à¤\85नà¥\81भाà¤\97)",
-       "editconflict": "सà¤\82पादन à¤\85à¤\82तरà¥\8dविरोध: $1",
-       "explainconflict": "à¤\86पà¤\95à¥\80 à¤¸à¤\82पादन à¤¶à¥\81रà¥\82 à¤\95à¤\87ला à¤\95à¥\80 à¤¬à¤¾à¤¦ à¤¸à¥\87 à¤\95à¥\87हà¥\82 à¤\85à¤\89रà¥\80 à¤\8f à¤ªà¤¨à¥\8dना à¤®à¥\87à¤\82 à¤¬à¤¦à¤²à¤¾à¤µ à¤\95 à¤\9aà¥\81à¤\95ल à¤¬à¤¾à¤\9fà¥\87।\nà¤\8aपर à¤\95à¥\87 à¤ªà¤¾à¤  à¤¹à¤¿à¤¸à¥\8dसा à¤®à¥\87à¤\82 à¤²à¥\87à¤\96 à¤\95à¥\80 à¤ªà¤¾à¤  à¤\95à¥\87 à¤µà¤°à¥\8dतमान à¤¸à¥\8dथिति à¤¦à¥\87à¤\96ावल à¤\9cात à¤¬à¤¾à¥¤\nराà¤\89र à¤¸à¤\82पादन à¤¨à¥\80à¤\9aà¥\87 à¤\95à¥\80 पाठ हिस्सा में देखावल गइल बा।\nरउआँ के आपन बदलाव एह पहिले से मौजूद पाठ में मिलावे के परी।\n<strong>खाली</strong> ऊपर की पाठ हिस्सा में लउकत पाठ सहेजल जाई अगर आप \"{{int:savearticle}}\" बटन दबाइब।",
-       "yourtext": "राउर पाठ्य",
-       "storedversion": "सà¥\81रà¤\95à¥\8dषित à¤\95रल à¤\97à¤\88ल संशोधन",
+       "editingcomment": "$1 à¤¸à¤\82पादन (नया à¤\96à¤\82ड)",
+       "editconflict": "सà¤\82पादन à¤\85à¤\82तरà¥\8dबिरोध: $1",
+       "explainconflict": "à¤\86पà¤\95à¥\87 à¤¦à¥\8dवारा à¤¸à¤\82पादन à¤¸à¥\81रà¥\82 à¤\95à¤\87ला à¤\95à¥\87 à¤¬à¤¾à¤¦ à¤¸à¥\87 à¤\95à¥\87हà¥\82 à¤\85à¤\89रà¥\80 à¤\8f à¤ªà¤¨à¥\8dना à¤®à¥\87à¤\82 à¤¬à¤¦à¤²à¤¾à¤µ à¤\95 à¤\9aà¥\81à¤\95ल à¤¬à¤¾à¤\9fà¥\87।\nà¤\8aपर à¤\95à¥\87 à¤ªà¤¾à¤  à¤¹à¤¿à¤¸à¥\8dसा à¤®à¥\87à¤\82 à¤²à¥\87à¤\96 à¤\95à¥\87 à¤ªà¤¾à¤  à¤\95à¥\87 à¤µà¤°à¥\8dतमान à¤¸à¥\8dथिति à¤¦à¥\87à¤\96ावल à¤\9cात à¤¬à¤¾à¥¤\nराà¤\89र à¤¸à¤\82पादन à¤¨à¥\80à¤\9aà¥\87 à¤\95à¥\87 पाठ हिस्सा में देखावल गइल बा।\nरउआँ के आपन बदलाव एह पहिले से मौजूद पाठ में मिलावे के परी।\n<strong>खाली</strong> ऊपर की पाठ हिस्सा में लउकत पाठ सहेजल जाई अगर आप \"{{int:savearticle}}\" बटन दबाइब।",
+       "yourtext": "राउर पाठ",
+       "storedversion": "सà¥\81रà¤\95à¥\8dषित à¤\95à¤\87ल à¤\97à¤\87ल संशोधन",
        "nonunicodebrowser": "<strong>चेतावनी: राउर ब्राउसर युनिकोड समर्थ नइखे।</strong>\nपन्ना सभ के सुरक्षित संपादित करे के एगो तरीका सुझावल जात बा: गैर-ASCII अक्षर सभ संपादन बॉक्स में हेक्साडेसिमल कोड की रूप में देखावल जाई।",
        "editingold": "<strong>चेतावनी: रउआँ ए पन्ना क एगो पुरान अवतरण के संपादन करत बानी।</strong>\nअगर आप एकरा के सहेज देइब, त एकरी बाद के सगरी बदलाव गायब हो जाई।",
        "yourdiff": "अंतर",
        "templatesusedpreview": "इ पुर्वावलोकन में प्रयुक्त {{PLURAL:$1|टेम्पलेट|टेम्पलेट कुल}}:",
        "templatesusedsection": "एह खण्ड में इस्तेमाल {{PLURAL:$1|टेम्पलेट|कुल}}:",
        "template-protected": "(सुरक्षित)",
-       "template-semiprotected": "(à¤\95à¥\81à¤\9b-सुरक्षित)",
+       "template-semiprotected": "(à¤\86धा-सुरक्षित)",
        "hiddencategories": "ई पन्ना {{PLURAL:$1|1 छिपल श्रेणी|$1 छिपल श्रेणीसभ}} के सदस्य बा:",
        "nocreatetext": "{{SITENAME}} नया पन्ना बनावे पर रोक लगवले बा।\nपीछे जाईं आ पहिले से बनल पन्ना संपादित करीं या फिर [[Special:UserLogin|लॉगिन करीं या नया खाता बनाईं]]।",
-       "nocreate-loggedin": "नया पन्ना बनावे रउआ अधिकार नइखे।",
-       "sectioneditnotsupported-title": "अनुभाग सम्पादन समर्थित नइखे",
-       "sectioneditnotsupported-text": "इ पन्ना पर अनुभाग सम्पादन समर्थित नइखे",
-       "permissionserrors": "अनुमति त्रुटी",
-       "permissionserrorstext": "निम्नलिखित {{PLURAL:$1|कारण|कारणन}} के चलते आपके अइसन करे के अनुमति नइखे:",
-       "permissionserrorstext-withaction": "नीचे दिहल {{PLURAL:$1|कारण|कारणन}} से रउआँ के $2 के परमीशन नइखे:",
+       "nocreate-loggedin": "रउआँ के नया पन्ना बनावे के अधिकार नइखे।",
+       "sectioneditnotsupported-title": "खंड संपादन समर्थित नइखे",
+       "sectioneditnotsupported-text": "एह पन्ना पर खंड संपादन समर्थित नइखे",
+       "permissionserrors": "परमीशन खराबी",
+       "permissionserrorstext": "नीचे दिहल {{PLURAL:$1|कारण|कारणन}} के चलते आपके अइसन करे के परमीशन नइखे:",
+       "permissionserrorstext-withaction": "नीचे दिहल {{PLURAL:$1|कारण|कारणन}} के चलते रउआँ के $2 के परमीशन नइखे:",
+       "contentmodelediterror": "रउआँ एह अवतरण के संपादन नइखीं कर सकत काहें से कि एकर सामग्री मॉडल <code>$1</code> बा जवन पन्ना के के वर्तमान मॉडल <code>$2</code> से अलग बाटे।",
        "recreate-moveddeleted-warn": "<strong>चेतावनी: रउआँ एगो अइसन पन्ना दुबारा बनावे जा रहल बानी जेवन पहिले हटावल जा चुकल बा</strong>\n\nआपके ई बिचार क लेवे के चाहीं की आगे संपादन कइल ठीक बा की ना।\n\nसुविधा खातिर, ए पन्ना के हटवले आ स्थानांतरण के लॉग नीचे दिहल जात बा:",
        "moveddeleted-notice": "ई पन्ना हटा दिहल गइल बा।\nसंदर्भ खातिर हटावे आ स्थानांतरण के लॉग नीचे दिहल जात बाटे।",
        "log-fulllog": "पूरा लॉग देखीं",
        "edit-hook-aborted": "संपादन के हुक निरस्त क दिहलस।\nई कौनों कारन ना बतवलस।",
        "edit-gone-missing": "पन्ना अपडेट ना हो पावल।\nबुझात बा कि ई हटा दिहल गइल बा।",
-       "edit-conflict": "सà¤\82पादन à¤\85à¤\82तरà¥\8dविरोध",
-       "edit-no-change": "à¤\86पà¤\95à¥\87 à¤¸à¤®à¥\8dपादन à¤ªà¤° à¤§à¤¿à¤¯à¤¾à¤¨ à¤¨à¤¾ à¤¦à¤¿à¤¹à¤² à¤\97à¤\87ल à¤\95ाहà¥\87à¤\82 à¤¸à¥\87 à¤\95à¥\80 à¤ªà¤¾à¤  à¤®à¥\87à¤\82 à¤\95à¥\8cनà¥\8bà¤\82 à¤¬à¤¦à¤²à¤¾à¤µ à¤¨à¤¾ à¤\95à¤\87ल à¤\97à¤\87ल à¤°à¤¹ल।",
-       "postedit-confirmation-created": "पनà¥\8dना à¤¬à¤¨à¤¾ à¤¦à¤¿à¤¹à¤² à¤\97à¤\88ल।",
+       "edit-conflict": "सà¤\82पादन à¤\85à¤\82तरà¥\8dबिरोध",
+       "edit-no-change": "पाठ à¤®à¥\87à¤\82 à¤\95à¥\8cनà¥\8bà¤\82 à¤\85à¤\82तर à¤¨à¤¾ à¤¹à¥\8bà¤\96à¥\87 à¤\95à¥\87 à¤\95ारण à¤°à¤¾à¤\89र à¤¸à¤\82पादन à¤ªà¤° à¤§à¤¿à¤¯à¤¾à¤¨ à¤¨à¤¾ à¤¦à¤¿à¤¹à¤² à¤\97à¤\87ल।",
+       "postedit-confirmation-created": "पनà¥\8dना à¤¬à¤¨à¤¾ à¤¦à¤¿à¤¹à¤² à¤\97à¤\87ल।",
        "postedit-confirmation-restored": "पन्ना के दुबारा अस्थापित कइल गइल।",
-       "postedit-confirmation-saved": "राà¤\89र à¤¸à¤®à¥\8dपादन à¤¸à¥\81रà¤\95à¥\8dषित à¤\95र à¤¦à¤¿à¤¹à¤² à¤\97à¤\88ल।",
+       "postedit-confirmation-saved": "राà¤\89र à¤¸à¤\82पादन à¤¸à¤¹à¥\87à¤\9c à¤¦à¤¿à¤¹à¤² à¤\97à¤\87ल।",
        "edit-already-exists": "नया पन्ना ना बनावल जा सकत बा।\nई पहिलहीं से मौजूद बाटे।",
-       "defaultmessagetext": "संदेश के डिफ़ॉल्ट पाठ्य",
-       "content-failed-to-parse": "$2 के सामग्री, $1 मॉडल खातिर पार्स (parse) ना हो पावल: $3",
-       "invalid-content-data": "अवैध डाटा सामग्री",
-       "content-not-allowed-here": "\"$1\" सामग्री, पन्ना [[$2]] पर ना डालल जा सकेला।",
-       "editwarning-warning": "ए पन्ना के छोड़ के हटला पर आपके कइल बदलाव गायब हो जाई।\nअगर आप लॉगिन कइले बानी तब ए चेतावनी के अपनी सेटिंग में \"{{int:prefs-editing}}\" खंड में जा के बन्द क सकत बानीं।",
+       "defaultmessagetext": "डिफॉल्ट संदेस पाठ",
+       "content-failed-to-parse": "$2 के सामग्री, $1 मॉडल खातिर प्राप्त (पार्स) ना हो पावल: $3",
+       "invalid-content-data": "अवैध सामग्री डाटा",
+       "content-not-allowed-here": "पन्ना [[$2]] पर \"$1\" सामग्री डाले के इजाजत नइखे।",
+       "editwarning-warning": "ए पन्ना के छोड़ के हटला पर आपके द्वारा कइल बदलाव गायब हो सके लें।\nअगर आप लॉगिन कइले बानी तब ए चेतावनी के अपनी सेटिंग में \"{{int:prefs-editing}}\" खंड में जा के बंद कर सकत बानीं।",
+       "editpage-invalidcontentmodel-title": "सामग्री मॉडल सपोर्टेड नइखे",
+       "editpage-invalidcontentmodel-text": "सामग्री मॉडल \"$1\" सपोर्टेड नइखे।",
        "editpage-notsupportedcontentformat-title": "सामग्री के फॉरमैट सपोर्टेड नइखे।",
-       "editpage-notsupportedcontentformat-text": "सामà¤\97à¥\8dरà¥\80 à¤«à¥\89रमà¥\88à¤\9f $1 à¤\95à¥\87 à¤¸à¤¾à¤®à¤\97à¥\8dरà¥\80 à¤®à¥\89डल $2 à¤¸à¤ªà¥\8bरà¥\8dà¤\9f à¤¨à¤\87à¤\96à¥\87 à¤\95रत।",
-       "content-model-wikitext": "विà¤\95à¥\80पाठà¥\8dय",
-       "content-model-text": "सामानà¥\8dय पाठ",
+       "editpage-notsupportedcontentformat-text": "सामà¤\97à¥\8dरà¥\80 à¤®à¥\89डल $2 à¤¦à¥\8dवारा à¤¸à¤¾à¤®à¤\97à¥\8dरà¥\80 à¤«à¥\89रमà¥\88à¤\9f $1 à¤¸à¤ªà¥\8bरà¥\8dà¤\9fà¥\87ड à¤¨à¤\87à¤\96à¥\87।",
+       "content-model-wikitext": "विà¤\95िपाठ",
+       "content-model-text": "à¤\86म पाठ",
        "content-model-javascript": "जावास्क्रिप्ट",
        "content-model-css": "सी॰एस॰एस",
-       "content-json-empty-object": "खाली चीज (Empty object)",
-       "content-json-empty-array": "खाली अरे (Empty array)",
+       "content-json-empty-object": "खाली चीज (एम्प्टी ऑब्जेक्ट)",
+       "content-json-empty-array": "खाली ऍरे",
+       "deprecated-self-close-category-desc": "पन्ना में अवैध सेल्फ-क्लोज्ड ऍचटीऍमऍल टैग बाड़ें, जइसे कि <code>&lt;b/></code> या फिर <code>&lt;span/></code>। जल्दिये इनहन के बेहवार ऍचटीऍमऍल5 स्पेसिफिकेशन के साथ सामंजस्य वाला होखे खातिर बदल जाई, एही से इनहन के विकिपाठ में प्रयोग खाराबीयुक्त बाटे।",
        "duplicate-args-warning": "<strong>चेतावनी:</strong> [[:$1]], [[:$2]] के \"$3\" पैरामीटर खातिर एक से अधिका वैल्यू की संघे काल करत बाटे। दिहल गइल वैल्यू में से खाली सबसे आखिरी वैल्यू के प्रयोग कइल जाई।",
        "duplicate-args-category": "टेम्पलेट कॉल में डुप्लिकेट तर्क इस्तेमाल वाला पन्ना",
        "duplicate-args-category-desc": "पन्ना पर अइसन टेम्पलेट काल मौजूद बा जेवन डुप्लीकेट (दोहरा) आर्गुमेंट इस्तेमाल करत बाटे, जइसे की <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> या <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "<strong>चेतावनी:</strong> ई पन्ना बहुत ढेर सारा  खर्चीला पार्सर फंक्शन काल के इस्तेमाल करत बा।\n\nए पन्ना पर $2 {{PLURAL:$2|काल|काल कुल}} से कम संख्या में काल होखे के चाहीं, बाकी इहाँ ए समय {{PLURAL:$1|$1 काल बा|$1 काल कुल बाड़ी}}।",
        "expensive-parserfunction-category": "बहुत ढेर खर्चीला पार्सर फंक्शन काल वाला पन्ना सभ",
-       "post-expand-template-inclusion-warning": "'''à¤\9aà¥\87तावनà¥\80:''' à¤\96ाà¤\81à¤\9aा à¤\9cà¥\8bड़à¥\87 à¤\95à¥\87 à¤¸à¥\80मा à¤ªà¤¾à¤° à¤¹à¥\8b à¤\9aà¥\81à¤\95ल à¤¬à¤¾à¥¤\nà¤\95à¥\81à¤\9b à¤\96ाà¤\81à¤\9aा à¤¨à¤¾ à¤\9cà¥\8bड़ल à¤\9cाà¤\88।",
-       "post-expand-template-inclusion-category": "à¤\85à¤\87सन à¤ªà¥\83षà¥\8dठ à¤\9cà¥\87 à¤ªà¤° à¤¸à¤¾à¤\81à¤\9aा à¤\9cà¥\8bडे के सीमा पार हो गइल बा",
+       "post-expand-template-inclusion-warning": "'''à¤\9aà¥\87तावनà¥\80:''' à¤\9fà¥\87मà¥\8dपलà¥\87à¤\9f à¤\9cà¥\8bड़à¥\87 à¤\95à¥\87 à¤¸à¥\80मा à¤ªà¤¾à¤° à¤¹à¥\8b à¤\9aà¥\81à¤\95ल à¤¬à¤¾à¥¤\nà¤\95à¥\81à¤\9b à¤\9fà¥\87मà¥\8dपलà¥\87à¤\9f à¤¸à¤¾à¤®à¤¿à¤² à¤¨à¤¾ à¤¹à¥\8bà¤\96िहà¥\87à¤\82।",
+       "post-expand-template-inclusion-category": "पनà¥\8dना à¤\9cहाà¤\81 à¤\9fà¥\87मà¥\8dपलà¥\87à¤\9f à¤¸à¤¾à¤®à¤¿à¤² à¤\95रे के सीमा पार हो गइल बा",
        "post-expand-template-argument-warning": "<strong>चेतावनी:</strong> ए पन्ना पर कम से कम एक ठो अइसन टेम्पलेट आर्गुमेंट बा जेवन बहुत बड़ खर्चीला साइज के बा।\nअइसन आर्गुमेंट के लोप कइ दिहल गइल बा।",
        "post-expand-template-argument-category": "पन्ना जिनहन में लोप कइल गइल टेम्पलेट आर्गुमेंट बा",
        "parser-template-loop-warning": "टेम्पलेट लूप पकड़ में आइल बा:[[$1]]",
        "expansion-depth-exceeded-warning": "पन्ना अधिकतम बिस्तार गहिराई के पार क गइल",
        "parser-unstrip-loop-warning": "अनस्ट्रिप लूप पकड़ में आइल बा",
        "parser-unstrip-recursion-limit": "अनस्ट्रिप रिकर्शन सीमा पार हो गइल ($1)",
-       "converter-manual-rule-error": "मà¥\88नà¥\81à¤\85ल à¤­à¤¾à¤·à¤¾ à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤¨à¤¿à¤¯à¤® à¤®à¤¬ खराबी पकड़ल गइल",
+       "converter-manual-rule-error": "मà¥\88नà¥\81à¤\85ल à¤­à¤¾à¤·à¤¾ à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤¨à¤¿à¤¯à¤® à¤®à¥\87à¤\82 खराबी पकड़ल गइल",
        "undo-success": "संपादन वापस कइल जा सकत बा।\nनीचे दिहल तुलना के चेक करीं आ पुष्टी करीं की आप इहे कइल चाहत बाड़ीं, ओकरा बाद बदलाव सहेज के संपादन वापसी के पूरा करीं।",
        "undo-failure": "बीच में अउरी संपादन होखला की कारण ई संपादन वापस नइखे लिहल जा सकत।",
        "undo-norev": "संपादन वापस नइखे लिहल जा सकत, काहें से की या त ई हइये नइखे या हटा दिहल गइल बाटे।",
        "undo-nochange": "लागत बा की ई संपादन पहिलहीं वापस लिहल जा चुकल बाटे।",
-       "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|वारà¥\8dता]]) à¤\95à¥\87 à¤¦à¥\8dवारा à¤\95à¤\87ल $1 à¤¬à¤¦à¤²à¤¾à¤µ à¤\95à¥\87 वापस कइल गइल",
-       "undo-summary-username-hidden": "à¤\8fà¤\97à¥\8b छिपल सदस्य द्वारा कइल बदलाव $1 वापस कइल गइल",
-       "cantcreateaccount-text": "एह आइपी पता (IP address)(<strong>$1</strong>) द्वारा नया खाता बनावे पर  [[User:$3|$3]] द्वारा रोक लगावल गइल बा।\n\nएकरा खातिर $3 के दिहल कारण:<em>$2</em>",
+       "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|वारà¥\8dता]]) à¤\95à¥\87 à¤\95à¤\87ल $1 à¤¬à¤¦à¤²à¤¾à¤µ वापस कइल गइल",
+       "undo-summary-username-hidden": "à¤\95à¥\87हà¥\82 छिपल सदस्य द्वारा कइल बदलाव $1 वापस कइल गइल",
+       "cantcreateaccount-text": "एह आइपी पता (IP address)(<strong>$1</strong>) द्वारा नया खाता बनावे पर [[User:$3|$3]] द्वारा रोक लगावल गइल बा।\n\nएकरा खातिर $3 के दिहल कारण:<em>$2</em>",
        "cantcreateaccount-range-text": "आइपी पता बिस्तार (IP address range) <strong>$1</strong> पर, जेवना में आपके आइपी (<strong>$4</strong>) भी बा, नया खाता बनावे पर [[User:$3|$3]] द्वारा रोक लगावल गइल बा।\n\nएकरा खातिर $3 के दिहल कारण बा:<em>$2</em>",
        "viewpagelogs": "ए पन्ना खातिर लॉग कुल देखीं",
        "nohistory": "ए पन्ना के कौनों संपादन इतिहास नइखे",
        "currentrev": "सबसे नया बदलाव",
        "currentrev-asof": "$1 ले भइल नया बदलाव",
        "revisionasof": "$1 ले भइल नया बदलाव",
-       "revision-info": "{{GENDER:$6|$2}}$7 à¤\95à¥\87 à¤¦à¥\8dवारा $1 à¤\95à¥\87 à¤¸à¤\82शà¥\8bधन",
-       "previousrevision": "â\86\90 à¤ªà¥\81रान à¤¸à¤\82शà¥\8bधन",
-       "nextrevision": "नया à¤¸à¤\82सà¥\8bधन →",
+       "revision-info": "{{GENDER:$6|$2}}$7 à¤\95à¥\87 à¤¦à¥\8dवारा $1 à¤\95à¥\87 à¤¬à¤¦à¤²à¤¾à¤µ",
+       "previousrevision": "â\86\90 à¤ªà¥\81रान à¤¬à¤¦à¤²à¤¾à¤µ",
+       "nextrevision": "नया à¤¬à¤¦à¤²à¤¾à¤µ →",
        "currentrevisionlink": "हाल के संसोधन",
        "cur": "हाल",
        "next": "अगिला",
        "last": "पछिला",
        "page_first": "पहिलका",
        "page_last": "आखिरी",
-       "histlegend": "à¤\9aà¥\81नाव à¤\85नà¥\8dतर: à¤¤à¥\81लना à¤\95रà¥\87 à¤\96ातिर à¤¸à¤\82शà¥\8bधन à¤\95à¥\87 à¤°à¥\87डियà¥\8b à¤¬à¤\9fन à¤ªà¤° à¤¨à¤¿à¤¶à¤¾à¤¨ à¤²à¤\97ाà¤\88à¤\82 à¤\86 enter à¤¬à¤\9fन à¤¦à¤¬à¤¾à¤\88à¤\82 à¤\86 à¤\9aाहà¥\87 à¤¨à¤¿à¤\9aला à¤¬à¤\9fन à¤¦à¤¬à¤¾à¤\88à¤\82।<br />\nLegend: '''({{int:cur}})''' = à¤¹à¤¾à¤² à¤\95à¥\87 à¤¸à¤\82शà¥\8bधन à¤\95à¥\87 à¤¸à¤¾à¤¥ à¤\85à¤\82तर, '''({{int:last}})''' = à¤ªà¥\81रà¥\8dववरà¥\8dतà¥\80 à¤¸à¤\82शà¥\8bधन à¤\95à¥\87 à¤¸à¤¾à¤¥ à¤\85à¤\82तर, '''{{int:minoreditletter}}''' = à¤\9bà¥\8bà¤\9f à¤¸à¤®à¥\8dपादन।",
-       "history-fieldset-title": "à¤\87तिहास à¤¨à¤¿à¤¹à¤¾à¤°ीं",
+       "histlegend": "à¤\85à¤\82तर à¤¬à¥\80à¤\9bà¥\80à¤\82: à¤¤à¥\81लना à¤¦à¥\87à¤\96à¥\87 à¤\96ातिर à¤¬à¤¦à¤²à¤¾à¤µà¤¨ à¤\95à¥\87 à¤°à¥\87डियà¥\8b à¤¬à¤\9fन à¤\9aिनà¥\8dहित à¤\95रà¥\80à¤\82 à¤\86 à¤\8fà¤\82à¤\9fर à¤¯à¤¾ à¤«à¤¿à¤° à¤¨à¥\80à¤\9aà¥\87 à¤¦à¤¿à¤¹à¤² à¤¬à¤\9fन à¤¦à¤¬à¤¾à¤\88à¤\82।<br />\nसà¤\82à¤\95à¥\87त: <strong>({{int:cur}})</strong> = à¤¸à¤­à¤¸à¥\87 à¤¨à¤¯à¤¾ à¤¬à¤¦à¤²à¤¾à¤µ à¤\95à¥\87 à¤¸à¤¾à¤¥ à¤\85à¤\82तर, <strong>({{int:last}})</strong> = à¤ªà¤\9bिला à¤¬à¤¦à¤²à¤¾à¤µ à¤\95à¥\87 à¤¸à¤¾à¤¥ à¤\85à¤\82तर, <strong>{{int:minoreditletter}}</strong> = à¤\9bà¥\8bà¤\9f à¤¸à¤\82पादन।",
+       "history-fieldset-title": "à¤\87तिहास à¤¦à¥\87à¤\96ीं",
        "history-show-deleted": "खाली मेटावल",
        "histfirst": "सबसे पुरान",
        "histlast": "सबसे नया",
        "historysize": "({{PLURAL:$1|1 बाइट|$1 बाइट}})",
        "historyempty": "(खाली)",
-       "history-feed-title": "सà¤\82शà¥\8bधन इतिहास",
-       "history-feed-description": "विà¤\95ि à¤ªà¤° à¤\87 पन्ना के संशोधन के इतिहास",
+       "history-feed-title": "बदलाव इतिहास",
+       "history-feed-description": "विà¤\95ि à¤ªà¤° à¤\8fह पन्ना के संशोधन के इतिहास",
        "history-feed-item-nocomment": "$1 $2 पर",
-       "history-feed-empty": "à¤\85नà¥\81रà¥\8bध à¤\95रल à¤\97à¤\88ल à¤ªà¤¨à¥\8dना à¤\89पलबà¥\8dध à¤¨à¤\88à¤\96à¥\87। à¤¹à¥\8b à¤¸à¤\95त à¤¬à¤¾ à¤\89 à¤\95à¥\87 à¤µà¤¿à¤\95ि à¤ªà¤° à¤¸à¥\87 à¤®à¤¿à¤\9fा à¤¦à¤¿à¤¹à¤² à¤\97à¤\88ल à¤¹à¥\8bà¤\96à¥\87, à¤\86 à¤\9aाहà¥\87 à¤\89 à¤\95à¥\87 à¤¨à¤¾à¤® à¤¬à¤¦à¤² à¤¦à¥\87वल à¤\97à¤\88ल à¤¹à¥\8bà¤\96à¥\87।\nपà¥\8dरासà¤\82à¤\97िà¤\95 à¤ªà¤¨à¥\8dना à¤\95à¥\87 [[Special:Search|विà¤\95ि à¤ªà¤° à¤\96à¥\8bà¤\9cà¥\87 à¤\95à¥\87]] à¤\95à¥\8bशिश à¤\95रत à¤°à¤¹ीं।",
+       "history-feed-empty": "à¤\85नà¥\81रà¥\8bध à¤\95रल à¤\97à¤\87ल à¤ªà¤¨à¥\8dना à¤\89पलबà¥\8dध à¤¨à¤\87à¤\96à¥\87। à¤¹à¥\8b à¤¸à¤\95त à¤¬à¤¾ à¤\8fà¤\95रा à¤\95à¥\87 à¤µà¤¿à¤\95ि à¤ªà¤° à¤¸à¥\87 à¤¹à¤\9fा à¤¦à¤¿à¤¹à¤² à¤\97à¤\87ल à¤¹à¥\8bà¤\96à¥\87, à¤¯à¤¾ à¤\8fà¤\95र à¤¨à¤¾à¤\81व à¤¬à¤¦à¤²à¤² à¤\97à¤\87ल à¤¹à¥\8bà¤\96à¥\87।\nपà¥\8dरसà¤\82à¤\97 à¤\85नà¥\81सार à¤¨à¤¯à¤¾ à¤ªà¤¨à¥\8dना à¤\8fह [[Special:Search|विà¤\95ि à¤ªà¤° à¤\96à¥\8bà¤\9cà¥\87 à¤\95à¥\87]] à¤\95à¥\8bशिश à¤\95रीं।",
        "history-edit-tags": "सेलेक्ट कइल बदलाव खातिर संपादन टैग",
-       "rev-deleted-comment": "(समà¥\8dपादन à¤¸à¤¾à¤°à¤¾à¤\82श à¤¹à¤\9fावल à¤\97à¤\88ल)",
-       "rev-deleted-user": "(पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤\95à¥\87 à¤¨à¤¾à¤® à¤®à¤¿à¤\9fा à¤¦à¤¿à¤¹à¤² à¤\97à¤\88ल बा)",
-       "rev-deleted-event": "(लà¥\89à¤\97 à¤µà¤¿à¤µà¤°à¤£ à¤¹à¤\9fा à¤¦à¤¿à¤¹à¤² à¤\97à¤\88ल बा)",
-       "rev-deleted-user-contribs": "[पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤¨à¤¾à¤® à¤\86 à¤\9aाहà¥\87 à¤\86à¤\87 à¤ªà¥\80 à¤ªà¤¤à¤¾ à¤¹à¤\9fा à¤¦à¤¿à¤¹à¤² à¤\97à¤\88ल à¤¬à¤¾ - à¤¯à¥\8bà¤\97दान à¤¸à¥\87 à¤¸à¤®à¥\8dपादन à¤\9bà¥\81प à¤\97à¤\88ल बा]",
+       "rev-deleted-comment": "(समà¥\8dपादन à¤¸à¤¾à¤°à¤¾à¤\82श à¤¹à¤\9fावल à¤\97à¤\87ल)",
+       "rev-deleted-user": "(पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤\95à¥\87 à¤¨à¤¾à¤\81व à¤®à¤¿à¤\9fा à¤¦à¤¿à¤¹à¤² à¤\97à¤\87ल बा)",
+       "rev-deleted-event": "(लà¥\89à¤\97 à¤µà¤¿à¤µà¤°à¤£ à¤¹à¤\9fा à¤¦à¤¿à¤¹à¤² à¤\97à¤\87ल बा)",
+       "rev-deleted-user-contribs": "[पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤¨à¤¾à¤® à¤¯à¤¾ à¤\86à¤\87पà¥\80 à¤ªà¤¤à¤¾ à¤¹à¤\9fा à¤¦à¤¿à¤¹à¤² à¤\97à¤\87ल à¤¬à¤¾ - à¤¯à¥\8bà¤\97दान à¤²à¤¿à¤¸à¥\8dà¤\9f à¤¸à¥\87 à¤¸à¤\82पादन à¤\9bिप à¤\97à¤\87ल बा]",
        "rev-deleted-text-permission": "ई पन्ना के संशोधन '''मिटा'''' दिहल गईल बा।\nमेटावल जानकारी [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} डिलेशन लॉग] में मिली।",
        "rev-suppressed-text-permission": "ए पन्ना के बदलाव<strong>दबा दिहल गइल बा</strong>।\nबिस्तृत जानकारी [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} दबावल चीज के लॉग] पर मिल जाई।",
        "rev-deleted-text-unhide": "पन्ना पर क ई बदलाव <strong>हटा दिहल गइल बा</strong>।\nएकर डिटेल जानकारी [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} हटवले के लॉग] में मिल सकेला।\nअभी भी आप [$1 ई बदलाव देख सकत बानी]  अगर आप आगे देखल चाहत होखीं।",
        "searchprofile-everything-tooltip": "सब जगह खोजीं (बातचीत पन्ना सहित)",
        "searchprofile-advanced-tooltip": "विशेष नामस्थान में खोजीं",
        "search-result-size": "$1 ({{PLURAL:$2|1 शब्द|$2 शब्द}})",
-       "search-redirect": "(अनुप्रेषण$1)",
+       "search-redirect": "($1 से अनुप्रेषित)",
        "search-section": "(खंड $1)",
        "search-category": "(श्रेणी $1)",
        "search-suggest": "का राउर मतलब बा: $1",
        "rightslogtext": "ई सदस्यन के सदस्य-अधिकार के बदलाव के लॉग बा",
        "action-read": "ई पन्ना पढ़ीं",
        "action-edit": "ई पन्ना संपादित करीं",
-       "action-createpage": "पन्ना बनाईं",
-       "action-createtalk": "वारà¥\8dता पन्ना बनाईं",
+       "action-createpage": "à¤\88 à¤ªà¤¨à¥\8dना à¤¬à¤¨à¤¾à¤\88à¤\82",
+       "action-createtalk": "à¤\88 à¤¬à¤¾à¤¤à¤\9aà¥\80त पन्ना बनाईं",
        "action-createaccount": "ई सदस्यखाता बनाईं",
        "action-history": "ए पन्ना के इतिहास देखीं",
        "action-minoredit": "ए संपादन के छोट चिह्नित करीं",
        "action-delete": "ई पन्ना के मिटाईं",
        "action-unwatchedpages": "ध्यानसूची में जवन पन्ना नइखे ओकर सूची देखीं",
        "enhancedrc-history": "इतिहास",
-       "recentchanges": "तà¥\81रà¤\82त à¤­à¤\87ल बदलाव",
+       "recentchanges": "हाल à¤\95à¥\87 बदलाव",
        "recentchanges-legend": "हाल के बदलाव संबंधी बिकल्प",
        "recentchanges-summary": "ए विकि पर हाल में भइल बदलाव इहाँ देखल जा सकत बा।",
+       "recentchanges-noresult": "दिहल गइल समयअवधि खातिर एह पैमाना पर सही उतरे वाला कौनों बदलाव नइखे।",
+       "recentchanges-feed-description": "एह विकि पर सभसे हालिया बदलाव के एह फीड में निगरानी करीं।",
        "recentchanges-label-newpage": "ए संपादन से एगो नया पन्ना बनल",
        "recentchanges-label-minor": "ई एगो छोट संपादन बा",
        "recentchanges-label-bot": "इ संपादन एगो बॉट द्वारा कइल गइल बा",
        "recentchanges-label-unpatrolled": "ए संपादन के अभिन ले जाँचल नइखे गइल",
-       "recentchanges-label-plusminus": "à¤\8fतना à¤¬à¤¾à¤\87à¤\9fसà¥\8d से पन्ना के साइज बदलल गइल",
+       "recentchanges-label-plusminus": "à¤\8fतना à¤¬à¤¾à¤\87à¤\9fà¥\8dस से पन्ना के साइज बदलल गइल",
        "recentchanges-legend-heading": "<strong>संकेत:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (इहो देखीं [[Special:NewPages|नया पन्नवन के लिस्ट]])",
-       "rclistfrom": "$2, $3 से शुरु नया बदलाव देखाईं",
+       "recentchanges-submit": "देखावल जाय",
+       "rcnotefrom": "<strong>$3, $4</strong> से (<strong>$1</strong> तक ले के) {{PLURAL:$5|बदलाव|बदलाव सभ}} नीचे दिहल गइल बा।",
+       "rclistfrom": "$2, $3 से शुरु होखे वाला नया बदलाव देखावल जाय",
        "rcshowhideminor": "$1 छोट संपादन",
-       "rcshowhideminor-show": "दà¥\87à¤\96ाà¤\88à¤\82",
-       "rcshowhideminor-hide": "à¤\9bिपाà¤\88à¤\82",
+       "rcshowhideminor-show": "दà¥\87à¤\96ावल à¤\9cाय",
+       "rcshowhideminor-hide": "à¤\9bिपावल à¤\9cाय",
        "rcshowhidebots": "बॉट $1",
-       "rcshowhidebots-show": "दà¥\87à¤\96ाà¤\88à¤\82",
-       "rcshowhidebots-hide": "à¤\9bिपाà¤\88à¤\82",
+       "rcshowhidebots-show": "दà¥\87à¤\96ावल à¤\9cाय",
+       "rcshowhidebots-hide": "à¤\9bिपावल à¤\9cाय",
        "rcshowhideliu": "रजिस्टर्ड सदस्य $1",
-       "rcshowhideliu-show": "दà¥\87à¤\96ाà¤\88à¤\82",
-       "rcshowhideliu-hide": "à¤\9bिपाà¤\88à¤\82",
+       "rcshowhideliu-show": "दà¥\87à¤\96ावल à¤\9cाय",
+       "rcshowhideliu-hide": "à¤\9bिपावल à¤\9cाय",
        "rcshowhideanons": "बेनाम सदस्य $1",
-       "rcshowhideanons-show": "दà¥\87à¤\96ाà¤\88à¤\82",
-       "rcshowhideanons-hide": "à¤\9bिपाà¤\88à¤\82",
+       "rcshowhideanons-show": "दà¥\87à¤\96ावल à¤\9cाय",
+       "rcshowhideanons-hide": "à¤\9bिपावल à¤\9cाय",
        "rcshowhidepatr": "जाँचल बदलाव $1",
-       "rcshowhidepatr-show": "दà¥\87à¤\96ाà¤\88à¤\82",
-       "rcshowhidepatr-hide": "à¤\9bिपाà¤\88à¤\82",
+       "rcshowhidepatr-show": "दà¥\87à¤\96ावल à¤\9cाय",
+       "rcshowhidepatr-hide": "à¤\9bिपावल à¤\9cाय",
        "rcshowhidemine": "हमार संपादन $1",
-       "rcshowhidemine-show": "देखाईं",
-       "rcshowhidemine-hide": "छिपाईं",
-       "rclinks": "पछिला $2 दिन में भइल $1 बदलाव देखाईं<br />$3",
-       "diff": "अन्तर",
-       "hist": "इति",
-       "hide": "छिपाईं",
-       "show": "देखाईं",
+       "rcshowhidemine-show": "देखावल जाय",
+       "rcshowhidemine-hide": "छिपावल जाय",
+       "rcshowhidecategorization": "$1 पन्ना श्रेणीकरण",
+       "rcshowhidecategorization-show": "देखावल जाय",
+       "rcshowhidecategorization-hide": "छिपावल जाय",
+       "rclinks": "पछिला $2 दिन में भइल $1 बदलाव देखावल जाय<br />$3",
+       "diff": "अंतर",
+       "hist": "इतिहास",
+       "hide": "छिपावल जाय",
+       "show": "देखावल जाय",
        "minoreditletter": "छो",
        "newpageletter": "न",
        "boteditletter": "बॉ",
-       "number_of_watching_users_pageview": "[$1 देखल जा रहल बा {{PLURAL:$1|प्रयोगकर्ता|प्रयोगकर्ता}}]",
-       "rc_categories": "श्रेणिन के सीमा (\"|\" से अलगा करीं)",
-       "rc_categories_any": "कौनों",
-       "rc-change-size-new": "$1 {{PLURAL:$1|बाइट|बाइट सब}} बदलाव के बाद",
+       "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|प्रयोगकर्ता|प्रयोगकर्ता लोग}} के धियानसूची में बा]",
+       "rc_categories": "श्रेणिन के सीमा (\"|\" से अलगा करीं):",
+       "rc_categories_any": "बीछल में से कौनों एक ठो",
+       "rc-change-size-new": "बदलाव के बाद $1 {{PLURAL:$1|बाइट|बाइट्स}}",
+       "newsectionsummary": "/* $1 */ नया खंड",
+       "rc-enhanced-expand": "डिटेल देखावल जाय",
+       "rc-enhanced-hide": "डिटेल छिपावल जाय",
+       "rc-old-title": "मूल $1 नाँव से बनावल गइल",
        "recentchangeslinked": "संबंधित बदलाव",
-       "recentchangeslinked-feed": "समà¥\8dबनà¥\8dधित बदलाव",
+       "recentchangeslinked-feed": "सà¤\82बà¤\82धित बदलाव",
        "recentchangeslinked-toolbox": "संबंधित बदलाव",
-       "recentchangeslinked-title": "\"$1\" à¤¸à¥\87 à¤¸à¤\82बधी बदलाव",
+       "recentchangeslinked-title": "\"$1\" à¤¸à¤\82बà¤\82धी बदलाव",
        "recentchangeslinked-summary": "ई एगो पन्ना बिसेस से (या एगो श्रेणी बिसेस की सदस्य से) जुड़ल पन्नवन में हाल में भइल बदलाव के एगो लिस्ट हवे। \n[[Special:Watchlist|आपकी धियानसूची]] के पन्ना सब <strong>मोट अच्छर में</strong> लउकत बाटे।",
        "recentchangeslinked-page": "पन्ना नाँव:",
-       "recentchangeslinked-to": "ए पन्ना से जुड़ल पन्नवन मे भइल बदलाव भले देखाईं",
+       "recentchangeslinked-to": "एकरे बजाय ए पन्ना से जुड़ल पन्नवन मे भइल बदलाव देखावल जाय",
+       "recentchanges-page-added-to-category": "[[:$1]] श्रेणी में जोड़ल गइल",
        "upload": "फाइल अपलोड करीं",
        "uploadlogpage": "लदनी (अपलोड) के लॉग",
        "uploadlogpagetext": "नीचे हाल में अपलोड करल गइल फाइलन के सूची बा।\nदृश्य अवलोकन खातिर [[Special:NewFiles|नया फाइलन के गैलरी]] देखीं।",
        "unwatchedpages": "ध्यान न दिहल गइल पन्ना",
        "listredirects": "पुनर्निर्देशन के सूची",
        "unusedtemplates": "बिना प्रयोग के खाँचा",
-       "randompage": "बà¥\87तरतà¥\80ब पन्ना",
+       "randompage": "à¤\95à¥\8cनà¥\8bà¤\82 à¤\8fà¤\97à¥\8b पन्ना",
        "randomincategory": "श्रेणी में अनियमित पन्ना",
        "randomincategory-nopages": "[[:Category:$1|$1]] श्रेणी में कउनो पन्ना नइखे।",
        "randomincategory-category": "श्रेणी:",
        "wantedpages": "पन्ना चाहत बा",
        "wantedfiles": "जरुरत के फाईलसभ",
        "wantedfiletext-nocat-noforeign": "ई फाइल सभ इस्तेमाल में बाटे बाकी मौजूद नइखे।",
-       "wantedtemplates": "जरुरत के खाँचा",
-       "mostlinked": "सबसे ढेर पन्ना-जोड़ वाला",
-       "mostlinkedcategories": "सबसे अधिक से जुड़ल श्रेणीसभ",
-       "mostlinkedtemplates": "सभसे ढेर ट्रांसक्लूजन वाला पन्ना",
-       "mostcategories": "सबसे अधिक श्रेणी वाला पन्नाकुल",
-       "mostimages": "सभसे ढेर फाइल-जोड़ वाला",
-       "mostinterwikis": "सभसे ढेर इंटरविकि वाला पन्ना",
-       "mostrevisions": "सभसे ढेर रिवीजन वाला पन्ना सभ",
-       "prefixindex": "उपसर्ग अनुसार पन्ना",
-       "shortpages": "छोट पन्नासभ",
+       "wantedtemplates": "टेम्पलेट जिनहन के जरूरत बा",
+       "mostlinked": "पन्ना जहाँ सभसे ढेर कड़ी आ के जुड़त बा",
+       "mostlinkedcategories": "सबसे अधिक से जुड़ल श्रेणी",
+       "mostlinkedtemplates": "सभसे ढेर ट्रांसक्लूड पन्ना",
+       "mostcategories": "पन्ना जिनहन पर सभसे ढेर श्रेणी बा",
+       "mostimages": "पन्ना जिनहन पर सभसे ढेर फाइल बा",
+       "mostinterwikis": "पन्ना जिनहन में सभसे ढेर इंटरविकि कड़ी बा",
+       "mostrevisions": "सभसे ढेर बदलाव इतिहास वाला पन्ना",
+       "prefixindex": "सगरी पन्ना जिनहन में उपसर्ग बा",
+       "prefixindex-namespace": "सगरी पन्ना जिनहन में उपसर्ग ($1 नाँवस्थान) बा",
+       "prefixindex-submit": "देखीं",
+       "shortpages": "छोट पन्ना",
        "longpages": "लमहर पन्ना",
-       "deadendpages": "मरल-à¤\96पल पन्ना",
+       "deadendpages": "à¤\85à¤\82तिम à¤\9bà¥\8bर à¤ªà¤° à¤\9bà¥\82à¤\9fल पन्ना",
        "protectedpages": "सुरक्षित पन्ना",
        "protectedpages-noredirect": "अनुप्रेषण छिपाईं",
        "protectedpagesempty": "कौनों पन्ना के सुरक्षा ए पैमान पर नइखे",
        "protectedpages-timestamp": "टाइममोहर",
        "protectedpages-page": "पन्ना",
        "protectedpages-expiry": "एक्सपायर हो जाई",
-       "protectedpages-performer": "सदसà¥\8dय à¤¸à¥\81रà¤\95à¥\8dषा",
+       "protectedpages-performer": "सà¥\81रà¤\95à¥\8dषा à¤²à¤\97ावà¥\87 à¤µà¤¾à¤²à¤¾ à¤¸à¤¦à¤¸à¥\8dय",
        "protectedpages-params": "सुरक्षा पैमाना",
        "protectedpages-reason": "कारण",
+       "protectedpages-submit": "पन्ना देखीं",
        "protectedpages-unknown-timestamp": "नामालूम",
        "protectedpages-unknown-performer": "नामालूम सदस्य",
        "protectedtitles": "सुरक्षित शीर्षक",
        "protectedtitlesempty": "कौनों टाइटिल के सुरक्षा एह पैमान पर नइखे।",
+       "protectedtitles-submit": "शीर्षक देखीं",
        "listusers": "सदस्यसूची",
        "listusers-editsonly": "उहे सदस्य देखाईं जे संपादन कइले होखे",
        "listusers-creationsort": "बनवले की तारीख की हिसाब से सरियाईं",
        "usereditcount": "$1 {{PLURAL:$1|संपादन|संपादन सभ}}",
        "newpages": "नया पन्ना",
        "newpages-username": "सदस्यनाँव:",
-       "ancientpages": "सभन à¤¸à¥\87 à¤ªà¥\81रान à¤ªà¤¨à¥\8dनासभ",
-       "move": "सà¥\8dथानà¥\8dतरण",
-       "movethispage": "à¤\88 à¤ªà¤¨à¥\8dना à¤\95à¥\87 à¤¸à¥\8dथांतरण करीं",
+       "ancientpages": "पà¥\81रान à¤ªà¤¨à¥\8dना",
+       "move": "सà¥\8dथानाà¤\82तरण",
+       "movethispage": "à¤\8fह à¤ªà¤¨à¥\8dना à¤\95à¥\87 à¤¸à¥\8dथानांतरण करीं",
        "suppress": "ओवरसाइटर",
        "apihelp": "एपीआइ (API) मदद",
        "apihelp-no-such-module": "मॉड्युल $1 ना मिलल।",
        "trackingcategories-msg": "निगरानी श्रेणी",
        "trackingcategories-name": "संदेस नाँव",
        "emailuser": "ई प्रयोगकर्ता के ईमेल करीं",
-       "watchlist": "धà¥\8dयानसूची",
+       "watchlist": "धियानसूची",
        "mywatchlist": "धियानसूची",
        "watch": "धियानसूची में डालीं",
        "watchthispage": "ई पन्ना ध्यानसूची में डालीं",
-       "unwatch": "धà¥\8dयानसूची से हटाईं",
+       "unwatch": "धियानसूची से हटाईं",
        "watching": "ध्यानसूची में जाते हुए",
        "unwatching": "ध्यानसूची से हटते हुए",
        "created": "बनावल गईल",
        "actioncomplete": "काम पुरा भइल",
        "dellogpage": "हटवले के लिस्ट",
-       "rollbacklink": "वापिस à¤²à¥\80à¤\82",
+       "rollbacklink": "रà¥\8bलबà¥\88à¤\95",
        "rollbacklinkcount": "रोलबैक $1 {{PLURAL:$1|संपादन|संपादन सब}}",
        "protectlogpage": "सुरक्षा लॉग",
        "protectlogtext": "नीचे पन्ना सुरक्षा में भइल बदलावकुल के सूची बा।\nहाल में सुरक्षित पन्नन के सूची खातिर [[Special:ProtectedPages|सुरक्षित पन्नन के सूची]] देखीं।",
        "undelete": "हटावल पन्ना देखीं",
        "undeletepage": "हटावल पन्ना देखीं आ वापिस ले आईं",
        "undeletelink": "देखीं/बहाल करीं",
-       "namespace": "नामस्थान:",
+       "namespace": "नाà¤\81वस्थान:",
        "invert": "चुनाव पलटीं",
        "tooltip-invert": "चुनल गइल नामस्थान की संघे बदलाव छिपावे खातिर ए बाकस के चिन्हित करीं (सम्बन्धित नामस्थान के भी, अगर चिन्हित होखे)",
        "namespace_association": "संबंधित नामस्थान",
        "mycontris": "हमार योगदान",
        "anoncontribs": "योगदान",
        "nocontribs": "ई मानदंड से मिलत जुलत कौनो बदलाव ना मिलल।",
-       "uctop": "(हाल à¤\95à¥\87)",
+       "uctop": "(वरà¥\8dतमान)",
        "month": "महीना से (आ ओ से पहिले):",
        "year": "साल से (आ ओ से पहिले):",
        "sp-contributions-newbies": "खाली नया खाता के योगदान देखीं।",
        "sp-contributions-newbies-sub": "नया खाता खातिर",
        "sp-contributions-newbies-title": "नया खाता खातिर प्रयोगकर्ता के योगदान।",
-       "sp-contributions-blocklog": "निषà¥\8dà¤\95à¥\8dरà¥\80य à¤\96ाता",
+       "sp-contributions-blocklog": "बà¥\8dलà¥\89à¤\95 à¤²à¥\89à¤\97",
        "sp-contributions-deleted": "नष्ट प्रयोगकर्ता के योगदान।",
-       "sp-contributions-logs": "लà¥\8cग",
-       "sp-contributions-talk": "बात-चीत",
+       "sp-contributions-logs": "लà¥\89ग",
+       "sp-contributions-talk": "बातचीत",
        "sp-contributions-userrights": "प्रयोगकर्ता अधिकार प्रबन्धन",
        "sp-contributions-blocked-notice": "ई प्रयोगकर्ता के ई समय निष्क्रीय करल गईल बा।\nनविनतम नष्ट लौग प्रविष्टी उद्धरण खातिर निचे दिहल बा:",
        "whatlinkshere": "इहाँ का जुड़ल बा",
        "exif-iimcategory": "श्रेणी",
        "exif-orientation-1": "सामान्य",
        "namespacesall": "सगरी",
-       "monthsall": "सब",
-       "confirmemail": "à¤\87-मेल पता कन्फर्म करीं",
+       "monthsall": "सà¤\97रà¥\80",
+       "confirmemail": "à¤\88मेल पता कन्फर्म करीं",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|बात करीं]])",
        "version-no-ext-name": "[अज्ञात नाम]",
        "fileduplicatesearch": "नकल प्रति फाइल खोजीं",
        "logentry-newusers-create": "खाता $1 {{GENDER:$2|बनावल गइल}}",
        "revdelete-summary": "सारांश संपादन",
        "searchsuggest-search": "खोजीं",
-       "api-error-nomodule": "भितरà¥\80 à¤¤à¥\8dरà¥\81à¤\9fी:कउनो अपलोड मॉड्युल सेट नइखे",
-       "expandtemplates": "फà¥\88लल à¤\96ाà¤\81à¤\9aा",
-       "mediastatistics": "मिडिया à¤¤à¤¥à¥\8dयाà¤\82à¤\95"
+       "api-error-nomodule": "भितरà¥\80 à¤\96राबी:कउनो अपलोड मॉड्युल सेट नइखे",
+       "expandtemplates": "à¤\9fà¥\87मà¥\8dपलà¥\87à¤\9f à¤¬à¤¿à¤¸à¥\8dतार",
+       "mediastatistics": "मà¥\80डिया à¤¸à¤¾à¤\82à¤\96à¥\8dयिà¤\95à¥\80"
 }
index 8a0eb59..3e79912 100644 (file)
        "yourname": "Ngaran pamakai:",
        "yourpassword": "Katasunduk:",
        "yourpasswordagain": "Katik pulang katasunduk:",
-       "remembermypassword": "Ingatakan log babuat ulun dalam komputer naya (salawas $1 {{PLURAL:$1|hari|hari}})",
        "yourdomainname": "Domain Pian:",
        "password-change-forbidden": "Pian kada kawa ma-ubah kata sunduk pada wiki ngini.",
        "externaldberror": "Ada kasalahan apakah kacucukan basis data atawa Pian kada bulih mamutakhirakan akun luar.",
        "passwordreset-emailtext-user": "Ada urang (pinanya Pian, matan alamat IP $1) maminta sabuting pangingat hagan rarincian akun Pian gasan {{SITENAME}} ($4). Pamakai barikut {{PLURAL:$3|akun|akun}}\ntarait awan suril:\n\n$2\n\n{{PLURAL:$3|katasunduk pahadangan ngini|kakatasunduk pahadangan ngini}} akan kadaluarsa dalam {{PLURAL:$5|asa hari|$5 hari}}.\nPian parlu babuat log wan mamilih katasunduk hanyar wayah ini jua. Amun urang lain nang maminta ngini, atawa amun Pian sudah paingatan awan katasunduk Pian, wan Pian kada handak maubahnya, Pian kawa kada mahuwal pasan ngini wan manyambung mamuruk katasunduk lawas Pian.",
        "passwordreset-emailelement": "Ngaran pamakai: \n$1\n\nKatasunduk pahadangan: \n$2",
        "passwordreset-emailsentemail": "Sabuting suril pangingat sudah takirim.",
-       "passwordreset-emailsent-capture": "Sabuting suril pangingat sudah dikirim, nangkaya ditampaiakan di bawah.",
-       "passwordreset-emailerror-capture": "Suril paugingat, nang ditampaikan di bawah, hudah dihasilakan, tagal gagal mangirimakannya ka pamakai: $1",
        "changeemail": "Ganti alamat suril",
        "changeemail-header": "Ganti akun alamat suril",
        "changeemail-no-info": "Pian musti babuat log hagan babuat ka tungkaran ngini langsung.",
        "undo-failure": "Babakan ini kada kawa diwalangi karana ada cakutan di tangah babakan-babakan.",
        "undo-norev": "Babakan kada kawa diwalangi karana ini kadada atawa tahapus.",
        "undo-summary": "←Mawalangakan ralatan $1 ulih [[Special:Contributions/$2|$2]] ([[User talk:$2|Pandir]])",
-       "cantcreateaccounttitle": "Akun kada kawa diulah",
        "cantcreateaccount-text": "Paulahan akun matan alamat IP ('''$1''') sudah diblukir ulih [[User:$3|$3]].\n\nAlasan nang dibari ulih $3 adalah ''$2''",
        "viewpagelogs": "Tiringi log tungkaran ini",
        "nohistory": "Kadada halam babakan gasan tungkaran ini.",
        "activeusers-intro": "Ngini adalah sabuah daptar papamuruk sabuah bantuk kagiatan dalam tauncit $1 {{PLURAL:$1|hari|hahari}}.",
        "activeusers-count": "$1 {{PLURAL:$1|babak|babakan}} dalam tauncit {{PLURAL:$3|hari|$3 hahari}}",
        "activeusers-from": "Manampaiakan papamuruk mulai matan:",
-       "activeusers-hidebots": "Sungkupakan bot",
-       "activeusers-hidesysops": "Sungkupakan pambakal",
        "activeusers-noresult": "Kadada papamuruk tatamu.",
        "listgrouprights": "Galambang hak pamuruk",
        "listgrouprights-summary": "Barikut adalah sabuah daptar matan galambang pamuruk nang ada di wiki ngini, lawan hak ungkai masing-masing.\nAda di [[{{MediaWiki:Listgrouprights-helppage}}|tambahan panjalasan]] pasal hak par urangan.",
        "htmlform-submit": "Kirim",
        "htmlform-reset": "Walangi paubahan",
        "htmlform-selectorother-other": "Lain-lain",
-       "sqlite-has-fts": "$1 awan sukungan panggagaian naskah-hibak",
-       "sqlite-no-fts": "$1 kada-awan sukungan panggagaian naskah-hibak",
        "logentry-delete-delete": "$1 mahapus tungkaran $3",
        "logentry-delete-restore": "$1 dibulikakan tungkaran $3",
        "logentry-delete-event": "$1 mangganti kakawaan dijanaki {{PLURAL:$5|sabuah log kajadian|$5 log kajadian}} pintangan $3: $4",
index 4ec9f55..87e4ebe 100644 (file)
        "botpasswords-deleted-title": "বট পাসওয়ার্ড অপসারণ করা হয়েছে",
        "botpasswords-deleted-body": "ব্যবহারকারী \"$2\"-এর \"$1\" নামের বটের জন্য বট পাসওয়ার্ড মুছে ফেলা হয়েছিল।",
        "botpasswords-no-provider": "BotPasswordsSessionProvider উপলব্ধ নয়।",
+       "botpasswords-restriction-failed": "বট পাসওয়ার্ডের সীমাবদ্ধতা এই প্রবেশ প্রতিরোধ করেছে।",
+       "botpasswords-not-exist": "ব্যবহারকারী \"$1\"-এর \"$2\" নামক বট পাসওয়ার্ডটি নেই।",
        "resetpass_forbidden": "পাসওয়ার্ড পরিবর্তন করা সম্ভব নয়",
        "resetpass_forbidden-reason": "পাসওয়ার্ড পরিবর্তন করা যাবে না: $1",
        "resetpass-no-info": "এই পাতাটিতে সরাসরি প্রবেশাধিকার পেতে আপনাকে অবশ্যই প্রবেশ করতে হবে।",
        "passwordreset-emailelement": "ব্যবহারকারী নাম: \n$1\n\nঅস্থায়ী পাসওয়ার্ড: \n$2",
        "passwordreset-emailsentemail": "যদি এই ই-মেইল ঠিকানা আপনার অ্যাকাউন্টের সাথে সংযুক্ত করা থাকে, তাহলে একটি পাসওয়ার্ড বদলের ইমেইল পাঠানো হবে।",
        "passwordreset-emailsentusername": "যদি এই ব্যবহারকারী নামের সাথে ই-মেইল ঠিকানা সংযুক্ত করা থাকে, তাহলে একটি পাসওয়ার্ড বদলের ইমেইল পাঠানো হবে।",
+       "passwordreset-emailsent-capture2": "পাসওয়ার্ড পুনঃধার্যকরণের {{PLURAL:$1|ইমেইল পাঠানো}} হয়েছে। {{PLURAL:$1|ব্যবহারকারী নাম ও পাসওয়ার্ড|ব্যবহারকারী নাম ও পাসওয়ার্ডের তালিকা}} এখানে দেখা যাবে।",
+       "passwordreset-emailerror-capture2": "{{GENDER:$2|ব্যবহারকারীকে}} ইমেইল পাঠানো যায়নি: $1 {{PLURAL:$3|ব্যবহারকারী নাম ও পাসওয়ার্ড|ব্যবহারকারী নাম ও পাসওয়ার্ডের তালিকা}} এখানে দেখা যাবে।",
        "passwordreset-nocaller": "একটি আহ্বানকারী প্রদান করা আবশ্যক",
        "passwordreset-nosuchcaller": "আহ্বানকারীর অস্তিত্ব নেই: $1",
-       "passwordreset-invalideamil": "ভুল ইমেইল ঠিকানা",
+       "passwordreset-ignored": "পাসওয়ার্ড পুনঃধার্যকরণ করা যায়নি। হয়তো কোন প্রদানকারী কনফিগার করা হয়েনি?",
+       "passwordreset-invalidemail": "ভুল ইমেইল ঠিকানা",
        "passwordreset-nodata": "একটি ব্যবহারকারীর নাম বা একটি ইমেল ঠিকানা দুটির একটিও সরবরা দেয়া হয়নি",
        "changeemail": "ই-মেইল ঠিকানা পরিবর্তন বা বাতিল",
        "changeemail-header": "আপনার ইমেল ঠিকানা পরিবর্তন করতে এই ফরমটি পূরণ করুন। আপনি যদি আপনার একাউন্ট থেকে যে কোন ইমেল ঠিকানার এসোসিয়েশন অপসারণ করতে চান, তাহলে ফরমটি জমা দেওয়ার সময় নতুন ইমেইল ঠিকানা খালি রাখুন।",
        "changeemail-no-info": "এই পাতাটিতে সরাসরি প্রবেশাধিকার পেতে আপনাকে অবশ্যই প্রবেশ করতে হবে।",
        "changeemail-oldemail": "বর্তমান ই-মেইল ঠিকানা:",
        "changeemail-newemail": "নতুন ই-মেইল ঠিকানা:",
+       "changeemail-newemail-help": "আপনার ইমেইল ঠিকানা অপসরণ করতে চাইলে এই জায়গাটি ফাঁকা ছেড়ে দেওয়া উচিত। ইমেইল ঠিকানা অপসরণ করলে আপনি ভুলে যাওয়া পাসওয়ার্ড পুনঃধার্য করতে পারবেন না এবং এই উইকি থেকে আপনাকে কোন ইমেইল পাঠানো হবে না।",
        "changeemail-none": "(কিছু নাই)",
        "changeemail-password": "আপনার {{SITENAME}} পাসওয়ার্ড:",
        "changeemail-submit": "ই-মেইল পরিবর্তন",
        "permissionserrors": "অনুমতি ত্রুটিসমূহ",
        "permissionserrorstext": "আপনার এটা করার অনুমতি নেই, নিচের {{PLURAL:$1|টি কারণের|টি কারণের}} জন্য:",
        "permissionserrorstext-withaction": "আপনার $2 অনুমতি নেই, যার {{PLURAL:$1|কারণ|কারণসমূহ}} হল:",
+       "contentmodelediterror": "আপনি এই পুনর্বিবেচনা সম্পাদনা করতে পারবেন না কারণ এর বিষয়বস্তু মডেল <code>$1</code>, যা বর্তমান বিষয়বস্তু মডেল <code>$2</code>-এর থেকে ভিন্ন।",
        "recreate-moveddeleted-warn": "'''সতর্কীকরণ: আপনি এমন একটি পাতা পুনরায় তৈরি করছেন যা পূর্বে অপসারণ করা হয়েছিল।'''\n\nআপনি পাতাটি সম্পাদনা চালিয়ে যাওয়া ঠিক হবে কিনা, তা বিবেচনা করুন।\nআপনার সুবিধার্থে পাতাটির অপলুপ্তি লগ এখানে দেয়া হলো:",
        "moveddeleted-notice": "এই পাতাটি অপসারণ করা হয়েছে।\nসূত্র হিসেবে নিচে এ পাতার অবলুপ্তি লগ দেওয়া হলো।",
        "moveddeleted-notice-recent": "দুঃখিত, এই পাতাটি সাম্প্রতি অপসারিত হয়েছে (সর্বশেষ ২৪ ঘণ্টায়)।\nসূত্র হিসেবে নিচে এই পাতা অপসারণ ও স্থানান্তর লগ দেয়া হয়েছে।",
        "content-not-allowed-here": "\"$1\" কন্টেন্টটি [[$2]] পাতায় অনুমোদিত নয়",
        "editwarning-warning": "এই পাতাটি ত্যাগ করলে আপনার আপনার করা পরিবর্তনগুলো হারিয়ে যেতে পারে।\nআপনি যদি প্রবেশ করা থাকেন, আপনি এই সতর্কীকরণ বার্তাটি আপনার পছন্দের \"সম্পাদনা\" অনুচ্ছেদ থেকে নিস্ক্রিয় করতে পারেন।",
        "editpage-invalidcontentmodel-title": "বিষয়বস্তু মডেল সমর্থিত নয়",
+       "editpage-invalidcontentmodel-text": "এই \"$1\" বিষয়বস্তু মডেলটি অসমর্থিত।",
        "editpage-notsupportedcontentformat-title": "উল্লেখিত পদ্ধতি সমর্থনযোগ্য নয়।",
        "editpage-notsupportedcontentformat-text": "$1 লেখার ফরম্যাট, $2 কন্টেন্ট মডেলের উপযোগী নয়।",
        "content-model-wikitext": "উইকিটেক্সট",
        "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-toobig": "ইতিহাস থেকে আগের পাতাগুলো একীকরণ সম্ভব নয়, কারণ এর ফলে সর্বোচ্চ $1 টি {{PLURAL:$1|সংস্করণ}} স্থানান্তরের সীমানা অতিক্রম করবে।",
        "searchprofile-advanced-tooltip": "স্বনির্ধারিত নামস্থানে অনুসন্ধান করো",
        "search-result-size": "$1 ({{PLURAL:$2|১টি শব্দ|$2টি শব্দ}})",
        "search-result-category-size": "{{PLURAL:$1 |১টি সদস্য |$1টি সদস্য}} ({{PLURAL:$2 |১টি উপবিষয়শ্রেণী|$2টি উপবিষয়শ্রেণী}}, {{PLURAL:$3 |১টি ফাইল |$3টি ফাইল}})",
-       "search-redirect": "(পুনর্নিদেশনা $1)",
+       "search-redirect": "($1 থেকে পুনর্নির্দেশিত)",
        "search-section": "(অনুচ্ছেদ $1)",
        "search-category": "(বিষয়শ্রেণী $1)",
        "search-file-match": "(নথির বিষয়বস্তু মিলে যায়)",
        "userrights-removed-self": "আপনি আপনার নিজের অধিকার পরিবর্তন করেছেন। এর ফলে এখন থেকে আপনি আর এই পাতায় প্রবেশ করতে পারবেন না।",
        "group": "দল:",
        "group-user": "ব্যবহারকারীগণ",
-       "group-autoconfirmed": "সà§\8dবয়à¦\82à¦\95à§\8dরিয়ভাবà§\87 à¦¨à¦¿à¦¶à§\8dà¦\9aিতà¦\95à§\83ত à¦¬à§\8dযবহারà¦\95ারà§\80রা",
+       "group-autoconfirmed": "সà§\8dবয়à¦\82নিশà§\8dà¦\9aিতà¦\95à§\83ত à¦¬à§\8dযবহারà¦\95ারà§\80à¦\97ণ",
        "group-bot": "বট",
        "group-sysop": "প্রশাসক",
        "group-bureaucrat": "ব্যুরোক্র্যাট",
        "right-changetags": "নির্দিষ্ট সংস্করণ এবং দীর্ঘ সম্পাদনাগুলোতে [[Special:Tags|ট্যাগ]] সংযোজন ও অপসারণ করুন",
        "right-deletechangetags": "ডাটাবেজ থেকে [[Special:Tags|ট্যাগ]] অপসারণ করা",
        "grant-group-email": "ইমেইল পাঠান",
+       "grant-group-customization": "অনুকূলকরণ ও পছন্দ",
+       "grant-group-administration": "প্রশাসনিক কাজ সঞ্চালন করুন",
        "grant-group-private-information": "আপনার সম্পর্কিত ব্যক্তিগত তথ্যে প্রবেশাধিকার পায়",
        "grant-group-other": "বিবিধ কার্যকলাপ",
+       "grant-blockusers": "বাধা দেওয়া ও মুক্ত ব্যবহারকারীগণ",
        "grant-createaccount": "অ্যাকাউন্ট তৈরি করুন",
        "grant-createeditmovepage": "পাতা তৈরি, সম্পাদনা এবং স্থানান্তর করুন",
+       "grant-delete": "পাতা, পুনর্বিবেচনা ও লগ ভুক্তিসমূহ মুছে ফেলুন।",
+       "grant-editinterface": "মিডিয়াউইকি নামস্থান এবং ব্যবহারকারীর সিএসএস/জাভাস্ক্রিপ্ট সম্পাদনা করে",
        "grant-editmycssjs": "আপনার সিএসএস/জাভাস্ক্রিপ্ট সম্পাদনা করুন",
        "grant-editmyoptions": "আপনার ব্যবহারকারী পছন্দসমূহ সম্পাদনা করুন",
        "grant-editmywatchlist": "আপনার নজরতালিকা সম্পাদনা করুন",
        "upload-dialog-disabled": "এই ডায়ালগ ব্যবহার করে ফাইল আপলোড করা এই উইকিতে নিষ্ক্রিয় করা হয়েছে।",
        "upload-dialog-title": "ফাইল আপলোড করুন",
        "upload-dialog-button-cancel": "বাতিল",
+       "upload-dialog-button-back": "পিছনে",
        "upload-dialog-button-done": "সম্পন্ন",
        "upload-dialog-button-save": "সংরক্ষণ",
        "upload-dialog-button-upload": "আপলোড",
        "newpages": "নতুন পাতাসমূহ",
        "newpages-submit": "দেখাও",
        "newpages-username": "ব্যবহারকারী নাম:",
-       "ancientpages": "পà§\81রানà§\8b à¦¨à¦¿à¦¬à¦¨à§\8dধ",
+       "ancientpages": "পà§\81রানà§\8b à¦ªà¦¾à¦¤à¦¾",
        "move": "সরিয়ে ফেলুন",
        "movethispage": "সরিয়ে ফেলুন",
        "unusedimagestext": "নিচের ফাইলগুলি কোনো পাতার অন্তর্ভুক্ত নয়।\nঅনুগ্রহ করে খেয়াল রাখবেন যে অন্য ওয়েবসাইট থেকে কোন ফাইলে সরাসরি URL-এর মাধ্যমে সংযোগ দেওয়া থাকতে পারে, এবং সেজন্য সক্রিয়ভাবে ব্যবহৃত হওয়া সত্ত্বেও ফাইলটি এখানে তালিকাভুক্ত হতে পারে।",
        "apisandbox-dynamic-parameters": "অতিরিক্ত প্যারামিটার",
        "apisandbox-dynamic-parameters-add-label": "প্যারামিটার যোগ করুন:",
        "apisandbox-dynamic-parameters-add-placeholder": "প্যারামিটারের নাম",
+       "apisandbox-dynamic-error-exists": "\"$1\" নামক একটি প্যারামিটার আগে থেকেই বিদ্যমান।",
        "apisandbox-results": "ফলাফল",
        "apisandbox-sending-request": "API অনুরোধ পাঠানো হচ্ছে...",
        "apisandbox-loading-results": "API ফলাফল গ্রহণ করা হচ্ছে...",
        "apisandbox-request-url-label": "অনুরোধের URL:",
        "apisandbox-request-time": "অনুরোধের সময়: {{PLURAL:$1|$1 মি.সে.}}",
+       "apisandbox-continue": "অব্যাহত",
+       "apisandbox-continue-clear": "পরিস্কার",
        "booksources": "বইয়ের উৎস",
        "booksources-search-legend": "বইয়ের উৎসের জন্য অনুসন্ধান করা হোক",
        "booksources-isbn": "আইএসবিএন:",
        "booksources-search": "অনুসন্ধান",
        "booksources-text": "নতুন ও পুরাতন ব্যবহৃত বই বিক্রি করে, এমন কতগুলি সাইটের সংযোগের তালিকা নিচে দেওয়া হল, যে সাইটগুলিতে আপনার অনুসন্ধানকৃত বইগুলির উপর আরও তথ্য থাকতে পারে:",
        "booksources-invalid-isbn": "উল্লেখিত ISBN সঠিক নয়; অনুগ্রহ করে মূল উৎস থেকে আবার পরীক্ষা করুন।",
+       "magiclink-tracking-rfc": "আরএফসি জাদু সংযোগ ব্যবহার করা পাতা",
+       "magiclink-tracking-pmid": "পিএমআইডি জাদু সংযোগ ব্যবহার করা পাতা",
+       "magiclink-tracking-isbn": "আইএসবিএন জাদু সংযোগ ব্যবহার করা পাতা",
        "specialloguserlabel": "সম্পাদক:",
        "speciallogtitlelabel": "লক্ষ্য (শিরোনাম বা {{ns:user}}:ব্যবহারকারীর জন্য ব্যবহারকারী নাম):",
        "log": "লগগুলি",
        "activeusers-intro": "এটি ব্যবহারকারী তালিকা যাদের $1 {{PLURAL:$1|দিনে|দিনে}} যেকোন কর্মকান্ড রয়েছে।",
        "activeusers-count": "গত {{PLURAL:$3|কালে|$3 দিনে}} সর্বমোট {{PLURAL:$1|কর্মের}} সংখ্যা $1টি",
        "activeusers-from": "ব্যবহারকারী দেখাও যাদের নাম এই অক্ষর দিয়ে শুরু:",
-       "activeusers-hidebots": "বট লুকাও",
-       "activeusers-hidesysops": "প্রশাসক লুকাও",
        "activeusers-noresult": "কোনো ব্যবহারকারী পাওয়া যায়নি।",
        "activeusers-submit": "সক্রিয় ব্যবহারকারী প্রদর্শন করুন",
        "listgrouprights": "দলগত ব্যবহারকারী অধিকার",
        "changecontentmodel-submit": "পরিবর্তন করুন",
        "changecontentmodel-success-title": "বিষয়বস্তুর প্রতিরূপ পরিবর্তিত হয়েছিলো",
        "changecontentmodel-success-text": "[[:$1]]-এর বিষয়বস্তুর ধরণ পরিবর্তন হয়েছে।",
+       "changecontentmodel-emptymodels-title": "কোন বিষয়বস্তুর মডেল উপলব্ধ নয়",
        "log-name-contentmodel": "বিষয়বস্তুর মডেল পরিবর্তন লগ",
        "logentry-contentmodel-change": "$1 $3 পাতার বিষয়বস্তুর মডেল \"$4\" থেকে \"$5\"-এ {{GENDER:$2|পরিবর্তন করেছেন}}",
        "logentry-contentmodel-change-revertlink": "প্রত্যাবর্তন",
        "modifiedarticleprotection": "\"[[$1]]\"-এর জন্য সুরক্ষার স্তর পরিবর্তন করা হয়েছে",
        "unprotectedarticle": "\"[[$1]]\"-এর সুরক্ষা সরিয়ে নেওয়া হয়েছে",
        "movedarticleprotection": "সুরক্ষা সেটিংস \"[[$2]]\" থেকে \"[[$1]]\"-এ স্থানান্তরিত হয়েছে",
+       "protectedarticle-comment": "\"[[$1]]\" {{GENDER:$2|সুরক্ষিত করা হয়েছে}}",
+       "modifiedarticleprotection-comment": "\"[[$1]]\"-এর {{GENDER:$2|সুরক্ষার স্তর পরিবর্তন করা হয়েছে}}",
+       "unprotectedarticle-comment": "\"[[$1]]\" থেকে {{GENDER:$2|সুরক্ষা সরানো হয়েছে}}",
        "protect-title": "\"$1\" সুরক্ষিত করা হচ্ছে",
        "protect-title-notallowed": "\"$1\" এর সুরক্ষা মাত্রা দেখুন",
        "prot_1movedto2": "[[$1]]-কে [[$2]]-এ সরিয়ে নেওয়া হয়েছে",
        "pageinfo-category-pages": "পাতার সংখ্যা",
        "pageinfo-category-subcats": "উপবিষয়শ্রেণীর সংখ্যা",
        "pageinfo-category-files": "ফাইলের সংখ্যা",
+       "pageinfo-user-id": "ব্যবহারকারী আইডি",
        "markaspatrolleddiff": "পরীক্ষিত হিসেবে চিহ্নিত করুন",
        "markaspatrolledtext": "এই পাতাটি পরীক্ষিত হিসেবে চিহ্নিত করুন",
        "markaspatrolledtext-file": "এই ফাইলের সংস্করণ পরীক্ষিত হিসেবে চিহ্নিত করুন",
        "patrol-log-header": "এটি যাচাইকৃত রিভিশনের তালিকা।",
        "log-show-hide-patrol": "পরীক্ষণ লগ $1",
        "log-show-hide-tag": "ট্যাগ লগ $1",
+       "confirm-markpatrolled-button": "ঠিক আছে",
+       "confirm-markpatrolled-top": "$2-এর $3 নং সংস্করণটি পরীক্ষিত হিসেবে চিহ্নিত করবেন?",
        "deletedrevision": "মুছে ফেলা পুরাতন সংশোধন $1",
        "filedeleteerror-short": "ফাইল মুছতে গিয়ে ত্রুটি: $1",
        "filedeleteerror-long": "ফাইলটি মুছার সময় ত্রুটি দেখা দিয়েছে:\n\n$1",
        "newimages-showbots": "বটের আপলোড গুলো দেখাও।",
        "newimages-hidepatrolled": "টহলকৃত আপলোড আড়াল করো",
        "noimages": "দেখার মত কিছু নেই।",
+       "gallery-slideshow-toggle": "থাম্বনেল ভাসান",
        "ilsubmit": "অনুসন্ধান",
        "bydate": "তারিখ অনুযায়ী",
        "sp-newimages-showfrom": "$2, $1 এর পরের নতুন ছবিগুলো দেখাও",
+       "seconds-abbrev": "$1 সে",
        "minutes-abbrev": "$1 মিনিট",
+       "hours-abbrev": "$1 ঘ",
+       "days-abbrev": "$1 দিন",
        "seconds": "{{PLURAL:$1|$1 সেকেন্ড|$1 সেকেন্ড}}",
        "minutes": "{{PLURAL:$1|$1 মিনিট|$1 মিনিট}}",
        "hours": "{{PLURAL:$1|$1 ঘণ্টা|$1 ঘণ্টা}}",
        "confirmemail_body_set": "কেউ একজন, সম্ভবত আপনি, $1 আইপি ঠিকানা থেকে,\n{{SITENAME}}-এ \"$2\" অ্যকাউন্টের ইমেইল ঠিকানা নির্ধারণ করেছেন।\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: HTTP $2 এর জন্য টেমপ্লেট আনা বিফল হয়েছে]",
        "tags-delete-reason": "কারণ:",
        "tags-delete-submit": "অপরিবর্তনীয় এই ট্যাগ অপসারন করো",
        "tags-delete-not-found": "\"$1\" ট্যাগ বিদ্যমান নয়।",
+       "tags-delete-no-permission": "আপনার পরিবর্তন ট্যাগ মুছে ফেলার অনুমতি নেই।",
        "tags-activate-title": "সক্রিয় ট্যাগ",
        "tags-activate-question": "আপনি ট্যাগ \"$1\" সক্রিয় করতে চলেছেন।",
        "tags-activate-reason": "কারণ:",
        "htmlform-cloner-create": "আরও যোগ করুন",
        "htmlform-cloner-delete": "অপসারণ",
        "htmlform-cloner-required": "অন্তত একটি মূল্য আবশ্যক।",
+       "htmlform-date-placeholder": "বববব-মম-দদ",
+       "htmlform-time-placeholder": "ঘঘ:মম:সস",
+       "htmlform-datetime-placeholder": "বববব-মম-দদ ঘঘ:মম:সস",
        "htmlform-title-badnamespace": "[[:$1]] \"{{ns:$2}}\" নামস্থানে খুঁজে পাওয়া যায়নি।",
        "htmlform-title-not-creatable": "\"$1\" সৃষ্টিযোগ্য পাতার শিরোনাম নয়",
        "htmlform-title-not-exists": "$1-এর অস্তিত্ব নেই।",
        "feedback-external-bug-report-button": "প্রযুক্তিগত কাজ ফাইল করুন",
        "feedback-dialog-title": "প্রতিক্রিয়া জমা দিন",
        "feedback-dialog-intro": "আপনি আপনার প্রতিক্রিয়া জানাতে নীচের সহজ ফরম ব্যবহার করতে পারেন। আপনার মন্তব্য আপনার ব্যবহারকারী নামসহ, \"$1\" পাতায় যোগ করা হবে।",
-       "feedback-error-title": "ত্রুটি",
        "feedback-error1": "ত্রুটি: এপিআই হতে অজানা ফলাফল এসেছে",
        "feedback-error2": "ত্রুটি: সম্পাদনা ব্যর্থ",
        "feedback-error3": "ত্রুটি: এপিআই হতে কোন সাড়া নেই",
        "feedback-thanks": "ধন্যবাদ! আপনার প্রতিক্রিয়া \"[$2 $1]\" পাতায় পোস্ট করা হয়েছে।",
        "feedback-thanks-title": "আপনাকে ধন্যবাদ!",
        "feedback-useragent": "ব্যবহারকারী এজেন্ট:",
-       "searchsuggest-search": "অনুসন্ধান",
+       "searchsuggest-search": "{{SITENAME}} অনুসন্ধান",
        "searchsuggest-containing": "যা আছে...",
        "api-error-badaccess-groups": "আপনার এই উইকিতে ফাইল আপলোডের অনুমতি নেই।",
        "api-error-badtoken": "অভ্যন্তরীণ ত্রুটি: খারাপ টোকেন।",
        "mediastatistics-header-drawing": "অংকন (ভেক্টর চিত্র)",
        "mediastatistics-header-audio": "অডিও",
        "mediastatistics-header-video": "ভিডিও",
+       "mediastatistics-header-multimedia": "মিডিয়া",
        "mediastatistics-header-office": "অফিস",
+       "mediastatistics-header-text": "পাঠগত",
+       "mediastatistics-header-executable": "সঞ্চালনযোগ্য",
        "mediastatistics-header-archive": "সংকুচিত বিন্যাস",
        "mediastatistics-header-total": "সকল ফাইল",
        "json-warn-trailing-comma": "JSON থেকে $1টি সর্বশেষ {{PLURAL:$1|কমা}} সরানো হয়েছে",
        "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-delete-delete": "পাতা অপসারণ",
        "log-action-filter-delete-restore": "পাতা পুনঃরুদ্ধার",
        "log-action-filter-delete-event": "লগ অপসারণ",
        "log-action-filter-upload-upload": "নতুন আপলোড",
        "log-action-filter-upload-overwrite": "পুনঃআপলোড",
        "authmanager-authn-no-primary": "সরবরাহকৃত পরিচয়পত্রের অনুমোদন যাচাই করা যায়নি।",
+       "authmanager-authn-autocreate-failed": "একটি স্থানীয় অ্যাকাউন্টের স্বয়ংক্রিয়-সৃষ্টি ব্যর্থ হয়েছে: $1",
        "authmanager-create-disabled": "অ্যাকাউন্ট সৃষ্টিকরণ নিষ্ক্রিয় করা হয়েছে।",
-       "authmanager-create-from-login": "à¦\86পনার à¦\8fà¦\95াà¦\89নà§\8dà¦\9f à¦¤à§\88রি à¦\95রতà§\87, à¦¨à§\80à¦\9aà§\87র à¦\95à§\8dষà§\87তà§\8dরà¦\97à§\81লি à¦ªà§\82রণ à¦\95রà§\81ন।",
+       "authmanager-create-from-login": "আপনার একাউন্ট তৈরি করতে, ক্ষেত্রগুলি পূরণ করুন।",
        "authmanager-authplugin-setpass-failed-title": "পাসওয়ার্ড পরিবর্তন ব্যর্থ হয়েছে",
        "authmanager-authplugin-setpass-bad-domain": "অবৈধ ডোমেইন।",
        "authmanager-autocreate-noperm": "স্বয়ংক্রিয় অ্যাকাউন্ট সৃষ্টি মঞ্জুরিপ্রাপ্ত নয়।",
        "authmanager-userdoesnotexist": "ব্যবহারকারী অ্যাকাউন্ট \"$1\" অনিবন্ধিত।",
+       "authmanager-username-help": "প্রমাণীকরণের জন্য ব্যবহারকারী নাম।",
+       "authmanager-password-help": "প্রমাণীকরণের জন্য পাসওয়ার্ড।",
+       "authmanager-domain-help": "বহিঃস্থ প্রমাণীকরণের জন্য ডোমেইন।",
+       "authmanager-retype-help": "নিশ্চিত করার জন্য আবার পাসওয়ার্ড লিখুন।",
        "authmanager-email-label": "ইমেইল",
        "authmanager-email-help": "ইমেইল ঠিকানা",
        "authmanager-realname-label": "প্রকৃত নাম",
        "authmanager-realname-help": "ব্যবহারকারীর প্রকৃত নাম",
+       "authmanager-provider-password": "পাসওয়ার্ড-ভিত্তিক প্রমাণীকরণ।",
+       "authmanager-provider-password-domain": "পাসওয়ার্ড ও ডোমেইন-ভিত্তিক প্রমাণীকরণ।",
        "authmanager-provider-temporarypassword": "অস্থায়ী পাসওয়ার্ড",
        "authprovider-confirmlink-success-line": "$1: সংযোগ করা সফল হয়েছে।",
        "authprovider-resetpass-skip-label": "উপেক্ষা করো",
        "credentialsform-provider": "পরিচয়পত্রের ধরন:",
        "credentialsform-account": "অ্যাকাউন্টের নাম:",
        "linkaccounts": "অ্যাকাউন্ট সংযোগ করুন",
+       "linkaccounts-success-text": "অ্যাকাউন্টটি সংযোগ করা হয়েছে।",
        "linkaccounts-submit": "অ্যাকাউন্ট সংযুক্ত করুন",
        "unlinkaccounts": "অ্যাকাউন্ট সংযোগ বিচ্ছিন্ন করুন",
        "unlinkaccounts-success": "অ্যাকাউন্টের সংযোগ বিচ্ছিন্ন করা হয়েছে।",
+       "authenticationdatachange-ignored": "প্রমাণীকরণ উপাত্তের পরিবর্তন পরিচালনা করা হয়নি। হয়তো কোন প্রদানকারী কনফিগার করা হয়নি?",
        "userjsispublic": "অনুগ্রহ করে লক্ষ্য করুন: জাভাস্ক্রিপ্টের উপপাতাগুলিতে গোপনীয় তথ্য থাকা উচিত নয় যেহেতু অন্যান্য ব্যবহারকারীও এগুলি দেখতে পান।",
-       "usercssispublic": "অনুগ্রহ করে লক্ষ্য করুন: সিএসএসের উপপাতাগুলিতে গোপনীয় তথ্য থাকা উচিত নয় যেহেতু অন্যান্য ব্যবহারকারীও এগুলি দেখতে পান।"
+       "usercssispublic": "অনুগ্রহ করে লক্ষ্য করুন: সিএসএসের উপপাতাগুলিতে গোপনীয় তথ্য থাকা উচিত নয় যেহেতু অন্যান্য ব্যবহারকারীও এগুলি দেখতে পান।",
+       "restrictionsfield-badip": "আইপি ঠিকানা অথবা পরিসীমা অবৈধ: $1",
+       "restrictionsfield-label": "অনুমোদিত আইপি পরিসীমা:",
+       "restrictionsfield-help": "লাইন প্রতি একটি আইপি ঠিকানা বা CIDR পরিসীমা। সবকিছু সক্রিয় করতে<br><code>0.0.0.0/0</code><br><code>::/0</code><br>ব্যবহার করুন",
+       "edit-error-short": "ত্রুটি: $1",
+       "edit-error-long": "ত্রুটিসমূহ:\n\n$1"
 }
index 5553398..085bd1f 100644 (file)
        "yourpassword": "ལམ་ཡིག",
        "userlogin-yourpassword-ph": "ཁྱེད་ཀྱི་གསང་བའི་ཨང་གྲངས་བླུག་རོགས།",
        "yourpasswordagain": "གསང་བའི་ཨང་ངོས་འཛིན་གནང་རོགས།",
-       "remembermypassword": "ངའི་ལམ་ཡིག་འདིར་(མང་མཐའ་ཉིན $1 {{PLURAL:$1}}) དྲན་པར་བྱས།",
        "yourdomainname": "ཁྱེད་ཀྱི་ཁྱབ་ཁུལ།",
        "login": "ནང་འཛུལ།",
        "nav-login-createaccount": "ནང་འཛུལ། / ཐོ་འགོད།",
index 152a1ec..0bdaf65 100644 (file)
        "yourname": "আতাকুরার নাংহান (Username)",
        "yourpassword": "খন্তাচাবিগ (password)",
        "yourpasswordagain": "খন্তাচাবিগ (password) আরাকমু ইকর",
-       "remembermypassword": "আহার গজে সেশনর কা খন্তাচাবি মনে থ(সর্বোচ্চ $1 {{PLURAL:$1|দিনর|দিনর}} কা)",
        "yourdomainname": "তর ডোমেইনগ",
        "externaldberror": "ডাটেবেজর মা বেসেপ আহান ইসে নাইলে তরতা বারেদের একাউন্ট বদালানির য়্যাথাং নেই।",
        "login": "হমানি",
        "post-expand-template-argument-warning": "' ' ' সিঙুইস: ' ' ' এরে পাতাহাত তিলসে টেম্পলেট এহার যুক্তি আহান লাম হেলসে। অহানে যুক্তি অহান বেলানি অইল।",
        "post-expand-template-argument-category": "পতাহাত পুসিসি মডেলর জর থা পরসেগা",
        "parser-template-loop-warning": "মডেলর তরিগ দেখরাং: [[$1]]",
-       "cantcreateaccounttitle": "একাউন্টহান হঙকরানি নাইব",
        "viewpagelogs": "পাতাহানর লগ চা",
        "nohistory": "পাতা এহান পতানির কোন ইতিহাস নেই।",
        "currentrev": "হাদিএহানর পতানি",
index 8537087..e18bf6c 100644 (file)
@@ -7,7 +7,8 @@
                        "Huji",
                        "Meno25",
                        "Mogoeilor",
-                       "아라"
+                       "아라",
+                       "Mjbmr"
                ]
        },
        "tog-underline": "لینکهای خط به زیر",
        "thu": "پنجشنبه",
        "fri": "جمعه",
        "sat": "شنبه",
-       "january": "ژانویه",
-       "february": "فوریه",
+       "january": "جانڤیە",
+       "february": "فئڤریە",
        "march": "مارس",
-       "april": "آوریل",
-       "may_long": "مه",
-       "june": "ژوئن",
-       "july": "ژوئیه",
-       "august": "اÙ\88ت",
-       "september": "سپتامبر",
-       "october": "اکتبر",
-       "november": "نوامبر",
-       "december": "دساÙ\85بر",
+       "april": "آڤریل",
+       "may_long": "مە",
+       "june": "جوٙأن",
+       "july": "جوٙئیە",
+       "august": "Ø¢Ú¯Ù\88ست",
+       "september": "سئپتامر",
+       "october": "ئÙ\88کتÙ\88بر",
+       "november": "نوڤامر",
+       "december": "دئساÙ\85ر",
        "january-gen": "ژانویه",
        "february-gen": "فوریه",
        "march-gen": "مارس",
        "october-gen": "اکتبر",
        "november-gen": "نوامبر",
        "december-gen": "دسامبر",
-       "jan": "ژانویه",
-       "feb": "فوریه",
+       "jan": "جانڤیە",
+       "feb": "فئڤریە",
        "mar": "مارس",
-       "apr": "آوریل",
-       "may": "مه",
-       "jun": "ژوئن",
-       "jul": "ژوئیه",
-       "aug": "اوت",
-       "sep": "سپتامبر",
-       "oct": "اکتبر",
-       "nov": "نوامبر",
-       "dec": "دسامبر",
+       "apr": "آڤریل",
+       "may": "مە",
+       "jun": "جوٙأن",
+       "jul": "جوٙئیە",
+       "aug": "آگوست",
+       "sep": "سئپتامر",
+       "oct": "ئوکتوبر",
+       "nov": "نوڤامر",
+       "dec": "دئسامر",
+       "period-am": "دم سوڤ",
+       "period-pm": "پسين",
        "pagecategories": "{{PLURAL:$1|دسته|دسته ها}}",
        "category_header": "صفحات دردسته \"$1\"",
        "subcategories": "دسته های فرعی",
        "about": "درباره",
        "newwindow": "(پنجره تازه واز کن)",
        "cancel": "لغو",
-       "mytalk": "صحبت مو",
+       "mypage": "بألگأ",
+       "mytalk": "چأک چنأ",
+       "anontalk": "چأک چنأ",
+       "navigation": "ناڤجوری",
+       "and": "&#32;و",
        "qbfind": "پیدا کردن",
+       "qbbrowse": "قأرز کردن",
        "qbedit": "اصلاح",
+       "qbpageoptions": "اي بألگأ",
        "faq": "اف ای کیو",
        "faqpage": "Project:اف ای کیو",
+       "namespaces": "نوم ڤأرگأ آ",
+       "variants": "آلشدگأرا",
+       "navigation-heading": "نوم جاگأ ناڤگردي",
        "errorpagetitle": "خطا",
        "returnto": "بازگشت به $1.",
        "tagline": "از {{SITENAME}}",
        "help": "راهنما",
-       "search": "جستن",
-       "searchbutton": "جستن",
+       "search": "پئی جوٙری",
+       "searchbutton": "پئی جوٙری",
        "searcharticle": "برو",
        "history": "گزارش صفحه",
        "history_short": "گزارش تاریخی",
-       "printableversion": "نسخه قابل چاپ",
+       "printableversion": "نوسقئ پئلا ڤابیدٙئنی",
        "permalink": "لینک دایمی",
+       "view": "ديئن",
+       "view-foreign": "مئن $1 نه بوینین",
        "edit": "اصلاح",
        "editthispage": "اصلاح ای صفحه",
        "delete": "حذف",
        "protect": "حفاظت وحمایت",
        "newpage": "صفحه تازه",
        "talkpage": "بحث ای صفحه",
-       "talkpagelinktext": "صحبت",
+       "talkpagelinktext": "چأک چئنە",
        "specialpage": "صفحه مخصوص",
        "personaltools": "ابزارهای شخصی",
        "articlepage": "دیدن صفحه محتوا",
        "jumpto": "پریدن به:",
        "jumptonavigation": "راندن یا هدایت کردن",
        "jumptosearch": "جستن",
-       "aboutsite": "دربارÙ\87 {{SITENAME}}",
-       "aboutpage": "Project:دربارÙ\87",
+       "aboutsite": "راجÙ\88Ú¤ Ø¨Ø¦ {{SITENAME}}",
+       "aboutpage": "Project:راجڤ Ø¨Ø¦",
        "copyright": "محتوا باای شماره قابل دسترسیه\n $1.",
        "copyrightpage": "{{ns:project}}:کپی رایت",
        "currentevents": "اتفاقات جاری",
        "currentevents-url": "Project:اتفاقات جاری",
-       "disclaimers": "اÙ\86کار Ú©Ù\86Ù\86دÙ\87 Ù\87ا",
-       "disclaimerpage": "Project:انکار کاربران",
+       "disclaimers": "تÛ\8cÛ\95 Ù¾Ù\88Ù\99Ø´Ù\86ا",
+       "disclaimerpage": "Project: تیە پوشنیدٙئنئ کولی",
        "edithelp": "کمک برای اصلاح",
-       "mainpage": "صÙ\81Ø­Ù\87 Ø§ØµÙ\84Û\8c",
+       "mainpage": "سأرآسÙ\88Ù\99Ù\86Û\95",
        "mainpage-description": "صفحه اصلی",
        "policy-url": "Project:خط مشی",
        "portal": "درگاه کاربران",
        "portal-url": "Project:درگاه کاربران",
-       "privacy": "خط Ù\85Ø´Û\8c Ø±Ø§Ø²Ø¯اری",
-       "privacypage": "Project:خط Ù\85Ø´Û\8c Ø±Ø§Ø²داری",
+       "privacy": "رأدÛ\8cارکÙ\88Ù\86Û\8c Ø±Ø§Ø²Ú¤Ø§Ø¯Ù\99اری",
+       "privacypage": "Project:رأدÛ\8cارکÙ\88Ù\86Û\8c Ø±Ø§Ø²Ú¤Ø§داری",
        "badaccess": "خطا :اجازه بگیر",
        "badaccess-group0": "ایسا اجازه انجام کاری که خواستین را ندارین",
        "badaccess-groups": "او کاری که ایسا درخواست کردین فقط سی کاربرانیه که من ای  گروهن\n{{PLURAL:$2|آن گروه|یکی زه گروهها}}: $1.",
        "versionrequiredtext": "یه نسخه زه ویکی مدیا($1) نیازمند ه به استفاده زه ای صفحه\nبوین :[[Special:Version|version page]].",
        "ok": "خووه",
        "pagetitle-view-mainpage": "سرصفحه",
-       "retrievedfrom": "بازÛ\8cاÙ\81ت Ø§Ø²\"$1\"",
+       "retrievedfrom": "دÙ\88ڤارتئ Ø¬Ù\88Ù\99رÛ\8c Ø² \"$1\"",
        "youhavenewmessages": "پیام تاره داری $1 ($2).",
        "youhavenewmessagesmulti": "ایسا پیام تازه دارین منه\n$1",
-       "editsection": "اصلاح",
+       "editsection": "ڤیرایئشت کاری",
        "editold": "اصلاح",
        "viewsourceold": "دیدن منبع",
-       "editsectionhint": "اصلاح یه قسمت: $1",
+       "editlink": "ڤیرایئشت",
+       "viewsourcelink": "سئیل سرچشمه کنین",
+       "editsectionhint": "ڤیرایئشت بأرجا: $1",
        "toc": "محتواها",
        "showtoc": "نمایش",
        "hidetoc": "قایم",
        "feedlinks": "تغذیه:",
        "feed-invalid": "اشتراک  زه راه  تایپ باطله",
        "site-rss-feed": "خبرخو RSS سی $1",
-       "site-atom-feed": "خبرخÙ\88 Atom سی $1",
+       "site-atom-feed": "حأڤاÙ\84 Ø®Ù\88Ù\99Ù\86ئ Atom سی $1",
        "page-rss-feed": "خبرخو RSS سی «$1»",
+       "page-atom-feed": "هأڤال خۈن Atom سي $1",
+       "red-link-title": "$1 (چونو بألگئ یی نیدٙئس)",
+       "nstab-main": "بلگه",
        "nstab-user": "صفحه کاربر",
+       "nstab-special": "بألگه ڤیجه",
        "nstab-project": "صفحه پروژه",
        "nstab-image": "فایل",
        "nstab-template": "قالب یا الگو",
        "nstab-category": "دسته",
+       "mainpage-nstab": "سأرآسوٙنە",
        "badtitle": "عنوان بد",
        "badtitletext": "عنوان درخواستی نامعتبر، خالی، یا عنوانی بین زبانی یا بین‌ویکی‌ای با پیوند نادرسته\nو ممکنه دارای یک یا چند کاراکتر بوه که در عنوان مربوط نوا زش استفاده کنین",
        "viewsource": "مشاهده منبع",
        "viewsourcetext": "ایسا ترین بوینین وکپی کنین منبع ای صفحه را:",
        "yourname": "نام کاربر:",
+       "userlogin-yourname": "نوم کارياري",
+       "userlogin-yourname-ph": "نوم کاریاريتونأ بزنين",
        "yourpassword": "رمز:",
-       "remembermypassword": "رمز اویدن به سیستم را دراین رایانه به خاطر بسپار (for a maximum of $1 {{PLURAL:$1|day|days}})",
+       "userlogin-yourpassword": "رازينإ گوڤأرتن",
        "login": "اویدن به سیستم",
        "nav-login-createaccount": "اویدن به سیستم",
        "userlogin": "اویدن به سیستم / درست کردن حساب کاربری",
        "gotaccountlink": "اویدن به",
        "loginsuccesstitle": "اویدن با بخت وتوفیق به سیستم",
        "loginsuccess": "''' ایسا اویدن به داخل سایت {{SITENAME}} بعنوان \"$1\".'''",
-       "nosuchuser": "کاربری به ای نام وجود نداره \"$1\".\nحروف نام را چک کنین, یا [[Special:UserLogin/signup|درست کنین یه حساب کاربری تازه]].",
+       "nosuchuser": "کاربری به ای نام وجود نداره \"$1\".\nحروف نام را چک کنین, یا [[Special:CreateAccount|درست کنین یه حساب کاربری تازه]].",
        "nosuchusershort": "کاربری به ای نام وجود نداره\"$1\".\nحروف نام راچک کنین.",
        "nouserspecified": "ایسا دارین یه نام کاربر ذکر اکنین.",
        "wrongpassword": "رمز وارد وابیده درست نه.\nلطفا دوباره سعی کنین.",
        "passwordremindertext": "یه نفر (شاید خودتو, زه نشانی آی پی$1) درخواست یه رمز تازه کرده سی {{SITENAME}} ($4). یه رمز موقتی سی کاربر\n\"$2\" درست شده وگذاشته وابیده به\"$3\". ایر مطابق میل ایسا بوه, نیازه که داخل سیستم بوین ویه رمز تازه انتخاب کنین.\n\nایر آن فرد همچنین درخواست کرده بوه  یونه, یا ایر ایسا رمزتو را به خاط داشته این ,\nوسی مدت طولانی نه خوین هونه تغییر بدین, ایسا وا نادیده بگیرین ای پیام  را وهمچنان زه رمز قدیمی خوتو استفاده کنین",
        "noemail": "وجود نداره نشانی امیل ضبط وابده زه کاریر \"$1\".",
        "passwordsent": "یه رمز تازه ارسال وابید به نشانی امیل ثبت وابده سی \"$1\".\nلطفا بعد از دریافت آن داخل سیستم بوین.",
-       "eauthentsent": "یه نامه الکترونیکی سی تایید نشانی پست الکترونیکی به نشانی مورنظر ارسال وابید. قبل زه یو که نامه دیگری قابل ارسال به این نشانی بوه، وا دستورهایی که در آن نامه اویده را جهت تأیید ای مساله که ای نشانی مال ایسانه اجرا کنین.",
+       "eauthentsent": "یه ایمیل سی تایید آدرس ایمیل به آدرس مورنظر ارسال وابید. قبل زه یو که ایمیل دیگری قابل ارسال به این آدرس بوه، وا دستورهایی که در آن ایمیل اویده را جهت تأیید ای مساله که ای آدرس مال ایسانه اجرا کنین.",
+       "loginlanguagelabel": "زۈن:$1",
+       "pt-login": "ڤامین اوڤیڌن",
+       "pt-createaccount": "راسد کردن هساڤ کارياري",
+       "pt-userlogout": "ز سامۈنإ درأڤوڌن",
        "retypenew": "تایپ دوباره رمز:",
        "bold_sample": "متن گپ نما",
        "bold_tip": "متن گپ نما",
        "anoneditwarning": "'''توجه:''' ایسا داخل سیستم نوابیدین.\nآی پی آدرستو درگزارش اصلاح صفحه ضبط ابوه.",
        "summary-preview": "پیش نمایش - خلاصه:",
        "blockedtext": " \"'''دسترسی نام کاربری یا نشانی اینترنتی ایسا بسته وابیده.'''\nای کار توسط $1 انجام شده‌است.\nدلیلی که گده اینه: $2''\n* آغاز قطع دسترسی: $8\n* زمان اتمام ای قطع دسترسی: $6\n* کاربری که قطع دسترسی‌اش در نظر بیده: $7\nایساترین با $1 یا یکی از [[{{MediaWiki:Grouppage-sysop}}|مدیران]] تماس بگیرین و در ای باره صحبت کنین.\nتوجه کنین که ایسا نترین زه امکان «ارسال پست الکترونیکی به ای کاربر» استفاده کنین مگر این که نشانی پست الکترونیکی معتبری در [[Special:Preferences|اولویتهای کاربری]]خود ثبت کرده بوین.\nنشانی IP ایسا $3 و شماره قطع دسترسی ایسا $5 است. لطفاً ای شماره‌ها را در همه کاوشهاتون ذکر کنین.\nایسا ترین با $1 یا یکی دیه زه [[{{MediaWiki:Grouppage-sysop}}|مدیران]] تماس بگیرین، تا در باره ای قطع دسترسی صحبت کنین.\nدقت کنین که سی ارسال پست الکترونیکی در ویکی، وا پست الکترونیکی خود را زه طریق صفحه[[Special:Preferences|تنظیمات]] فعال کرده بوین، و نیز، وا امکان استفاده زه ای ویژگی سی ایساقطع نبوه.\nنشانی اینترنتی الان ایسا $3 است و شماره قطع دسترسی $5 است.\nلطفاً ای شماره را در هر درخواستی که در ای مورد مطرح اکنین ذکر کنین",
+       "loginreqlink": "ڤامین اوڤیڌن",
        "newarticle": "(تازه)",
        "newarticletext": "ایسا لینکی را دنبال کردین و به صفحه‌ای رسیدین که هنی درست نوابیده.\nسی ایجاد صفحه، داخل مستطیل زیر شروع به تایپ کنین (سی اطلاعات بیشتر به [[{{ns:project}}:راهنما|صفحه راهنما] برین).\nایر اشتباهی ایچو اویدین دکمه «برگشت» مرورگرتو را بزنین.",
        "noarticletext": " الان ای صفحه متنی نداره، ایسا ترین [[Special:Search/{{PAGENAME}}عنوان ای صفحه را در صفحه‌های دیگر جستجو کنین]] یا [{{fullurl:{{FULLPAGENAME}}|action=edit}} ای صفحه را اصلاح کنین].",
        "lineno": "سطر $1:",
        "compareselectedversions": "مقایسه نسخه‌های انتخاب‌ وابیده",
        "editundo": "لغو اصلاح آخر",
+       "searchresults": "نتيجأ آ پی جۈري سي",
+       "searchresults-title": "نتيجإ آ پی جوري سي \"$1\"",
        "prevn": "قبلی {{PLURAL:$1|$1}}",
        "nextn": "بعدی {{PLURAL:$1|$1}}",
+       "nextn-title": "نيایي $1 {{PLURAL:$1|نتيجه|نتيجإآ}}",
        "viewprevnext": "مشاهده ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchprofile-articles": "بلگه آ مینونه دار",
+       "searchprofile-images": "ڤارسگرا خلکمند",
+       "searchprofile-everything": "همه چی",
+       "searchprofile-advanced": "پیشکرده",
+       "searchprofile-articles-tooltip": "بگرد مئن $1",
+       "searchprofile-images-tooltip": "جانیاانه پی جوری کو",
+       "search-result-size": "$1 ({{PLURAL:$2|1 ڤاجه یل|$2 ڤاجه یل}})",
+       "search-redirect": "(ڤاگردۈني ز $1)",
+       "search-section": "(بهرجا $1)",
+       "searchall": "همه",
+       "search-nonefound": "هیژ نتیجه یی وا پی جست تو یکی نئ.",
        "preferences": "اولویتها",
-       "mypreferences": "اÙ\88Ù\84Ù\88Û\8cتÙ\87اÛ\8c Ù\85Ù\88",
+       "mypreferences": "Ø®Ù\88صÙ\88Ù\99Û\8cات Ù\87Ø£Ù\86Û\8c",
        "yourrealname": "نام واقعی:",
        "prefs-help-realname": "ذکر نام واقعی اختیاریه ایر تصمیم به گدن بگیرین هنگام ارجاع به آثارتو و انتساب هونو به ایسا زه نام واقعیتو استفاده ابوه",
        "grouppage-sysop": "{{ns:project}}:مدیران",
+       "right-writeapi": "سي نڤشدن اي پ آی ڤأنين ڤاکار",
+       "newuserlogpage": "راسد ڤابیه وا کاریار",
        "rightslog": "نمایه حقوق کاربر",
        "nchanges": "$1 {{PLURAL:$1|تغییر|تغییرات}}",
+       "enhancedrc-history": "ڤیرگار",
        "recentchanges": "تغییرات اخیر",
+       "recentchanges-legend": "گزينإ آ آلشدا ايسإني",
        "recentchanges-feed-description": "ردیابی آخرین تغییرات  ویکی در ای خورد",
+       "recentchanges-label-newpage": "ای ويرايشت يه بلگه تازه راس كرده",
+       "recentchanges-label-minor": "یو یه ويرايشت کوچيره",
+       "recentchanges-label-unpatrolled": "ای ويرايشت هنی تيه واداشت نوابيه",
+       "recentchanges-legend-heading": "<strong>میراث:</strong>",
        "rcnotefrom": "در زیر تغییرات زه تاریخ <b>$2</b> آمده‌اند (تا <b>$1</b> مورد نشو داده ابوه).",
        "rclistfrom": "نشودادن تغییرات تازه با شروع زه $3 $2",
        "rcshowhideminor": "اصلاحات کوچیک $1",
+       "rcshowhideminor-hide": "قام کردن",
        "rcshowhidebots": "$1 ربات‌ها یا بوتها",
-       "rcshowhideliu": "$1 کاربران داخل وابیده",
+       "rcshowhidebots-show": "نشون دائن",
+       "rcshowhideliu": "$1 کاریارا ثوت نام کرده",
+       "rcshowhideliu-hide": "قام کئردئن",
        "rcshowhideanons": "$1 کاربران داخل نوابیده",
+       "rcshowhideanons-hide": "قام کئردئن",
        "rcshowhidepatr": "$1 اصلاحات پاسداری شده",
        "rcshowhidemine": "$1 اصلاحات مو",
+       "rcshowhidemine-hide": "قام کئردئن",
        "rclinks": "نشودادن آخرین $1 تغییر در $2 روز اخیر؛ $3",
        "diff": "تفاوت",
        "hist": "گزارش",
        "minoreditletter": "رز",
        "newpageletter": "تا",
        "boteditletter": "ر",
+       "rc-change-size-new": "$1 {{PLURAL:$1|بایت|بایتا}} بئ نیا آلئشتکاری",
        "recentchangeslinked": "تغییرات مرتبط",
        "recentchangeslinked-feed": "تغییرات مرتبط",
        "recentchangeslinked-toolbox": "تغییرات مرتبط",
        "recentchangeslinked-title": "تغییرهای مرتبط با $1",
        "recentchangeslinked-summary": " ای صفحه خاص تغییرات اخیر در صفحه‌های لینک داده شده به این صفحه را نشو اده.\nصفحه‌هایی که در لیست پی‌گیریهای ایسا بون به شکل '''سیاه''' نشو داده ابون.",
+       "recentchangeslinked-page": "نوم بألگە:",
        "upload": "آپلود فایل",
        "uploadbtn": "آپلود فایل",
        "uploadlogpage": "نمایه آپلود",
+       "filedesc": "چكستأ",
+       "license-header": "ب حال وبال ليسانس دار ڤابيڌن",
+       "imgfile": "جانيا",
        "listfiles": "لیست فایل",
        "file-anchor-link": "فایل",
        "filehist": "گزارش تاریخی فایل",
        "filehist-help": "رو تاریخ‌ها کلیک کنید تا نسخه مرتبط را ببینین.",
        "filehist-current": "جاری",
        "filehist-datetime": "تاریخ/زمان",
+       "filehist-thumb": "عسگ کۈچير وابيه",
        "filehist-user": "کاربر",
        "filehist-dimensions": "ابعاد",
        "filehist-filesize": "اندازه فایل",
        "filehist-comment": "توضیح",
-       "imagelinks": "لینکها",
+       "imagelinks": "به کار گرهڌن جانيا",
        "linkstoimage": "ذیل الذکر {{PLURAL:$1|لینکهای صفحه|$1 لینک صفحات}} به ای فایل:",
        "nolinkstoimage": "هیچ صفحه ای نه که لینک وابیده بوه به ای فایل",
        "sharedupload": "ای فایل یک آپلود اشتراکی هده و ممکنه زه طریق  پروژه‌های دیگه  هم قابل دسترسی بوه",
        "categories": "دسته آ",
        "emailuser": "امیل ای کاربر",
        "watchlist": "لیست پیگیریهای مو",
-       "mywatchlist": "لیست پیگیریهای مو",
+       "mywatchlist": "سإیل برگ",
        "addedwatchtext": "صفحه «<nowiki>$1</nowiki>» به [[Special:Watchlist|لیست پی‌گیری‌های ]] ایسا\nاضاف وابید.\nتغییرات این صفحه و صفحه صحبت مر بوطه اش در آینده ایچو لیست ابوه. به‌علاوه، ای صفحه، سی واضح‌تر دیده وابیدن در [[Special:RecentChanges|فهرست تغییرات اخیر]] به شکل <b>سیاه</b> ایا.\n\nایر بعدا خواستین ای  صفحه زه لیست پی‌گیریهاتو ورداشته بوه، رو «'''عدم پی‌گیری'''» در بالای صفحه کلیک کنین.",
        "removedwatchtext": "آن صفحه\"[[:$1]]\" جابجا وابیده زه[[Special:لیست پیگیری|لیست پیگیری ایسا]].",
        "watch": "پی‌گیری",
        "undeletebtn": "بازیافت",
        "namespace": "فضای نام:",
        "invert": "انتخاب برعکس بوه",
+       "namespace_association": "نوم جایل یأکاگرهڌأ",
        "blanknamespace": "(اصلی)",
-       "contributions": "شراکتهای کاربر",
-       "mycontris": "شراکتهای مو",
+       "contributions": "{{GENDER:$1|کاریار}} هومیاریا",
+       "mycontris": "هومياریا",
+       "anoncontribs": "هومياریا",
        "contribsub2": "سی $1 ($2)",
        "uctop": "(بالا)",
        "month": "در این ماه (و قبل زه آن):",
        "sp-contributions-talk": "صحبت",
        "whatlinkshere": "لینک های ای صفحه",
        "whatlinkshere-title": "صفحات آن لینک به \"$1\"",
+       "whatlinkshere-page": "بألگە",
        "linkshere": "لینک صفحات ذیل الذکر به '''[[:$1]]''':",
        "nolinkshere": "هیچ صفحه ای پیوند نداردبه '''[[:$1]]'''.",
        "isredirect": "صفحه تغییر مسیر",
        "whatlinkshere-prev": "{{PLURAL:$1|قبلی |مورد قبلی$1}}",
        "whatlinkshere-next": "{{PLURAL:$1|بعدی |مورد بعدی $1}}",
        "whatlinkshere-links": "← لینکها",
+       "whatlinkshere-hideredirs": "$1 redirects",
+       "whatlinkshere-hidelinks": "هوم پیڤأندا $1",
+       "whatlinkshere-filters": "فيلترا",
        "blockip": "بستن کاربر",
        "ipboptions": "۲ ساعت:2 hours,۱ روز:1 day,۳ روز:3 days,۱ هفته:1 week,۲ هفته:2 weeks,۱ ماه:1 month,۳ ماه:3 months,۶ ماه:6 months,۱ سال:1 year,بی‌نهایت:infinite",
        "ipblocklist": "آدرسهای  آی پی وکاربران بسته وابیدند",
        "blocklink": "بسته بوه !",
        "unblocklink": "باز بوه",
-       "contribslink": "شراکت",
+       "contribslink": "ھأیاری",
        "blocklogpage": "نمایه _ بسته‌وابیده‌ها",
        "blocklogentry": "بسته وابید [[$1]] با سپری وابیدن وقت زه $2 $3",
        "movepagetext": "با استفاده زه فرم زیر نام صفحه تغییر اکنه و همه گزارش تاریخی هو به نام تازه جابجا ابوه.\nعنوان کهنه تبدیل به یک صفحه تغییر مسیر به عنوان جدید ابوه.\nایسا ترین بطور اتوماتیک تغییر مسیر های مربوط به عنوان اصلی رو به روز رسانی کنین. ایر ایسا مطمئن نهدین با دیدن یونو مطمئن بوین:\n[[Special:تغییر مسیر دوبل|دوبل ]] یا[[Special:تغییرمسیر خروا یا اشکسته|تغییرمسیرهای خراو یا اشکسته]].\n\nلینکهایی که به عنوان صفحه قدیمی هدن تغییر نه کنن حتماً تغییر مسیرهای دوبل یا اشکسته و خراو را بررسی کنین.\n'''ایسا''' مسئول اطمینان زه یو هدین که لینکها هنی به همان‌جایی که قرار هده برن.\n\nتوجه کنین که ایر زه قبل صفحه‌ای در عنوان تازه وجود داشته بوه صفحه منتقل '''نه بوه'''،\nمیر یو که آن صفحه خالی یا تغییر مسیر بوه و گزارش تاریخی اصلاح نداشته بوه.\n یعنی ایر اشتباه کردین ترین صفحه را به همان جایی که زه هو جابجا وابیدین برگردانین، و  نترین رو صفحات موجود بنویسین\n\n'''هشدار!'''\nجابجایی صفحات به نام تازه ممکنه  تغییر کلی و غیرمنتظره‌ای سی\n صفحات دوست داشتنی داشته بوه ؛\nلطفاً مطمئن بوین که قبل زه جابجا کردن صفحه، عواقب ای کار را درک اکنین.",
        "movepagetalktext": "صفحه صحبت مربوط، ایر وجود داشته بوه، بطور اتوماتیک همراه با صفحه اصلی\n جابجا ابوه '''میر یو که''' :\n* در حال جابجایی صفحه زه ای فضای نام به فضای نام دیگری بوین،\n* یه صفحه صحبت غیرخالی تحت ای نام تازه وجود داشته بوه، یا\n* کادر زیر را تیک نزده بوین.\n\nدر ای موارد، وا صفحه را بطور دستی جابجا کرده و یا محتویات دو صفحه را با اصلاح ادغام کنین.",
-       "movearticle": "جابجایی صفحه:",
        "newtitle": "به عنوان تازه:",
        "move-watch": "پیگیری ای صفحه",
        "movepagebtn": "جابجایی صفحه",
        "thumbnail-more": "گپ کردن",
        "thumbnail_error": "خطا سی درست کردن ناخن دانه: $1",
        "importlogpage": "داخل نمایه کردن",
-       "tooltip-pt-userpage": "صفحه کاربری مو",
+       "tooltip-pt-userpage": "{{GENDER:|بألگأ کارياريتۈن}} بألگأ",
        "tooltip-pt-mytalk": "صفحه صحبت مو",
-       "tooltip-pt-preferences": "اولویت های مو",
+       "tooltip-pt-preferences": "{{GENDER:|ايسا}} أصل کاريا",
        "tooltip-pt-watchlist": "لیست صفحه‌هایی که ایسا تغییرات هونو  دنبال اکنین",
        "tooltip-pt-mycontris": "لیست شراکتهای مو",
        "tooltip-pt-login": "توصیه ابوه که به سیستم داخل بوین اما اجباری نه.",
        "tooltip-pt-logout": "رهدن زه سیستم",
        "tooltip-ca-talk": "صحبت درباره صفحه محتوا",
-       "tooltip-ca-edit": "ایسا ترین ای  صفحه را اصلاح کنین. لطفاً قبل  ذخیره کردن زه دکمه پیش‌ نمایش استفاده کنین",
-       "tooltip-ca-addsection": "اضاÙ\81 Ú©Ø±Ø¯Ù\86 Û\8cÙ\87 ØªÙ\88ضÛ\8cØ­ Ø¨Ù\87 Ø§Û\8c Ù\85بحث",
+       "tooltip-ca-edit": "ڤيرایشت اي بلگه",
+       "tooltip-ca-addsection": "Ø´Ù\88رÛ\88 Ú©Ø±Ø¯Ù\86 Û\8cÙ\87 Ø¨Ù\87رجا Ø¯Û\8cÙ\87",
        "tooltip-ca-viewsource": "ای صفحه  تحت حمایته ایساترین منبعسه بوینین",
+       "tooltip-ca-history": "دوواره ديئن ای بلگه",
        "tooltip-ca-protect": "حفاظت وحمایت زه ای صفحه",
        "tooltip-ca-delete": "حذف ای صفحه",
        "tooltip-ca-move": "جابجاکردن ای صفحه",
        "tooltip-ca-watch": "اضاف کردن ای صفحه به لیست پیگیریهاتو",
        "tooltip-ca-unwatch": "حذف ای صفحه زه لیست پی‌گیری‌های ایسا",
        "tooltip-search": "جستن {{SITENAME}}",
+       "tooltip-search-fulltext": "بألگأ آنأ سي چونو نإڤشدإیي پإی جۈري کو",
+       "tooltip-p-logo": "بإنیرين بإ سرآسۈنأ",
        "tooltip-n-mainpage": "دیدن صفحه اصلی",
+       "tooltip-n-mainpage-description": "بإنیرين به سرآسونه",
        "tooltip-n-portal": "درباره ای پروژه چه ترین  کنین و  کیه  ترین آن جیزها رو پیدا کنین",
        "tooltip-n-currentevents": "پیداکردن اطلاعات زمینه یاسابقه اطلاعات در اتفاقات جاری",
        "tooltip-n-recentchanges": "فهرست  تغییرات آخری درویکی",
        "tooltip-ca-nstab-main": "دیدن آن صفحه محتوا",
        "tooltip-ca-nstab-user": "دیدن صفحه کاربر",
        "tooltip-ca-nstab-media": "دیدن صفحه مدیا",
-       "tooltip-ca-nstab-special": "ای صفحه مخصوصه وایسا نترین خود ای صفحه رااصلاح کنین",
+       "tooltip-ca-nstab-special": "اي بلگه بلگه ویجه و ايسا نترين هونه ڤیرایشت کونین",
        "tooltip-ca-nstab-project": "دیدن صفحه پروژه",
        "tooltip-ca-nstab-image": "دیدن صفحه فایل",
        "tooltip-ca-nstab-mediawiki": "دیدن پیام سیستم",
        "tooltip-recreate": "دوباره درست کردن صفحه ای که زه رو کینه وغرض پاک وابیده",
        "tooltip-upload": "شروع آپلود",
        "tooltip-rollback": "\"اعاده\" برگرداندن به وضع اولیه سی ای صفحه که بخاطر مشارکت  آخر اصلاح وابیده بایک کلیک",
+       "tooltip-summary": "یأ چکسدأ کۈچير ڤارڌ کونين",
+       "pageinfo-toolboxlink": "دونسمندیا بلگه",
        "previousdiff": "← اصلاح قدیمی",
        "nextdiff": "تفاوت بعدی→",
        "file-info-size": "$1 × $2 پیکسل, اندازه فایل: $3, MIME نوع: $4",
        "file-nohires": "قابلیت تفکیک بالاتری در دسترس نه.",
        "svg-long-desc": "SVG فایل, تقریبا$1 × $2 پیکسل, اندازه فایل: $3",
-       "show-big-image": "تصویر با قابلیت تفکیک کامل",
+       "show-big-image": "جانیا اصلی",
+       "show-big-image-preview": "أندازإ اي پیش سیل:$1.",
+       "show-big-image-other": "هنی{{PLURAL:$2|گپ نما کردن|گپ نما کردنیا}}: $1.",
+       "show-big-image-size": "$1 × $2 پیکسل",
        "newimages": "گالری فایلهای تازه",
        "bad_image_list": "اطلاعات را وا به ای شکل وارد کنین:\n\nفقط سطرهایی که با * آغاز ابون در نظر گریده ابون. اولین لینک در هر سطر، باید لینکی به یک تصویر بد باشد.\nلینکهای بعدی در همان سطر، به عنوان موارد استثنا در نظر گریده ابون",
        "metadata": "فراداده",
        "metadata-expand": "نشودادن جزئیات تفصیلی",
        "metadata-collapse": "قایم کردن جزئیات تفصیلی",
        "metadata-fields": "فراداده EXIF نشو داده وابیده در این پیام وقتی جدول فراداده‌های تصویر جمع وابیده بوه هم نمایش داده ابوه.\nبقیه موارد فقط وقتی نشوداده ابوه که جدول یادشده واز بوه.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "exif-orientation": "سرچشمأ",
+       "exif-xresolution": "گپ نما کردن اوفقي",
+       "exif-yresolution": "گپ نما کردن ز وارو",
+       "exif-make": "سازیار دیربین",
+       "exif-model": "مودل ديربين",
+       "exif-software": "نرم افزار ب کارگرهڌني",
+       "exif-exifversion": "نوسقإ Exif",
+       "exif-colorspace": "رنگ ڤأرگأ",
+       "exif-datetimedigitized": "گات و وخت دیجیتالی کردن",
+       "exif-orientation-1": "عادي",
        "namespacesall": "همه",
        "monthsall": "همه ماهها",
+       "semicolon-separator": "؛&#32;",
        "watchlisttools-view": "نشودادن تغییرات مربوطه",
        "watchlisttools-edit": "نشودادن واصلاح کردن لیست پیگیریها",
        "watchlisttools-raw": "اصلاح لیست خام پی‌گیری‌ها",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|چک چنه]])",
        "version": "ترجمه یا تفسیر",
-       "specialpages": "صفحات ویژه"
+       "specialpages": "صفحات ویژه",
+       "tag-filter": "[[Special:سرديسا|سرديس]] فيلتر:",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|سرديس|سرديسا}}]]: $2)",
+       "logentry-delete-delete": "$1 بألگأ {{GENDER:$2|پاکسا ڤابيأ}} $3",
+       "searchsuggest-search": "جستن {{SITENAME}}"
 }
index c0c6e29..8962400 100644 (file)
        "activeusers-intro": "Setu aze ur roll eus an implijerien zo bet oberiant mui pe vui e-pad an $1 {{PLURAL:$1|deiz|deiz}} diwezhañ.",
        "activeusers-count": "$1 {{PLURAL:$1|oberiadenn}} abaoe an {{PLURAL:$3|deiz|$3 deiz}} diwezhañ",
        "activeusers-from": "Diskouez an implijerien adal :",
-       "activeusers-hidebots": "Kuzhat ar botoù",
-       "activeusers-hidesysops": "Kuzhat ar verourien",
        "activeusers-noresult": "N'eus bet kavet implijer ebet.",
        "listgrouprights": "Gwirioù ar strolladoù implijer",
        "listgrouprights-summary": "Da-heul ez eus ur roll eus ar strolladoù implijerien termenet war ar wiki-mañ, gant ar gwirioù moned stag outo.\nGallout a ra bezañ [[{{MediaWiki:Listgrouprights-helppage}}|titouroù ouzhpenn]] diwar-benn ar gwirioù hiniennel.",
        "feedback-bugornote": "Ma'z oc'h prest da zeskrivañ ur gudenn deknikel dre ar munud e c'hallit [$1 kemenn un draen].\nA-hend-all e c'hallit ober gant ar furmskrid eeunaet dindan. Ouzhpennet e vo hoc'h evezhiadenn d'ar bajenn \"[$3 $2]\", a-gevret gant hoc'h anv implijer hag anv ar merdeer a rit gantañ.",
        "feedback-cancel": "Nullañ",
        "feedback-close": "Graet",
-       "feedback-error-title": "Fazi",
        "feedback-error1": "Fazi : disoc'h dianav a-berzh an API",
        "feedback-error2": "Fazi : N'eus ket bet gallet degemer ar c'hemmoù",
        "feedback-error3": "Fazi : respont ebet a-berzh an API",
index c2b1d88..114b000 100644 (file)
@@ -51,7 +51,7 @@
        "tog-enotifminoredits": "Također mi pošalji e-poštu za male izmjene na stranicama i datotekama",
        "tog-enotifrevealaddr": "Otkrij adresu moje e-pošte u porukama obavještenja",
        "tog-shownumberswatching": "Prikaži broj korisnika koji prate",
-       "tog-oldsig": "Postojeći potpis:",
+       "tog-oldsig": "Vaš postojeći potpis:",
        "tog-fancysig": "Smatraj potpis kao wikitekst (bez automatskog linka)",
        "tog-uselivepreview": "Koristi pregled uživo",
        "tog-forceeditsummary": "Opomeni me pri unosu praznog sažetka",
@@ -68,7 +68,7 @@
        "tog-showhiddencats": "Prikaži skrivene kategorije",
        "tog-norollbackdiff": "Ne prikazuj razliku nakon izvršenog vraćanja",
        "tog-useeditwarning": "Upozori me kad napuštam stranicu za izmjene bez sačuvanih promjena",
-       "tog-prefershttps": "Uvijek koristi sigurnu konekciju kada sam prijavljen.",
+       "tog-prefershttps": "Uvijek koristi sigurnu vezu dok sam prijavljen",
        "underline-always": "Uvijek",
        "underline-never": "Nikad",
        "underline-default": "Prema predodređenim postavkama teme ili preglednika",
        "october-date": "$1. oktobar",
        "november-date": "$1. novembar",
        "december-date": "$1. decembar",
+       "period-am": "AM",
+       "period-pm": "PM",
        "pagecategories": "{{PLURAL:$1|Kategorija|Kategorije}}",
-       "category_header": "Članci u kategoriji \"$1\"",
-       "subcategories": "Podkategorije",
+       "category_header": "Stranice u kategoriji \"$1\"",
+       "subcategories": "Potkategorije",
        "category-media-header": "Datoteke u kategoriji \"$1\"",
        "category-empty": "''Ova kategorija trenutno ne sadrži članke ni medije.''",
        "hidden-categories": "{{PLURAL:$1|Sakrivena kategorija|Sakrivene kategorije}}",
        "hidden-category-category": "Skrivene kategorije",
        "category-subcat-count": "{{PLURAL:$2|Ova kategorija samo ima sljedeću potkategoriju.|Ova kategorija ima {{PLURAL:$1|sljedeću potkategoriju|sljedeće $1 potkategorije|sljedećih $1 potkategorija}}, od $2 ukupno.}}",
        "category-subcat-count-limited": "Ova kategorija sadrži {{PLURAL:$1|sljedeću $1 potkategoriju|sljedeće $1 potkategorije|sljedećih $1 potkategorija}}.",
-       "category-article-count": "{{PLURAL:$2|U ovoj kategoriji nalazi se $1 članak.|{{PLURAL:$1|Prikazan je $1 članak|Prikazana su $1 članka|Prikazano je $1 članaka}} od ukupno $2 u ovoj kategoriji.}}",
+       "category-article-count": "{{PLURAL:$2|Ova kategorija sadrži samo sljedeću stranicu.|{{PLURAL:$1|Sljedeća stranica je|Sljedeće $1 stranice su|Sljedećih $1 stranica je}} u ovoj kategoriji, od ukupno $2.}}",
        "category-article-count-limited": "{{PLURAL:$1|Slijedeća $1 stranica je|Slijedeće $1 stranice su|Slijedećih $1 stranica je}} u ovoj kategoriji.",
        "category-file-count": "{{PLURAL:$2|Ova kategorija ima slijedeću $1 datoteku.|{{PLURAL:$1|Prikazana je $1 datoteka|Prikazane su $1 datoteke|Prikazano je $1 datoteka}} u ovoj kategoriji, od ukupno $2.}}",
        "category-file-count-limited": "{{PLURAL:$1|Slijedeća $1 datoteka je|Slijedeće $1 datoteke su|Slijedećih $1 datoteka je}} u ovoj kategoriji.",
        "newwindow": "(otvara se u novom prozoru)",
        "cancel": "Odustani",
        "moredotdotdot": "Više...",
-       "morenotlisted": "Ovaj spisak nije potpun.",
+       "morenotlisted": "Ovaj spisak možda nije potpun.",
        "mypage": "Stranica",
        "mytalk": "Razgovor",
        "anontalk": "Razgovor",
        "talk": "Razgovor",
        "views": "Pregledi",
        "toolbox": "Alati",
+       "tool-link-userrights": "Promijeni {{GENDER:$1|korisničke}} grupe",
+       "tool-link-emailuser": "Pošalji e-poruku {{GENDER:$1|korisniku|korisnici}}",
        "userpage": "Pogledaj korisničku stranicu",
        "projectpage": "Pogledaj stranicu projekta",
        "imagepage": "Pogledajte stranicu datoteke",
        "confirmable-confirm": "Da li {{GENDER:$1|ste}} sigurni?",
        "confirmable-yes": "Da",
        "confirmable-no": "Ne",
-       "thisisdeleted": "Pogledati ili vratiti $1?",
+       "thisisdeleted": "Pogledaj ili vrati $1?",
        "viewdeleted": "Pogledaj $1?",
-       "restorelink": "{{PLURAL:$1|$1 izbrisana izmjena|$1 izbrisanih izmjena}}",
+       "restorelink": "{{PLURAL:$1|jednu obrisanu izmjenu|$1 obrisane izmjene|$1 obrisanih izmjena}}",
        "feedlinks": "Fid:",
        "feed-invalid": "Nedozvoljen tip potpisa",
        "feed-unavailable": "RSS izvori nisu dostupni",
        "laggedslavemode": "'''Upozorenje''': Stranica, možda, nije ažurirana.",
        "readonly": "Baza je zaključana",
        "enterlockreason": "Unesite razlog za zaključavanje, uključujući procjenu vremena otključavanja",
-       "readonlytext": "Baza je trenutno zaključana za nove unose i ostale izmjene, vjerovatno zbog rutinskog održavanja, posle čega će biti vraćena u uobičajeno stanje.\n\nAdministrator koji ju je zaključao je ponudio ovo objašnjenje: $1",
+       "readonlytext": "Baza podataka trenutno je zaključana za nove unose i druge izmjene, vjerovatno zbog rutinskog održavanja, nakon čega će biti vraćena u uobičajeno stanje.\n\nSistemski administrator koji ju je zaključao naveo je sljedeće objašnjenje: $1",
        "missing-article": "U bazi podataka nije pronađen tekst stranice tražen pod nazivom \"$1\" $2.\n\nDo ovoga dolazi kad se prati pomjeranje ili historija linka za stranicu koja je pobrisana.\n\n\nU slučaju da se ne radi o gore navedenom moguće je da ste pronašli grešku u programu.\nMolimo Vas da ovo prijavite [[Special:ListUsers/sysop|administratoru]] s navođenjem tačne adrese stranice.",
        "missingarticle-rev": "(revizija#: $1)",
        "missingarticle-diff": "(Razlika: $1, $2)",
        "userlogin-resetpassword-link": "Zaboravili ste lozinku?",
        "userlogin-helplink2": "Pomoć pri prijavljivanju",
        "userlogin-loggedin": "Već ste prijavljeni kao {{GENDER:$1|$1}}.\nKoristite donji obrazac da biste se prijavili kao drugi korisnik.",
+       "userlogin-reauth": "Morate se ponovo prijaviti da bismo potvrdili da ste zaista {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Napravi još jedan račun",
        "createacct-emailrequired": "Adresa e-pošte",
        "createacct-emailoptional": "Adresa e-pošte (opcionalno)",
        "noname": "Niste izabrali ispravno korisničko ime.",
        "loginsuccesstitle": "Prijavljen",
        "loginsuccess": "'''Sad ste prijavljeni na {{SITENAME}} kao \"$1\".'''",
-       "nosuchuser": "Ne postoji korisnik s imenom \"$1\".\nKorisnička imena razlikuju velika i mala slova.\nProvjerite Vaš unos ili [[Special:CreateAccount|napravite novi korisnički račun]].",
+       "nosuchuser": "Ne postoji korisnik s imenom \"$1\".\nKorisnička imena razlikuju velika i mala slova.\nProvjerite jeste li ga tačno upisali ili [[Special:CreateAccount|otvorite novi račun]].",
        "nosuchusershort": "Ne postoji korisnik s imenom \"$1\".\nProvjerite jeste li dobro ukucali.",
        "nouserspecified": "Morate izabrati korisničko ime.",
        "login-userblocked": "Ovaj korisnik je blokiran. Prijava nije dopuštena.",
        "wrongpasswordempty": "Lozinka koju ste unijeli je bila prazna.\nMolimo Vas da pokušate ponovno.",
        "passwordtooshort": "Lozinka mora imati najmanje {{PLURAL:$1|1 znak|$1 znaka|$1 znakova}}.",
        "passwordtoolong": "Lozinke ne mogu biti duže od {{PLURAL:$1|jednog znaka|$1 znaka|$1 znakova}}.",
+       "passwordtoopopular": "Ovo je često korištena lozinka i ne može se koristiti. Molimo Vas da izaberete jaču lozinku.",
        "password-name-match": "Vaša lozinka mora biti različita od Vašeg korisničkog imena.",
        "password-login-forbidden": "Korištenje ovih korisničkih imena i šifara je zabranjeo.",
        "mailmypassword": "Poništi lozinku",
        "noemail": "Ne postoji adresa e-pošte za korisnika \"$1\".",
        "noemailcreate": "Morate da navedete validnu e-mail adresu",
        "passwordsent": "Nova lozinka poslana je na adresu e-pošte korisnika \"$1\".\nMolimo Vas da se prijavite nakon što je primite.",
-       "blocked-mailpassword": "Da bi se spriječila nedozvoljena akcija, Vašoj IP adresi je onemogućeno uređivanje stranica kao i mogućnost zahtijevanje nove lozinke.",
+       "blocked-mailpassword": "Vašoj IP-adresi onemogućeno je uređivanje. Da bi se spriječila zloupotreba, s nje nije moguće zahtijevati novu lozinku.",
        "eauthentsent": "Na navedenu adresu e-pošte poslana je poruka s potvrdom.\nPrije nego što pošaljemo daljnje poruke, pratite uputstva s e-pošte da biste potvrdili da je račun zaista Vaš.",
        "throttled-mailpassword": "Već Vam je poslana e-poruka za promjenu lozinke u {{PLURAL:$1|posljednjih sat vremena|posljednja $1 sata|posljednjih $1 sati}}.\nDa bi se spriječila zloupotreba, može se poslati samo jedna e-poruka za promjenu lozinke {{PLURAL:$1|svakih sat vremena|svaka $1 sata|svakih $1 sati}}.",
        "mailerror": "Greška pri slanju e-pošte: $1",
        "passwordreset-emailtext-ip": "Neko (vjerovatno Vi, s IP adrese $1) je zatražio podsjetnik Vaših detalja računa za {{SITENAME}} ($4). Sljedeći {{PLURAL:$3|račun korisnika je|računi korisnika su}} povezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena šifra|Ove privremene šifre}} će isteći za {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu šifru. Ako je neko drugi napravio ovaj zahtjev, ili ako ste se sjetili Vaše početne šifre, a ne želite je promijeniti, možete zanemariti ovu poruku i nastaviti koristiti staru šifru.",
        "passwordreset-emailtext-user": "Korisnik $1 na {{SITENAME}} je zatražio podsjetnik o detaljima Vašeg računa za {{SITENAME}} ($4). Sljedeći {{PLURAL:$3|korisnički račun je|korisnički računi su}} povezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena šifra|Ove privremene šifre}} će isteći za {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu šifru. Ako je neko drugi napravio ovaj zahtjev, ili ako ste se sjetili Vaše originalne šifre, a ne želite je više promijeniti, možete zanemariti ovu poruku i nastaviti koristiti staru šifru.",
        "passwordreset-emailelement": "Korisničko ime: \n$1\n\nPrivremena šifra: \n$2",
-       "passwordreset-emailsentemail": "Ako je ovo adresa e-pošte s kojom ste registrirali ovaj račun, podsjetnik šifre će vam biti poslan na vašu adresu e-pošte.",
+       "passwordreset-emailsentemail": "Ako je ova adresa e-pošte povezana s Vašim računom, podsjetnik o lozinci bit će Vam poslan na adresu e-pošte.",
        "changeemail": "Promjena ili uklanjanje e-adrese",
        "changeemail-header": "Ispunite sljedeći formular da biste promijenili adresu e-pošte. Ako želite ukloniti postojeću adresu e-pošte s vašeg korisničkog računa, pri ispunjavanju formulara, polje nove adrese e-pošte ostavite prazno.",
        "changeemail-no-info": "Morate biti prijavljeni za direktan pristup ovoj stranici.",
        "accmailtext": "Nasumično odabrana šifra za [[User talk:$1|$1]] je poslata na adresu $2.\n\nŠifra/lozinka za ovaj novi račun može biti promijenjena na stranici ''[[Special:ChangePassword|izmjene šifre]]'' nakon prijave.",
        "newarticle": "(Novi)",
        "newarticletext": "Došli ste na stranicu koja još nema sadržaja.\n*Ako želite unijeti sadržaj, počnite tipkati u prozor ispod ovog teksta.\n*Ako Vam treba pomoć, idite na [$1 stranicu za pomoć].\n*Ako ste ovamo dospjeli slučajno, kliknite na dugme \"Nazad\" (''Back'') u Vašem internetskom pregledniku.",
-       "anontalkpagetext": "----''Ovo je stranica za razgovor za anonimnog korisnika koji još nije napravio nalog ili ga ne koristi.\nZbog toga moramo da koristimo brojčanu IP adresu kako bismo identifikovali njega ili nju.\nTakvu adresu može dijeliti više korisnika.\nAko ste anonimni korisnik i mislite da su vam upućene nebitne primjedbe, molimo Vas da [[Special:CreateAccount|napravite nalog]] ili se [[Special:UserLogin|prijavite]] da biste izbjegli buduću zabunu sa ostalim anonimnim korisnicima.''",
+       "anontalkpagetext": "----\n<em>Ovo je stranica za razgovor s anonimnim korisnikom koji još nije napravio račun ili ga ne koristi.</em>\nZbog toga moramo koristiti brojčanu IP-adresu kako bismo ga prepoznali.\nTakvu adresu može dijeliti više korisnika.\nAko ste anonimni korisnik i smatrate da su Vam upućene nebitne primjedbe, molimo Vas da [[Special:CreateAccount|napravite račun]] ili se [[Special:UserLogin|prijavite]] da biste izbjegli buduću zabunu s ostalim anonimnim korisnicima.",
        "noarticletext": "Na ovoj stranici trenutno nema teksta.\nMožete [[Special:Search/{{PAGENAME}}|tražiti naslov ove stranice]] na drugim stranicama,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} tražiti u povezanim zapisnicima] ili [{{fullurl:{{FULLPAGENAME}}|action=edit}} napraviti ovu stranicu]</span>.",
        "noarticletext-nopermission": "Trenutno nema teksta na ovoj stranici.\nMožete [[Special:Search/{{PAGENAME}}|tražiti ovaj naslov stranice]] na drugim stranicama ili <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} pretražiti povezane zapisnike]</span>, ali nemate dozvolu da napravite ovu stranicu.",
        "missing-revision": "Uređivanje broj $1 na stranici \"{{FULLPAGENAME}}\" ne postoji.\n\nOvo se obično dešava kad pratite zastarjelu vezu na stranicu koja je obrisana.\nViše informacija možete pronaći u [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} protokolu brisanja].",
        "previewnote": "<strong>Ne zaboravite da je ovo samo pregled.</strong>\nVaše izmjene još nisu sačuvane!",
        "continue-editing": "Idi na područje uređivanja",
        "previewconflict": "Ovaj pregled prikazuje kako će tekst u gornjem polju\nizgledati ako kliknete \"Sačuvaj članak\".",
-       "session_fail_preview": "<strong>Izvinjavamo se! Nismo mogli obraditi vašu izmjenu zbog gubitka podataka o prijavi.\nMolimo pokušajte ponovno.\nAko i dalje ne bude radilo, pokušajte se [[Special:UserLogout|odjaviti]] i ponovno prijaviti.</strong>",
+       "session_fail_preview": "Izvinjavamo se! Nismo mogli obraditi Vašu izmjenu zbog gubitka podataka o prijavi.\n\nMožda ste odjavljeni. <strong>Provjerite jeste li prijavljeni i pokušajte ponovo</strong>.\nAko i dalje ne radi, pokušajte se [[Special:UserLogout|odjaviti]] i ponovo prijaviti i provjerite dozvoljava li Vaš preglednik kolačiće s ovog sajta.",
        "session_fail_preview_html": "'''Žao nam je! Nismo mogli da obradimo vašu izmjenu zbog gubitka podataka.'''\n\n''Zbog toga što {{SITENAME}} ima omogućen izvorni HTML, predpregled je sakriven kao predostrožnost protiv JavaScript napada.''\n\n'''Ako ste pokušali da napravite pravu izmjenu, molimo pokušajte ponovo. Ako i dalje ne radi, pokušajte da se [[Special:UserLogout|odjavite]] i ponovo prijavite.'''",
        "token_suffix_mismatch": "'''Vaša izmjena nije prihvaćena jer je Vaš web preglednik ubacio znakove interpunkcije u token uređivanja.\nIzmjena je odbačena da bi se spriječilo uništavanje teksta stranice.\nTo se događa ponekad kad korisite problematični anonimni proxy koji je baziran na web-u.'''",
        "edit_form_incomplete": "'''Neki dijelovi uređivačkog obrasca nisu došli do servera; dvaput provjerite da su vaše izmjene nepromjenjene i pokušajte ponovno.'''",
        "nohistory": "Ne postoji historija izmjena za ovu stranicu.",
        "currentrev": "Trenutna verzija",
        "currentrev-asof": "Trenutna verzija na dan $2 u $3",
-       "revisionasof": "Verzija od $1",
+       "revisionasof": "Verzija na dan $2 u $3",
        "revision-info": "Izmjena od $1 od {{GENDER:$6|$2}}$7",
        "previousrevision": "← Starija izmjena",
        "nextrevision": "Novija izmjena →",
        "revdelete-submit": "Primijeni na odabrane {{PLURAL:$1|reviziju|revizije}}",
        "revdelete-success": "'''Vidljivost izmjene je ažurirana.'''",
        "revdelete-failure": "'''Vidljivost revizije nije mogla biti ažurirana:'''\n$1",
-       "logdelete-success": "'''Vidljivost evidencije uspješno postavljena.'''",
+       "logdelete-success": "Postavljena je vidljivost unosa u zapisniku.",
        "logdelete-failure": "'''Zapisnik vidljivosti nije mogao biti postavljen:'''\n$1",
        "revdel-restore": "Promijeni dostupnost",
        "pagehist": "Historija stranice",
        "difference-multipage": "(Razlika između stranica)",
        "lineno": "Red $1:",
        "compareselectedversions": "Uporedi označene verzije",
-       "showhideselectedversions": "Pokaži/sakrij odabrane verzije",
+       "showhideselectedversions": "Prikaži/sakrij izabrane izmjene",
        "editundo": "poništi",
        "diff-empty": "(Nema razlike)",
        "diff-multi-sameuser": "({{PLURAL:$1|Nije prikazana jedna međurevizija|Nisu prikazane $1 međurevizije}} istog korisnika)",
        "editusergroup": "Uredi {{GENDER:$1|korisničke}} grupe",
        "editinguser": "Mijenjate korisnička prava korisnika <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Uredi korisničke grupe",
-       "saveusergroups": "Sačuvaj korisničke grupe",
+       "saveusergroups": "Sačuvaj {{GENDER:$1|korisničke}} grupe",
        "userrights-groupsmember": "Član:",
        "userrights-groupsmember-auto": "Uključeni član od:",
        "userrights-groups-help": "Možete promijeniti grupe kojima ovaj korisnik pripada:\n* Označeni kvadratić znači da je korisnik u toj grupi.\n* Neoznačen kvadratić znači da korisnik nije u toj grupi.\n* Oznaka * (zvjezdica) označava da Vi ne možete izbrisati ovu grupu ako je dodate i obrnutno.",
        "right-override-export-depth": "Izvoz stranica uključujući povezane stranice do dubine od 5 linkova",
        "right-sendemail": "Slanje e-maila drugim korisnicima",
        "right-passwordreset": "Pogledaj e-mailove za obnavljanje šifre",
-       "right-managechangetags": "Napravi i briši [[Special:Tags|oznake]] iz baze podataka",
+       "right-managechangetags": "Napravi i (de)aktiviraj [[Special:Tags|oznake]]",
        "right-applychangetags": "Primijeni [[Special:Tags|oznake]] na nečije izmjene",
        "right-changetags": "Dodavanje ili uklanjanje raznih [[Special:Tags|oznaka]] na pojedinačnim verzijama i unosima zapisnika",
        "grant-group-page-interaction": "Upravljanje stranicama",
        "uploadstash-clear": "Očisti sakrivene datoteke",
        "uploadstash-nofiles": "Nemate sakrivenih datoteka.",
        "uploadstash-badtoken": "Izvršavanje ove akcije je bilo neuspješno, možda zato što su vaša uređivačka odobrenja istekla. Pokušajte ponovo.",
-       "uploadstash-errclear": "Brisanje sakrivenih datoteka je bilo neuspješno.",
+       "uploadstash-errclear": "Brisanje datoteka nije uspjelo.",
        "uploadstash-refresh": "Osvježi spisak datoteka",
        "invalid-chunk-offset": "Neispravna polazna tačka",
        "img-auth-accessdenied": "Pristup onemogućen",
        "filehist-filesize": "Veličina datoteke",
        "filehist-comment": "Komentar",
        "imagelinks": "Upotreba datoteke",
-       "linkstoimage": "{{PLURAL:$1|Slijedeća stranica koristi|Slijedećih $1 stranica koriste}} ovu sliku:",
+       "linkstoimage": "{{PLURAL:$1|Sljedeća stranica koristi|Sljedeće $1 stranice koriste|Sljedećih $1 stranica koristi}} ovu datoteku:",
        "linkstoimage-more": "Više od $1 {{PLURAL:$1|datoteke|datoteka}} povezano je s ovom datotekom.\nSljedeći spisak pokazuje samo {{PLURAL:$1|prvu stranicu povezanu|prve $1 stranice povezane|prvih $1 stranica povezanih}} s ovom datotekom.\nOvdje je dostupan [[Special:WhatLinksHere/$2|potpuni spisak]].",
        "nolinkstoimage": "Nema stranica koje koriste ovu datoteku.",
        "morelinkstoimage": "Vidi [[Special:WhatLinksHere/$1|ostale linkove]] prema ovoj datoteci.",
        "pageswithprop-prophidden-long": "sakriveno dugo tekstualno svojstvo ($1)",
        "pageswithprop-prophidden-binary": "sakriveno dugo binarno svojstvo ($1)",
        "doubleredirects": "Dvostruka preusmjerenja",
-       "doubleredirectstext": "Ova stranica prikazuje stranice koje preusmjeravaju na druga preusmjerenja.\nSvaki red sadrži veze na prvo i drugo preusmjerenje, kao i na prvu liniju teksta drugog preusmjerenja, što obično daje \"pravi\" ciljni članak, na koji bi prvo preusmjerenje i trebalo da pokazuje.\n<del>Precrtane</del> stavke su riješene.",
+       "doubleredirectstext": "Ova stranica prikazuje stranice koje preusmjeravaju na druga preusmjerenja.\nSvaki red sadrži linkove na prvo i drugo preusmjerenje, kao i na odredišnu stranicu drugog preusmjerenja koja je obično \"pravi\" članak na koji bi prvo preusmjerenje trebalo upućivati.\n<del>Precrtane</del> stavke su riješene.",
        "double-redirect-fixed-move": "[[$1]] je premješten.\nAutomatski je ažuriran i sada preusmjerava na [[$2]].",
        "double-redirect-fixed-maintenance": "Automatsko ospravljanje dvostrukih preusmjerenja sa [[$1]] na [[$2]] je posao održavanja.",
        "double-redirect-fixer": "Popravljač preusmjerenja",
        "withoutinterwiki-legend": "Prefiks",
        "withoutinterwiki-submit": "Prikaži",
        "fewestrevisions": "Stranice sa najmanje izmjena",
-       "nbytes": "$1 {{PLURAL:$1|bajt|bajtova}}",
+       "nbytes": "$1 {{PLURAL:$1|bajt|bajta|bajtova}}",
        "ncategories": "$1 {{PLURAL:$1|kategorija|kategorije}}",
        "ninterwikis": "$1 {{PLURAL:$1|međujezična veza|međujezične veze}}",
        "nlinks": "$1 {{PLURAL:$1|veza|veze}}",
        "log-title-wildcard": "Traži naslove koji počinju ovim tekstom",
        "showhideselectedlogentries": "Pokaži/sakrij izabrane zapise u evidenciji",
        "log-edit-tags": "Uredi oznake izabranih zapisničkih unosa",
+       "checkbox-select": "Izaberi: $1",
+       "checkbox-all": "Sve",
+       "checkbox-none": "Ništa",
+       "checkbox-invert": "Obrni",
        "allpages": "Sve stranice",
        "nextpage": "Sljedeća stranica ($1)",
        "prevpage": "Prethodna stranica ($1)",
        "activeusers-intro": "Ovo je spisak korisnika koji su imali neku aktivnost u {{PLURAL:$1|posljednji $1 dan|posljednja $1 dana|posljednjih $1 dana}}.",
        "activeusers-count": "$1 {{PLURAL:$1|izmjena|izmjene|izmjena}} u {{PLURAL:$3|posljednji $3 dan|posljednja $3 dana|posljednjih $3 dana}}",
        "activeusers-from": "Prikaži korisnike koji počinju sa:",
-       "activeusers-hidebots": "Sakrij botove",
-       "activeusers-hidesysops": "Sakrij administratore",
        "activeusers-noresult": "Nije pronađen korisnik.",
        "listgrouprights": "Prava korisničkih grupa",
        "listgrouprights-summary": "Slijedi spisak korisničkih grupa na ovoj wiki, s njihovim pripadajućim pravima pristupa.\nMoguće je da o svakoj grupi postoje [[{{MediaWiki:Listgrouprights-helppage}}|dodatne informacije]].",
        "enotif_body": "Poštovani $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nSažetak urednika: $PAGESUMMARY $PAGEMINOREDIT\n\nKontaktirajte urednika:\ne-pošta: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nNeće biti drugih obavještenja u slučaju daljnjih izmjena osim ako prijavljeni ponovno posjetite stranicu. Također možete poništiti oznake obavijesti za sve praćene stranice koje imate na vašem spisku praćenja.\n\nVaš prijateljski {{SITENAME}} sistem obavještavanja\n\n--\nZa promjenu vaših postavki email obavijesti, posjetite\n{{canonicalurl:{{#special:Preferences}}}}\n\nZa promjenu postavki vašeg praćenja, posjetite\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nDa obrišete stranicu sa vašeg spiska praćenja, posjetite\n$UNWATCHURL\n\nPovratne informacije i daljnja pomoć:\n$HELPPAGE",
        "created": "napravljena",
        "changed": "promijenjena",
-       "deletepage": "Obrišite stranicu",
+       "deletepage": "Obriši stranicu",
        "confirm": "Potvrdite",
        "excontent": "sadržaj je bio: \"$1\"",
        "excontentauthor": "sadržaj je bio: \"$1\", a jedini urednik \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|razgovor]])",
        "exbeforeblank": "sadržaj prije brisanja je bio: \"$1\"",
        "delete-confirm": "Brisanje \"$1\"",
        "delete-legend": "Obriši",
-       "historywarning": "<strong>Upozorenje</strong>: Stranica koju želite da obrišete ima historiju sa otprilike $1 {{PLURAL:$1|revizijom|revizije|revizija}}:",
+       "historywarning": "<strong>Upozorenje:</strong> Stranica koju želite obrisati ima historiju sa $1 {{PLURAL:$1|izmjenom|izmjene|izmjena}}:",
        "historyaction-submit": "Prikaži",
-       "confirmdeletetext": "Brisanjem ćete obrisati stranicu ili sliku zajedno sa historijom iz baze podataka, ali će se iste moći vratiti kasnije.\nMolim potvrdite svoju namjeru, da razumijete posljedice i da ovo radite u skladu sa [[{{MediaWiki:Policy-url}}|pravilima]].",
+       "confirmdeletetext": "Obrisat ćete stranicu i njenu historiju.\nPotvrdite svoju namjeru, da razumijete posljedice i da ovo radite u skladu s [[{{MediaWiki:Policy-url}}|pravilima]].",
        "actioncomplete": "Radnja je izvršena",
        "actionfailed": "Akcija nije uspjela",
        "deletedtext": "Stranica \"$1\" je obrisana.\nPogledajte $2 za zapisnik nedavnih brisanja.",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|promijenio|promijenila}} je model sadržaja stranice $3 iz \"$4\" u \"$5\"",
        "logentry-contentmodel-change-revertlink": "vrati",
        "logentry-contentmodel-change-revert": "vrati",
-       "protectlogpage": "Zapisnik zaključavanja",
+       "protectlogpage": "Zapisnik zaštite",
        "protectlogtext": "Ispod je spisak promjena zaštićenja stranice.\nPogledajte [[Special:ProtectedPages|spisak zaštićenih stranica]] za pregled trenutno zaštićenih stranica.",
        "protectedarticle": "{{GENDER:|zaštitio|zaštitila}} je stranicu \"[[$1]]\"",
        "modifiedarticleprotection": "{{GENDER:|promijenio|promijenila}} je stepen zaštite stranice \"[[$1]]\"",
        "restriction-level-all": "svi nivoi",
        "undelete": "Pregled obrisanih stranica",
        "undeletepage": "Pregled i vraćanje obrisanih stranica",
-       "undeletepagetitle": "'''Sljedeći sadržaj prikazuje obrisane revizije od [[:$1|$1]]'''.",
+       "undeletepagetitle": "<strong>Sljedeći sadržaj prikazuje obrisane izmjene stranice [[:$1|$1]]</strong>.",
        "viewdeletedpage": "Pregled obrisanih stranica",
        "undeletepagetext": "{{PLURAL:$1|Slijedeća $1 stranica je obrisana|Slijedeće $1 stranice su obrisane|Slijedećih $1 je obrisano}} ali su još uvijek u arhivi i mogu biti vraćene.\nArhiva moše biti periodično čišćena.",
-       "undelete-fieldset-title": "Vraćanje revizija",
-       "undeleteextrahelp": "Da biste vratili cijelu historiju stranice, ostavite sve kućice neoznačene i kliknite na <strong><em>{{int:undeletebtn}}</em></strong>.\nDa biste vratili određene stranice, izaberite verzije koje želite vratiti i kliknite na <strong><em>{{int:undeletebtn}}</em></strong>.",
+       "undelete-fieldset-title": "Vraćanje izmjena",
+       "undeleteextrahelp": "Da biste vratili cijelu historiju stranice, ostavite sve kućice neoznačene i kliknite na <strong><em>{{int:undeletebtn}}</em></strong>.\nDa biste vratili određene izmjene, označite ih i kliknite na <strong><em>{{int:undeletebtn}}</em></strong>.",
        "undeleterevisions": "$1 {{PLURAL:$1|izmjena je obrisana|izmjena je obrisano}}",
-       "undeletehistory": "Ako vratite stranicu, sve će verzije biti vraćene u njenu historiju.\nAko je u međuvremenu napravljena nova verzija s istim nazivom, vraćene verzije će se pojaviti njenoj ranijoj historiji.",
-       "undeleterevdel": "Vraćanje obrisanog se neće izvršiti ako bi rezultiralo da zaglavlje stranice ili revizija datoteke bude djelimično obrisano.\nU takvim slučajevima, morate ukloniti označene ili otkriti sakrivene najskorije obrisane revizije.",
+       "undeletehistory": "Ako vratite stranicu, sve će izmjene biti vraćene u njenu historiju.\nAko je u međuvremenu napravljena nova izmjena s istim nazivom, vraćene izmjene pojavit će se u njenoj ranijoj historiji.",
+       "undeleterevdel": "Vraćanje neće biti izvršeno ako je rezultat toga djelomično brisanje posljednje izmjene.\nU takvim slučajevima morate isključiti ili otkriti najnoviju obrisanu izmjenu.",
        "undeletehistorynoadmin": "Ova stranica je obrisana.\nRazlog za brisanje se nalazi ispod, zajedno s detaljima o korisniku koji je mijenjao stranicu prije brisanja.\nTekst obrisanih verzija dostupan je samo administratorima.",
        "undelete-revision": "Obrisana izmjena stranice $1 (dana $4, u $5) koju je {{GENDER:$3|napravio|napravila}} $3:",
        "undeleterevision-missing": "Nepoznata ili nedostajuća revizija.\nMožda ste unijeli pogrešan link, ili je revizija vraćena ili uklonjena iz arhive.",
        "undeletebtn": "Vrati",
        "undeletelink": "pogledaj/vrati",
        "undeleteviewlink": "pogledaj",
-       "undeleteinvert": "Izmijeni odabir",
+       "undeleteinvert": "Obrni izbor",
        "undeletecomment": "Razlog:",
        "undeletedrevisions": "{{PLURAL:$1|vraćena $1 verzija|vraćene $1 verzije|vraćeno $1 verzija}}",
        "undeletedrevisions-files": "{{PLURAL:$1|1 verzija|$1 verzije|$1 verzija}} i {{PLURAL:$2|1 datoteka|$2 datoteke|$2 datoteka}} vraćeno",
        "undeletedfiles": "{{PLURAL:$1|1 datoteka vraćena|$1 datoteke vraćene|$1 datoteka vraćeno}}",
-       "cannotundelete": "Vraćanje nije uspjelo:\n$1",
+       "cannotundelete": "Vraćanje jedne ili svih stavki nije uspjelo:\n$1",
        "undeletedpage": "'''$1 je vraćena'''\n\nProvjerite [[Special:Log/delete|zapis brisanja]] za zapise najskorijih brisanja i vraćanja.",
        "undelete-header": "Pogledajte [[Special:Log/delete|zapisnik brisanja]] za nedavno obrisane stranice.",
        "undelete-search-title": "Pretraga obrisanih stranica",
        "sp-contributions-newbies-sub": "Za nove korisnike",
        "sp-contributions-newbies-title": "Doprinosi novih korisnika",
        "sp-contributions-blocklog": "zapisnik blokiranja",
-       "sp-contributions-suppresslog": "obrisani doprinosi korisnika",
-       "sp-contributions-deleted": "obrisani doprinosi korisnika",
+       "sp-contributions-suppresslog": "obrisani {{GENDER:$1|korisnički}} doprinosi",
+       "sp-contributions-deleted": "obrisani {{GENDER:$1|korisnički}} doprinosi",
        "sp-contributions-uploads": "postavljanja",
        "sp-contributions-logs": "zapisnici",
        "sp-contributions-talk": "razgovor",
        "whatlinkshere-hideredirs": "$1 preusmjerenja",
        "whatlinkshere-hidetrans": "$1 uključenja",
        "whatlinkshere-hidelinks": "$1 linkove",
-       "whatlinkshere-hideimages": "Veze do datoteke $1",
+       "whatlinkshere-hideimages": "$1 linkova do datoteke",
        "whatlinkshere-filters": "Filteri",
        "autoblockid": "Automatska blokada #$1",
        "block": "Blokiraj korisnika",
        "move-page": "Premjesti $1",
        "move-page-legend": "Premjesti stranicu",
        "movepagetext": "Korištenjem ovog formulara možete preimenovati stranicu, premještajući cijelu historiju na novo ime.\nČlanak pod starim imenom postat će stranica koja preusmjerava na članak pod novim imenom. \nMožete automatski izmijeniti preusmjerenje do izvornog naslova.\nAko se ne odlučite na to, provjerite [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|neispravna preusmjeravanja]].\nDužni ste provjeriti da svi linkovi i dalje nastave voditi na prave stranice.\n\nImajte na umu da članak '''neće''' biti premješten ako već postoji članak pod imenom na koje ga namjeravate preusmjeriti osim u slučaju stranice za preusmjeravanje koja nema nikakvih starih izmjena.\nTo znači da možete vratiti stranicu na prethodno mjesto ako pogriješite, ali ne možete zamijeniti postojeću stranicu.\n\n'''Pažnja!'''\nOvo može biti drastična i neočekivana promjena kad su u pitanju popularne stranice.\nMolimo da dobro razmislite prije no što premjestite stranicu.",
-       "movepagetext-noredirectfixer": "Koristeći donji obrazac, preimenovat ćete stranicu i premjestiti cijelu njenu historiju na novi naziv.\nStari naziv postat će preusmjerenje na novi naziv.\nMolimo da provjerite postoje li [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|nedovršena preusmjerenja]].\nVi ste za to odgovorni te morate provjeriti jesu li linkovi ispravni i vode li tamo kamo bi trebali voditi.\n\nImajte na umu da stranica '''neće''' biti premještena ako već postoji stranica s tim imenom, osim ako je prazna ili je preusmjerenje ili nema ranije historije.\nOvo znači da možete preimenovati stranicu nazad gdje je ranije bila preimenovana ako ste pogriješili, ali ne možete ponovo preimenovati postojeću stranicu.\n\n'''Pažnja!'''\nImajte na umu da premještanje popularnog članka može biti\ndrastična i neočekivana promjena za korisnike; molimo da budete sigurni da ste shvatili posljedice prije no što nastavite.",
+       "movepagetext-noredirectfixer": "Koristeći donji obrazac, preimenovat ćete stranicu i premjestiti cijelu njenu historiju na novi naziv.\nStari naziv postat će preusmjerenje na novi naziv.\nMolimo da provjerite postoje li [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|nedovršena preusmjerenja]].\nVi ste za to odgovorni te morate provjeriti jesu li linkovi ispravni i vode li tamo kamo bi trebali voditi.\n\nImajte na umu da stranica '''neće''' biti premještena ako već postoji stranica s tim imenom, osim ako je prazna ili je preusmjerenje ili nema ranije historije.\nOvo znači da možete preimenovati stranicu nazad gdje je ranije bila preimenovana ako ste pogriješili, ali ne možete ponovo preimenovati postojeću stranicu.\n\n<strong>Napomena:</strong>\nImajte na umu da premještanje popularnog članka može biti\ndrastična i neočekivana promjena za korisnike; molimo da budete sigurni da ste shvatili posljedice prije no što nastavite.",
        "movepagetalktext": "Ako označite ovu kutijicu, odgovarajuća stranica za razgovor, ako postoji, automatski će biti premještena na novi naziv, osim ako već postoji sadržaj na odredišnoj stranici za razgovor.\n\nU tom slučaju, morat ćete ručno premjestiti ili prekopirati stranicu ako to želite.",
-       "moveuserpage-warning": "'''Upozorenje:''' Premještate korisničku stranicu. Molimo da zapamtite da će se samo stranica premjestiti a korisnik se ''neće'' preimenovati.",
+       "moveuserpage-warning": "<strong>Upozorenje:</strong> Premještate korisničku stranicu. Imajte u vidu da će samo stranica biti premještena, a sam korisnik <em>neće</em> biti preimenovan.",
        "movecategorypage-warning": "<strong>Upozorenje:</strong> Premještate stranicu kategorije. Imajte na umu da će samo stranica biti premještena i da sve stranice u staroj kategoriji <em>neće</em> biti ponovo kategorirane u novu kategoriju.",
        "movenologintext": "Morate biti registrovani korisnik i [[Special:UserLogin|prijavljeni]] da biste premjestili stranicu.",
        "movenotallowed": "Nemate dopuštenje za premještanje stranica.",
        "cant-move-category-page": "Nemate dopuštene da premještate stranice kategorija.",
        "cant-move-to-category-page": "Nemate dopuštenje da premjestite stranicu na stranicu kategorije.",
        "newtitle": "Novi naslov:",
-       "move-watch": "Prati ovu stranicu",
+       "move-watch": "Prati izvornu i odredišnu stranicu",
        "movepagebtn": "Premjesti stranicu",
        "pagemovedsub": "Premještanje uspjelo",
-       "movepage-moved": "'''\"$1\" je premještena na \"$2\"'''",
+       "movepage-moved": "<strong>\"$1\" je premještena na \"$2\"</strong>",
        "movepage-moved-redirect": "Preusmjerenje je napravljeno.",
        "movepage-moved-noredirect": "Pravljenje preusmjerenja je onemogućeno.",
        "articleexists": "Stranica pod tim imenom već postoji ili je ime koje ste izabrali neispravno. Molimo Vas da izaberete drugo ime.",
        "cantmove-titleprotected": "Ne možete premjestiti stranicu na ovu lokaciju jer je novi naslov zaštićen od pravljenja.",
-       "movetalk": "Premjestite i stranicu za razgovor ako je moguće.",
+       "movetalk": "Premjesti i stranicu za razgovor",
        "move-subpages": "Premjesti sve podstranice (do $1)",
        "move-talk-subpages": "Premjesti podstranice stranica za razgovor (do $1)",
        "movepage-page-exists": "Stranica $1 već postoji i ne može biti automatski zamijenjena.",
        "movenosubpage": "Ova stranica nema podstranica.",
        "movereason": "Razlog:",
        "revertmove": "vrati",
-       "delete_and_move_text": "==Potebno brisanje==\nOdredišna stranica \"[[:$1]]\" već postoji.\nDa li je želite obrisati kako bi ste mogli izvršiti premještanje?",
+       "delete_and_move_text": "Odredišna stranica \"[[:$1]]\" već postoji.\nŽelite li je obrisati da biste oslobodili mjesto za premještanje?",
        "delete_and_move_confirm": "Da, obriši stranicu",
-       "delete_and_move_reason": "Obrisano da bi se napravio prostor za premještanje iz \"[[$1]]\"",
+       "delete_and_move_reason": "Obrisano da se oslobodi mjesto za premještanje iz \"[[$1]]\"",
        "selfmove": "Izvorni i ciljani naziv su isti; strana ne može da se premjesti preko same sebe.",
        "immobile-source-namespace": "Ne mogu premjestiti stranice u imenski prostor \"$1\"",
        "immobile-target-namespace": "Ne mogu se premjestiti stranice u imenski prostor \"$1\"",
        "tooltip-ca-move": "Premjesti ovu stranicu",
        "tooltip-ca-watch": "Dodajte stranicu u listu praćnih članaka",
        "tooltip-ca-unwatch": "Ukloni ovu stranicu sa spiska praćenih članaka",
-       "tooltip-search": "Pretraži projekat {{SITENAME}}",
+       "tooltip-search": "Pretraži {{GRAMMAR:akuzativ|{{SITENAME}}}}",
        "tooltip-search-go": "Idi na stranicu s tačno ovim imenom ako postoji",
        "tooltip-search-fulltext": "Pretražite stranice s ovim tekstom",
        "tooltip-p-logo": "Glavna stranica",
        "pageinfo-category-subcats": "Broj potkategorija",
        "pageinfo-category-files": "Broj datoteka",
        "markaspatrolleddiff": "Označi kao patrolirano",
-       "markaspatrolledtext": "Označi ovaj članak kao patroliran",
+       "markaspatrolledtext": "Označi stranicu kao patroliranu",
        "markedaspatrolled": "Označeno kao patrolirano",
        "markedaspatrolledtext": "Izabrana revizija [[:$1]] je bila označena kao patrolirana.",
        "rcpatroldisabled": "Patroliranje nedavnih izmjena onemogućeno",
        "tags-actions-header": "Radnje",
        "tags-active-yes": "Da",
        "tags-active-no": "Ne",
-       "tags-source-extension": "Definirano preko proširenja",
+       "tags-source-extension": "Definirano softverom",
        "tags-source-manual": "Ručno postavili korisnici ili botovi",
        "tags-source-none": "Više se ne koristi",
        "tags-edit": "uređivanje",
        "htmlform-user-not-valid": "<strong>$1</strong> nije ispravno korisničko ime.",
        "logentry-delete-delete": "$1 {{GENDER:$2|obrisao|obrisala}} je stranicu $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|vratio|vratila}} je stranicu $3",
-       "logentry-delete-event": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost {{PLURAL:$5|događaja|$5 događaja}} u evidenciji na $3: $4",
+       "logentry-delete-event": "$1 {{GENDER:$2|promijenio|promijenila}} je vidljivost {{PLURAL:$5|unosa|$5 unosa}} u zapisniku na $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|promijenio|promijenila}} je vidljivost {{PLURAL:$5|izmjene|$5 izmjene|$5 izmjena}} na stranici $3: $4",
        "logentry-delete-event-legacy": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost događaja u evidenciji na $3",
        "logentry-delete-revision-legacy": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost izmjena na stranici $3",
        "feedback-external-bug-report-button": "Podnesi tehnički zadatak",
        "feedback-dialog-title": "Pošalji povratne informacije",
        "feedback-dialog-intro": "Možete koristiti jednostavni formular ispod kako biste poslali povratne informacije. Vaš komentar će biti dodan stranici \"$1\" zajedno s vašim korisničkim imenom.",
-       "feedback-error-title": "Greška",
        "feedback-error1": "Greška: Neprepoznati rezultat od API",
        "feedback-error2": "Greška: Uređivanje nije uspjelo",
        "feedback-error3": "Greška: Nema odgovora od API",
        "mw-widgets-titleinput-description-redirect": "preusmjerava na $1",
        "randomrootpage": "Slučajna root stranica",
        "log-action-filter-block": "Vrsta blokiranja:",
+       "log-action-filter-contentmodel": "Vrsta izmjene modela sadržaja:",
        "log-action-filter-delete": "Vrsta brisanja:",
+       "log-action-filter-import": "Vrsta uvoza:",
+       "log-action-filter-managetags": "Vrsta uređivanja oznaka:",
+       "log-action-filter-move": "Vrsta premještanja:",
+       "log-action-filter-newusers": "Način stvaranja računa:",
+       "log-action-filter-patrol": "Vrsta patroliranja:",
+       "log-action-filter-protect": "Vrsta zaštite:",
+       "log-action-filter-rights": "Vrsta izmjene korisničkih prava:",
+       "log-action-filter-upload": "Vrsta postavljanja:",
        "log-action-filter-all": "Sve",
        "log-action-filter-block-block": "Blokiranje",
        "log-action-filter-block-reblock": "Izmjena blokiranja",
        "log-action-filter-block-unblock": "Deblokiranje",
+       "log-action-filter-contentmodel-change": "Izmjena modela sadržaja",
+       "log-action-filter-contentmodel-new": "Nova stranica s nestandardnim modelom sadržaja",
        "log-action-filter-delete-delete": "Brisanje stranice",
        "log-action-filter-delete-restore": "Vraćanje obrisane stranice",
        "log-action-filter-delete-event": "Brisanje unosa u zapisniku",
-       "log-action-filter-delete-revision": "Brisanje izmjene"
+       "log-action-filter-delete-revision": "Brisanje izmjene",
+       "log-action-filter-import-interwiki": "Uvoz između wikija",
+       "log-action-filter-import-upload": "Uvoz postavljanjem XML-a",
+       "log-action-filter-managetags-create": "Nova oznaka",
+       "log-action-filter-managetags-delete": "Brisanje oznake",
+       "log-action-filter-managetags-activate": "Aktiviranje oznake",
+       "log-action-filter-managetags-deactivate": "Deaktiviranje oznake",
+       "log-action-filter-move-move": "Premještanje bez presnimavanja preusmjerenja",
+       "log-action-filter-move-move_redir": "Premještanje s presnimavanjem preusmjerenja",
+       "log-action-filter-newusers-create": "Stvorio anonimni korisnik",
+       "log-action-filter-newusers-create2": "Stvorio registrirani korisnik",
+       "log-action-filter-newusers-autocreate": "Automatski stvoren",
+       "log-action-filter-newusers-byemail": "Stvoren lozinkom poslanom na adresu e-pošte",
+       "log-action-filter-patrol-patrol": "Ručno patrolirano",
+       "log-action-filter-patrol-autopatrol": "Automatski patrolirano",
+       "log-action-filter-protect-protect": "Dodavanje zaštite",
+       "log-action-filter-protect-modify": "Izmjena zaštite",
+       "log-action-filter-protect-unprotect": "Uklanjanje zaštite",
+       "log-action-filter-protect-move_prot": "Premještanje zaštite",
+       "log-action-filter-rights-rights": "Ručna izmjena",
+       "log-action-filter-rights-autopromote": "Automatska izmjena",
+       "log-action-filter-upload-upload": "Nova datoteka",
+       "log-action-filter-upload-overwrite": "Izmjena postojeće datoteke"
 }
index bf8c180..8bed43c 100644 (file)
        "content-model-text": "simpleng teksto",
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
-       "cantcreateaccounttitle": "Diri makagibo sa account",
        "next": "sunod",
        "last": "sinundan",
        "page_first": "una",
        "deletedcontributions": "Napurang mga ambag ka user",
        "linksearch-ok": "Pag-anapon",
        "listusers-submit": "Ipabayad",
-       "activeusers-hidebots": "Itago a bots",
        "listgrouprights-group": "Grupo",
        "listgrouprights-addgroup": "Mairurugang a {{PLURAL:$2|grupo|mga grupo}}: $1",
        "listgrouprights-addgroup-all": "Irugang ngamin na mga grupo",
index 1c3ddf7..3fc6bea 100644 (file)
@@ -83,7 +83,7 @@
        "tog-enotifminoredits": "Notifica'm per correu també en casos d'edicions menors",
        "tog-enotifrevealaddr": "Mostra la meua adreça electrònica en els missatges d'avís per correu",
        "tog-shownumberswatching": "Mostra el nombre d'usuaris que hi vigilen",
-       "tog-oldsig": "Signatura actual:",
+       "tog-oldsig": "La vostra signatura actual:",
        "tog-fancysig": "Tractar la signatura com a text wiki (sense enllaç automàtic)",
        "tog-uselivepreview": "Utilitza la previsualització automàtica",
        "tog-forceeditsummary": "Avisa'm en deixar el resum de la modificació en blanc",
        "newwindow": "(obre en una nova finestra)",
        "cancel": "Cancel·la",
        "moredotdotdot": "Més...",
-       "morenotlisted": "Aquesta llista no és completa.",
+       "morenotlisted": "Aquesta llista pot ser incompleta.",
        "mypage": "Pàgina",
        "mytalk": "Discussió",
        "anontalk": "Discussió",
        "talk": "Discussió",
        "views": "Vistes",
        "toolbox": "Eines",
+       "tool-link-userrights": "Canvia els grups de l'{{GENDER:$1|usuari|usuària}}",
+       "tool-link-emailuser": "Envia un missatge electrònic a l'{{GENDER:$1|usuari|usuària}}",
        "userpage": "Visualitza la pàgina d'usuari",
        "projectpage": "Visualitza la pàgina del projecte",
        "imagepage": "Visualitza la pàgina del fitxer",
        "createacct-yourpasswordagain-ph": "Introduïu de nou la contrasenya",
        "userlogin-remembermypassword": "Mantén-me connectat",
        "userlogin-signwithsecure": "Connexió segura",
+       "cannotlogin-title": "No es pot iniciar la sessió",
+       "cannotlogin-text": "No és possible iniciar la sessió.",
        "cannotloginnow-title": "Ara no es pot iniciar la sessió",
        "cannotloginnow-text": "No es pot iniciar la sessió quan s'utilitza $1.",
+       "cannotcreateaccount-title": "No es poden crear comptes",
+       "cannotcreateaccount-text": "La creació de comptes directa no està habilitada en aquest wiki.",
        "yourdomainname": "El vostre domini",
        "password-change-forbidden": "No podeu canviar les contrasenyes en aquest wiki.",
        "externaldberror": "Hi ha hagut un error en la base de dades d'autenticació o bé no teniu permís per a actualitzar el vostre compte extern.",
        "passwordreset-emailsentemail": "Si aquesta adreça electrònica està associada al vostre compte, s’enviarà un missatge de restabliment de contrasenya.",
        "passwordreset-emailsentusername": "Si existeix una adreça electrònica associada a aquest nom d'usuari, s’hi enviarà un missatge de reestabliment de contrasenya.",
        "passwordreset-emailsent-capture2": "{{PLURAL:$1|S'ha enviat el correu|S'han enviat els correus}} de restabliment de {{PLURAL:$1|contrasenya|contrasenyes}}. A continuació es mostra {{PLURAL:$1|l'usuari i contrasenya|la llista d'usuaris i contrasenyes}}.",
-       "passwordreset-invalideamil": "Adreça de correu electrònic no vàlida",
+       "passwordreset-invalidemail": "Adreça de correu electrònic no vàlida",
        "passwordreset-nodata": "No s'ha proporcionat cap nom d'usuari ni adreça electrònica",
        "changeemail": "Canvia o elimina l’adreça electrònica",
        "changeemail-header": "Empleneu aquest formulari per canviar la vostra adreça electrònica. Si voleu eliminar qualssevol associacions d’adreces electròniques del vostre compte, deixeu en blanc el camp i envieu el formulari.",
        "mergehistory-fail-bad-timestamp": "La marca horària no és vàlida.",
        "mergehistory-fail-invalid-source": "La pàgina font no és vàlida.",
        "mergehistory-fail-invalid-dest": "La pàgina de destinació no és vàlida.",
+       "mergehistory-fail-permission": "No hi ha permisos suficients per fusionar l'historial.",
        "mergehistory-fail-self-merge": "Les pàgines d'origen i de destinació no poden ser la mateixa",
        "mergehistory-fail-toobig": "No s'ha pogut fer la fusió de l'historial perquè es mourien més del límit de $1 {{PLURAL:$1|revisió|revisions}}.",
        "mergehistory-no-source": "La pàgina d'origen $1 no existeix.",
        "searchprofile-advanced-tooltip": "Cerca als espais de noms personalitzats",
        "search-result-size": "$1 ({{PLURAL:$2|1 paraula|$2 paraules}})",
        "search-result-category-size": "{{PLURAL:$1|1 membre|$1 membres}} ({{PLURAL:$2|1 subcategoria|$2 subcategories}}, {{PLURAL:$3|1 fitxer|$3 fitxers}})",
-       "search-redirect": "(redirigit des de $1)",
+       "search-redirect": "(redirecció des de $1)",
        "search-section": "(secció $1)",
        "search-category": "(categoria $1)",
        "search-file-match": "(coincideix amb el contingut del fitxer)",
        "grant-group-file-interaction": "Interacció amb fitxes multimèdia",
        "grant-group-watchlist-interaction": "Interacció amb la vostra llista de seguiment",
        "grant-group-email": "Enviament de correu",
+       "grant-group-high-volume": "Realitzeu activat d'alt volum",
        "grant-group-customization": "Personalització i preferències",
        "grant-group-administration": "Realitza accions administratives",
+       "grant-group-private-information": "Accedeix a les vostres dades privades",
        "grant-group-other": "Activitat miscel·lània",
        "grant-blockusers": "Bloca i desbloca usuaris",
        "grant-createaccount": "Crea comptes",
        "grant-createeditmovepage": "Crea, modifica i reanomena pàgines",
        "grant-delete": "Suprimeix pàgines, revisions i entrades de registre",
        "grant-editinterface": "Modifica l'espai de noms MediaWiki i els CSS/JavaScript d'usuari",
+       "grant-editmycssjs": "Modifiqueu el vostre CSS/JavaScript d'usuari",
        "grant-editmyoptions": "Editeu les vostres preferències d'usuari",
        "grant-editmywatchlist": "Modifica la llista de seguiment",
        "grant-editpage": "Modifica les pàgines existents",
        "grant-highvolume": "Edició d'alt volum",
        "grant-oversight": "Amaga usuaris i suprimeix revisions",
        "grant-patrol": "Patrulla els canvis de les pàgines",
+       "grant-privateinfo": "Accedeix a informació privada",
        "grant-protect": "Protecció i desprotecció de pàgines",
        "grant-rollback": "Reversió de canvis en pàgines",
        "grant-sendemail": "Enviament de correus a altres usuaris",
        "file-thumbnail-no": "El nom del fitxer comença per <strong>$1</strong>.\nSembla una imatge de mida reduïda <em>(miniatura)</em>.\nSi teniu la imatge en alta resolució, pugeu-la. Si no, mireu de canviar-li el nom.",
        "fileexists-forbidden": "Ja hi existeix un fitxer amb aquest nom i no es pot sobreescriure.\nSi us plau, torneu enrere i carregueu aquest fitxer sota un altre nom. [[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Ja hi ha un fitxer amb aquest nom en el fons comú de fitxers.\nSi encara voleu pujar el fitxer, torneu enrere i pugeu-ne una còpia amb un altre nom. [[File:$1|thumb|center|$1]]",
+       "fileexists-no-change": "La càrrega és un duplicat exacte de la versió actual de <strong>[[:$1]]</strong>.",
        "file-exists-duplicate": "Aquest fitxer és un duplicat {{PLURAL:$1|del fitxer |dels següents fitxers:}}",
        "file-deleted-duplicate": "S'ha suprimit anteriorment un fitxer idèntic a aquest ([[:$1]]). Hauríeu de comprovar el registre de supressions del fitxer abans de tornar-lo a carregar.",
        "file-deleted-duplicate-notitle": "Un fitxer idèntic a aquest fitxer havia estat suprimit abans, i també el títol. Hauríeu de demanar a algú que pugui veure les dades suprimides del fitxer que revisi la situació abans de procedir a tornar a carregar-lo.",
        "upload-dialog-disabled": "La càrrega de fitxers utilitzant aquest quadre de diàleg està desactivada en aquest wiki.",
        "upload-dialog-title": "Carrega un fitxer",
        "upload-dialog-button-cancel": "Cancel·la",
+       "upload-dialog-button-back": "Enrere",
        "upload-dialog-button-done": "Fet",
        "upload-dialog-button-save": "Desa",
        "upload-dialog-button-upload": "Carrega",
        "apisandbox-deprecated-parameters": "Paràmetres obsolets",
        "apisandbox-submit-invalid-fields-title": "Alguns camps no són vàlids",
        "apisandbox-results": "Resultats",
+       "apisandbox-sending-request": "S'està enviant una sol·licitud API...",
        "apisandbox-request-url-label": "Sol·licita URL:",
        "apisandbox-request-time": "Temps de sol·licitud: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-continue": "Continua",
+       "apisandbox-continue-clear": "Neteja",
        "booksources": "Obres de referència",
        "booksources-search-legend": "Cerca fonts de llibres",
        "booksources-isbn": "ISBN:",
        "booksources-search": "Cerca",
        "booksources-text": "A sota hi ha una llista d'enllaços d'altres llocs que venen llibres nous i de segona mà, i també podrien tenir més informació dels llibres que esteu cercant:",
        "booksources-invalid-isbn": "El codi ISBN donat no és vàlid. Comproveu si l'heu copiat correctament.",
+       "magiclink-tracking-rfc": "Pàgines que usen enllaços màgics RFC",
+       "magiclink-tracking-pmid": "Pàgines que usen enllaços màgics PMID",
+       "magiclink-tracking-isbn": "Pàgines que usen enllaços màgics d'ISBN",
        "specialloguserlabel": "Realitzador:",
        "speciallogtitlelabel": "Objectiu (títol o «{{ns:user}}:nom d’usuari» per a un usuari):",
        "log": "Registres",
        "activeusers-intro": "Aquí hi ha una llista d'usuaris que han tingut algun tipus d'activitat en {{PLURAL:$1|el darrer dia|els darrers $1 dies}}.",
        "activeusers-count": "$1 {{PLURAL:$1|acció|accions}} en {{PLURAL:$3|el darrer dia|els $3 darrers dies}}",
        "activeusers-from": "Mostra els usuaris començant per:",
-       "activeusers-hidebots": "Amaga bots",
-       "activeusers-hidesysops": "Amaga administradors",
        "activeusers-noresult": "No s'han trobat usuaris.",
        "activeusers-submit": "Mostra els usuaris actius",
        "listgrouprights": "Drets dels grups d'usuaris",
        "ipb-unblock": "Desbloca un usuari o una adreça IP",
        "ipb-blocklist": "Llista els bloquejos existents",
        "ipb-blocklist-contribs": "Contribucions de {{GENDER:$1|$1}}",
+       "ipb-blocklist-duration-left": "$1 restant",
        "unblockip": "Desbloca l'usuari",
        "unblockiptext": "Empreu el següent formulari per restaurar\nl'accés a l'escriptura a una adreça IP o un usuari prèviament bloquejat.",
        "ipusubmit": "Desbloca aquesta adreça",
        "block-log-flags-hiddenname": "nom d'usuari ocult",
        "range_block_disabled": "La facultat dels administradors per a crear bloquejos de rang està desactivada.",
        "ipb_expiry_invalid": "Data d'acabament no vàlida.",
+       "ipb_expiry_old": "El temps de vençuda és en el passat.",
        "ipb_expiry_temp": "Els blocatges amb ocultació de nom d'usuari haurien de ser permanents.",
        "ipb_hide_invalid": "No s'ha pogut eliminar el compte; té més {{PLURAL:$1|d'una edició|de $1 edicions}}.",
        "ipb_already_blocked": "«$1» ja està blocat",
        "pageinfo-article-id": "ID de la pàgina",
        "pageinfo-language": "Llengua del contingut de la pàgina",
        "pageinfo-content-model": "Plantilla de contingut de pàgina",
+       "pageinfo-content-model-change": "canvia",
        "pageinfo-robot-policy": "Indexació per robots",
        "pageinfo-robot-index": "Permès",
        "pageinfo-robot-noindex": "No permès",
        "pageinfo-category-pages": "Nombre de pàgines",
        "pageinfo-category-subcats": "ombre de subcategories",
        "pageinfo-category-files": "Nombre d'arxius",
+       "pageinfo-user-id": "ID d'usuari",
        "markaspatrolleddiff": "Marca com a supervisat",
        "markaspatrolledtext": "Marca la pàgina com a supervisada",
        "markaspatrolledtext-file": "Marc la versió del fitxer com patrullada",
        "filedelete-old-unregistered": "La revisió de fitxer especificada «$1» no es troba a la base de dades.",
        "filedelete-current-unregistered": "El fitxer especificat «$1» no es troba a la base de dades.",
        "filedelete-archive-read-only": "El directori d'arxiu «$1» no té permisos d'escriptura per al servidor web.",
-       "previousdiff": "← Vés a l'edició anterior",
-       "nextdiff": "Vés a l'edició següent →",
+       "previousdiff": "← Edició anterior",
+       "nextdiff": "Edició següent →",
        "mediawarning": "'''Advertència''': Aquest fitxer podria contenir codi maliciós.\nSi l'executeu, podeu comprometre la seguretat del vostre sistema.",
        "imagemaxsize": "Límit de mida d'imatges:<br />''(per a pàgines de descripció de fitxers)''",
        "thumbsize": "Mida de la miniatura:",
        "newimages-showbots": "Mostra les càrregues dels bots",
        "newimages-hidepatrolled": "Amaga les càrregues patrullades",
        "noimages": "Res per veure.",
+       "gallery-slideshow-toggle": "Canvia les miniatures",
        "ilsubmit": "Cerca",
        "bydate": "per data",
        "sp-newimages-showfrom": "Mostra fitxers nous des del $1 a les $2",
        "tag-filter": "Filtre d'[[Special:Tags|etiquetes]]:",
        "tag-filter-submit": "Filtra",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Etiqueta|Etiquetes}}]]: $2)",
+       "tag-mw-contentmodelchange": "canvi de model de contingut",
        "tags-title": "Etiquetes",
        "tags-intro": "Aquesta pàgina llista les etiquetes amb què el programari pot marcar una modificació, i el seu significat.",
        "tags-tag": "Nom de l'etiqueta",
        "htmlform-cloner-create": "Afegeix més",
        "htmlform-cloner-delete": "Suprimeix",
        "htmlform-cloner-required": "Cal com a mínim un valor.",
+       "htmlform-time-placeholder": "HH:MM:SS",
        "htmlform-title-badnamespace": "[[:$1]] no es troba en l'espai de noms \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" és un títol de pàgina no editable",
        "htmlform-title-not-exists": "$1 no existeix.",
        "feedback-external-bug-report-button": "Arxiva una tasca tècnica",
        "feedback-dialog-title": "Envia el comentari",
        "feedback-dialog-intro": "Podeu utilitzar el senzill formulari de sota per a trametre la vostra opinió. El comentari s'afegirà a la pàgina «$1» juntament amb el vostre nom d'usuari.",
-       "feedback-error-title": "Error",
        "feedback-error1": "Error: Resultat de l'API no reconegut",
        "feedback-error2": "Error: Edició fallida",
        "feedback-error3": "Error: No hi ha resposta de l'API",
        "feedback-thanks": "Gràcies! S'ha publicat la vostra opinió a la pàgina «[$2 $1]».",
        "feedback-thanks-title": "Gràcies!",
        "feedback-useragent": "Agent d'usuari:",
-       "searchsuggest-search": "Cerca",
+       "searchsuggest-search": "Cerca a {{SITENAME}}",
        "searchsuggest-containing": "que conté ...",
+       "api-error-autoblocked": "S'ha blocat la vostra IP automàticament perquè la va utilitzar un usuari blocat.",
        "api-error-badaccess-groups": "No teniu permís per a carregar fitxers en aquest wiki.",
        "api-error-badtoken": "Error intern: argument incorrecte.",
        "api-error-copyuploaddisabled": "Les càrregues via URL estan desactivades en aquest servidor.",
        "log-action-filter-protect-protect": "Protecció",
        "log-action-filter-protect-modify": "Modificació de la protecció",
        "log-action-filter-protect-unprotect": "Desprotecció",
+       "log-action-filter-rights-rights": "Canvi manual",
+       "log-action-filter-rights-autopromote": "Canvi automàtic",
+       "log-action-filter-suppress-event": "Supressió de registres",
+       "log-action-filter-suppress-revision": "Supressió de revisions",
+       "log-action-filter-suppress-delete": "Supressió de pàgines",
        "log-action-filter-upload-upload": "Nova càrrega",
        "log-action-filter-upload-overwrite": "Torna a carregar",
        "authmanager-authn-not-in-progress": "L'autenticació no està en curs o les dades de sessió s'han perdut. Comenceu de nou des del principi.",
        "authmanager-authn-no-primary": "Les dades credencials no s'han pogut autenticar.",
        "authmanager-authn-autocreate-failed": "Ha fallat la creació automàtica d'un compte local: $1",
+       "authmanager-create-disabled": "S'ha inhabilitat la creació de comptes.",
+       "authmanager-create-from-login": "Per crear un compte, ompliu els camps de sota.",
+       "authmanager-authplugin-setpass-bad-domain": "Domini invàlid.",
+       "authmanager-retype-help": "Contrasenya de nou per confirmar",
+       "authmanager-email-label": "Correu electrònic",
+       "authmanager-email-help": "Adreça electrònica",
        "authmanager-realname-label": "Nom real",
        "authmanager-realname-help": "Nom real de l'usuari",
+       "authmanager-provider-password": "Autenticació basada en contrasenya",
+       "authmanager-provider-password-domain": "Autenticació basada en contrasenya i en domini",
        "authmanager-provider-temporarypassword": "Contrasenya temporal",
        "authprovider-resetpass-skip-label": "Omet",
+       "specialpage-securitylevel-not-allowed-title": "No permès",
+       "authpage-cannot-login": "No s'ha pogut iniciar la sessió.",
        "authpage-cannot-login-continue": "No es pot continuar amb l'inicio de sessió. Probablement la vostra sessió ha expirat.",
+       "authpage-cannot-create": "No s'ha pogut iniciar la creació del compte.",
        "authpage-cannot-create-continue": "No es pot prosseguir la creació del compte. Probablement la vostra sessió ha expirat.",
+       "authpage-cannot-link": "No s'ha pogut iniciar l'enllaç del compte.",
+       "cannotauth-not-allowed-title": "S'ha denegat el permís",
+       "cannotauth-not-allowed": "No teniu permisos per utilitzar la pàgina",
        "changecredentials": "Canvi de dades credencials",
        "changecredentials-submit": "Canvia les dades credencials",
        "credentialsform-provider": "Tipus de dades credencials:",
        "credentialsform-account": "Nom del compte:",
+       "cannotlink-no-provider-title": "No hi ha cap compte enllaçable",
+       "cannotlink-no-provider": "No hi ha cap compte enllaçable.",
+       "linkaccounts": "Enllaça els comptes",
+       "linkaccounts-success-text": "S'ha enllaçat el compte.",
        "linkaccounts-submit": "Enllaça els comptes",
        "unlinkaccounts": "Desenllaça els comptes",
        "unlinkaccounts-success": "El compte s'ha desenllaçat.",
-       "authenticationdatachange-ignored": "No s'ha gestionat el canvi de dades d'autenticació. Potser no s'ha configurat cap proveïdor?"
+       "authenticationdatachange-ignored": "No s'ha gestionat el canvi de dades d'autenticació. Potser no s'ha configurat cap proveïdor?",
+       "edit-error-short": "Error: $1",
+       "edit-error-long": "Errors:\n\n$1"
 }
index 15b39de..e4ed07f 100644 (file)
@@ -55,7 +55,7 @@
        "tog-showhiddencats": "㪗藏類別",
        "tog-norollbackdiff": "Cék-hèng huòi-gūng ī-hâiu ng-sāi hiēng-sê chă-biék",
        "tog-useeditwarning": "我編輯頁面其時候離開,起動警告我蜀下",
-       "tog-prefershttps": "Láuk-diē ī-hâiu sṳ̄-cṳ̆ng sāi ăng-cuòng lièng-giék",
+       "tog-prefershttps": "Láuk-diē ī-hâiu tié-lāu sāi ăng-ciòng lièng-giék",
        "underline-always": "直頭",
        "underline-never": "頭𡅏無",
        "underline-default": "皮膚或者瀏覽器默認其",
        "december-date": "十二月$1號",
        "period-am": "AM",
        "period-pm": "PM",
-       "pagecategories": "{{PLURAL:$1}} Lôi-biék",
+       "pagecategories": "{{PLURAL:$1|Lôi-biék}}",
        "category_header": "「$1」類別下底其頁面",
        "subcategories": "子類別",
        "category-media-header": "「$1」類別下底其媒體",
        "morenotlisted": "Ciā dăng-dăng mâ̤ uòng-cīng.",
        "mypage": "頁面",
        "mytalk": "我其討論",
-       "anontalk": "Páng-gōng",
+       "anontalk": "Păng-gōng",
        "navigation": "Īng-dô̤:",
        "and": "&#32;gâe̤ng",
        "qbfind": "討",
        "redirectedfrom": "(téng $1 tṳ̀ng-déng-hióng guó-lì)",
        "redirectpagesub": "重定向頁",
        "redirectto": "重定向遘",
-       "lastmodifiedat": "Cī siŏh hiĕh sê diŏh $1 $2 sèng-hâiu có̤i-âu siŭ-gāi gì.",
+       "lastmodifiedat": "Cī siŏh hiĕk sê diŏh $1 $2 sèng-hâiu có̤i-hâiu siŭ-gāi gì.",
        "viewcount": "茲蜀頁已經乞訪問$1回了。{{PLURAL:$1}}",
        "protectedpage": "保護頁",
        "jumpto": "Tiéu gáu:",
        "site-atom-feed": "$1 Atom déng-iŏk",
        "page-rss-feed": "「$1」RSS訂閱",
        "page-atom-feed": "$1 Atom déng-iŏk",
-       "red-link-title": "$1 (mò̤ hī hiĕh)",
+       "red-link-title": "$1 (mò̤ hī hiĕk)",
        "sort-descending": "降序排序",
        "sort-ascending": "升序排序",
        "nstab-main": "Ùng-ciŏng",
        "thumbnail-more": "Huóng-duâi",
        "tooltip-pt-userpage": "汝其用戶頁",
        "tooltip-pt-mytalk": "汝其討論頁",
+       "tooltip-pt-anontalk": "Cī ciáh IP ôi-cī iū-guăng siŭ-gāi gì tō̤-lâung",
        "tooltip-pt-preferences": "汝其設定",
        "tooltip-pt-watchlist": "汝監視其頁面有改過其單單",
        "tooltip-pt-mycontris": "汝其貢獻其單單",
-       "tooltip-pt-login": "Hĭ-uông nṳ̄ sĕng láuk-diē; bók-guó nàng-gă mò̤ ăng nṳ̄ cūng-kuāng có̤.",
+       "tooltip-pt-login": "Gióng-ngiê nṳ̄ sĕng láuk-diē; bók-guó nàng-gă mò̤ ăng nṳ̄ cūng-kuāng có̤.",
        "tooltip-pt-logout": "躒出",
+       "tooltip-pt-createaccount": "Gióng-ngiê nṳ̄ sĕng kŭi dióng-hô gái láuk-diē; bók-guó nàng-gă mò̤ ăng nṳ̄ cūng-kuāng có̤.",
        "tooltip-ca-talk": "Nô̤i-ṳ̀ng gì tō̤-lâung",
-       "tooltip-ca-edit": "汝會使修改茲蜀頁。起動敆保存以前使預覽按鈕",
+       "tooltip-ca-edit": "Siŭ-gāi cī hiĕk",
        "tooltip-ca-addsection": "Gă sĭng dâung",
        "tooltip-ca-viewsource": "茲蜀頁乞保護起去。\n汝會使看伊其源代碼。",
        "tooltip-ca-history": "Ché̤ṳ cī hiĕk gó̤-dā̤ gì bēng-buōng",
        "tooltip-ca-watch": "Ciŏng cī siŏh hiĕk gă diē nṳ̄ gì gáng-sê-dăng",
        "tooltip-ca-unwatch": "共茲頁趁監視單𡅏移開去",
        "tooltip-search": "Sìng-tō̤ {{SITENAME}} [alt-f]",
+       "tooltip-search-go": "Nâ ô dè̤ng-miàng gì hiĕk còng-câi, cô kó̤ hiā hiĕk",
        "tooltip-search-fulltext": "Sìng-tō̤ sāi-ê̤ṳng ciā ùng-cê gì hiĕk-miêng",
        "tooltip-p-logo": "Ché̤ṳ-siŏh-ché̤ṳ tàu-hiĕk",
        "tooltip-n-mainpage": "Ché̤ṳ-siŏh-ché̤ṳ tàu-hiĕk",
        "tooltip-n-mainpage-description": "Ché̤ṳ-siŏh-ché̤ṳ tàu-hiĕk",
+       "tooltip-n-portal": "Guăng-ṳ̀ ciā gĕ̤ng-tiàng, nṳ̄ â̤ có̤ gì, kó̤ diē-nē̤ tō̤ nó̤h",
        "tooltip-n-recentchanges": "Cī-bŏng diŏh wiki ô gāi-biéng gì dăng-dăng",
        "tooltip-n-randompage": "Sùi-biêng muōng ché̤ṳ",
-       "tooltip-t-whatlinkshere": "鏈遘嚽塊其所有維基頁面其單單\nCuòng-buô lièng-gáu cŭ-uái gì wiki hiĕk-miêng dăng-dăng",
+       "tooltip-n-help": "Sìng-tō̤ bŏng-cô gì sū-câi",
+       "tooltip-t-whatlinkshere": "Ciòng-buô lièng-gáu cŭ-uái gì wiki hiĕk-miêng dăng-dăng",
        "tooltip-t-recentchangeslinked": "鏈遘茲頁其頁面其最近修改\nCī hiĕk lièng gáu bĕk hiĕk gì cī-bŏng gì gāi-biéng",
        "tooltip-t-contributions": "茲蜀用戶其貢獻單單",
        "tooltip-t-emailuser": "向茲蜀隻用戶寄電批",
        "tooltip-watch": "共茲蜀頁加遘汝其監視單[alt-w]",
        "anonymous": "{{SITENAME}}其無名{{PLURAL:$1|用戶}}",
        "lastmodifiedatby": "茲頁最後是$3著$1$2改變其。",
+       "pageinfo-toolboxlink": "Hiĕk-miêng séng-sék",
        "deletedrevision": "刪掉舊其版本$1",
        "previousdiff": "← 舊其修改",
        "nextdiff": "新其修改 →",
        "file-nohires": "無更高決斷",
+       "show-big-image-size": "$1 × $2 chiông-só",
        "ilsubmit": "尋討",
        "bydate": "按日期",
        "metadata": "Nguòng-só-gé̤ṳ",
        "exif-meteringmode-0": "𣍐八",
        "exif-lightsource-0": "𣍐八",
        "exif-subjectdistancerange-0": "𣍐八",
-       "namespacesall": "cuòng-buô",
+       "namespacesall": "ciòng-buô",
        "monthsall": "囫圇年",
        "confirmemail": "確定電批地址",
        "confirmemail_invalid": "確認碼無效。\n可能已經過期了。",
index c35d64a..c5df957 100644 (file)
        "talk": "Дийцаре",
        "views": "Хьажарш",
        "toolbox": "ГӀирсаш",
+       "tool-link-userrights": "{{GENDER:$1|Декъашхочун}} бакъо хийцар",
+       "tool-link-emailuser": "Язде {{GENDER:$1|декъашхочунга}} кехат",
        "userpage": "Хьажа декъашхочуьна агӀоне",
        "projectpage": "Хьажа кхолламан агӀоне",
        "imagepage": "Хьажа файлан агӀоне",
        "userrights": "Декъашхочун бакъонашна урхалладар",
        "userrights-lookup-user": "Декъашхойн бакъонашна урхалладар",
        "userrights-user-editname": "Язъе цӀе:",
-       "editusergroup": "Хийца декъашхочун бакъо",
+       "editusergroup": "{{GENDER:$1|Декъашхочун}} бакъо хийцар",
        "editinguser": "Хийца декъашхочуьна бакъо '''[[User:$1|$1]]''' ([[User talk:$1|{{int:talkpagelinktext}}]]{{int:pipe-separator}}[[Special:Contributions/$1|{{int:contribslink}}]])",
        "userrights-editusergroup": "Хийца декъашхочун бакъо",
        "saveusergroups": "Декъашхочун бакъонаш Ӏалашъян",
        "upload-http-error": "Даьлла гӀалат HTTP: $1",
        "upload-dialog-title": "Файл чуяккхар",
        "upload-dialog-button-cancel": "Цаоьшу",
+       "upload-dialog-button-back": "Юха",
        "upload-dialog-button-done": "Кийчча ю",
        "upload-dialog-button-save": "Ӏалашъян",
        "upload-dialog-button-upload": "Чуяккха",
        "booksources-search-legend": "Жайнех лаьцна хаам лахар",
        "booksources-search": "Лахар",
        "booksources-text": "ХӀокху агӀонгахь гул бина сайтийн тӀе хьажоргийн могӀам оцу чохь шуна жайнах лаьцна хаам каро мега. И ю интернет-туьканаш а категорийн библиотекийн категорешкахь лахаран система а.",
+       "magiclink-tracking-rfc": "RFC хьажоргаш лелош йолу агӀонаш",
+       "magiclink-tracking-rfc-desc": "ХӀокху агӀогахь лелош ю RFC хьажоргаш. Хьажа [[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] дихьаяккхар муха кхочушдан деза дуьйцу.",
+       "magiclink-tracking-pmid": "PMID хьажоргаш лелош йолу агӀонаш",
+       "magiclink-tracking-pmid-desc": "ХӀокху агӀогахь лелош ю PMID хьажоргаш. Хьажа [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] дихьаяккхар муха кхочушдан деза дуьйцу.",
+       "magiclink-tracking-isbn": "ISBN хьажоргаш лелош йолу агӀонаш",
+       "magiclink-tracking-isbn-desc": "ХӀокху агӀогахь лелош ю ISBN хьажоргаш. Хьажа [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] дихьаяккхар муха кхочушдан деза дуьйцу.",
        "specialloguserlabel": "Декъашхо:",
        "speciallogtitlelabel": "Ӏалашо (цӀе я декъашхо):",
        "log": "Тéптарш",
        "activeusers-intro": "Лахахь гойтуш бу  {{PLURAL:$1|1=тӀаьхьара $1 динахь|тӀаьхьара $1 деношкахь}} хийцамаш бина декъашхой.",
        "activeusers-count": "{{PLURAL:$3|1=тӀаьхьарчу $3 динахь|тӀаьхьара $3 деношкахь}} $1 {{PLURAL:$1|1=нисдар|нисдарш}} дина",
        "activeusers-from": "Гучé баха декъашхой, болалуш болу тӀера:",
-       "activeusers-hidebots": "Къайлабаха боташ",
-       "activeusers-hidesysops": "Къайлабаха куьйгалхой",
        "activeusers-noresult": "Декъашхой цакарий.",
        "activeusers-submit": "Гайта жигара декъашхой",
        "listgrouprights": "Декъашхойн тобанийн бакъонаш",
        "htmlform-chosen-placeholder": "Харжа кеп",
        "htmlform-cloner-create": "ТӀетоха кхин",
        "htmlform-cloner-delete": "ДӀаяккха",
+       "htmlform-datetime-placeholder": "ШШШШ-ББ-ДД СС:ММ:СС",
        "htmlform-title-not-exists": "«$1» яц.",
        "htmlform-user-not-exists": "<strong>$1</strong> яц.",
        "htmlform-user-not-valid": "<strong>$1</strong> — декъашхочун магийна йоцу цӀе.",
        "feedback-bugornote": "Хьайн техникин халонах лаьцна яздан хӀума делахь, дехар до, [$1 хаам бе тхоьга].\nДацахь хьан йиш ю хӀокху атта кепаца «[$3 $2]» агӀонг къамел тӀетоха хьан декъашхочун цӀарца, кхин лелош йолу браузер билгал еш.",
        "feedback-cancel": "Цаоьшу",
        "feedback-close": "Кийчча ю",
-       "feedback-error-title": "ГӀалат",
        "feedback-message": "Хаам:",
        "feedback-subject": "Къамел:",
        "feedback-submit": "Дахьийта",
        "special-characters-group-ipa": "ДАЭ (IPA)",
        "special-characters-group-symbols": "Символаш",
        "special-characters-group-greek": "Грекийн",
-       "special-characters-group-greekextended": "Грекийн шординарш",
+       "special-characters-group-greekextended": "Грекийн алсам",
        "special-characters-group-cyrillic": "Кирилан",
        "special-characters-group-arabic": "Ӏарбийн",
-       "special-characters-group-arabicextended": "Iаьрбийн шординарш",
+       "special-characters-group-arabicextended": "Ӏаьрбийн алсам",
        "special-characters-group-persian": "Пхьарсхойн",
        "special-characters-group-hebrew": "Жуьгтийн",
        "special-characters-group-bangla": "Бангалойн",
        "special-characters-group-tamil": "Тамилхойн",
        "special-characters-group-telugu": "Телугойн",
        "special-characters-group-sinhala": "Синхалойн",
-       "special-characters-group-gujarati": "Ð\93Ñ\83жаÑ\80аÑ\82ойн",
+       "special-characters-group-gujarati": "Ð\93Ñ\83джаÑ\80аÑ\82и",
        "special-characters-group-devanagari": "Деванагари",
        "special-characters-group-thai": "Тайхойн",
        "special-characters-group-lao": "Лаохойн",
index 8dccaba..2a9ecd5 100644 (file)
        "yourname": "Ngalan sa tiggamit:",
        "yourpassword": "Pasword:",
        "yourpasswordagain": "Itayp og usab ang pasword:",
-       "remembermypassword": "Hinumdomi ako niining brawser (sa kadugayon nga $1 {{PLURAL:$1|ka adlaw|ka mga adlaw}})",
        "yourdomainname": "Ang imong domain:",
        "externaldberror": "May nahitabong authentication database error o kaha wala ka tugoti nga mag-update sa imong eksternal nga akawnt.",
        "login": "Sulod",
        "undo-failure": "Ang pag-usab dili puyde mapa-way-bili tungod sa mga naka-conflict nga intermediate nga mga pag-usab.",
        "undo-norev": "Ang pag-usab dili puyde mapa-way-bili tungod kay wala pa ni mahimo o kaha natangtang na kini.",
        "undo-summary": "Giway-bili  ang rebisyon  $1 ni [[Special:Contributions/$2|$2]] ([[User talk:$2|Hisgot]])",
-       "cantcreateaccounttitle": "Dili makahimo og akawnt",
        "cantcreateaccount-text": "Ang paghimo og akawnt gikan niining IP address ('''$1''') gi-block ni [[User:$3|$3]].\n\nAng rason nga gihatag ni $3 mao nga ''$2''",
        "viewpagelogs": "Tan-awa ang mga log niining panid",
        "nohistory": "Walay kaagi sa pag-usab niining panid.",
index 4274025..b104745 100644 (file)
        "yourname": "Nå'an ni muna'setbi:",
        "yourpassword": "Password:",
        "yourpasswordagain": "Taip ta'lo i password:",
-       "remembermypassword": "Na'hasso iyo-ku login gi este na komputer (for a maximum of $1 {{PLURAL:$1|day|days}})",
        "yourdomainname": "Lugat-mu:",
        "login": "Log in",
        "nav-login-createaccount": "Hålom / fa'tinas kuenta-mu",
        "expensive-parserfunction-category": "Påhinas siha ni meggai mampos na inagang fungksion parser",
        "post-expand-template-inclusion-warning": "Adahi: Mampos dangkolo i mineddong muna'saonao plantiyas.\nTi para u na'saonao palu na plantiyas.",
        "post-expand-template-inclusion-category": "Påhina siha ni maloffan i mineddong muna'saonao plantiyas",
-       "cantcreateaccounttitle": "Ti siña mama'tinas kuenta",
        "cantcreateaccount-text": "Chinemma' mama'tinas kuenta ginen i IP ('''$1''') as [[User:$3|$3]].\n\nNina'i i rasion ''$2'' as $3",
        "viewpagelogs": "Atan i historian påhina",
        "nohistory": "Tåya' historian tinilaika este na påhina.",
index 71a2c6b..b68ae67 100644 (file)
        "activeusers-intro": "ئەمە لیستێکی ئەو بەکارھێنەرانەیە کە لە  $1 {{PLURAL:$1|ڕۆژ|ڕۆژ}}ی ڕابردوودا بە جۆرێک چالاکییەکیان ھەبووە.",
        "activeusers-count": "$1 {{PLURAL:$1|کردەوە}} لە دوایین {{PLURAL:$3|ڕۆژ|$3 ڕۆژ}}دا",
        "activeusers-from": "نیشاندانی بەکارھێنەران بە دەستپێکردن لە:",
-       "activeusers-hidebots": "بۆتەکان بشارەوە",
-       "activeusers-hidesysops": "بەڕێوبەران بشارەوە",
        "activeusers-noresult": "هیچ بەکارهێنەرێک نەدۆزرایەوە",
        "listgrouprights": "مافەکانی گرووپی بەکارھێنەر",
        "listgrouprights-summary": "ئەمە لیستێکە لە گرووپەکانی بەکارهێنەر لەسەر ئەم ویکی‌یە، دەگەڵ مافەکانی دەست‌پێ‌گەیشتنی هاوپەیوەندیان.\nلێرەدا لەوانەیە [[{{MediaWiki:Listgrouprights-helppage}}|زانیاری زیاترت]] دەست‌کەوێت سەبارەت بە مافە تاکەکەسیەکان.",
index 9eee086..457ee31 100644 (file)
        "post-expand-template-inclusion-warning": "'''Attenti:''' a dimensione di i mudelli inclusi è troppa maiò.\nParechji mudelli ùn seranu micca inclusi.",
        "post-expand-template-inclusion-category": "Pagine per e quale a dimensione di i mudelli inclusi supereghja a limita",
        "post-expand-template-argument-category": "Pagine cuntinenti argumenti di mudellu mancanti",
-       "cantcreateaccounttitle": "Registramentu micca pussibile",
        "currentrev": "Ultima revisione",
        "currentrev-asof": "Versione attuale di e $1",
        "revisionasof": "Versione di e $1",
index 9829a07..0899e65 100644 (file)
        "yourname": "Hayo (username):",
        "yourpassword": "Password:",
        "yourpasswordagain": "Liwata ka pindot ang password:",
-       "remembermypassword": "Dumduma ang pagsulod ko sa mini nga kompyuter (pinakadamu na ang $1 {{PLURAL:$1|adlaw|mga adlaw}})",
        "yourdomainname": "Imo domain:",
        "login": "Mag sulod",
        "nav-login-createaccount": "Magsulod / mag-ubra sang account",
index 5ef9124..ddced48 100644 (file)
@@ -8,7 +8,8 @@
                        "아라",
                        "Исмаил Садуев",
                        "Умар",
-                       "Macofe"
+                       "Macofe",
+                       "Danvintius Bookix"
                ]
        },
        "tog-underline": "Багълантыларнынъ тюбюни сызув:",
        "nstab-template": "Шаблон",
        "nstab-help": "Ярдым",
        "nstab-category": "Категория",
+       "mainpage-nstab": "Баш Саифе",
        "nosuchaction": "Бойле бир арекет ёкъ",
        "nosuchactiontext": "URL-де бильдирильген арекет рухсетсиз.\nБельки де URL-ни янълыш язгъандырсыз, я да догъру олмагъан бир багълантыны къуллангъандырсыз.\nБу, {{SITENAME}} сайтындаки бир хатаны да косьтерип ола.",
        "nosuchspecialpage": "Бу исимде бир махсус саифе ёкъ",
        "yourpasswordagain": "Парольни бир даа язынъыз:",
        "createacct-yourpasswordagain": "Парольни тасдыкълав",
        "createacct-yourpasswordagain-ph": "Парольни бир даа язынъыз",
-       "remembermypassword": "Киришимни бу компьютерде хатырла (энъ чокъ $1 {{PLURAL:$1|1=кунь|кунь}} ичюн)",
        "userlogin-remembermypassword": "Системада къалайым",
        "userlogin-signwithsecure": "Телюкесиз багълама къулланылсын",
        "yourdomainname": "Домен адынъыз",
        "undo-failure": "Арадаки денъиштирмелер бир-бирине келишикли олмагъаны ичюн денъиштирме лягъу этилип оламай.",
        "undo-norev": "Денъиштирме лягъу этилип оламаз, чюнки о я да ёкъ, я да бар эди, амма ёкъ этильген.",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|музакере]]) къулланыджысынынъ $1 номералы денъиштирмесини лягъу этюв.",
-       "cantcreateaccounttitle": "Эсап яратмакънынъ ич чареси ёкъ.",
        "cantcreateaccount-text": "Бу IP адресинден ('''$1''') эсап яратув [[User:$3|$3]] тарафындан блок этильди.\n\n$3 мына бу себепни бильдирди: ''$2''",
        "viewpagelogs": "Бу саифенинъ журналларыны косьтер",
        "nohistory": "Бу саифенинъ кечмиш версиясы ёкъ.",
        "rightslog": "Къулланыджынынъ акълары журналы",
        "action-edit": "бу саифени денъиштирмеге",
        "nchanges": "$1 {{PLURAL:$1|денъиштирме}}",
+       "enhancedrc-history": "тарих",
        "recentchanges": "Сонъки денъиштирмелер",
        "recentchanges-legend": "Сонъки денъиштирмелер сазламалары",
        "recentchanges-summary": "Япылгъан энъ сонъки денъиштирмелерни бу саифеде корип оласынъыз.",
        "contributions": "{{GENDER:$1|Къулланыджынынъ}} исселери",
        "contributions-title": "$1 къулланыджысынынъ исселери",
        "mycontris": "Исселер",
+       "anoncontribs": "Исселер",
        "contribsub2": "$1 ($2)",
        "nocontribs": "Бу критерийлерге уйгъан денъиштирме тапыламады",
        "uctop": "(сонъки)",
index 4d8a73c..e48be9f 100644 (file)
        "yourpasswordagain": "Parolni bir daa yazıñız:",
        "createacct-yourpasswordagain": "Parolni tasdıqlav",
        "createacct-yourpasswordagain-ph": "Parolni bir daa yazıñız",
-       "remembermypassword": "Kirişimni bu kompyuterde hatırla (eñ çoq $1 {{PLURAL:$1|kün|kün}} içün)",
        "userlogin-remembermypassword": "Sistemada qalayım",
        "userlogin-signwithsecure": "Telükesiz bağlama qullanılsın",
        "yourdomainname": "Domen adıñız",
        "undo-failure": "Aradaki deñiştirmeler bir-birine kelişikli olmağanı içün deñiştirme lâğu etilip olamay.",
        "undo-norev": "Deñiştirme lâğu etilip olamaz, çünki o ya da yoq, ya da bar edi, amma yoq etilgen.",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|muzakere]]) qullanıcısınıñ $1 nomeralı deñiştirmesini lâğu etüv.",
-       "cantcreateaccounttitle": "Esap yaratmaqnıñ iç çaresi yoq.",
        "cantcreateaccount-text": "Bu IP adresinden ('''$1''') esap yaratuv [[User:$3|$3]] tarafından blok etildi.\n\n$3 mına bu sebepni bildirdi: ''$2''",
        "viewpagelogs": "Bu saifeniñ jurnallarını köster",
        "nohistory": "Bu saifeniñ keçmiş versiyası yoq.",
index d12fe17..cd5784c 100644 (file)
        "botpasswords-label-delete": "Smazat",
        "botpasswords-label-resetpassword": "Resetovat heslo",
        "botpasswords-label-grants": "Použitelná oprávnění:",
-       "botpasswords-help-grants": "Každé přidělení dává přístup k uvedeným uživatelským oprávněním, která uživatelský účet již má. Viz [[Special:ListGrants|table of grants]] pro více informací.",
+       "botpasswords-help-grants": "Přidělení dávají přístup k oprávněním, která váš uživatelský účet již má. Zaškrtnutím přidělení zde nezíská váš účet jakákoli práva, která by jinak neměl. Viz [[Special:ListGrants|table of grants]] pro více informací.",
        "botpasswords-label-grants-column": "Přiděleno",
        "botpasswords-bad-appid": "Název bota „$1“ není platný.",
        "botpasswords-insert-failed": "Nepodařilo se přidat název bota „$1“. Nebyl už přidán?",
        "passwordreset-nocaller": "Musí být uveden volající",
        "passwordreset-nosuchcaller": "Volající neexistuje: $1",
        "passwordreset-ignored": "Žádost o nové heslo nebyla zpracována. Možná není nakonfigurován žádný poskytovatel?",
-       "passwordreset-invalideamil": "Neplatná e-mailová adresa",
+       "passwordreset-invalidemail": "Neplatná e-mailová adresa",
        "passwordreset-nodata": "Nebylo zadáno uživatelské jméno ani e-mailová adresa",
        "changeemail": "Změna nebo odstranění e-mailové adresy",
        "changeemail-header": "Vyplněním tohoto formuláře můžete změnit svou e-mailovou adresu. Pokud chcete ze svého účtu odstranit vazbu na všechny e-mailové adresy, ponechte při odeslání formuláře novou e-mailovou adresu prázdnou.",
        "searchprofile-advanced-tooltip": "Nastavit jmenné prostory, ve kterých se má hledat",
        "search-result-size": "$1 ({{PLURAL:$2|1 slovo|$2 slova|$2 slov}})",
        "search-result-category-size": "{{PLURAL:$1|1 položka|$1 položky|$1 položek}} ({{PLURAL:$2|1 podkategorie|$2 podkategorie|$2 podkategorií}}, {{PLURAL:$3|1 soubor|$3 soubory|$3 souborů}})",
-       "search-redirect": "(přesměrování $1)",
+       "search-redirect": "(přesměrování $1)",
        "search-section": "(část $1)",
        "search-category": "(kategorie $1)",
        "search-file-match": "(odpovídá obsahu souboru)",
        "grant-basic": "Základní oprávnění",
        "grant-viewdeleted": "Prohlížet si smazané soubory a stránky",
        "grant-viewmywatchlist": "Prohlížet si váš seznam sledovaných stránek",
+       "grant-viewrestrictedlogs": "Prohlížet si tajné protokolovací záznamy",
        "newuserlogpage": "Kniha nových uživatelů",
        "newuserlogpagetext": "Toto je záznam nově zaregistrovaných uživatelů.",
        "rightslog": "Kniha práv uživatelů",
        "rcshowhideminor": "$1 malé editace",
        "rcshowhideminor-show": "Zobrazit",
        "rcshowhideminor-hide": "Skrýt",
-       "rcshowhidebots": "$1 boty",
+       "rcshowhidebots": "$1 roboty",
        "rcshowhidebots-show": "Zobrazit",
        "rcshowhidebots-hide": "Skrýt",
        "rcshowhideliu": "$1 registrované uživatele",
        "upload-dialog-disabled": "Načítání souborů pomocí tohoto dialogu je na této wiki vypnuto.",
        "upload-dialog-title": "Načtení souboru",
        "upload-dialog-button-cancel": "Storno",
+       "upload-dialog-button-back": "Zpět",
        "upload-dialog-button-done": "Hotovo",
        "upload-dialog-button-save": "Uložit",
        "upload-dialog-button-upload": "Načíst",
        "apisandbox-results-fixtoken-fail": "Nepodařilo se načíst token „$1“.",
        "apisandbox-alert-page": "Pole na této stránce nejsou platná.",
        "apisandbox-alert-field": "Hodnota tohoto pole není platná.",
+       "apisandbox-continue": "Pokračovat",
+       "apisandbox-continue-clear": "Vymazat",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} bude [https://www.mediawiki.org/wiki/API:Query#Continuing_queries pokračovat] v posledním požadavku; {{int:apisandbox-continue-clear}} vymaže parametry související s pokračováním.",
        "booksources": "Zdroje knih",
        "booksources-search-legend": "Vyhledat knižní zdroje",
        "booksources-search": "Hledat",
        "booksources-text": "Níže je seznam odkazů na servery prodávající knihy, nebo které mohou mít další informace o knihách, které hledáte.",
        "booksources-invalid-isbn": "Zadané ISBN se zdá být neplatné. Zkontrolujte jej s originálním zdrojem.",
+       "magiclink-tracking-rfc": "Stránky obsahující kouzelné odkazy RFC",
+       "magiclink-tracking-rfc-desc": "Tato stránka používá kouzelné odkazy RFC. Více informací k migraci najdete na [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
+       "magiclink-tracking-pmid": "Stránky obsahující kouzelné odkazy PMID",
+       "magiclink-tracking-pmid-desc": "Tato stránka používá kouzelné odkazy PMID. Více informací k migraci najdete na [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
+       "magiclink-tracking-isbn": "Stránky obsahující kouzelné odkazy ISBN",
+       "magiclink-tracking-isbn-desc": "Tato stránka používá kouzelné odkazy ISBN. Více informací k migraci najdete na [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
        "specialloguserlabel": "Původce:",
        "speciallogtitlelabel": "Cíl (název nebo {{ns:user}}:Jméno pro uživatele):",
        "log": "Protokolovací záznamy",
        "activeusers-intro": "Toto je seznam uživatelů, kteří byli nějak aktivní v {{PLURAL:$1|posledním dni|posledních $1 dnech}}.",
        "activeusers-count": "$1 {{PLURAL:$1|akce|akce|akcí}} během {{PLURAL:$3|posledního dne|posledních $3 dnů}}",
        "activeusers-from": "Zobrazit uživatele počínaje od:",
-       "activeusers-hidebots": "Skrýt roboty",
-       "activeusers-hidesysops": "Skrýt správce",
+       "activeusers-groups": "Zobrazit uživatele patřící do skupin:",
        "activeusers-noresult": "Nenalezen žádný uživatel.",
        "activeusers-submit": "Zobrazit aktivní uživatele",
        "listgrouprights": "Práva skupin uživatelů",
        "watchlist-submit": "Zobrazit",
        "wlshowtime": "Zobrazené období:",
        "wlshowhideminor": "malé editace",
-       "wlshowhidebots": "boty",
+       "wlshowhidebots": "roboty",
        "wlshowhideliu": "registrované uživatele",
        "wlshowhideanons": "anonymní uživatele",
        "wlshowhidepatr": "prověřené editace",
        "modifiedarticleprotection": "mění zámek stránky „[[$1]]“",
        "unprotectedarticle": "odemyká „[[$1]]“",
        "movedarticleprotection": "nastavení zámků přesunuto z „[[$2]]“ na „[[$1]]“",
+       "protectedarticle-comment": "{{GENDER:$2|Zamkl|Zamkla}} stránku „[[$1]]“",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Změnil|Změnila}} nastavení zámků stránky „[[$1]]“",
+       "unprotectedarticle-comment": "{{GENDER:$2|Odemkl|Odemkla}} stránku „[[$1]]“",
        "protect-title": "Zamyká se „$1“",
        "protect-title-notallowed": "Zobrazení zámků na „$1“",
        "prot_1movedto2": "Stránka [[$1]] přemístěna na stránku [[$2]]",
        "movelogpagetext": "Toto je záznam všech přesunů stránek.",
        "movesubpage": "{{PLURAL:$1|Podstránka|Podstránky}}",
        "movesubpagetext": "Tato stránka má $1 {{PLURAL:$1|podstránku uvedenou|podstránky vypsané|podstránek vypsaných}} níže.",
+       "movesubpagetalktext": "Odpovídající diskusní stránka má {{PLURAL:$1|jednu podstránku, zobrazenou|$1 podstránky, zobrazené|$1 podstránek, zobrazených}} níže.",
        "movenosubpage": "Tato stránka nemá žádné podstránky.",
        "movereason": "Důvod:",
        "revertmove": "vrátit",
        "pageinfo-category-pages": "Počet stránek",
        "pageinfo-category-subcats": "Počet podkategorií",
        "pageinfo-category-files": "Počet souborů",
+       "pageinfo-user-id": "ID uživatele",
        "markaspatrolleddiff": "Označit jako prověřené",
        "markaspatrolledtext": "Označit tuto stránku jako prověřenou",
        "markaspatrolledtext-file": "Označit tuto verzi souboru jako prověřenou",
        "patrol-log-header": "Toto je kniha prověřených verzí.",
        "log-show-hide-patrol": "$1 knihu záznamů patroly",
        "log-show-hide-tag": "$1 knihu značek",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Označit revizi $3 stránky $2 jako prověřenou?",
        "deletedrevision": "Smazána stará revize $1",
        "filedeleteerror-short": "Chyba při mazání souboru: $1",
        "filedeleteerror-long": "Vyskytla se chyba při mazání souboru:\n\n$1",
        "newimages-summary": "Na této speciální stránce se zobrazují poslední načtené soubory.",
        "newimages-legend": "Filtr",
        "newimages-label": "Název souboru (nebo jeho část):",
-       "newimages-showbots": "Zobrazit soubory načtené boty",
+       "newimages-showbots": "Zobrazit soubory načtené roboty",
        "newimages-hidepatrolled": "Skrýt prověřená načtení souborů",
        "noimages": "Není co zobrazit.",
+       "gallery-slideshow-toggle": "Přepnout náhledy",
        "ilsubmit": "Hledat",
        "bydate": "podle data",
        "sp-newimages-showfrom": "Zobrazit nové soubory počínaje od $2, $1",
        "tags-active-yes": "Ano",
        "tags-active-no": "Ne",
        "tags-source-extension": "Definována softwarem",
-       "tags-source-manual": "Přidávána ručně uživateli a boty",
+       "tags-source-manual": "Přidávána ručně uživateli a roboty",
        "tags-source-none": "Už nepoužívána",
        "tags-edit": "editovat",
        "tags-delete": "smazat",
        "tags-deactivate": "deaktivovat",
        "tags-hitcount": "$1 {{PLURAL:$1|změna|změny|změn}}",
        "tags-manage-no-permission": "Nemáte oprávnění spravovat značky pro změny.",
-       "tags-manage-blocked": "Nemůžete spravovat značky, když jste {{GENDER:|zablokován|zablokována|zablokováni}}.",
+       "tags-manage-blocked": "Nemůžete spravovat značky, když jste {{GENDER:$1|zablokován|zablokována|zablokováni}}.",
        "tags-create-heading": "Vytvořit novou značku",
        "tags-create-explanation": "Nově vytvořené značky jsou implicitně k dispozici uživatelům a botům.",
        "tags-create-tag-name": "Název značky:",
        "tags-deactivate-not-allowed": "Značku „$1“ nelze deaktivovat.",
        "tags-deactivate-submit": "Deaktivovat",
        "tags-apply-no-permission": "Nemáte oprávnění přidávat značky k vlastním změnám",
-       "tags-apply-blocked": "Nemůžete ke svým změnám přidávat značky, když jste {{GENDER:|zablokován|zablokována|zablokováni}}.",
+       "tags-apply-blocked": "Nemůžete ke svým změnám přidávat značky, když jste {{GENDER:$1|zablokován|zablokována|zablokováni}}.",
        "tags-apply-not-allowed-one": "Značku „$1“ není dovoleno ručně přidávat.",
        "tags-apply-not-allowed-multi": "Následující {{PLURAL:$2|značku|značky}} není dovoleno ručně přidávat: $1",
        "tags-update-no-permission": "Nemáte oprávnění přidávat libovolné značky na jednotlivé revize a protokolovací záznamy a odebírat je",
-       "tags-update-blocked": "Nemůžete přidávat nebo odebírat značky, když jste {{GENDER:|zablokován|zablokována|zablokováni}}.",
+       "tags-update-blocked": "Nemůžete přidávat nebo odebírat značky, když jste {{GENDER:$1|zablokován|zablokována|zablokováni}}.",
        "tags-update-add-not-allowed-one": "Značku „$1“ není dovoleno ručně přidávat.",
        "tags-update-add-not-allowed-multi": "Následující {{PLURAL:$2|značku|značky}} není dovoleno ručně přidávat: $1",
        "tags-update-remove-not-allowed-one": "Značku „$1“ není dovoleno odebírat.",
        "htmlform-cloner-create": "Přidat další",
        "htmlform-cloner-delete": "Odstranit",
        "htmlform-cloner-required": "Je povinná nejméně jedna hodnota.",
+       "htmlform-date-placeholder": "RRRR-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "RRRR-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "Uvedená hodnota není platné datum. Zkuste použít formát RRRR-MM-DD.",
+       "htmlform-time-invalid": "Uvedená hodnota není platný čas. Zkuste použít formát HH:MM:SS.",
+       "htmlform-datetime-invalid": "Uvedená hodnota není platné datum a čas. Zkuste použít formát RRRR-MM-DD HH:MM:SS.",
+       "htmlform-date-toolow": "Uvedená hodnota je před nejdřívějším dovoleným datem $1.",
+       "htmlform-date-toohigh": "Uvedená hodnota je po nejpozdějším dovoleném datu $1.",
+       "htmlform-time-toolow": "Uvedená hodnota je před nejdřívějším dovoleným časem $1.",
+       "htmlform-time-toohigh": "Uvedená hodnota je po nejpozdějším dovoleném čase $1.",
+       "htmlform-datetime-toolow": "Uvedená hodnota je před nejdřívějším dovoleným datem a časem $1.",
+       "htmlform-datetime-toohigh": "Uvedená hodnota je po nejpozdějším dovoleném datu a času $1.",
        "htmlform-title-badnamespace": "Stránka [[:$1]] není ve jmenném prostoru „{{ns:$2}}“.",
        "htmlform-title-not-creatable": "Pod názvem „$1“ nelze vytvořit stránku",
        "htmlform-title-not-exists": "Stránka $1 neexistuje.",
        "log-description-managetags": "Tato stránka obsahuje seznam správcovských úkonů týkajících se [[Special:Tags|značek]]. Protokol obsahuje pouze akce, které provedl ručně správce; značky může vytvářet či mazat přímo software wiki, aniž by v tomto protokolu vznikl záznam.",
        "logentry-managetags-create": "$1 {{GENDER:$2|vytvořil|vytvořila}} značku „$4“",
        "logentry-managetags-delete": "$1 {{GENDER:$2|smazal|smazala}} značku „$4“ (odstraněna z $5 {{PLURAL:$5|revize nebo protokolovacího záznamu|revizí nebo protokolovacích záznamů}})",
-       "logentry-managetags-activate": "$1 {{GENDER:$2|aktivoval|aktivovala}} značku „$4“ pro uživatele a boty",
-       "logentry-managetags-deactivate": "$1 {{GENDER:$2|deaktivoval|deaktivovala}} značku „$4“ pro uživatele a boty",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|aktivoval|aktivovala}} značku „$4“ pro uživatele a roboty",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|deaktivoval|deaktivovala}} značku „$4“ pro uživatele a roboty",
        "log-name-tag": "Kniha značek",
        "log-description-tag": "Tato stránka zobrazuje přidání či odebrání [[Special:Tags|značek]] na stránkách či protokolovacích záznamech uživateli. Tato kniha nezaznamenává označování probíhající jako součást editace, smazání či podobné akce.",
        "logentry-tag-update-add-revision": "$1 {{GENDER:$2|přidal|přidala}} {{PLURAL:$7|značku|značky}} $6 na revizi $4 stránky $3",
        "feedback-external-bug-report-button": "Založit technický úkol",
        "feedback-dialog-title": "Odeslat názor",
        "feedback-dialog-intro": "Pomocí níže zobrazeného jednoduchého formuláře můžete odeslat svůj názor. Váš komentář se spolu s vaším uživatelským jménem přidá na stránku „$1“.",
-       "feedback-error-title": "Chyba",
        "feedback-error1": "Chyba: Nerozpoznaný výsledek z API",
        "feedback-error2": "Chyba: Editace se nezdařila",
        "feedback-error3": "Chyba: API nevrátilo žádnou odpověď",
        "feedback-thanks": "Děkujeme! Váš komentář byl přidán na stránku „[$2 $1]“.",
        "feedback-thanks-title": "Děkujeme!",
        "feedback-useragent": "Uživatelský agent:",
-       "searchsuggest-search": "Hledat",
+       "searchsuggest-search": "Hledat na {{GRAMMAR:6sg|{{SITENAME}}}}",
        "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.",
        "authmanager-authn-autocreate-failed": "Automatické založení lokálního účtu se nezdařilo: $1",
        "authmanager-change-not-supported": "Uvedené přihlašovací údaje nelze změnit, protože by je nikdo nepoužíval.",
        "authmanager-create-disabled": "Zakládání účtů je zakázáno.",
-       "authmanager-create-from-login": "Pro založení účtu vyplňte níže uvedená pole.",
+       "authmanager-create-from-login": "Pro založení účtu vyplňte uvedená pole.",
        "authmanager-create-not-in-progress": "Zakládání účtu neprobíhá nebo se ztratila data sezení. Začněte prosím znovu od začátku.",
        "authmanager-create-no-primary": "Uvedené přihlašovací údaje nelze použít pro založení účtu.",
        "authmanager-link-no-primary": "Uvedené přihlašovací údaje nelze použít pro propojení účtů.",
        "unlinkaccounts-success": "Propojení účtu bylo zrušeno.",
        "authenticationdatachange-ignored": "Změna autentizačních údajů nebyla zpracována. Možná není nakonfigurován žádný poskytovatel?",
        "userjsispublic": "Uvědomte si prosím, že podstránky s JavaScriptem by neměly obsahovat tajné údaje, protože jsou viditelné ostatním uživatelům.",
-       "usercssispublic": "Uvědomte si prosím, že podstránky s CSS by neměly obsahovat tajné údaje, protože jsou viditelné ostatním uživatelům."
+       "usercssispublic": "Uvědomte si prosím, že podstránky s CSS by neměly obsahovat tajné údaje, protože jsou viditelné ostatním uživatelům.",
+       "restrictionsfield-badip": "Neplatná IP adresa nebo rozsah: $1",
+       "restrictionsfield-label": "Povolené rozsahy IP adres:",
+       "restrictionsfield-help": "Jedna IP adresa nebo CIDR rozsah na řádek. Všechno povolíte pomocí<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Chyba: $1",
+       "edit-error-long": "Chyby:\n\n$1"
 }
index 44f9503..8877f73 100644 (file)
        "yourname": "Miono brëkòwnika",
        "yourpassword": "Twòja parola",
        "yourpasswordagain": "Pòwtórzë parolã",
-       "remembermypassword": "Spamiãtôj mòją parolã na tim kòmpùtrze (maksymalno przez $1 {{PLURAL:$1|dzéń|dni|dniów}})",
        "yourdomainname": "Twòjô domena",
        "login": "Wlogùjë mie",
        "nav-login-createaccount": "Logòwanié",
index d614209..7b44e84 100644 (file)
        "userlogin-yourname": "Усă куракан ят",
        "yourpassword": "Вăрттăн сăмах:",
        "yourpasswordagain": "Вăрттăн сăмах тепре çырăр:",
-       "remembermypassword": "Ку компьютер çинче мана астуса хăвармалла (for a maximum of $1 {{PLURAL:$1|1=day|days}})",
        "yourdomainname": "Сирĕн доменă:",
        "login": "Кĕрĕр",
        "nav-login-createaccount": "Сайта кĕр / регистрацилен",
        "post-expand-template-argument-category": "Шаблон аргуменчĕсене сиктерсе хăварнă страницăсем",
        "undo-norev": "Ку тӳрлетĕве пăрахăçлама май çук — вăл е пулман та, е ăна кăларса пăрахнă.",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|сӳтсе яв]]) $1 улăштарнине тавăрчĕ",
-       "cantcreateaccounttitle": "Хутшăнакана кĕртме май çук",
        "viewpagelogs": "Ку страницăн журналĕсене пăхмалли",
        "nohistory": "Ку страницăн улшăнусен журналĕ çук.",
        "currentrev": "Хальхи верси",
        "listusers-noresult": "Хутшăнакансем тупăнмарĕç.",
        "listusers-blocked": "(чарса хунă)",
        "activeusers-count": "$1 {{PLURAL:$1|тӳрлетни|тӳрлетнисем}} юлашки {{PLURAL:$3|кун|$3 кунсенче}}",
-       "activeusers-hidesysops": "Администраторĕсене пытар",
        "listgrouprights-group": "Ушкăн",
        "listgrouprights-helppage": "Help:Ушкăн прависем",
        "listgrouprights-members": "(хутшăнакансен списокĕ)",
index aca71bb..1ef05f9 100644 (file)
@@ -18,7 +18,8 @@
                        "Diafol",
                        "Nemo bis",
                        "Dafyddt",
-                       "Jdforrester"
+                       "Jdforrester",
+                       "Irus"
                ]
        },
        "tog-underline": "Tanlinellu cysylltiadau:",
@@ -36,6 +37,7 @@
        "tog-watchdefault": "Ychwanegu tudalennau a ffeiliau at fy rhestr wylio wrth i mi eu golygu",
        "tog-watchmoves": "Ychwanegu tudalennau a ffeiliau at fy rhestr wylio wrth i mi eu symud",
        "tog-watchdeletion": "Ychwanegu tudalennau a ffeiliau at fy rhestr wylio wrth i mi eu dileu",
+       "tog-watchuploads": "Ychwanegu ffeiliau newydd gan rhestr gwylio",
        "tog-watchrollback": "Ychwanegwch ddalennau dw i wedi perfformio 'rollback' i fy ffefrynnau",
        "tog-minordefault": "Marcio pob golygiad fel un bach yn ddiofyn",
        "tog-previewontop": "Dangos y rhagolwg cyn y blwch golygu",
        "yourpasswordagain": "Ail-deipiwch y cyfrinair:",
        "createacct-yourpasswordagain": "Gwirwch eich cyfrinair",
        "createacct-yourpasswordagain-ph": "Rhowch eich cyfrinair eto",
-       "remembermypassword": "Y porwr hwn i gofio'r manylion mewngofnodi (am hyd at $1 {{PLURAL:$1||diwrnod|ddiwrnod|diwrnod}})",
        "userlogin-remembermypassword": "Cadw'r sesiwn yn fyw tan i mi allgofnodi",
        "userlogin-signwithsecure": "Defnyddio cysylltiad diogel",
+       "cannotcreateaccount-title": "Yn methu creu cyfrif",
        "yourdomainname": "Eich parth:",
        "password-change-forbidden": "Ni allwch newid cyfrineiriau ar y wici hwn.",
        "externaldberror": "Naill ai: cafwyd gwall dilysu allanol ar databas neu: ar y llaw arall efallai nad oes hawl gennych chi i ddiwygio'ch cyfrif allanol.",
        "createacct-reason": "Rheswm",
        "createacct-reason-ph": "Pam ydych yn creu cyfrif arall?",
        "createacct-submit": "Creer y cyfrif",
-       "createacct-another-submit": "Creer y cyfrif ychwanegol",
+       "createacct-another-submit": "Creu cyfrif",
+       "createacct-continue-submit": "Parhau i greu cyfrif",
        "createacct-benefit-heading": "Ffrwyth llafur pobl fel chi yw {{SITENAME}}.",
        "createacct-benefit-body1": "{{PLURAL:$1|golygiad|golygiad|olygiad|golygiad}}",
        "createacct-benefit-body2": "{{PLURAL:$1|tudalen|dudalen|dudalen|tudalen|thudalen|tudalen}}",
        "resetpass_submit": "Gosod y cyfrinair a mewngofnodi",
        "changepassword-success": "Newidiwyd eich cyfrinair!",
        "changepassword-throttled": "Rydych wedi ceisio logio mewn yn rhy aml.\nArhoswch am $1 cyn trio eto.",
+       "botpasswords-label-create": "Dechrau",
+       "botpasswords-label-update": "Diweddaru",
+       "botpasswords-label-cancel": "Canslo",
        "botpasswords-label-delete": "Diddymu neu ddileu",
        "botpasswords-label-resetpassword": "Ailosod y cyfrinair",
        "botpasswords-label-grants": "Nawdd perthnasol:",
+       "botpasswords-label-grants-column": "Ganiataol",
+       "botpasswords-not-exist": "Defnyddiwr \"$1\" nad oes gyfrinair bot enw \"$2\".",
        "resetpass_forbidden": "Ni ellir newid cyfrineiriau",
+       "resetpass_forbidden-reason": "Ni allwn newid cyfrinair: $1",
        "resetpass-no-info": "Ni allwch fynd at y dudalen hon yn uniongyrchol heblaw eich bod wedi mewngofnodi.",
        "resetpass-submit-loggedin": "Newidier y cyfrinair",
        "resetpass-submit-cancel": "Diddymu",
        "passwordreset-emailtext-user": "Gofynodd y defnyddiwr $1 ar {{SITENAME}} am gael ailosod ei gyfrinair ar {{SITENAME}}\n($4). Mae'r {{PLURAL:$3||cyfrif|cyfrifon}} canlynol ynghlwm wrth y cyfeiriad e-bost hwn:\n\n$2\n\nBydd y {{PLURAL:$3||cyfrinair|cyfrineiriau}} dros dro hyn yn dod i ben ymhen {{PLURAL:$5||diwrnod|deuddydd|tridiau|$5 diwrnod}}.\nDylech fewngofnodi nawr a dewis cyfrinair newydd. Os mai rhywun arall a ofynodd am ailosod y cyfrinair, neu os ydych wedi cofio eich cyfrinair gwreiddiol, neu os nad ydych am ei newid bellach, gallwch anwybyddu'r neges hon a pharhau i ddefnyddio eich hen gyfrinair.",
        "passwordreset-emailelement": "Enw'r defnyddiwr: \n$1\n\nY cyfrinair dros dro: \n$2",
        "passwordreset-emailsentemail": "Anfonwyd e-bost i ailosod eich cyfrinair atoch.",
+       "passwordreset-ignored": "Ailosod y cyfrinair nad ymdriniwyd â. Efallai y nid y darparwr yn osod?",
+       "passwordreset-invalidemail": "Cyfeiriad e-bost annilys",
        "changeemail": "Newid y cyfeiriad e-bost",
        "changeemail-header": "Cwbwlhewch y ffurflen hon i newid cyfeiriad e-bost y cyfrifi. I ddileu pob cysylltiad i bob cyfeiriad ebost, gadewch e'n wag.",
        "changeemail-no-info": "Ni allwch fynd at y dudalen hon heblaw eich bod wedi mewngofnodi.",
        "minoredit": "Golygiad bychan yw hwn",
        "watchthis": "Gwylier y dudalen hon",
        "savearticle": "Cadw'r dudalen",
+       "savechanges": "Cadw'r holl newidiadau",
        "publishpage": "Cyhoeddi tudalen",
        "publishchanges": "Cyhoeddi newidiadau",
        "preview": "Rhagolwg",
        "activeusers-intro": "Dyma restr y defnyddwyr a fuont yn weithgar o fewn y {{PLURAL:$1|diwrnod|diwrnod|deuddydd|tridiau|$1 diwrnod|$1 diwrnod}} diwethaf.",
        "activeusers-count": "$1 {{PLURAL:$1|golygiad|golygiad|olygiad|golygiad}} yn ystod y {{PLURAL:$3|diwrnod|diwrnod|deuddydd|tridiau|$3 diwrnod}} diwethaf",
        "activeusers-from": "Rhestru'r defnyddwyr gan ddechrau gyda:",
-       "activeusers-hidebots": "Cuddio botiau",
-       "activeusers-hidesysops": "Cuddio gweinyddwyr",
        "activeusers-noresult": "Dim defnyddwyr i'w cael.",
        "activeusers-submit": "Dangos defnyddwyr byw",
        "listgrouprights": "Galluoedd grwpiau defnyddwyr",
        "htmlform-cloner-create": "Ychwaneger rhes",
        "htmlform-cloner-delete": "Tynner i ffwrdd",
        "htmlform-cloner-required": "Mae angen o leiaf un peth!",
-       "sqlite-has-fts": "$1 gyda chymorth chwilio yr holl destun",
-       "sqlite-no-fts": "$1 heb gymorth chwiliad yr holl destun",
        "logentry-delete-delete": "Dileodd $1 dudalen $3",
        "logentry-delete-restore": "Adferodd $1 y dudalen $3",
        "logentry-delete-event": "Newidiodd $1 ymddangosiad {{PLURAL:$5||cofnod lòg|$5 gofnod lòg|$5 chofnod lòg|$5 chofnod lòg|$5 cofnod lòg}} ar $3: $4",
index c2eeeba..df0b4e1 100644 (file)
@@ -86,7 +86,7 @@
        "tog-enotifminoredits": "Send mig også en e-mail ved mindre ændringer af sider og filer på min overvågningsliste",
        "tog-enotifrevealaddr": "Vis min e-mailadresse i e-mails med besked om ændringer",
        "tog-shownumberswatching": "Vis antal brugere, der overvåger",
-       "tog-oldsig": "Nuværende signatur:",
+       "tog-oldsig": "Din nuværende signatur:",
        "tog-fancysig": "Behandl signatur som wikitekst uden automatisk henvisning",
        "tog-uselivepreview": "Benyt løbende forhåndsvisning",
        "tog-forceeditsummary": "Advar mig hvis jeg ikke udfylder beskrivelsesfeltet",
        "newwindow": "(åbner i et nyt vindue)",
        "cancel": "Afbryd",
        "moredotdotdot": "Mere...",
-       "morenotlisted": "Denne liste er ikke komplet.",
+       "morenotlisted": "Denne liste er måske ikke fuldstændig.",
        "mypage": "Side",
        "mytalk": "Diskussion",
        "anontalk": "Diskussion",
        "searchprofile-advanced-tooltip": "Søg i bestemte navnerum",
        "search-result-size": "$1 ({{PLURAL:$2|et ord|$2 ord}})",
        "search-result-category-size": "{{PLURAL:$1|1 medlem|$1 medlemmer}} ({{PLURAL:$2|1 underkategori|$2 underkategorier}}, {{PLURAL:$3|1 fil|$3 filer}})",
-       "search-redirect": "(omdirigering $1)",
+       "search-redirect": "(omdirigering fra $1)",
        "search-section": "(afsnit $1)",
        "search-category": "(kategorien $1)",
        "search-file-match": "(svarer til filens indhold)",
        "upload-copy-upload-invalid-domain": "Uploads af kopier er ikke tilgængelig fra dette domæne.",
        "upload-dialog-title": "Læg en fil op",
        "upload-dialog-button-cancel": "Annuller",
+       "upload-dialog-button-back": "Tilbage",
        "upload-dialog-button-done": "Færdig",
        "upload-dialog-button-save": "Gem",
        "upload-dialog-button-upload": "Læg op",
        "upload-form-label-infoform-description": "Beskrivelse",
        "upload-form-label-usage-title": "Anvendelse",
        "upload-form-label-usage-filename": "Filnavn",
+       "upload-form-label-own-work": "Dette er mit eget værk",
        "upload-form-label-infoform-categories": "Kategorier",
        "upload-form-label-infoform-date": "Dato",
        "upload-form-label-own-work-message-generic-local": "Jeg bekræfter at jeg uploader filen i overenstemmelse med betingelser for brug og licenseringspoltikken på {{SITENAME}}.",
        "activeusers-intro": "Dette er en liste over brugere, som har haft en eller anden form for aktivitet inden for {{PLURAL:$1|den|de}} seneste {{PLURAL:$1|dag|$1 dage}}.",
        "activeusers-count": "$1 {{PLURAL:$1|handling|handlinger}} i {{PLURAL:$3|det seneste døgn|de seneste $3 dage}}",
        "activeusers-from": "Vis brugere som starter med:",
-       "activeusers-hidebots": "Skjul robotter",
-       "activeusers-hidesysops": "Skjul administratorer",
        "activeusers-noresult": "Ingen brugere fundet.",
        "listgrouprights": "Brugergrupperettigheder",
        "listgrouprights-summary": "Denne side viser de brugergrupper der er defineret på denne wiki og de enkelte gruppers rettigheder.\n\nDer findes muligvis [[{{MediaWiki:Listgrouprights-helppage}}|yderligere information]] om de enkelte rettigheder.",
        "export-download": "Tilbyd at gemme som en fil",
        "export-templates": "Medtag skabeloner",
        "export-pagelinks": "Inkluder henviste sider til en dybde på:",
+       "export-manual": "Tilføj sider manuelt:",
        "allmessages": "Alle beskeder",
        "allmessagesname": "Navn",
        "allmessagesdefault": "Standardtekst",
        "confirm-watch-top": "Tilføj denne side til din overvågningsliste?",
        "confirm-unwatch-button": "OK",
        "confirm-unwatch-top": "Fjern denne side fra din overvågningsliste?",
+       "confirm-rollback-button": "OK",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← forrige side",
        "imgmultipagenext": "næste side →",
        "htmlform-cloner-create": "Tilføj flere",
        "htmlform-cloner-delete": "Fjern",
        "htmlform-cloner-required": "Der kræves mindst en værdi.",
+       "htmlform-date-placeholder": "ÅÅÅÅ-MM-DD",
        "logentry-delete-delete": "$1 {{GENDER:$2|slettede}} siden $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|gendannede}} siden $3",
        "logentry-delete-event": "$1 {{GENDER:$2|ændrede}} synligheden af {{PLURAL:$5|en loghændelse|$5 loghændelser}} for siden $3: $4",
        "feedback-cancel": "Afbryd",
        "feedback-close": "Færdig",
        "feedback-dialog-title": "Indsend feedback",
-       "feedback-error-title": "Fejl",
        "feedback-error1": "Fejl: Ukendt resultat fra API",
        "feedback-error2": "Fejl: Redigering mislykkedes",
        "feedback-error3": "Fejl: Intet svar fra API",
        "feedback-submit": "Send",
        "feedback-thanks": "Tak! Dine tilbagemeldinger er blevet noteret på siden \"[$2 $1]\".",
        "feedback-thanks-title": "Tak!",
-       "searchsuggest-search": "Søg",
+       "searchsuggest-search": "Søg på {{SITENAME}}",
        "searchsuggest-containing": "indeholder...",
        "api-error-badaccess-groups": "Du har ikke tilladelse til at overføre filer til denne wiki.",
        "api-error-badtoken": "Intern fejl: ugyldigt mærke.",
        "special-characters-group-ipa": "IPA",
        "special-characters-group-symbols": "Symboler",
        "special-characters-group-greek": "Græsk",
+       "special-characters-group-greekextended": "Udvidet græsk",
        "special-characters-group-cyrillic": "Kyrillisk",
        "special-characters-group-arabic": "Arabisk",
        "special-characters-group-arabicextended": "Udvidet arabisk",
        "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"
+       "log-action-filter-protect-move_prot": "Flyttede beskyttelse",
+       "authmanager-provider-temporarypassword": "Midlertidig adgangskode",
+       "edit-error-short": "Fejl: $1"
 }
index 4497e13..a229aa9 100644 (file)
        "tog-enotifminoredits": "Auch bei kleinen Änderungen an Seiten und Dateien E-Mails senden",
        "tog-enotifrevealaddr": "Meine E-Mail-Adresse in Benachrichtigungs-E-Mails anzeigen",
        "tog-shownumberswatching": "Anzahl der beobachtenden Benutzer anzeigen",
-       "tog-oldsig": "Deine vorhandene Signatur:",
+       "tog-oldsig": "Die vorhandene Signatur:",
        "tog-fancysig": "Signatur als Wikitext behandeln (ohne automatische Verlinkung)",
        "tog-uselivepreview": "Vorschau sofort anzeigen",
        "tog-forceeditsummary": "Warnen, sofern beim Speichern die Zusammenfassung fehlt",
        "tog-watchlisthidepatrolled": "Kontrollierte Änderungen in der Beobachtungsliste ausblenden",
        "tog-watchlisthidecategorization": "Kategorisierungen von Seiten in der Beobachtungsliste ausblenden",
        "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-diffonly": "Nur die Unterschiede und nicht die vollständige Seite anzeigen",
        "tog-showhiddencats": "Versteckte Kategorien anzeigen",
-       "tog-norollbackdiff": "Unterschied nach dem Zurücksetzen nicht anzeigen",
+       "tog-norollbackdiff": "Unterschiede 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": "Während angemeldet, immer eine sichere Verbindung benutzen.",
        "underline-always": "immer",
        "botpasswords-label-delete": "Löschen",
        "botpasswords-label-resetpassword": "Passwort zurücksetzen",
        "botpasswords-label-grants": "Anwendbare Berechtigungen:",
-       "botpasswords-help-grants": "Jede Berechtigung gibt Zugriff auf gelistete Benutzerrechte, die ein Benutzerkonto bereits hat. Siehe die [[Special:ListGrants|Tabelle]] für weitere Informationen.",
+       "botpasswords-help-grants": "Berechtigungen erlauben den Zugriff auf Rechte, die bereits dein Benutzerkonto besitzt. Das Aktivieren einer Berechtigung hier bietet keinen Zugriff auf Rechte, die dein Benutzerkonto ansonsten nicht hat. Siehe die [[Special:ListGrants|Berechtigungstabelle]] für weitere Informationen.",
        "botpasswords-label-grants-column": "Gewährt",
        "botpasswords-bad-appid": "Der Botname „$1“ ist nicht gültig.",
        "botpasswords-insert-failed": "Der Botname „$1“ konnte nicht hinzugefügt werden. Wurde er bereits hinzugefügt?",
        "passwordreset-nocaller": "Es muss ein Rufer angegeben werden",
        "passwordreset-nosuchcaller": "Rufer ist nicht vorhanden: $1",
        "passwordreset-ignored": "Die Passwortzurücksetzung konnte nicht verarbeitet werden. Vielleicht wurde kein Dienstanbieter konfiguriert?",
-       "passwordreset-invalideamil": "Ungültige E-Mail-Adresse",
+       "passwordreset-invalidemail": "Ungültige E-Mail-Adresse",
        "passwordreset-nodata": "Weder ein Benutzername noch eine E-Mail-Adresse wurde angegeben",
        "changeemail": "E-Mail-Adresse ändern oder entfernen",
        "changeemail-header": "Fülle dieses Formular vollständig aus, um deine E-Mail-Adresse zu ändern. Falls du die Zuweisung einer E-Mail-Adresse zu deinem Benutzerkonto entfernen möchtest, lasse beim Übermitteln des Formulars das Feld für die neue E-Mail-Adresse leer.",
        "prefs-custom-js": "Benutzerdefiniertes JavaScript",
        "prefs-common-css-js": "Gemeinsames CSS/JavaScript aller Benutzeroberflächen:",
        "prefs-reset-intro": "Du kannst diese Seite verwenden, um die Einstellungen auf die Standards zurückzusetzen.\nDies kann nicht mehr rückgängig gemacht werden.",
-       "prefs-emailconfirm-label": "E-Mail-Bestätigung:",
+       "prefs-emailconfirm-label": "Bestätigung:",
        "youremail": "E-Mail-Adresse:",
        "username": "{{GENDER:$1|Benutzername}}:",
        "prefs-memberingroups": "{{GENDER:$2|Mitglied}} der {{PLURAL:$1|Benutzergruppe|Benutzergruppen}}:",
        "grant-basic": "Basisrechte",
        "grant-viewdeleted": "Gelöschte Dateien und Seiten ansehen",
        "grant-viewmywatchlist": "Deine Beobachtungsliste ansehen",
+       "grant-viewrestrictedlogs": "Beschränkte Logbucheinträge ansehen",
        "newuserlogpage": "Neuanmeldungs-Logbuch",
        "newuserlogpagetext": "Dies ist ein Logbuch der neu erstellten Benutzerkonten.",
        "rightslog": "Rechte-Logbuch",
        "upload-dialog-disabled": "Dateiuploads mit diesem Dialog sind auf diesem Wiki deaktiviert.",
        "upload-dialog-title": "Datei hochladen",
        "upload-dialog-button-cancel": "Abbrechen",
+       "upload-dialog-button-back": "Zurück",
        "upload-dialog-button-done": "Schließen",
        "upload-dialog-button-save": "Speichern",
        "upload-dialog-button-upload": "Hochladen",
        "apisandbox-results-fixtoken-fail": "Der „$1“-Token konnte nicht abgerufen werden.",
        "apisandbox-alert-page": "Felder auf dieser Seite sind nicht gültig.",
        "apisandbox-alert-field": "Der Wert dieses Feldes ist nicht gültig.",
+       "apisandbox-continue": "Fortfahren",
+       "apisandbox-continue-clear": "Löschen",
+       "apisandbox-continue-help": "Mit „{{int:apisandbox-continue}}“ kann man die letzte Anfrage [https://www.mediawiki.org/wiki/API:Query#Continuing_queries fortfahren]; „{{int:apisandbox-continue-clear}}“ löscht fortsetzungsbezogene Parameter.",
+       "apisandbox-param-limit": "Gib <kbd>max</kbd> ein, um das maximale Limit zu verwenden.",
        "booksources": "ISBN-Suche",
        "booksources-search-legend": "Suche nach Bezugsquellen für Bücher",
        "booksources-search": "Suchen",
        "booksources-text": "Dies ist eine Liste mit Links zu Internetseiten, die neue und gebrauchte Bücher verkaufen. Dort kann es auch weitere Informationen über die Bücher geben. {{SITENAME}} ist mit keinem dieser Anbieter geschäftlich verbunden.",
        "booksources-invalid-isbn": "Vermutlich ist die ISBN ungültig.\nBitte prüfe, ob sie korrekt von der Quelle übertragen wurde.",
+       "magiclink-tracking-rfc": "Seiten, die magische RFC-Links verwenden",
+       "magiclink-tracking-rfc-desc": "Diese Seite verwendet magische RFC-Links. Siehe [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] für die Migration.",
+       "magiclink-tracking-pmid": "Seiten, die magische PMID-Links verwenden",
+       "magiclink-tracking-pmid-desc": "Diese Seite verwendet magische PMID-Links. Siehe [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] für die Migration.",
+       "magiclink-tracking-isbn": "Seiten, die magische ISBN-Links verwenden",
+       "magiclink-tracking-isbn-desc": "Diese Seite verwendet magische ISBN-Links. Siehe [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] für die Migration.",
        "specialloguserlabel": "Ausführender Benutzer:",
        "speciallogtitlelabel": "Ziel (Titel oder {{ns:user}}:Benutzername für einen Benutzer):",
        "log": "Logbücher",
        "activeusers-intro": "Dies ist eine Liste von Benutzern, die innerhalb {{PLURAL:$1|des letzten Tages|der letzten $1 Tage}} Aktivitäten aufwiesen.",
        "activeusers-count": "$1 {{PLURAL:$1|Aktion|Aktionen}} in den {{PLURAL:$3|letzten 24 Stunden|vergangenen $3 Tagen}}",
        "activeusers-from": "Zeige Benutzer ab:",
-       "activeusers-hidebots": "Bots ausblenden",
-       "activeusers-hidesysops": "Administratoren ausblenden",
+       "activeusers-groups": "Benutzer anzeigen, die zu diesen Gruppen gehören:",
        "activeusers-noresult": "Keine Benutzer gefunden.",
        "activeusers-submit": "Aktive Benutzer anzeigen",
        "listgrouprights": "Benutzergruppenrechte",
        "modifiedarticleprotection": "änderte den Schutz von „[[$1]]“",
        "unprotectedarticle": "hob den Schutz von „[[$1]]“ auf",
        "movedarticleprotection": "übertrug den Seitenschutz von „[[$2]]“ auf „[[$1]]“",
+       "protectedarticle-comment": "{{GENDER:$2|Schützte}} „[[$1]]“",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Änderte}} den Schutzstatus für „[[$1]]“",
+       "unprotectedarticle-comment": "{{GENDER:$2|Entfernte}} den Schutz von „[[$1]]“",
        "protect-title": "Schutz ändern von „$1“",
        "protect-title-notallowed": "Schutz ansehen von „$1“",
        "prot_1movedto2": "hat „[[$1]]“ nach „[[$2]]“ verschoben",
        "movelogpagetext": "Dies ist eine Liste aller verschobenen Seiten.",
        "movesubpage": "{{PLURAL:$1|Unterseite|Unterseiten}}",
        "movesubpagetext": "Diese Seite hat $1 {{PLURAL:$1|Unterseite|Unterseiten}}.",
+       "movesubpagetalktext": "Die dazugehörige Diskussionsseite hat {{PLURAL:$1|eine Unterseite, die unten angezeigt wird|$1 Unterseiten, die unten angezeigt werden}}.",
        "movenosubpage": "Diese Seite hat keine Unterseiten.",
        "movereason": "Grund:",
        "revertmove": "zurück verschieben",
        "pageinfo-category-pages": "Anzahl der Seiten",
        "pageinfo-category-subcats": "Anzahl der Unterkategorien",
        "pageinfo-category-files": "Anzahl der Dateien",
+       "pageinfo-user-id": "Benutzerkennung",
        "markaspatrolleddiff": "Als kontrolliert markieren",
        "markaspatrolledtext": "Diese Seite als kontrolliert markieren",
        "markaspatrolledtext-file": "Diese Dateiversion als kontrolliert markieren",
        "patrol-log-header": "Dies ist das Kontroll-Logbuch.",
        "log-show-hide-patrol": "Kontroll-Logbuch $1",
        "log-show-hide-tag": "Markierungs-Logbuch $1",
+       "confirm-markpatrolled-button": "Okay",
+       "confirm-markpatrolled-top": "Version $3 von $2 als kontrolliert markieren?",
        "deletedrevision": "alte Version $1 gelöscht",
        "filedeleteerror-short": "Fehler bei Datei-Löschung: $1",
        "filedeleteerror-long": "Bei der Datei-Löschung wurden Fehler festgestellt:\n\n$1",
        "newimages-showbots": "Von Bots hochgeladene Dateien anzeigen",
        "newimages-hidepatrolled": "Kontrollierte Dateien ausblenden",
        "noimages": "Keine Dateien gefunden.",
+       "gallery-slideshow-toggle": "Vorschaubilder umschalten",
        "ilsubmit": "Suchen",
        "bydate": "nach Datum",
        "sp-newimages-showfrom": "Zeige neue Dateien ab $1, $2 Uhr",
        "tags-deactivate": "deaktivieren",
        "tags-hitcount": "$1 {{PLURAL:$1|Änderung|Änderungen}}",
        "tags-manage-no-permission": "Du hast keine Berechtigung, Änderungsmarkierungen zu verwalten.",
-       "tags-manage-blocked": "Du kannst keine Änderungsmarkierungen verwalten, während du gesperrt bist.",
+       "tags-manage-blocked": "Du kannst keine Änderungsmarkierungen verwalten, während {{GENDER:$1|du}} gesperrt bist.",
        "tags-create-heading": "Eine neue Markierung erstellen",
        "tags-create-explanation": "Standardmäßig werden neu erstellte Markierungen für die Verwendung durch Benutzer und Bots verfügbar gemacht.",
        "tags-create-tag-name": "Name der Markierung:",
        "tags-deactivate-not-allowed": "Es ist nicht möglich, die Markierung „$1“ zu deaktivieren.",
        "tags-deactivate-submit": "Deaktivieren",
        "tags-apply-no-permission": "Du hast keine Berechtigung, um Änderungsmarkierungen zusammen mit deinen Änderungen anzuwenden.",
-       "tags-apply-blocked": "Du kannst keine Änderungsmarkierungen zusammen mit deinen Änderungen anwenden, während du gesperrt bist.",
+       "tags-apply-blocked": "Du kannst keine Änderungsmarkierungen zusammen mit deinen Änderungen anwenden, während {{GENDER:$1|du}} gesperrt bist.",
        "tags-apply-not-allowed-one": "Die Markierung „$1“ darf nicht manuell angewendet werden.",
        "tags-apply-not-allowed-multi": "Die {{PLURAL:$2|folgende Markierung darf|folgenden Markierungen dürfen}} nicht manuell angewendet werden: $1",
        "tags-update-no-permission": "Du hast keine Berechtigung, um Änderungsmarkierungen von einzelnen Versionen oder Logbucheinträgen hinzuzufügen oder zu entfernen.",
-       "tags-update-blocked": "Du kannst keine Änderungsmarkierungen hinzufügen oder entfernen, während du gesperrt bist.",
+       "tags-update-blocked": "Du kannst keine Änderungsmarkierungen hinzufügen oder entfernen, während {{GENDER:$1|du}} gesperrt bist.",
        "tags-update-add-not-allowed-one": "Die Markierung „$1“ darf nicht manuell hinzugefügt werden.",
        "tags-update-add-not-allowed-multi": "Die {{PLURAL:$2|folgende Markierung darf|folgenden Markierungen dürfen}} nicht manuell hinzugefügt werden: $1",
        "tags-update-remove-not-allowed-one": "Die Markierung „$1“ darf nicht entfernt werden.",
        "htmlform-float-invalid": "Der angegebene Wert ist keine Zahl.",
        "htmlform-int-toolow": "Der angegebene Wert ist unter dem Minimum von $1",
        "htmlform-int-toohigh": "Der angegebene Wert ist über dem Maximum von $1",
-       "htmlform-required": "Dieser Wert wird benötigt",
+       "htmlform-required": "Diese Angabe wird benötigt.",
        "htmlform-submit": "Speichern",
        "htmlform-reset": "Änderungen rückgängig machen",
        "htmlform-selectorother-other": "Andere",
        "htmlform-cloner-create": "Weitere hinzufügen",
        "htmlform-cloner-delete": "Entfernen",
        "htmlform-cloner-required": "Es ist mindestens ein Wert erforderlich.",
-       "htmlform-date-toolow": "Der angegebene Wert liegt vor dem frühesten erlaubten Datum $1.",
+       "htmlform-date-placeholder": "JJJJ-MM-TT",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "JJJJ-MM-TT HH:MM:SS",
+       "htmlform-date-invalid": "Der eingegebene Wert ist kein erkanntes Datum. Versuche die Verwendung des Formats JJJJ-MM-TT.",
+       "htmlform-time-invalid": "Der eingegebene Wert ist keine erkannte Zeit. Versuche die Verwendung des Formats HH:MM:SS.",
+       "htmlform-datetime-invalid": "Der eingegebene Wert ist kein erkanntes Datum und keine Zeit. Versuche die Verwendung des Formats JJJJ-MM-TT HH:MM:SS.",
+       "htmlform-date-toolow": "Der eingegebene Wert liegt vor dem frühesten erlaubten Datum $1.",
+       "htmlform-date-toohigh": "Der eingegebene Wert liegt nach dem spätesten erlaubten Datum $1.",
+       "htmlform-time-toolow": "Der eingegebene Wert liegt vor der frühesten erlaubten Zeit $1.",
+       "htmlform-time-toohigh": "Der eingegebene Wert liegt nach der spätesten erlaubten Zeit $1.",
+       "htmlform-datetime-toolow": "Der eingegebene Wert liegt vor dem frühesten erlaubten Datum und der Zeit $1.",
+       "htmlform-datetime-toohigh": "Der eingegebene Wert liegt nach dem spätesten erlaubten Datum und der Zeit $1.",
        "htmlform-title-badnamespace": "[[:$1]] ist nicht im Namensraum „{{ns:$2}}“.",
        "htmlform-title-not-creatable": "„$1“ ist kein erstellbarer Seitentitel",
        "htmlform-title-not-exists": "$1 ist nicht vorhanden.",
        "feedback-external-bug-report-button": "Eine technische Aufgabe einreichen",
        "feedback-dialog-title": "Rückmeldung senden",
        "feedback-dialog-intro": "Du kannst das einfache Formular unten verwenden, um deine Rückmeldung einzureichen. Dein Kommentar wird zusammen mit deinem Benutzernamen zur Seite „$1“ hinzugefügt.",
-       "feedback-error-title": "Fehler",
        "feedback-error1": "Fehler: Unbekanntes Ergebnis der API",
        "feedback-error2": "Fehler: Bearbeitung gescheitert",
        "feedback-error3": "Fehler: Keine Antwort von der API",
        "feedback-thanks": "Vielen Dank. Deine Rückmeldung wurde auf der Seite „[$2 $1]“ gespeichert.",
        "feedback-thanks-title": "Danke!",
        "feedback-useragent": "User Agent:",
-       "searchsuggest-search": "Suchen",
+       "searchsuggest-search": "{{SITENAME}} durchsuchen",
        "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.",
        "authmanager-authn-autocreate-failed": "Die automatische Erstellung des lokalen Benutzerkontos ist fehlgeschlagen: $1",
        "authmanager-change-not-supported": "Die angegebenen Anmeldeinformationen konnten nicht geändert werden, da sie von nichts genutzt werden würden.",
        "authmanager-create-disabled": "Die Benutzerkontenerstellung ist deaktiviert.",
-       "authmanager-create-from-login": "Um dein Benutzerkonto zu erstellen, fülle bitte die unten stehenden Felder aus.",
+       "authmanager-create-from-login": "Um dein Benutzerkonto zu erstellen, fülle bitte die Felder aus.",
        "authmanager-create-not-in-progress": "Die Benutzerkontenerstellung ist nicht im Gang oder es sind Sitzungsdaten verloren gegangen. Bitte beginne von vorn.",
        "authmanager-create-no-primary": "Die angegebenen Anmeldeinformationen konnten nicht für die Benutzerkontenerstellung verwendet werden.",
        "authmanager-link-no-primary": "Die angegebenen Anmeldeinformationen konnten nicht für die Benutzerkontenverknüpfung verwendet werden.",
        "usercssispublic": "Bitte beachten: CSS-Unterseiten sollten keine vertraulichen Daten enthalten, da sie von anderen Benutzern eingesehen werden können.",
        "restrictionsfield-badip": "Ungültige IP-Adresse oder ungültiger IP-Adressbereich: $1",
        "restrictionsfield-label": "Erlaubte IP-Adressbereiche:",
-       "restrictionsfield-help": "Eine IP-Adresse oder ein CIDR-Bereich pro Zeile. Um alles zu aktivieren, verwende<br><code>0.0.0.0/0</code><br><code>::/0</code>"
+       "restrictionsfield-help": "Eine IP-Adresse oder ein CIDR-Bereich pro Zeile. Um alles zu aktivieren, verwende<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Fehler: $1",
+       "edit-error-long": "Fehler:\n\n$1"
 }
index 57b91f9..3d24553 100644 (file)
@@ -24,7 +24,9 @@
                        "Macofe",
                        "Matma Rex",
                        "Kumkumuk",
-                       "Gırd"
+                       "Gırd",
+                       "Velg",
+                       "1917 Ekim Devrimi"
                ]
        },
        "tog-underline": "Bınê gırey de xete bance:",
        "about": "Heqa cı de",
        "article": "Pela zerreki",
        "newwindow": "(pençereyê newey de beno a)",
-       "cancel": "Bıterkın",
+       "cancel": "Bıtekelne",
        "moredotdotdot": "Vêşi...",
        "morenotlisted": "Na lista qay kemi ya.",
        "mypage": "Pele",
        "newpage": "Pela newiye",
        "talkpage": "Ena pele sero werêne",
        "talkpagelinktext": "werênayış",
-       "specialpage": "Perra bağsi",
+       "specialpage": "Pela xısusiye",
        "personaltools": "Hacetê şexsiy",
        "articlepage": "Pera zerreki bıvin",
-       "talk": "Vaten",
+       "talk": "Werênayış",
        "views": "Asayışi",
        "toolbox": "Haceti",
        "tool-link-userrights": "Grubanê {{GENDER:$1|karberi}} bıvırnë",
        "viewhelppage": "Pera peşti bıvin",
        "categorypage": "Pela kategoriya bıasne",
        "viewtalkpage": "Werênayışi bıvêne",
-       "otherlanguages": "Zıwananê binan de",
+       "otherlanguages": "Zederna zıwani",
        "redirectedfrom": "($1 ra kırışı yê)",
        "redirectpagesub": "Pela berdışi",
        "redirectto": "Beno hetê:",
        "mainpage": "Pela Seri",
        "mainpage-description": "Pela seri",
        "policy-url": "Project:Terzê hereketi",
-       "portal": "Portalë Å\9fëlıgi",
+       "portal": "Portalê cemaeti",
        "portal-url": "Project:Portalë şëlıgi",
        "privacy": "Politikaya nımıteyiye",
        "privacypage": "Project:Xısusiyetê nımıtışi",
        "nstab-template": "Şablon",
        "nstab-help": "Pela peşti",
        "nstab-category": "Kategoriye",
-       "mainpage-nstab": "Pela seri",
+       "mainpage-nstab": "Pera esas",
        "nosuchaction": "Fealiyeto wınasi çıniyo",
        "nosuchactiontext": "URL ra kar qebul nêbı.\nŞıma belka URL şaş nuşt, ya zi gıreyi şaş ra ameyi.\nKeyepelê {{SITENAME}} eşkeno xeta eşkera bıkero.",
        "nosuchspecialpage": "Pela xasa wınasiye çıniya",
        "passwordreset-emailtext-ip": "Jeweri, {{SITENAME}} ra (ma heta şımayê, $1 IP adresi ra) ($4) teferuatê hesabdê şıma  va wa biyaro xo viri. Karbero ke cêrdeyo {{PLURAL:$3|hesaba|eno hesaba}} ena e-posta adresiya aleqey cı esto:\n\n$2\n\n{{PLURAL:$3|ena parola idaretena|ena parola idareten}} {{PLURAL:$5|jew roc|$5  roca}}rêya.\nEna parolaya deqewe de u xorê ju parolaya newi bıweçine. Parolaya şıma emaya şıma viri se  yana  ena e-posta şıma nê weştase u şıma qayıl niye parolaya xo bıvurnese, ena mesacer peygoş bıkerê.",
        "passwordreset-emailtext-user": "$1 enê karberi, {{SITENAME}}  ra ($4) teferuatê hesab dê şıma  va wa biyaro xo viri. Karbero ke cêrdeyo {{PLURAL:$3|hesaba|eno hesaba}} ena e-posta adresiya aleqey cı esto:\n\n$2\n\n{{PLURAL:$3|ena parola idaretena|ena parola idareten}} {{PLURAL:$5|jew roc|$5  roca}}rêya.\nEna parolaya deqewe de u xorê ju parolaya newi bıweçine. Parolaya şıma emaya şıma viri se  yana  ena e-posta şıma nê weştase u şıma qayıl niye parolaya xo bıvurnese, ena mesacer peygoş bıkerê.",
        "passwordreset-emailelement": "Nameyê karberi: \n$1\n\nParolaya vêrdiye: \n$2",
-       "passwordreset-emailsentemail": "Eke na seba hesabê şıma yew adresa e-posteyê qeydına, yew e-posteyê parola nênkerdışi rışiyeno.",
-       "passwordreset-invalideamil": "Adresê eposta raşt niya",
+       "passwordreset-emailsentemail": "Eger kı ena e-posta şıma rê se, yew e-posta do bırışiyo eno hesab.",
+       "passwordreset-invalidemail": "Adresê eposta raşt niya",
        "changeemail": "E-posta adresa xo wedarne",
        "changeemail-header": "E-posta adresa xo vuriyayışi rë ena former pır kerë. Eger kı şıma qayılë kı e postay adresi ra wedarnë se formi rıştış dı heruna e posta veng verdë",
        "changeemail-no-info": "Şıma gani bıkewê pele ke derdest bıresê na pele.",
        "hr_tip": "Xeta verardiye (teserrufın bıgureyne/bıxebetne)",
        "summary": "Xulasa:",
        "subject": "Mewzu:",
-       "minoredit": "Vurriyayışo werdiyo",
+       "minoredit": "No yew vurnayışo werdiyo",
        "watchthis": "Na pele seyr ke",
        "savearticle": "Qeyd ke",
        "savechanges": "Vurnayışan qeyd ke",
        "semiprotectedpagewarning": "'''Diqet: No pel pawyeno, teyna serkari eşkeni bıvurni.'''\nWexta ke şıma no pel vurneni diqet bıkeri, log bivini:",
        "cascadeprotectedwarning": "'''Diqet:''' Na pele kılit biya, tenya karberê idarekeri şenê ke naye bıvurnê, çıke na zerrey {{PLURAL:$1|na pela şipa-kılitkerdiye|nê pelanê şipanê-kılitkerdiyan}} dera:",
        "titleprotectedwarning": "'''Diqet: Na pele kılit biya, [[Special:ListGroupRights|heqê xususiy]] lazımê ke naye vırazê.'''\nLoge peniye cor de este:",
-       "templatesused": "{{PLURAL:$1|Şablon|Şabloni}} ke na pela de xebtênê:",
+       "templatesused": "{{PLURAL:$1|Şablon|Şabloni}} ke ena perrer de karneyayê:",
        "templatesusedpreview": "{{PLURAL:$1|Sablon|Sabloni}}  ke na verqayt de xebetnayê:",
        "templatesusedsection": "{{PLURAL:$1|Template|Templateyan}}  ke na qısım de xebetniyenê:",
        "template-protected": "(kılit biyo)",
        "searchprofile-advanced-tooltip": "Cayê nameyanê xısusiyan de cı geyre",
        "search-result-size": "$1 ({{PLURAL:$2|1 çeku|$2 çekuy}})",
        "search-result-category-size": "{{PLURAL:$1|1 eza|$1 ezayan}} ({{PLURAL:$2|1 kategoriyê bini|$2 kategirayanê binan}}, {{PLURAL:$3|1 dosya|$3 dosyayan}})",
-       "search-redirect": "($1 ra ardış)",
+       "search-redirect": "($1 ra kırışiyè)",
        "search-section": "(qısmê $1)",
        "search-category": "(kategori $1)",
        "search-file-match": "(zerreyê dosya yewbini gêno)",
        "prefs-labs": "Xacetê labs",
        "prefs-user-pages": "Pelê karberi",
        "prefs-personal": "Pela karberi",
-       "prefs-rc": "Vıryayışë newey",
+       "prefs-rc": "Vurriyayışê peyêni",
        "prefs-watchlist": "Lista seyrkerdışi",
        "prefs-editwatchlist": "Lista seyrkerdışi bıvurne",
        "prefs-editwatchlist-label": "Listey serkerdışanê cıkewtışi timar kerê",
        "grant-basic": "Heqê basiti",
        "grant-viewdeleted": "Besteryaya peran u dosyaya bıasne",
        "grant-viewmywatchlist": "Lista serykerdışê xo bıvêne",
-       "newuserlogpage": "Cıkewtışê hesabvıraştışi",
-       "newuserlogpagetext": "Ena log de viraştişê karberî esta.",
+       "newuserlogpage": "Roceka karberanê newa",
+       "newuserlogpagetext": "No yew qeydê afernayışanê karberio.",
        "rightslog": "Qeydê heqanê karberi",
        "rightslogtext": "Ena listeyê loganê ke heqqa karbaranî mucneno.",
        "action-read": "ena pela wanayış",
        "recentchanges-noresult": "Goreyê kriteranê kıfşkerdeyan ra qet yew vurnayış nêvêniya.",
        "recentchanges-feed-description": "Ena feed dı vurnayişanê tewr peniyan teqip bık.",
        "recentchanges-label-newpage": "Enê vurnayışi ra yu pera newi vıraziya ya",
-       "recentchanges-label-minor": "Vurriyayışo werdiyo",
+       "recentchanges-label-minor": "No yew vurnayışo werdiyo",
        "recentchanges-label-bot": "Eno vurnayış terefê yew boti ra vıraziyo",
        "recentchanges-label-unpatrolled": "Eno vurnayış hewna dewriya nêbiyo",
        "recentchanges-label-plusminus": "Ebadê pele de bazê bayti de vayeyê cı",
        "recentchanges-submit": "Bımocne",
        "rcnotefrom": "Cêr de <strong>$2</strong> ra nata {{PLURAL:$5|vurnayışiyê}} asenê (tewr vêşi <strong>$1</strong> asenê) <strong>$3, $4</strong>",
        "rclistfrom": "$3 $2 ra tepiya vurnayışanê neweyan bımocne",
-       "rcshowhideminor": "vurriyayışê werdi $1",
+       "rcshowhideminor": "Vurriyayışê werdiy $1",
        "rcshowhideminor-show": "Bımocne",
        "rcshowhideminor-hide": "Bınımne",
        "rcshowhidebots": "botan $1",
        "speciallogtitlelabel": "Meqsed (sername ya zi {{ns:user}}:karberi rê nameyê karberi):",
        "log": "Qeydi",
        "logeventslist-submit": "Bımocne",
-       "all-logs-page": "Umumi qeydi pêro",
+       "all-logs-page": "Qeydê umumi pêro",
        "alllogstext": "qey {{SITENAME}}i mocnayişê heme rocaneyani.\ntipa rocaneyi, nameyê karberi (herfa pil u qıci re hessas a), ya zi peli (reyna hessasiyê herfa pil u qıciyi) bıweçine u esayiş qıc kerê.",
        "logempty": "Qeydan dı malumato unasin çıni yo.",
-       "log-title-wildcard": "sername yê ke pê ney nuşteyi destkenêpê bıgêr.",
+       "log-title-wildcard": "Sernameyê ke be nê nuşteyi ra destkenê pê, cıgeyre",
        "showhideselectedlogentries": "Qeydê weçinayışê bımocne/bınımne dekerê",
        "log-edit-tags": "Etiketanê weçinayê qeydan bıvurnê",
        "checkbox-select": "Weçinaye: $1",
        "activeusers-intro": "Ena yew listeya karberê ke $1 {{PLURAL:$1|roc|rocan}} ra tepya iştiraq kerdo ênan mocneno.",
        "activeusers-count": "Peyni  {{PLURAL:$3|roc de|$3 rocan de}} $1  {{PLURAL:$1|hereket kerdo|hereketi kerdê}}",
        "activeusers-from": "Enê karberi ra tepya bımocne:",
-       "activeusers-hidebots": "Botan bınımne",
-       "activeusers-hidesysops": "İdarekaran bınımne",
        "activeusers-noresult": "Karberi nêdiyayê.",
        "activeusers-submit": "Karberanê aktivan bıasene",
        "listgrouprights": "heqê grubê karberi",
        "usermessage-editor": "Xeberdarê sistemi",
        "usermessage-template": "MediaWiki:UserMessage",
        "watchlist": "Listey pawıteyan",
-       "mywatchlist": "Listey pawıteyan",
+       "mywatchlist": "Lista mına cıewniyayışi",
        "watchlistfor2": "Qandê $1 ($2)",
        "nowatchlist": "listeya temaşa kerdıişê şıma de yew madde zi çina.",
        "watchlistanontext": "qey vurnayişê maddeya listeya temaşakerdiş ronıştış akerê",
        "watchlist-hide": "Bınımne",
        "watchlist-submit": "Bımocne",
        "wlshowtime": "Periyoda zemani asenayışi:",
-       "wlshowhideminor": "vurriyayışê werdi",
+       "wlshowhideminor": "vurriyayışê werdiy",
        "wlshowhidebots": "boti",
        "wlshowhideliu": "karberê qeydıni",
        "wlshowhideanons": "karberê anonimi",
        "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ê kılitbiyayeyi",
+       "sp-contributions-blocklog": "qeydê kılitkerdışi",
        "sp-contributions-deleted": "iştırakê {{GENDER:$1|karberi}} esterdi",
        "sp-contributions-uploads": "Barkerdışi",
        "sp-contributions-logs": "qeydi",
        "contribslink": "iştıraki",
        "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ê astengi",
+       "blocklogpage": "Qeydê kılitkerdışi",
        "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.",
        "feedback-subject": "Mewzu:",
        "feedback-submit": "Bırışe",
        "feedback-thanks": "Teşekkur kemê! Vatışê şıma pela da \"[$2 $1]\" esta.",
-       "searchsuggest-search": "Cı geyre",
+       "searchsuggest-search": "{{SITENAME}} de cı geyre",
        "searchsuggest-containing": "estebiyaye...",
        "api-error-badaccess-groups": "Ena wiki de dosya barkerdışi rê mısade nêdeyêno.",
        "api-error-badtoken": "Xetaya zerreki: Antışo xırabın.",
        "special-characters-title-minus": "işaretê kemiye",
        "mw-widgets-dateinput-placeholder-day": "SSSS-AA-RR",
        "mw-widgets-dateinput-placeholder-month": "SSSS-AA",
-       "mw-widgets-titleinput-description-redirect": "berd be $1"
+       "mw-widgets-titleinput-description-redirect": "berd be $1",
+       "log-action-filter-newusers": "Babetê hesabvıraştışi:"
 }
index cf025f0..f59d719 100644 (file)
        "yourpasswordagain": "Šćitne gronidło hyšći raz zapódaś:",
        "createacct-yourpasswordagain": "Gronidło wobkšuśiś",
        "createacct-yourpasswordagain-ph": "Zapódaj gronidło hyšći raz",
-       "remembermypassword": "Na toś tom licadle pśizjawjony wóstaś (za maksimalnje $1 {{PLURAL:$1|źeń|dnja|dny|dnjow}})",
        "userlogin-remembermypassword": "Pśizjawjony wóstaś",
        "userlogin-signwithsecure": "Wěsty zwisk wužywaś",
        "yourdomainname": "Twója domejna",
        "activeusers-intro": "To jo lisćina wužywarjow, kotrež su byli aktiwne za {{PLURAL:$1|slědny źeń|slědnej $1 dnja|slědne $1 dny|slědnych $1 dnjow}}.",
        "activeusers-count": "$1 {{PLURAL:$1|akcija|akciji|akcije|akcijow}} w {{PLURAL:$3|slědnem dnju|slědnyma $3 dnjoma|slědnych $3 dnjach}}",
        "activeusers-from": "Wužywarjow zwobrazniś, zachopinajucy z:",
-       "activeusers-hidebots": "Boty schowaś",
-       "activeusers-hidesysops": "Administratorow schowaś",
        "activeusers-noresult": "Žedne wužywarje namakane.",
        "listgrouprights": "Pšawa wužywarskeje kupki",
        "listgrouprights-summary": "To jo lisćina wužywarskich kupkow definěrowanych w toś tom wikiju z jich zwězanymi pśistupnymi pšawami. Móžo [[{{MediaWiki:Listgrouprights-helppage}}|pśidatne informacije]] wó jadnotliwych pšawach daś.",
        "htmlform-cloner-create": "Wěcej pśidaś",
        "htmlform-cloner-delete": "Wótpóraś",
        "htmlform-cloner-required": "Nanejmjenjej jadna gódnota jo trěbna.",
-       "sqlite-has-fts": "Wersija $1 z pódpěru za połnotekstowe pytanje",
-       "sqlite-no-fts": "Wersija $1 bźez pódpěry za połnotekstowe pytanje",
        "logentry-delete-delete": "$1 jo bok $3 {{GENDER:$2|wulašował|wulašowała}}",
        "logentry-delete-restore": "$1 jo bok $3 {{GENDER:$2|wótnowił|wótnowiła}}",
        "logentry-delete-event": "$1 jo {{GENDER:$2|změnił|změniła}} widobnosć {{PLURAL:$5|protokolowego zapiska|$5 protokoloweju zapiskowu|$5 protokolowych zapiskow}} na $3: $4",
index e40e405..68ce13c 100644 (file)
        "yourpasswordagain": "Mintaipo kaatalib:",
        "createacct-yourpasswordagain": "Kompomo borospanalib",
        "createacct-yourpasswordagain-ph": "Posuango kaagu borospanalib",
-       "remembermypassword": "Soroho ot loginku id popogihuman diti (gisom solinaid do $1 {{PLURAL:$1|tadau|madau}})",
        "userlogin-remembermypassword": "Potilombuso oku do poinsuang log",
        "userlogin-signwithsecure": "Gunoo noputan noumoligan",
        "yourdomainname": "Damin nu:",
        "passwordreset-emailtitle": "Kointalangan takaun id {{SITENAME}}",
        "passwordreset-emailelement": "Ngaranmoguno: \n$1\n\nKaatalib daamot: \n$2",
        "passwordreset-emailsentemail": "Surat-i pononsorou nakaatod noh.",
-       "passwordreset-emailsent-capture": "Surat-i pononsorou nakaatod noh, miagal id siriba diti.",
-       "passwordreset-emailerror-capture": "Surat-i pononsorou nopudali noh, miagal id siriba diti, nga awu kaatod id momomoguno: $1",
        "changeemail": "Alanai porikatan surat-i",
        "changeemail-header": "Alanai akaun porikatan surat-i",
        "changeemail-no-info": "Mositi sumuang log ko do mongoguno monilombus id bolikon diti.",
index 45a79b0..2685328 100644 (file)
        "qbpageoptions": "ये पानो",
        "qbmyoptions": "मेरो पानो",
        "faq": "भौत सोधिन्या प्रश्नहरू",
-       "faqpage": "Project:भà¥\8cत à¤¸à¥\8bधिà¤\8fà¤\95ा à¤ªà¥\8dरशà¥\8dनहरà¥\81",
+       "faqpage": "Project:भà¥\8cत à¤¸à¥\8bधियाà¤\95ा à¤ªà¥\8dरशà¥\8dनहरà¥\82",
        "actions": "कार्यहरू",
        "namespaces": "नेमस्पेस",
        "variants": "बहुरुपअन",
        "views": "अवलोकन गरऽ",
        "toolbox": "औजारअन",
        "tool-link-userrights": "परिवर्तन{{GENDER:$1|प्रयोगकर्ता}}समूहहरू",
-       "tool-link-emailuser": "यो ईमेल{{GENDER:$|प्रयोगकर्ता}}",
+       "tool-link-emailuser": "{{GENDER:$1|प्रयोगकर्ता}}लाई एइ इमेलमी पठाऽ",
        "userpage": "प्रयोगकर्ता पाना हेर्न्या",
        "projectpage": "प्रोजेक्ट पानो हेर्न्या",
        "imagepage": "चित्र पानो हेर",
        "databaseerror-query": "अनुरोध: $1",
        "databaseerror-function": "फङ्सन : $1",
        "databaseerror-error": "गल्ती: $1",
+       "transaction-duration-limit-exceeded": "To avoid creating high replication lag, this transaction was aborted because the write duration ($1) exceeded the $2 second limit.\nIf you are changing many items at once, try doing multiple smaller operations instead.",
        "laggedslavemode": "<strong>चेतावनी:</strong> पानामी हालका अद्यतनहरू नहुनस्कदान ।",
        "readonly": "डेटाबेस बन्द गरिया छ",
        "enterlockreason": "ताल्चा मार्नुको कारण दिया, साथै ताल्चा हटाउने समयको अवधि अनुमान लगा।",
        "title-invalid-interwiki": "अनुरोध गरियाको शिर्षकमी अन्तर विकि लिङ्क छ जइलाई शिर्षकमी प्रयोग गद्द नाइपाइनो ।",
        "title-invalid-talk-namespace": "निवेदन गरियाको पानाको शिर्षकले उपलब्ध नभएका कुरडी पानालाई सन्दर्भको रूपमी राख्याको छ ।",
        "title-invalid-characters": "निवेदन गरियाको यै पानाको शिर्षकमी अवैध अक्षर रयाको छः \"$1\" ।",
+       "title-invalid-relative": "शीर्षक एउटा सन्दर्भित मार्ग राख्दछ। सन्दर्भित पृष्ठको शीर्षक (./, ../)अमान्य छ, किनकि त्यो प्राय रूपले पहुँच बाहिर हुन्छ जब त्यसलाई प्रायोगकर्ताको ब्राउजरबाट प्रयोगमी ल्याउने प्रयास गर्ने गरिन्छ।",
        "title-invalid-magic-tilde": "अनुरोध अरिया: पन्ना: शीर्षकमी अमान्य म्याजिक टिल्ड शृङ्खला छ (<nowiki>~~~</nowiki>)।",
        "title-invalid-too-long": "अनुरोध अरिया: पन्ना: शीर्षक भौत लामु छ। यो UTF-8 इनकोडिङमी $1 {{PLURAL:$1|byte|bytes}} है लामु हुनु हुनैन।",
        "title-invalid-leading-colon": "निवेदन गरिया पृष्ठको शिर्षकको शुरूमी अवैध कोलोन रया छ ।",
        "viewsource": "स्रोत हेर",
        "viewsource-title": " $1 को स्रोत हेर",
        "actionthrottled": "कार्य रोकिईयो",
-       "actionthrottledtext": "स्पामको रोकथामको लागि , तमीलाई यो कार्य नापै समयमी मैथै पटक गद्दाबठे सिमित गरियाको छ, र तमीले आफ्नो सिमा पार गरिसक्याछौ ।\nकृपया केही मिनेट पछि पुन: प्रयास गर  ।",
+       "actionthrottledtext": "स्पाम रोकथाम खिलाइ, तमलाई येइ काम थोक्काइ बगतमी झिक्कै फेर अद्दा बठेइ सीमित अरीरैछ, रे तमले आफुनी सीमा पार अरिसकिराइछऽ।\nकृपया केइ मिनट पछा दोसर्‍याँ प्रयास अर्याऽ।",
        "protectedpagetext": "यो पृष्ठ सम्पादन हुनबठे बचाउन सम्पादनमी तथा अन्य कार्यमी रोक लगाइया छ।",
        "viewsourcetext": "तम ये पृष्ठको स्रोत हेद्दु सकुन्छौ और उईको नक्कल उताद्दु सकुन्छौ |",
        "viewyourtext": "यै पानामी रह्याका '''तमरा सम्पादनहरू''' हेद्द या प्रतिलिपी गद्द सक्द्या हौ :",
+       "protectedinterface": "यो पृष्ठले सफ्टवेयरको लागि अन्तरमोहडा पाठ प्रदान गर्दछ , र यसलाई दुरुपयोग हुनबाट बचाउन सुरक्षा प्रदान गरिएको छ।\nसम्पूर्ण विकिहरूका लागि अनुवादमी परिवर्तन गर्नको लागि [https://translatewiki.net/ translatewiki.net], प्रयोग गर्नुहोस् ,  मिडियाविकि स्थानियकरण परियोजना ।",
        "editinginterface": "<strong>चेतावनी:</strong> तमी यै पानालाई सम्पादन गद्द लाग्याछौ, जनले सफ्टवेयरको लागि \nइन्टरफेस सामग्रीहरू प्रदान गरन्छ।\nयै पानामी गरियाको परिवर्तनले यै विकिमी अरु प्रयोगकर्तानको इन्टरफेसको प्रदर्शनमी प्रभाव पडन्छ ।",
        "translateinterface": "सप्पै विकिइनखिलाइ अनुवाद थप्दाइ या बदेल्लाइ, कृपया [https://translatewiki.net/ translatewiki.net]को प्रयोग अर:, मिडियाविकि क्षेत्रीयकरण परियोजना:।",
+       "cascadeprotected": "यो पृष्ठ सम्पादन गर्नबाट सुरक्षित गरिएकोछ किनभनें {{PLURAL:$1|पृष्ठ |पृष्ठहरू}}मा सुरक्षित गर्नुका साथै प्रपात (\"cascading\") विकल्प खुल्ला राखिएको छ:\n$2",
        "namespaceprotected": "तमलाई '''$1'''  नेमस्पेसमी रह्याका पानाहरू सम्पादन गद्या अनुमति छैन ।",
        "customcssprotected": "तमलाई यो  पानो सम्पादन गद्दे अनुमति छैन, किनकी यैमी कुनै अर्को प्रयोगकर्ताको व्यक्तिगत अभिरुचीहरू संग्रहित छन् ।",
        "customjsprotected": "तमलाई यो जाभास्कृप्ट पानो सम्पादन गद्दे अनुमति छैन, किनकी यैमी कुनै अर्को प्रयोगकर्ताको व्यक्तिगत अभिरुचीहरू संग्रहित छन् ।",
        "wrongpassword": "पासवर्ड गलत हालियो।\nकृपया आजी प्रयास गरया।",
        "wrongpasswordempty": "हालिएया पासवर्ड खालि थ्यो।\nकृपया आजी प्रयास गरया।",
        "password-name-match": "तमरो प्रवेशशव्द प्रयोगकर्ता नाम है फरक हुनपडन्छ ।",
-       "password-login-forbidden": "यà¥\87 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤¨à¤¾à¤® à¤° à¤ªà¥\8dरवà¥\87श à¤¶à¤µ्द वर्जित गरिया छ।",
+       "password-login-forbidden": "यà¥\87 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤¨à¤¾à¤® à¤° à¤ªà¥\8dरवà¥\87श à¤¶à¤¬्द वर्जित गरिया छ।",
        "mailmypassword": "पासवर्ड पूर्वनिर्धारित गर",
        "passwordremindertitle": "{{SITENAME}}का लागि नयाँ अस्थायी पासवर्ड",
        "passwordremindertext": "कसैले (सायद तमी, IP ठेगाना $1 बाट), {{SITENAME}}($4) को लागि नौलो पासवर्ड अनुरोध गर्या छ । प्रयोगकर्ता \"$2\" को लागि नौलो अस्थायी पासवर्ड \"$3\"तयार पारिया छ । यदि यो तमरो इच्छामी भयाको भया अहिले तमीले लगइन गरीबर नौलो पासवर्ड छान्नु पड्ड्या हुन्छ ।\nतमरो अस्थायी पासवर्ड  {{PLURAL:$5|एक दिन|$5 दिनहरू पछि}} अमान्य हुन्याछ ।\n\nयदि कोही अरुले नै अनुरोध गर्याको हो भण्या , या तमीले आफ्नो पासवर्ड सम्झ्यौ भण्या, अथवा\nत्यैलाई परिवर्तन गर्न चाहन्नौ भण्या, तमीले यो सन्देसको वेवास्ता गद्दसक्द्याहौ र पुरानै पासवर्ड प्रयोग गरिरहन सक्द्याहौ ।",
        "changepassword-success": "तमरो पासवर्ड सफलतापूर्वक परिवर्तन भयो!",
        "changepassword-throttled": "तमले अलै भौत फेर प्रवेशका निम्ति प्रयास गरया छौ।\nकृपया $1 थोक्कै जागी मात्र प्रयास गर।",
        "botpasswords": "बोट पासवर्ड",
+       "botpasswords-createnew": "नौलो बोट पासवर्ड बनाऽ",
+       "botpasswords-editexisting": "भयाऽ बोट पासवर्ड सम्पादन अरऽ",
        "botpasswords-label-appid": "बोट नाम:",
        "botpasswords-label-create": "सृजना गर",
        "botpasswords-label-update": "नयाँ बनाउनु",
        "botpasswords-label-resetpassword": "पासवर्ड पूर्वनिर्धारित गर",
        "botpasswords-label-grants": "अनुदान आवेदन:",
        "botpasswords-label-grants-column": "प्रदान भयो",
+       "botpasswords-bad-appid": "बोट नाउँ \"$1\" नाइमाणीनो।",
+       "botpasswords-insert-failed": "बोट नाउँ \"$1\" थप्दाइ असफल। कि यो पैली थपीसकीरैछ?",
+       "botpasswords-update-failed": "बोट नाउँ \"$1\" अपडेट अद्दाइ असफल। कि यो मेट्याऽ हो?",
        "botpasswords-created-title": "बोट को पासवर्ड बन्यो",
+       "botpasswords-created-body": "प्रयोगकर्ता \"$2\" को बोट नाउँ \"$1\" खिलाइ बोट पासवर्ड बनायियो।",
        "botpasswords-updated-title": "बोट को पासवर्ड अपडेट भयो",
        "botpasswords-deleted-title": "बोट को पासवर्ड मेटियो",
        "resetpass_forbidden": "पासवर्ड परिवर्तन गर्न नाइँमिल्लो",
        "passwordreset-emailtitle": "{{SITENAME}}मा खाता विवरण",
        "passwordreset-emailelement": "प्रयोगकर्ताको नाम: \n$1\n\nअस्थाई पासवर्ड: \n$2",
        "passwordreset-emailsentemail": "यदि यो इमेल ठेगाना तम सित सम्बन्धित छ भण्या, तब यक पासवर्ड रिसेट इमेल पठाएलो।",
-       "passwordreset-invalideamil": "अबैध ई-मेल ठेगाना",
+       "passwordreset-invalidemail": "अबैध ई-मेल ठेगाना",
        "changeemail": "इमेल ठेगाना बदेल वा हटा",
        "changeemail-header": "तमरो इमेल ठेगाना बदेल्लाइ एइ फाराम पुराइ भरऽ। यदि तम तमरा खाता बठेइ कसै लै इमेल ठेगाना सितोऽ सम्बन्ध हटौन चाहन्छऽ भण्या, फाराम बुजौन्ज्याँ नौलो इमेल ठेगाना भण्ण्या ठौर खालि छाण्याऽ।",
        "changeemail-oldemail": "अईलको इमेल-ठेगाना:",
        "sectioneditnotsupported-text": "ये पृष्ठमी खण्ड सम्पादन असमर्थित",
        "permissionserrors": "अधिकारमी त्रुटी",
        "permissionserrorstext": "तइ काम अद्दाइ तम सित अधिकार आथिन, यिन {{PLURAL:$1|कारण|कारणअन}}ले अद्दा:",
-       "permissionserrorstext-withaction": "$2 कि लेखा तमलाईँ अनुमति नाइथिन , यिन {{PLURAL:$1|कारणले|कारणहरुले}} गद्दा :",
+       "permissionserrorstext-withaction": "$2 कि लेखा तमलाई अनुमति नाइथिन , यिन {{PLURAL:$1|कारणले|कारणहरू}}ले गद्दा :",
        "moveddeleted-notice": "पानो मेटियाको छ।\nमेटियाका और सारियाका पानाहरूको सूची तल्तिर सन्दर्भखी लेखा दियाको छ।",
        "log-fulllog": "पूरा लग हेर",
        "edit-hook-aborted": "हुकले सम्पादन बन्द गरिदियो ।\nयेले कोइ कारण दिएन ।",
        "prefs-editor": "सम्पादक",
        "prefs-preview": "पूर्वावलोकन",
        "prefs-advancedrc": "उन्नत विकल्पहरू",
-       "prefs-advancedrendering": "à¤\89नà¥\8dनत à¤µà¤¿à¤\95लà¥\8dपहरà¥\81",
+       "prefs-advancedrendering": "à¤\89नà¥\8dनत à¤µà¤¿à¤\95लà¥\8dपहरà¥\82",
        "prefs-advancedsearchoptions": "उन्नत विकल्पहरू",
        "prefs-advancedwatchlist": "उन्नत विकल्पहरू",
        "prefs-displayrc": "धेकिन्या विकल्पहरू",
        "activeusers-intro": "यो सूची ती प्रयोगकर्तानको हो जनले विगत $1 {{PLURAL:$1|दिन| दिन}}मी  गतिविधि देखायाकाछन्।",
        "activeusers-count": "विगत {{PLURAL:$3|दिनमी|$3 दिनहरूमी}}  $1 {{PLURAL:$1|सम्पादन गरियो|सम्पादनहरू गरिया}}",
        "activeusers-from": "यहाँबठे सुरु हुन्या प्रयोगकर्ताहरू धेकाओ:",
-       "activeusers-hidesysops": "प्रवन्धकहरू लुकाउन्या",
        "activeusers-noresult": "प्रयोगकर्ताहरू भेटियानन्",
        "mailnologintext": "तमीले अरु प्रयोगकर्तानलाई ईमेल पठाउनको लागि आफु पहिली [[Special:UserLogin|प्रवेश(लगइन)गर्याको]] हुनुपडन्छ र [[Special:Preferences|आफ्नो रोजाइहरूमी]] एउटा वैध ईमेल ठेगाना भयाको हुनुपडन्छ ।",
        "emailpagetext": "तल दियाको फार्मले तमी यै {{GENDER:$1|प्रयोगकर्ता}}लाई इमेल पठाउन सक्द्या हौ । तमीले जो ठेगाना [[Special:Preferences|आफ्नो प्रयोगकर्ता रोजाईहरू]]मी दियाका छियौ त्यो यै इमेललाई \"पठाउने\" को रूपमी आउन्याछ, अतः प्राप्तकर्ता तमीलाई सिधै जवाफ दिनसक्द्याछ ।",
        "protect-default": "सब्बै प्रयोगकर्तानहरूलाई अनुमति दिन्या",
        "protect-level-autoconfirmed": "नौला तथा दर्ता भयाका प्रयोगकर्तानलाई मात्र अनुमति दिन्या",
        "protect-cascade": "यै पानामी संलग्न सुरक्षित पानाहरू (लामबद्द सुरक्षा)",
+       "protect-expiry-options": "२ घण्टाहरू:2 hours,१ दिन :1 day,३ दिनहरू:3 days,१ हप्ता:1 week,२ हप्ताहरू:2 weeks,१ महिना:1 month,३ महिनाहरू:3 months,६ महिनाहरू:6 months,१ वर्ष:1 year,अनगिन्ती:infinite",
+       "restriction-type": "अनुमति:",
        "pagesize": "(अक्षरहरू)",
        "undeletepage": "मेट्याका पानाहरू हेद्या र पूर्वरुपमी फर्काउन्या",
        "undeleterevisions": "$1 {{PLURAL:$1|संशोधन|संशोधनहरू}} संग्रहित",
        "whatlinkshere-links": "← लिंकहरू",
        "whatlinkshere-hideredirs": "$1 पुन:निर्देशित हुन्छ",
        "whatlinkshere-hidetrans": "$1 सम्मील",
-       "whatlinkshere-hidelinks": "$1 लिङ्क",
+       "whatlinkshere-hidelinks": "$1 लिङ्कहरू",
        "whatlinkshere-hideimages": "$1 फाइलआ लिङ्कअन",
        "whatlinkshere-filters": "छानियाका",
        "ipbreason-dropdown": "* ब्लक गर्नुका समान्य कारणहरू\n** झूटो सूचना दियाको\n** पानानबठे सामाग्रीहरू हटायाको\n** बाहिरी जालक्षेत्र (sites)सित नचाहिंदो लिङ्क गर्याको \n** पानानमी बकवास/गाली-गलौच हाल्याको\n** भै धेकाउने व्यवहार/उत्पीडन (सताउने कार्य) गर्याको\n** धेरै गलत खाताहरू बनायाको\n** प्रयोगकर्ता नाम अस्वीकार्य",
        "newimages-summary": "यै खास पानाले अन्तिम अपलोड गर्याका फाइलहरू धेकाउँन्छ ।",
        "days": "{{PLURAL:$1|$1 दिन|$1 दिनहरू}}",
        "metadata": "मेटाडेटा",
-       "metadata-help": "यà¥\88 à¤«à¤¾à¤\87लमि à¤\85तिरिà¤\95à¥\8dत à¤\9cानà¤\95ारà¥\80हरà¥\81 à¤\9bनà¥\8d, à¤¯à¥\88लाà¤\88 à¤¬à¤¨à¤¾à¤\89न à¤¸à¤®à¥\8dभवतà¤\83 à¤¡à¤¿à¤\9cिà¤\9fल à¤\95à¥\8dयामà¥\87रा और स्क्यानर प्रयोग गरियाको हुनसकन्छ । यदि यै फाइललाई खास अवस्थाबठे फेरबदल गरियाको हो भण्या यै फाइलले  सब्बै विवरण प्रतिबिम्बित गद्द सक्यानाइथी ।",
+       "metadata-help": "यà¥\88 à¤«à¤¾à¤\87लमि à¤\85तिरिà¤\95à¥\8dत à¤\9cानà¤\95ारà¥\80हरà¥\82 à¤\9bनà¥\8d, à¤¯à¥\88लाà¤\88 à¤¬à¤£à¥\81à¤\89न à¤¸à¤®à¥\8dभवतà¤\83 à¤¡à¤¿à¤\9cिà¤\9fल à¤\95à¥\8dयामरा और स्क्यानर प्रयोग गरियाको हुनसकन्छ । यदि यै फाइललाई खास अवस्थाबठे फेरबदल गरियाको हो भण्या यै फाइलले  सब्बै विवरण प्रतिबिम्बित गद्द सक्यानाइथी ।",
        "metadata-fields": "Image metadata fields listed in this message will be included on image page display when the metadata table is collapsed.\nOthers will be hidden by default.\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-orientation": "अभिविन्यास",
        "exif-xresolution": "क्षैतिज संकल्प(resolution)",
index 8e70898..40d6931 100644 (file)
        "categories": "ގިސްމުތައް",
        "categoriespagetext": "ތިރީގައި މިވާ ގިސްމުތައް ވިކީ ގައި މައުޖޫދުވެގެން ވެއެވެ.\n[[Special:UnusedCategories|Unused categories]] are not shown here.\nAlso see [[Special:WantedCategories|wanted categories]].",
        "activeusers": "ހަރަކާތްތެރި މެމްބަރުންގެ ލިސްޓު",
-       "activeusers-hidebots": "ބޮޓް ފޮރުއްވާ",
-       "activeusers-hidesysops": "އެޑްމިނިސްޓްރޭޓަރުން ފޮރުއްވާ",
        "listgrouprights-members": "(މެމްބަރުންގެ ލިސްޓު)",
        "emailuser": "މި މެންބަރަށް އީމޭލު ފޮނުއްވާ",
        "watchlist": "މަގޭ ނަޒަރު",
index dfe09b4..1d12d07 100644 (file)
        "searchprofile-advanced-tooltip": "Sērca int i spâsi di nòm fât só mzûra.",
        "search-result-size": "$1 ({{PLURAL:$2|'na parôla|$2 parôli}})",
        "search-result-category-size": "{{PLURAL:$1|1 utèint|$1 utèint}} ({{PLURAL:$2|1 sotcategoréia|$2 sotcategoréi}},{{PLURAL:$3|1 file|$3 files}})",
-       "search-redirect": "(redirect $1)",
+       "search-redirect": "(redirect from $1)",
        "search-section": "(sesiòun $1)",
        "search-category": "(categoréia $1)",
        "search-file-match": "(relasiòun dèinter al file)",
index 615c4c1..f7b77be 100644 (file)
        "category-file-count-limited": "Η τρέχουσα κατηγορία περιέχει {{PLURAL:$1|το ακόλουθο αρχείο|τα ακόλουθα $1 αρχεία}}.",
        "listingcontinuesabbrev": "συνεχίζεται",
        "index-category": "Σελίδες καταλογογραφημένες για μηχανές αναζήτησης",
-       "noindex-category": "ΣελίδεÏ\82 Î¼Î· ÎºÎ±Ï\84αλογογÏ\81αÏ\86ημένες",
+       "noindex-category": "Î\9cη ÎºÎ±Ï\84αλογογÏ\81αÏ\86ημένεÏ\82 Ï\83ελίδες",
        "broken-file-category": "Σελίδες με κατεστραμμένους συνδέσμους",
        "about": "Σχετικά",
        "article": "Σελίδα περιεχομένου",
        "cannotlogin-text": "Η σύνδεση δεν είναι δυνατή.",
        "cannotloginnow-title": "Δεν μπορείτε να συνδεθείτε τώρα",
        "cannotloginnow-text": "Η σύνδεση δεν είναι δυνατή όταν χρησιμοποιείτε την $1.",
+       "cannotcreateaccount-title": "Αδυναμία δημιουργίας λογαριασμού",
        "yourdomainname": "Το domain σας:",
        "password-change-forbidden": "Δεν μπορείτε να αλλάξετε τους κωδικούς πρόσβασης σε αυτό το βίκι.",
        "externaldberror": "Είτε συνέβη κάποιο σφάλμα εξωτερικής πιστοποίησης της βάσης δεδομένων είτε δεν σας έχει επιτραπεί να ενημερώσετε τον εξωτερικό σας λογαριασμό.",
        "passwordreset-emailelement": "Όνομα χρήστη: \n$1\n\nΠροσωρινός κωδικός πρόσβασης:\n$2",
        "passwordreset-emailsentemail": "Αν αυτή η διεύθυνση ηλεκτρονικού ταχυδρομείου συνδέεται με το  λογαριασμό σας, τότε  θα σας αποσταλεί μήνυμα ηλεκτρονικού ταχυδρομείου για την επαναφορά του κωδικού πρόσβασης.",
        "passwordreset-emailsentusername": "Αν υπάρχει μια διεύθυνση ηλεκτρονικού ταχυδρομείου που συνδέεται με αυτό το όνομα χρήστη, τότε θα σας αποσταλεί ένα μήνυμα ηλεκτρονικού ταχυδρομείου για την επαναφορά του κωδικού πρόσβασης.",
-       "passwordreset-invalideamil": "Μη έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου",
+       "passwordreset-invalidemail": "Μη έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου",
        "changeemail": "Αλλαγή ή αφαίρεση της διεύθυνσης ηλεκτρονικού ταχυδρομείου",
        "changeemail-header": "Συμπληρώστε αυτήν τη φόρμα για να αλλάξετε τη διεύθυνσή σας ηλεκτρονικού ταχυδρομείου. Αν θέλετε να καταργήσετε τη σύνδεση οποιασδήποτε διεύθυνσης ηλεκτρονικού ταχυδρομείου με το λογαριασμό σας, αφήστε τη νέα διεύθυνση ηλεκτρονικού ταχυδρομείου κενή κατά την υποβολή της φόρμας.",
        "changeemail-no-info": "Πρέπει να έχετε συνδεθεί για άμεση πρόσβαση σε αυτήν τη σελίδα.",
        "continue-editing": "Μεταβείτε στην περιοχή επεξεργασίας",
        "previewconflict": "Αυτή η προεπισκόπηση απεικονίζει το κείμενο στην επάνω περιοχή επεξεργασίας κειμένου, όπως θα εμφανιστεί εάν επιλέξετε να το αποθηκεύσετε.",
        "session_fail_preview": "'''Συγγνώμη! Δεν μπορούσαμε να διεκπεραιώσουμε την επεξεργασία σας λόγω απώλειας των δεδομένων της συνεδρίας.\nΠαρακαλώ προσπαθήστε ξανά. Αν δεν δουλεύει ξανά, δοκιμάστε να [[Special:UserLogout|αποσυνδεθείτε]] και να συνδεθείτε πάλι.'''",
-       "session_fail_preview_html": "'''Λυπούμαστε! Δεν μπορέσαμε να διεκπεραιώσουμε την επεξεργασία σας λόγω απώλειας των δεδομένων της συνεδρίας.'''\n\n''Επειδή το {{SITENAME}} επιτρέπει την εισαγωγή ακατέργαστου HTML, η προεπισκόπηση είναι κρυμμένη ως προφύλαξη ενάντια σε επιθέσεις με Javascript.''\n\n'''Αν αυτή είναι μια έγκυρη προσπάθεια επεξεργασίας, παρακαλώ προσπαθήστε ξανά. Αν πάλι δε δουλεύει, δοκιμάστε να αποσυνδεθείτε και να συνδεθείτε πάλι.'''",
+       "session_fail_preview_html": "'''Λυπούμαστε! Δεν μπορέσαμε να διεκπεραιώσουμε την επεξεργασία σας λόγω απώλειας των δεδομένων της συνεδρίας.'''\n\n<em>Επειδή το {{SITENAME}} επιτρέπει την εισαγωγή ακατέργαστου HTML, η προεπισκόπηση είναι κρυμμένη ως προφύλαξη ενάντια σε επιθέσεις με Javascript.</em>\n\n<strong>Αν αυτή είναι μια έγκυρη προσπάθεια επεξεργασίας, παρακαλώ προσπαθήστε ξανά..</strong> Αν και πάλι δε λειτουργεί, δοκιμάστε να [[[[Special:UserLogout|αποσυνδεθείτε]] και να συνδεθείτε πάλι και δείτε αν ο φυλλομετρητής σας επιτρέπει cookies απ'αυτόν τον ιστότοπο.",
        "token_suffix_mismatch": "'''Η επεξεργασία σας απορρίφθηκε γιατί το πρόγραμμα-πελάτη σας κατακρεούργησε τους χαρακτήρες στίξης στο κουπόνι επεξεργασίας. Η επεξεργασία απορρίφθηκε για να αποφευχθεί η παραφθορά του κειμένου της σελίδας.\nΑυτό μερικές φορές συμβαίνει όταν χρησιμοποιείται ένας ανώνυμος διακομιστής μεσολάβησης διαθέσιμος μέσω του παγκόσμιου ιστού με σφάλματα.'''",
        "edit_form_incomplete": "'''Ορισμένα τμήματα της φόρμας επεξεργασίας δεν έφθασαν στο διακομιστή. Ελέγξτε ότι οι αλλαγές σας είναι άθικτες και προσπαθήστε ξανά.'''",
        "editing": "Επεξεργασία $1",
        "searchprofile-advanced-tooltip": "Αναζήτηση σε προσαρμοσμένους ονοματοχώρους",
        "search-result-size": "$1 ({{PLURAL:$2|1 λέξη|$2 λέξεις}})",
        "search-result-category-size": "{{PLURAL:$1|1 μέλος|$1 μέλη}} ({{PLURAL:$2|1 υποκατηγορία|$2 υποκατηγορίες}}, {{PLURAL:$3|1 αρχείο|$3 αρχεία}})",
-       "search-redirect": "(ανακατεύθυνση $1)",
+       "search-redirect": "(ανακατεύθυνση από $1)",
        "search-section": "(ενότητα $1)",
        "search-category": "(κατηγορία $1)",
        "search-file-match": "(ταιριάζει με το περιεχόμενο του αρχείου)",
        "userrights-changeable-col": "Ομάδες που μπορείτε να αλλάξετε",
        "userrights-unchangeable-col": "Ομάδες που δεν μπορείτε να αλλάξετε",
        "userrights-conflict": "Σύγκρουση αλλαγών στα δικαιώματα χρήστη! Παρακαλώ επανεξετάστε και επικυρώστε τις αλλαγές σας.",
-       "userrights-removed-self": "Έχετε καταργήσει επιτυχώς τα δικά σας δικαιώματα. Ως εκ τούτου, δεν είστε πλέον σε θέση να έχετε πρόσβαση σε αυτή τη σελίδα.",
+       "userrights-removed-self": "Έχετε καταργήσει τα δικά σας δικαιώματα. Ως εκ τούτου, δεν είστε πλέον σε θέση να έχετε πρόσβαση σε αυτή τη σελίδα.",
        "group": "Ομάδα:",
        "group-user": "Χρήστες",
        "group-autoconfirmed": "Αυτοεπιβεβαιωμένοι χρήστες",
        "right-override-export-depth": "Εξαγωγή σελίδων συμπεριλαμβάνοντας συνδεδεμένες σελίδες έως ένα βάθος 5 επιπέδων",
        "right-sendemail": "Αποστολή ηλεκτρονικού μηνύματος σε άλλους χρήστες",
        "right-passwordreset": "Εμφάνιση email επαναφοράς κωδικού πρόσβασης",
-       "right-managechangetags": "Δημιουργία και διαγραφή [[Special:Tags|ετικετών]] από τη βάση δεδομένων",
+       "right-managechangetags": "Δημιουργία και (απ)ενεργοποίηση [[Special:Tags|ετικετών]]",
        "right-applychangetags": "Εφαρμόστε [[Special:Tags|ετικέτες]] μαζί με τις αλλαγές",
        "right-changetags": "Προσθέστε και αφαιρέστε αυθαίρετες [[Special:Tags|ετικέτες]] σε μεμονωμένες εκδόσεις και καταχωρήσεις καταγραφών",
+       "right-deletechangetags": "Διαγραφή [[Special:Tags|ετικετών]] από τη βάση δεδομένων",
        "grant-group-page-interaction": "Αλληλεπίδραση με σελίδες",
        "grant-group-file-interaction": "Αλληλεπίδραση με πολυμέσα",
        "grant-group-watchlist-interaction": "Αλληλεπίδραση με τη λίστα παρακολούθησής σου",
        "activeusers-intro": "Αυτή είναι μια λίστα από χρήστες που είχαν κάποιου είδους δραστηριότητα {{PLURAL:$1|την τελευταία $1 μέρα|τις τελευταίες $1 μέρες}}.",
        "activeusers-count": "$1 {{PLURAL:$1|ενέργεια|ενέργειες}} {{PLURAL:$3|την τελευταία μέρα|τις τελευταίες $3 μέρες}}",
        "activeusers-from": "Προβολή χρηστών ξεκινώντας από:",
-       "activeusers-hidebots": "Απόκρυψη bots",
-       "activeusers-hidesysops": "Απόκρυψη διαχειριστών",
        "activeusers-noresult": "Δεν βρέθηκε χρήστης.",
        "activeusers-submit": "Προβολή ενεργών χρηστών",
        "listgrouprights": "Δικαιώματα ομάδων χρηστών",
        "htmlform-cloner-create": "Προσθήκη περισσοτέρων",
        "htmlform-cloner-delete": "Αφαίρεση",
        "htmlform-cloner-required": "Απαιτείται τουλάχιστον μία τιμή.",
+       "htmlform-date-placeholder": "ΕΕΕΕ-ΜΜ-ΗΗ",
+       "htmlform-date-invalid": "Η τιμή που καθορίσατε δεν είναι μια αναγνωρισμένη ημερομηνία. Δοκιμάστε να χρησιμοποιήσετε τη μορφή ΕΕΕΕ-MM-ΗΗ.",
        "htmlform-title-badnamespace": "[[:$1]] δεν είναι στο \"{{ns:$2}}\" ονοματοχώρο.",
        "htmlform-title-not-creatable": "\"$1\" - η  σελίδα τίτλου δεν είναι δυνατόν να δημιουργηθεί",
        "htmlform-title-not-exists": "Το $1 δεν υπάρχει.",
        "feedback-close": "Ολοκληρώθηκε",
        "feedback-dialog-title": "Υποβολή παρατηρήσεων",
        "feedback-dialog-intro": "Μπορείτε να χρησιμοποιήσετε την παρακάτω εύκολη φόρμα για να υποβάλετε τις παρατηρήσεις σας. Το σχόλιό σας θα προστεθεί στην σελίδα «$1», μαζί με το όνομα χρήστη σας.",
-       "feedback-error-title": "Σφάλμα",
        "feedback-error1": "Σφάλμα: Μη αναγνωρίσιμο αποτέλεσμα από το API",
        "feedback-error2": "Σφάλμα: Η επεξεργασία απέτυχε",
        "feedback-error3": "Σφάλμα: Καμία απάντηση από το API",
index cbe755d..719f304 100644 (file)
        "category-file-count-limited": "The following {{PLURAL:$1|file is|$1 files are}} in the current category.",
        "listingcontinuesabbrev": "cont.",
        "index-category": "Indexed pages",
-       "noindex-category": "Non-indexed pages",
+       "noindex-category": "Noindexed pages",
        "broken-file-category": "Pages with broken file links",
        "categoryviewer-pagedlinks": "($1) ($2)",
        "category-header-numerals": "$1–$2",
        "botpasswords-label-delete": "Delete",
        "botpasswords-label-resetpassword": "Reset the password",
        "botpasswords-label-grants": "Applicable grants:",
-       "botpasswords-help-grants": "Each grant gives access to listed user rights that a user account already has. See the [[Special:ListGrants|table of grants]] for more information.",
+       "botpasswords-help-grants": "Grants allow access to rights already held by your user account. Enabling a grant here does not provide access to any rights that your user account would not otherwise have. See the [[Special:ListGrants|table of grants]] for more information.",
        "botpasswords-label-grants-column": "Granted",
        "botpasswords-bad-appid": "The bot name \"$1\" is not valid.",
        "botpasswords-insert-failed": "Failed to add bot name \"$1\". Was it already added?",
        "passwordreset-nocaller": "A caller must be provided",
        "passwordreset-nosuchcaller": "Caller does not exist: $1",
        "passwordreset-ignored": "The password reset was not handled. Maybe no provider was configured?",
-       "passwordreset-invalideamil": "Invalid email address",
+       "passwordreset-invalidemail": "Invalid email address",
        "passwordreset-nodata": "Neither a username nor an email address was supplied",
        "changeemail": "Change or remove email address",
        "changeemail-summary": "",
        "searchprofile-advanced-tooltip": "Search in custom namespaces",
        "search-result-size": "$1 ({{PLURAL:$2|1 word|$2 words}})",
        "search-result-category-size": "{{PLURAL:$1|1 member|$1 members}} ({{PLURAL:$2|1 subcategory|$2 subcategories}}, {{PLURAL:$3|1 file|$3 files}})",
-       "search-redirect": "(redirect $1)",
+       "search-redirect": "(redirect from $1)",
        "search-section": "(section $1)",
        "search-category": "(category $1)",
        "search-file-match": "(matches file content)",
        "grant-basic": "Basic rights",
        "grant-viewdeleted": "View deleted files and pages",
        "grant-viewmywatchlist": "View your watchlist",
+       "grant-viewrestrictedlogs": "View restricted log entries",
        "newuserlogpage": "User creation log",
        "newuserlogpagetext": "This is a log of user creations.",
        "rightslog": "User rights log",
        "apisandbox-results-fixtoken-fail": "Failed to fetch \"$1\" token.",
        "apisandbox-alert-page": "Fields on this page are not valid.",
        "apisandbox-alert-field": "The value of this field is not valid.",
+       "apisandbox-continue": "Continue",
+       "apisandbox-continue-clear": "Clear",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} will [https://www.mediawiki.org/wiki/API:Query#Continuing_queries continue] the last request; {{int:apisandbox-continue-clear}} will clear continuation-related parameters.",
+       "apisandbox-param-limit": "Enter <kbd>max</kbd> to use the maximum limit.",
        "booksources": "Book sources",
        "booksources-summary": "",
        "booksources-search-legend": "Search for book sources",
        "booksources-search": "Search",
        "booksources-text": "Below is a list of links to other sites that sell new and used books, and may also have further information about books you are looking for:",
        "booksources-invalid-isbn": "The given ISBN does not appear to be valid; check for errors copying from the original source.",
+       "magiclink-tracking-rfc": "Pages using RFC magic links",
+       "magiclink-tracking-rfc-desc": "This page uses RFC magic links. See [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] on how to migrate.",
+       "magiclink-tracking-pmid": "Pages using PMID magic links",
+       "magiclink-tracking-pmid-desc": "This page uses PMID magic links. See [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] on how to migrate.",
+       "magiclink-tracking-isbn": "Pages using ISBN magic links",
+       "magiclink-tracking-isbn-desc": "This page uses ISBN magic links. See [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] on how to migrate.",
        "rfcurl": "//tools.ietf.org/html/rfc$1",
        "pubmedurl": "//www.ncbi.nlm.nih.gov/pubmed/$1?dopt=Abstract",
        "specialloguserlabel": "Performer:",
        "activeusers-intro": "This is a list of users who had some kind of activity within the last $1 {{PLURAL:$1|day|days}}.",
        "activeusers-count": "$1 {{PLURAL:$1|action|actions}} in the last {{PLURAL:$3|day|$3 days}}",
        "activeusers-from": "Display users starting at:",
-       "activeusers-hidebots": "Hide bots",
-       "activeusers-hidesysops": "Hide administrators",
+       "activeusers-groups": "Display users belonging to groups:",
        "activeusers-noresult": "No users found.",
        "activeusers-submit": "Display active users",
        "listgrouprights": "User group rights",
        "modifiedarticleprotection": "changed protection level for \"[[$1]]\"",
        "unprotectedarticle": "removed protection from \"[[$1]]\"",
        "movedarticleprotection": "moved protection settings from \"[[$2]]\" to \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|Protected}} \"[[$1]]\"",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Changed protection level}} for \"[[$1]]\"",
+       "unprotectedarticle-comment": "{{GENDER:$2|Removed protection}} from \"[[$1]]\"",
        "protect-title": "Change protection level for \"$1\"",
        "protect-title-notallowed": "View protection level of \"$1\"",
        "prot_1movedto2": "[[$1]] moved to [[$2]]",
        "movelogpagetext": "Below is a list of all page moves.",
        "movesubpage": "{{PLURAL:$1|Subpage|Subpages}}",
        "movesubpagetext": "This page has $1 {{PLURAL:$1|subpage|subpages}} shown below.",
+       "movesubpagetalktext": "The corresponding talk page has $1 {{PLURAL:$1|subpage|subpages}} shown below.",
        "movenosubpage": "This page has no subpages.",
        "movereason": "Reason:",
        "move-redirect-text": "",
        "pageinfo-category-pages": "Number of pages",
        "pageinfo-category-subcats": "Number of subcategories",
        "pageinfo-category-files": "Number of files",
+       "pageinfo-user-id": "User ID",
        "markaspatrolleddiff": "Mark as patrolled",
        "markaspatrolledlink": "[$1]",
        "markaspatrolledtext": "Mark this page as patrolled",
        "patrol-log-header": "This is a log of patrolled revisions.",
        "log-show-hide-patrol": "$1 patrol log",
        "log-show-hide-tag": "$1 tag log",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Mark revision $3 of $2 as patrolled?",
        "deletedrevision": "Deleted old revision $1",
        "filedeleteerror-short": "Error deleting file: $1",
        "filedeleteerror-long": "Errors were encountered while deleting the file:\n\n$1",
        "newimages-showbots": "Show uploads by bots",
        "newimages-hidepatrolled": "Hide patrolled uploads",
        "noimages": "Nothing to see.",
+       "gallery-slideshow-toggle": "Toggle thumbnails",
        "ilsubmit": "Search",
        "bydate": "by date",
        "sp-newimages-showfrom": "Show new files starting from $2, $1",
        "tags-deactivate": "deactivate",
        "tags-hitcount": "$1 {{PLURAL:$1|change|changes}}",
        "tags-manage-no-permission": "You do not have permission to manage change tags.",
-       "tags-manage-blocked": "You cannot manage change tags while blocked.",
+       "tags-manage-blocked": "You cannot manage change tags while {{GENDER:$1|you}} are blocked.",
        "tags-create-heading": "Create a new tag",
        "tags-create-explanation": "By default, newly created tags will be made available for use by users and bots.",
        "tags-create-tag-name": "Tag name:",
        "tags-deactivate-not-allowed": "It is not possible to deactivate the tag \"$1\".",
        "tags-deactivate-submit": "Deactivate",
        "tags-apply-no-permission": "You do not have permission to apply change tags along with your changes.",
-       "tags-apply-blocked": "You cannot apply change tags along with your changes while blocked.",
+       "tags-apply-blocked": "You cannot apply change tags along with your changes while {{GENDER:$1|you}} are blocked.",
        "tags-apply-not-allowed-one": "The tag \"$1\" is not allowed to be manually applied.",
        "tags-apply-not-allowed-multi": "The following {{PLURAL:$2|tag is|tags are}} not allowed to be manually applied: $1",
        "tags-update-no-permission": "You do not have permission to add or remove change tags from individual revisions or log entries.",
-       "tags-update-blocked": "You cannot add or remove change tags while blocked.",
+       "tags-update-blocked": "You cannot add or remove change tags while {{GENDER:$1|you}} are blocked.",
        "tags-update-add-not-allowed-one": "The tag \"$1\" is not allowed to be manually added.",
        "tags-update-add-not-allowed-multi": "The following {{PLURAL:$2|tag is|tags are}} not allowed to be manually added: $1",
        "tags-update-remove-not-allowed-one": "The tag \"$1\" is not allowed to be removed.",
        "feedback-external-bug-report-button": "File a technical task",
        "feedback-dialog-title": "Submit feedback",
        "feedback-dialog-intro": "You can use the easy form below to submit your feedback. Your comment will be added to the page \"$1\", along with your username.",
-       "feedback-error-title": "Error",
        "feedback-error1": "Error: Unrecognized result from API",
        "feedback-error2": "Error: Edit failed",
        "feedback-error3": "Error: No response from API",
        "feedback-thanks": "Thanks! Your feedback has been posted to the page \"[$2 $1]\".",
        "feedback-thanks-title": "Thank you!",
        "feedback-useragent": "User agent:",
-       "searchsuggest-search": "Search",
+       "searchsuggest-search": "Search {{SITENAME}}",
        "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.",
        "authmanager-authn-autocreate-failed": "Auto-creation of a local account failed: $1",
        "authmanager-change-not-supported": "The supplied credentials cannot be changed, as nothing would use them.",
        "authmanager-create-disabled": "Account creation is disabled.",
-       "authmanager-create-from-login": "To create your account, please fill in the fields below.",
+       "authmanager-create-from-login": "To create your account, please fill in the fields.",
        "authmanager-create-not-in-progress": "Account creation is not in progress or session data has been lost. Please start again from the beginning.",
        "authmanager-create-no-primary": "The supplied credentials could not be used for account creation.",
        "authmanager-link-no-primary": "The supplied credentials could not be used for account linking.",
        "usercssispublic": "Please note: CSS subpages should not contain confidential data as they are viewable by other users.",
        "restrictionsfield-badip": "Invalid IP address or range: $1",
        "restrictionsfield-label": "Allowed IP ranges:",
-       "restrictionsfield-help": "One IP address or CIDR range per line. To enable everything, use<br><code>0.0.0.0/0</code><br><code>::/0</code>"
+       "restrictionsfield-help": "One IP address or CIDR range per line. To enable everything, use<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Error: $1",
+       "edit-error-long": "Errors:\n\n$1"
 }
index a155ea3..31f0641 100644 (file)
@@ -48,7 +48,8 @@
                        "Zciric",
                        "Psychoslave",
                        "Orikrin1998",
-                       "Gamliel Fishkin"
+                       "Gamliel Fishkin",
+                       "Kastanoto"
                ]
        },
        "tog-underline": "Substrekado de ligiloj:",
        "talk": "Diskuto",
        "views": "Vidoj",
        "toolbox": "Iloj",
+       "tool-link-userrights": "Ŝanĝi grupojn de ĉi tiu {{GENDER:$1|uzanto}}",
+       "tool-link-emailuser": "Sendi retpoŝton al ĉi tiu {{GENDER:$1|uzanto}}",
        "userpage": "Vidi uzantopaĝon",
        "projectpage": "Rigardi projektopaĝon",
        "imagepage": "Vidi dosieropaĝon",
        "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 per <strong>$1</strong> estas <strong>$2</strong>. <em>Bonvolu noti ĝin por estonta konsultado.",
+       "botpasswords-newpassword": "La nova pasvorto por ensaluti per <strong>$1</strong> estas <strong>$2</strong>. <em>Bonvolu noti ĝin por estonta konsultado.</em> <br> (Por malnovaj robotoj, kiuj postulas, ke la ensaluta nomo estu sama kiel la eventuala uzantonomo, vi povas uzi <strong>$3</strong> kiel uzantonomon kaj <strong>$4</strong> kiel pasvorton.)",
        "botpasswords-no-provider": "Robotopasvortensalutoprovizilo (''BotPasswordsSessionProvider'') maldisponeblas.",
        "botpasswords-restriction-failed": "Limigoj pri robota pasvorto malebligas tiun ensalutadon.",
        "botpasswords-invalid-name": "La difinita uzantnomo malenhavas la robotopasvortan disigilon (\"$1\").",
        "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 asociita kun tiu uzantnomo, tiam ni sendos retpoŝtan mesaĝon pri reagordado de la pasvorto.",
-       "passwordreset-emailsent-capture2": "La {{PLURAL:$1|retpoŝto|retpoŝtojn}} de pasvorta reensignado estis sendita. La {{PLURAL:$1|salutnomo kaj pasvorto|listo de salutnomoj kaj pasvortoj}} estas vidigita sube.",
-       "passwordreset-emailerror-capture2": "Retpoŝtado al la {{GENDER:$2|uzanto}} malsukcesis: $1 La {{PLURAL:$3|uzantnomo kaj pasvorto|listo de uzantnomoj kaj pasvortoj}} estas vidigita malsupre.",
+       "passwordreset-emailsent-capture2": "La {{PLURAL:$1|retpoŝto|retpoŝtoj}} por pasvorta restarigo estis {{PLURAL:$1|sendita|senditaj}}. La {{PLURAL:$1|salutnomo kaj pasvorto|listo de salutnomoj kaj pasvortoj}} estas montrita ĉi tie.",
+       "passwordreset-emailerror-capture2": "Retpoŝtado al la {{GENDER:$2|uzanto}} malsukcesis: $1 La {{PLURAL:$3|uzantonomo kaj pasvorto|listo de uzantonomoj kaj pasvortoj}} estas montrita ĉi tie.",
        "passwordreset-nocaller": "Vokanto devas esti provizita",
        "passwordreset-nosuchcaller": "Vokanto ne ekzistas: $1",
        "passwordreset-ignored": "La pasvorta reensignado ne estis pritraktita. Eble neniu provizanto estis formita?",
-       "passwordreset-invalideamil": "Nevalida retpoŝta adreso",
+       "passwordreset-invalidemail": "Nevalida retpoŝta adreso",
        "passwordreset-nodata": "Nek salutnomo nek retpoŝta adreso estis provizita",
        "changeemail": "Ŝanĝi aŭ forigi retpoŝtadreson",
        "changeemail-header": "Plenigu ĉi tiun formularon por ŝanĝi vian retpoŝtadreson. Se vi volas forigi la difinon de retpoŝtadreso por via uzantokonto, lasu la kampon por la nova retpoŝtadreso malplena ĉe la transigo.",
        "invalid-content-data": "Enhavo estas malvalida",
        "content-not-allowed-here": "Enhavo de $1 ne estas permesita en paĝo [[$2]]",
        "editwarning-warning": "Forlaso de ĉi tiu paĝo kaŭzos al vi perdi iun ajn ŝanĝojn kiujn vi faris.\nSe vi estas ensalutinta, vi povas malŝalti ĉi tiun averton en la sekcio \"{{int:prefs-editing}}\" de viaj preferoj.",
+       "editpage-invalidcontentmodel-title": "Enhava modelo ne subtenata",
+       "editpage-invalidcontentmodel-text": "La enhava modelo \"$1\" ne estas subtenata.",
        "editpage-notsupportedcontentformat-title": "Nesubtenata enhavoformo",
        "editpage-notsupportedcontentformat-text": "La enhava aranĝo $1 ne estas subtenata de la enhava modelo $2.",
        "content-model-wikitext": "vikiteksto",
        "titlematches": "Trovitaj laŭ titolo",
        "textmatches": "Trovitaj laŭ enhavo",
        "notextmatches": "Neniu trovita laŭ enhavo",
-       "prevn": "{{PLURAL:$1|$1 antaŭa|$1 antaŭaj}}",
-       "nextn": "{{PLURAL:$1|$1 sekva|$1 sekvaj}}",
+       "prevn": "{{PLURAL:$1|$1 antaŭa|$1 antaŭaj}}n",
+       "nextn": "{{PLURAL:$1|$1 sekva|$1 sekvaj}}n",
        "prev-page": "antaŭa paĝo",
        "next-page": "sekva paĝo",
        "prevn-title": "{{PLURAL:$1|Antaŭa $1 rezulto|Antaŭaj $1 rezultoj}}",
        "searchprofile-advanced-tooltip": "Serĉi en specialaj nomspacoj",
        "search-result-size": "$1 ({{PLURAL:$2|1 vorto|$2 vortoj}})",
        "search-result-category-size": "{{PLURAL:$1|1 membro|$1 membroj}} ({{PLURAL:$2|1 subkategorio|$2 subkategorioj}}, {{PLURAL:$3|1 dosiero|$3 dosieroj}})",
-       "search-redirect": "(alidirektilo $1)",
+       "search-redirect": "(aldirekto el $1)",
        "search-section": "(sekcio $1)",
        "search-category": "(kategorio $1)",
        "search-file-match": "(kongruas kun dosiera enhavo)",
        "grant-basic": "Bazaj rajtoj",
        "grant-viewdeleted": "Vidi forigitajn dosierojn kaj paĝojn",
        "grant-viewmywatchlist": "Rigardi vian atentaron",
+       "grant-viewrestrictedlogs": "Rigardi protokolerojn kun limigita aliro",
        "newuserlogpage": "Protokolo de uzanto-kreado",
        "newuserlogpagetext": "Jen protokolo de lastaj kreadoj de uzantoj.",
        "rightslog": "Protokolo de uzanto-rajtoj",
        "upload-dialog-disabled": "Alŝutoj de dosiero per ĉi tiun dialogon estas malfunkciigita sur ĉi tiu vikio.",
        "upload-dialog-title": "Alŝuti dosieron",
        "upload-dialog-button-cancel": "Nuligi",
+       "upload-dialog-button-back": "Reen",
        "upload-dialog-button-done": "Farite",
        "upload-dialog-button-save": "Konservi",
        "upload-dialog-button-upload": "Alŝuti",
        "zip-wrong-format": "La specifigita dosiero ne estis ZIP-dosiero",
        "zip-bad": "La dosiero estas fuŝa aŭ alimaniere estas nelegebla ZIP-dosiero.\nĜi ne povas esti ĝuste kontrolita por sekureco.",
        "zip-unsupported": "Ĉi tiu dosiero estas ZIP-dosiero kiu uzas ZIP-funkciojn malsubtenita de MediaWiki.\nĜi ne povas esti ĝuste kontrolita por sekureco.",
-       "uploadstash": "Konservejo de alŝutoj",
+       "uploadstash": "Kaŝkonservejo de alŝutoj",
        "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-errclear": "Malsukcesis la forigo de la dosieroj.",
        "uploadstash-refresh": "Aktualigi la dosierliston.",
        "uploadstash-thumbnail": "Vidi bildeton",
+       "uploadstash-exception": "Ne eblas alŝuti en kaŝkonservejon ($1): \"$2\".",
        "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).",
        "filerevert-submit": "Restarigi",
        "filerevert-success": "'''[[Media:$1|$1]]''' estis restarigita al [$4 versio ekde $3, $2].",
        "filerevert-badversion": "Ne estas antaŭa loka versio de ĉi tiu dosiero ĉe tiu tempo.",
+       "filerevert-identical": "La nuntempa versio de la dosiero jam samas al la elektita.",
        "filedelete": "Forigi $1",
        "filedelete-legend": "Forigi dosieron.",
        "filedelete-intro": "Vi preskaŭ forigos dosieron '''[[Media:$1|$1]]''' kune kun ĉiom da ĝia historio.",
        "apisandbox-results-fixtoken-fail": "Malsukcese venigis ĵetonon je \"$1\".",
        "apisandbox-alert-page": "Kampoj de ĉi tiu paĝo ne estas validaj.",
        "apisandbox-alert-field": "La valoro de ĉi tiu kampo ne estas valida.",
+       "apisandbox-continue": "Daŭrigi",
+       "apisandbox-continue-clear": "Vakigi",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries daŭrigos] la lastan peton; {{int:apisandbox-continue-clear}} forviŝos parametrojn rilatajn al daŭrigo.",
        "booksources": "Librofontoj",
        "booksources-search-legend": "Serĉi librofontojn",
        "booksources-search": "Serĉi",
        "activeusers-intro": "Jen listo de uzantoj kiu faris iom da agoj dum la lastaj $1 {{PLURAL:$1|tago|tagoj}}.",
        "activeusers-count": "$1 {{PLURAL:$1|ago|agoj}} dum la {{PLURAL:$3|lasta tago|lastaj $3 tagoj}}",
        "activeusers-from": "Montri uzantojn ekde:",
-       "activeusers-hidebots": "kaŝi robotojn",
-       "activeusers-hidesysops": "Kaŝi administrantojn",
+       "activeusers-groups": "Montri uzantojn apartenantajn al grupoj:",
        "activeusers-noresult": "Neniuj uzantoj trovitaj.",
        "activeusers-submit": "Montri la agemajn uzantojn",
        "listgrouprights": "Gruprajtoj de uzantoj",
        "emailccsubject": "Kopio de via mesaĝo al $1: $2",
        "emailsent": "Retmesaĝo sendita",
        "emailsenttext": "Via retmesaĝo estas sendita.",
-       "emailuserfooter": "Ĉi tiun retpoŝton estis sendita far $1 al $2 per la funkcio \"{{int:emailuser}}\" el {{SITENAME}}.",
+       "emailuserfooter": "Ĉi tiu retpoŝtmesaĝo estis {{GENDER:$1|sendita}} de $1 al {{GENDER:$2|$2}} per la funkcio \"{{int:emailuser}}\" ĉe {{SITENAME}}.",
        "usermessage-summary": "Lasanta sisteman mesaĝon.",
        "usermessage-editor": "Mesaĝanto de sistemo",
        "watchlist": "Mia atentaro",
        "watchlist-hide": "Kaŝi",
        "watchlist-submit": "Montri",
        "wlshowtime": "Vidigenda tempodaŭro:",
-       "wlshowhideminor": "Etaj redaktoj",
-       "wlshowhidebots": "robotoj",
-       "wlshowhideliu": "registritaj uzantoj",
-       "wlshowhideanons": "anonimaj uzantoj",
+       "wlshowhideminor": "etajn redaktojn",
+       "wlshowhidebots": "robotojn",
+       "wlshowhideliu": "registritajn uzantojn",
+       "wlshowhideanons": "anonimajn uzantojn",
        "wlshowhidepatr": "patrolitaj redaktoj",
-       "wlshowhidemine": "miaj redaktoj",
-       "wlshowhidecategorization": "paĝa enkategoriigo.",
+       "wlshowhidemine": "miajn redaktojn",
+       "wlshowhidecategorization": "kategoriigon de paĝoj",
        "watchlist-options": "Opcioj por atentaro",
        "watching": "Aldonata al la atentaro...",
        "unwatching": "Malatentante...",
        "movelogpagetext": "Jen listo de movitaj paĝoj",
        "movesubpage": "{{PLURAL:$1|Subpaĝo|Subpaĝoj}}",
        "movesubpagetext": "Ĉi tiu paĝo havas $1 {{PLURAL:$1|subpaĝon montritan|subpaĝojn montritajn}} sube.",
+       "movesubpagetalktext": "La koncerna diskutpaĝo havas $1 {{PLURAL:$1|subpaĝon montritan|subpaĝojn montritajn}} sube.",
        "movenosubpage": "Ĉi tiu paĝo havas neniujn subpaĝojn.",
        "movereason": "Kialo:",
        "revertmove": "restarigi",
        "pageinfo-category-pages": "Nombro de paĝoj",
        "pageinfo-category-subcats": "Nombro de subkategorioj",
        "pageinfo-category-files": "Nombro de dosieroj",
+       "pageinfo-user-id": "Identigilo de uzanto",
        "markaspatrolleddiff": "Marki kiel patrolitan",
        "markaspatrolledtext": "Marki ĉi tiun paĝon patrolita",
        "markaspatrolledtext-file": "Marki ĉi tiu versio de dosiero kiel patrolita",
        "newimages-showbots": "Montri alŝutojn per robotoj",
        "newimages-hidepatrolled": "Malvidigi la patrolitajn alŝutitojn",
        "noimages": "Nenio videbla.",
+       "gallery-slideshow-toggle": "Baskuligi miniaturojn",
        "ilsubmit": "Serĉi",
        "bydate": "laŭ dato",
        "sp-newimages-showfrom": "Montru novajn dosierojn komencante de $2, $1",
        "tag-filter": "[[Special:Tags|Etikeda]] filtrilo:",
        "tag-filter-submit": "Filtrilo",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Etikedo|Etikedoj}}]]: $2)",
+       "tag-mw-contentmodelchange": "ŝanĝo de enhavomodelo",
+       "tag-mw-contentmodelchange-description": "Redaktoj kiuj [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel ŝanĝas la enhavmodelon] de paĝo",
        "tags-title": "Etikedoj",
        "tags-intro": "Ĉi tiu paĝo montras la etikedojn kun kiuj la programaro markus redakton, kaj iliaj signifoj.",
        "tags-tag": "Etikeda nomo",
        "htmlform-cloner-create": "Aldoni plian",
        "htmlform-cloner-delete": "Forigi",
        "htmlform-cloner-required": "Almenaŭ unu valoro estas nepra.",
+       "htmlform-date-placeholder": "JJJJ-MM-TT",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "JJJJ-MM-TT HH:MM:SS",
+       "htmlform-date-invalid": "La valoro, kiun vi indikis, ne estas rekonita kiel dato. Provu uzi la formon JJJJ-MM-TT.",
+       "htmlform-time-invalid": "La valoro, kiun vi indikis, ne estas rekonita kiel tempo. Provu uzi la formon HH:MM:SS.",
+       "htmlform-datetime-invalid": "La valoro, kiun vi indikis, ne estas rekonita kiel dato kaj tempo. Provu uzi la formon JJJJ-MM-TT HH:MM:SS.",
+       "htmlform-date-toolow": "La valoro, kiun vi indikis estas antaŭ la plej frua permesita dato $1.",
+       "htmlform-date-toohigh": "La valoro, kiun vi indikis estas post la plej malfrua permesita dato $1.",
+       "htmlform-time-toolow": "La valoro, kiun vi indikis estas antaŭ la plej frua permesita tempo $1.",
+       "htmlform-time-toohigh": "La valoro, kiun vi indikis estas post la plej malfrua permesita tempo $1.",
+       "htmlform-datetime-toolow": "La valoro, kiun vi indikis estas antaŭ la plej frua permesita dato kaj tempo $1.",
+       "htmlform-datetime-toohigh": "La valoro, kiun vi indikis estas post la plej malfrua permesita dato kaj tempo $1.",
        "htmlform-title-badnamespace": "[[:$1]] ne  estas en \"{{ns:$2}}\" nomspaco.",
        "htmlform-title-not-creatable": "\"$1\" estas nekreebla titolo por paĝo",
        "htmlform-title-not-exists": "$1 ne ekzistas.",
        "logentry-newusers-autocreate": "Uzantokonto $1 estis {{GENDER:$2|kreita}} aŭtomate",
        "logentry-protect-move_prot": "$1 {{GENDER:$2|movis}} protektajn agordojn el $4 al $3",
        "logentry-protect-unprotect": "$1 {{GENDER:$2|forigis}} protekton el $3",
-       "logentry-protect-protect": "$1 {{GENDER:$2|protektis}} $3 $4",
+       "logentry-protect-protect": "$1 {{GENDER:$2|protektis}} la paĝon $3 $4",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protektis}} $3 $4 [rikure]",
        "logentry-protect-modify": "$1 {{GENDER:$2|ŝanĝis}} la nivelon de protekto de $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|ŝanĝis}} la nivelon de protekto de $3 $4 [rikure]",
        "feedback-external-bug-report-button": "Krei teĥnikan taskon",
        "feedback-dialog-title": "Sendi prijuĝajn rimarkojn",
        "feedback-dialog-intro": "Vi povas uzi suban simplan formularon por sendi viajn prijuĝajn rimarkojn. Via komento estos aldonita al la paĝo \"$1\" kun via uzanto-nomo.",
-       "feedback-error-title": "Eraro",
        "feedback-error1": "Eraro: Nerekonita rezulto de API",
        "feedback-error2": "Eraro: La redakto malsukcesis",
        "feedback-error3": "Eraro: Neniu respondo de API",
        "feedback-thanks": "Dankon! Via opinio-esprimo estis afiŝita al la paĝo \"[$2 $1]\".",
        "feedback-thanks-title": "Dankon!",
        "feedback-useragent": "Klienta aplikaĵo:",
-       "searchsuggest-search": "Serĉi",
+       "searchsuggest-search": "Serĉi tra {{SITENAME}}",
        "searchsuggest-containing": "enhavas...",
        "api-error-autoblocked": "Via IPa adreso estis blokita aŭtomate, ĉar ĝi estis uzita far forbara uzanto.",
        "api-error-badaccess-groups": "Vi ne havas permeson alŝuti dosierojn al tiu ĉi vikio.",
        "unlinkaccounts-success": "La konto estis malligita.",
        "authenticationdatachange-ignored": "La ŝanĝo de dateno pri aŭtentikigado ne estis traktita. Eble neniu provizanto estis agorda?",
        "userjsispublic": "Bonvolu noti: subpaĝoj en JavaScript ne enhavu konfidenciajn datumojn ĉar ili estas videblaj por aliaj uzantoj.",
-       "usercssispublic": "Bonvolu noti: subpaĝoj en CSS ne enhavu konfidenciajn datumojn ĉar ili estas videblaj por aliaj uzantoj."
+       "usercssispublic": "Bonvolu noti: subpaĝoj en CSS ne enhavu konfidenciajn datumojn ĉar ili estas videblaj por aliaj uzantoj.",
+       "restrictionsfield-badip": "Malvalida IP-adreso de la intervalo: $1",
+       "restrictionsfield-label": "Permesita IP-intervalo:",
+       "restrictionsfield-help": "Unu IP-adreso aŭ CIDR-intervalo per linio. Por permesigi ĉion, uzu<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Eraro: $1",
+       "edit-error-long": "Eraroj\n\n$1"
 }
index 922729f..7aa39da 100644 (file)
                        "Copper12",
                        "Ivanhercaz",
                        "AlvaroMolina",
-                       "Tokvo"
+                       "Tokvo",
+                       "Irus",
+                       "Sophivorus",
+                       "Pompilos",
+                       "Igv"
                ]
        },
        "tog-underline": "Subrayar los enlaces:",
        "userlogin-remembermypassword": "Mantener mi sesión iniciada",
        "userlogin-signwithsecure": "Usar conexión segura",
        "cannotlogin-title": "No se puede iniciar sesión",
+       "cannotlogin-text": "No ha sido posible iniciar sesión.",
        "cannotloginnow-title": "No se puede iniciar sesión ahora",
        "cannotloginnow-text": "No se puede iniciar sesión cuando se usa $1.",
        "cannotcreateaccount-title": "No se pueden crear cuentas",
        "eauthentsent": "Se ha enviado un correo electrónico de confirmación a la dirección especificada.\nAntes de que se envíe cualquier otro correo a la cuenta tienes que seguir las instrucciones enviadas en el mensaje para así confirmar que la dirección te pertenece.",
        "throttled-mailpassword": "Ya se ha enviado un recordatorio de contraseña en {{PLURAL:$1|la última hora|las últimas $1 horas}}.\nPara evitar los abusos, solo se enviará un recordatorio de contraseña cada {{PLURAL:$1|hora|$1 horas}}.",
        "mailerror": "Error al enviar el mensaje: $1",
-       "acct_creation_throttle_hit": "Los visitantes a este wiki usando tu dirección IP han creado {{PLURAL:$1|una cuenta|$1 cuentas}} en el último día, lo cual es lo máximo permitido en este periodo de tiempo.\nComo resultado, los visitantes usando esta dirección IP no pueden crear más cuentas en este momento.",
+       "acct_creation_throttle_hit": "Por medio de tu dirección IP ya {{PLURAL:$1|se ha creado una cuenta|se han creado $1 cuentas}} durante $2, lo cual es lo máximo permitido por este período de tiempo.\nPor este motivo, desde esta dirección IP no se pueden crear más cuentas por el momento.",
        "emailauthenticated": "Tu dirección de correo electrónico fue confirmada el $2 a las $3.",
        "emailnotauthenticated": "Aún no has confirmado tu dirección de correo electrónico.\nHasta que lo hagas, las siguientes funciones no estarán disponibles.",
        "noemailprefs": "Especifica una dirección electrónica para habilitar estas características.",
        "botpasswords-updated-body": "Se actualizó la contraseña del bot llamado \"$1\" del usuario \"$2\".",
        "botpasswords-deleted-title": "Se eliminó la contraseña de bot",
        "botpasswords-deleted-body": "Se eliminó la contraseña del bot llamado \"$1\" del usuario \"$2\".",
-       "botpasswords-newpassword": "La nueva contraseña para iniciar sesión con <strong>$1</strong> es <strong>$2</strong>. <em>Conserva estos datos para usos futuros.</em>",
+       "botpasswords-newpassword": "La contraseña nueva para acceder con <strong>$1</strong> es <strong>$2</strong>. <em>Guarda esta información para su consulta futura.</em> <br> (En caso de robots antiguos que requieren que el nombre de acceso coincida con el de usuario, también puedes utilizar <strong>$3</strong> como nombre de usuario y <strong>$4</strong> como contraseña.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider no está disponible.",
        "botpasswords-restriction-failed": "Las restricciones de la contraseña de bot impiden este inicio de sesión.",
        "botpasswords-invalid-name": "El nombre de usuario especificado no contiene el separador de contraseña de bot (\"$1\").",
        "passwordreset-emailelement": "Nombre de {{GENDER:$1|usuario|usuaria}}: \n$1\n\nContraseña temporal: \n$2",
        "passwordreset-emailsentemail": "Si esta dirección de correo electrónico está asociada a tu cuenta, entonces se enviará un correo electrónico para restablecer la contraseña.",
        "passwordreset-emailsentusername": "Si existe una dirección de correo electrónico asociada a este nombre de usuario, entonces se enviará un correo para restablecer la contraseña.",
-       "passwordreset-emailsent-capture2": "{{PLURAL:$1|El e-mail de restablecimiento de contraseña ha sido enviado|Los e-mails de restablecimiento de contraseña han sido enviados}}. {{PLURAL:$1|El nombre de usuario y la contraseña se muestra|La lista de nombres de usuarios y contraseñas se muestra}} aquí.",
+       "passwordreset-emailsent-capture2": "{{PLURAL:$1|Se ha enviado el mensaje de restablecimiento de contraseña|Se han enviado los mensajes de restablecimiento de contraseña}}. {{PLURAL:$1|El nombre de usuario y la contraseña|La lista de nombres de usuarios y contraseñas}} se muestra aquí.",
        "passwordreset-emailerror-capture2": "No fue posible mandar un correo electrónico {{GENDER:$2|al usuario|a la usuaria}}: $1 {{PLURAL:$3|El nombre de usuario y la contraseña|La lista de nombres de usuarios y contraseñas}} se muestra aquí.",
        "passwordreset-nocaller": "Debe de proporcionarse un interlocutor",
        "passwordreset-nosuchcaller": "La persona que llama no existe: $1",
        "passwordreset-ignored": "No se logró el reestablecimiento de la contraseña. ¿Tal vez no se configuró un proveedor?",
-       "passwordreset-invalideamil": "Dirección de correo electrónico no válida.",
+       "passwordreset-invalidemail": "Dirección de correo electrónico no válida.",
        "passwordreset-nodata": "No se ha proporcionado ni un nombre de usuario ni una dirección de correo electrónico",
        "changeemail": "Cambiar o eliminar la dirección de correo electrónico",
        "changeemail-header": "Completa este formulario para cambiar tu dirección de correo electrónico. Si quieres eliminar la asociación de cualquier dirección de correo electrónico con tu cuenta, deja en blanco la nueva dirección de correo electrónico cuando envíes el formulario.",
        "invalid-content-data": "Datos de contenido incorrectos",
        "content-not-allowed-here": "El contenido «$1» no está permitido en la página [[$2]]",
        "editwarning-warning": "Se perderán los cambios si se cierra esta página.\nSi has iniciado sesión, puedes desactivar este aviso en la sección «{{int:prefs-editing}}» de las preferencias.",
+       "editpage-invalidcontentmodel-title": "Modelo de contenido no admitido",
+       "editpage-invalidcontentmodel-text": "El modelo de contenido «$1» no se admite.",
        "editpage-notsupportedcontentformat-title": "Formato de contenido no compatible",
        "editpage-notsupportedcontentformat-text": "El formato de contenido $1 no es compatible con el modelo de contenido $2.",
        "content-model-wikitext": "texto wiki",
        "searchprofile-advanced-tooltip": "Buscar en espacios de nombres personalizados",
        "search-result-size": "$1 ({{PLURAL:$2|1 palabra|$2 palabras}})",
        "search-result-category-size": "{{PLURAL:$1|1 miembro|$1 miembros}} ({{PLURAL:$2|1 subcategoría|$2 subcategorías}}, {{PLURAL:$3|1 archivo|$3 archivos}})",
-       "search-redirect": "(redirige desde $1)",
+       "search-redirect": "(redirección desde $1)",
        "search-section": "(sección $1)",
        "search-category": "(categoría $1)",
        "search-file-match": "(coincide con el contenido del archivo)",
        "right-block": "Bloquear a otros usuarios para que no editen",
        "right-blockemail": "Bloquear a un usuario para que no pueda mandar correos electrónicos",
        "right-hideuser": "Bloquear un nombre de usuario, haciéndolo invisible",
-       "right-ipblock-exempt": "Quedar exento de bloqueos a IPs, autobloqueos y bloqueos de rango.",
+       "right-ipblock-exempt": "Evitar bloqueos a IP, automáticos y por intervalos",
        "right-unblockself": "Desbloquearse a sí mismo",
        "right-protect": "Cambiar niveles de protección y editar páginas protegidas en cascada",
        "right-editprotected": "Editar páginas protegidas como «{{int:protect-level-sysop}}»",
        "grant-basic": "Permisos básicos",
        "grant-viewdeleted": "Ver archivos y páginas eliminados",
        "grant-viewmywatchlist": "Ver tu lista de seguimiento",
+       "grant-viewrestrictedlogs": "Ver entradas restringidas del registro",
        "newuserlogpage": "Registro de creación de usuarios",
        "newuserlogpagetext": "Este es un registro de creación de usuarios.",
        "rightslog": "Registro de permisos de usuario",
        "enhancedrc-history": "historial",
        "recentchanges": "Cambios recientes",
        "recentchanges-legend": "Opciones sobre cambios recientes",
-       "recentchanges-summary": "Sigue los cambios más recientes de la wiki en esta página.",
+       "recentchanges-summary": "Sigue los cambios más recientes del wiki en esta página.",
        "recentchanges-noresult": "No hubo cambios que respondan a esos criterios durante el período seleccionado.",
        "recentchanges-feed-description": "Realiza un seguimiento de los cambios más recientes en el wiki con este canal.",
        "recentchanges-label-newpage": "Esta edición creó una página",
        "file-thumbnail-no": "El nombre del archivo comienza con <strong>$1</strong>.\nParece ser una imagen de tamaño reducido ''(thumbnail)''.\nSi tiene esta imagen a toda resolución súbala, si no, por favor cambie el nombre del archivo.",
        "fileexists-forbidden": "Ya existe un archivo con este nombre, y no puede ser grabado encima de otro. Si quiere subir su archivo de todos modos, por favor vuelva atrás y utilice otro nombre. [[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Ya existe un archivo con este nombre en el repositorio compartido.\nSi todavía quiere subir su archivo, por favor, regrese a la página anterior y use otro nombre. [[File:$1|thumb|center|$1]]",
+       "fileexists-no-change": "Este es un duplicado exacto de la versión actual de <strong>[[:$1]]</strong>.",
+       "fileexists-duplicate-version": "Este es un duplicado exacto de {{PLURAL:$2|una versión anterior|versiones anteriores}} de <strong>[[:$1]]</strong>.",
        "file-exists-duplicate": "Este archivo es un duplicado {{PLURAL:$1|del siguiente|de los siguientes}}:",
        "file-deleted-duplicate": "Un archivo idéntico a este ([[:$1]]) ha sido borrado con anterioridad. Debes comprobar el historial de borrado del archivo ante de volver a subirlo.",
        "file-deleted-duplicate-notitle": "Un archivo idéntico a este ha sido borrado con anterioridad, y el título ha sido suprimido. Deberías contactar con alguien capaz de ver los datos de archivos borrados para que revise esta situación antes de proceder a subir de nuevo este archivo.",
        "upload-dialog-disabled": "En este wiki están desactivadas las subidas de archivos mediante este cuadro de diálogo.",
        "upload-dialog-title": "Subir archivo",
        "upload-dialog-button-cancel": "Cancelar",
+       "upload-dialog-button-back": "Volver",
        "upload-dialog-button-done": "Hecho",
        "upload-dialog-button-save": "Guardar",
        "upload-dialog-button-upload": "Subir",
        "apisandbox-results-fixtoken-fail": "No fue posible recuperar el token \"$1\".",
        "apisandbox-alert-page": "Los campos de esta página no son válidos.",
        "apisandbox-alert-field": "El valor de este campo no es válido.",
+       "apisandbox-continue": "Continuar",
+       "apisandbox-continue-clear": "Vaciar",
+       "apisandbox-param-limit": "Escribe <kbd>max</kbd> para usar el límite máximo.",
        "booksources": "Fuentes de libros",
        "booksources-search-legend": "Buscar fuentes de libros",
        "booksources-search": "Buscar",
        "booksources-text": "Abajo hay una lista de enlaces a otros sitios que venden libros nuevos y usados, puede que contengan más información sobre los libros que estás buscando.",
        "booksources-invalid-isbn": "El número de ISBN no parece ser válido; comprueba los errores copiándolo de la fuente original.",
+       "magiclink-tracking-rfc": "Páginas que usan enlaces mágicos de RFC",
+       "magiclink-tracking-rfc-desc": "Esta página usa enlaces mágicos de RFC. Véase [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] sobre cómo migrar.",
+       "magiclink-tracking-pmid": "Páginas que usan enlaces mágicos de PMID",
+       "magiclink-tracking-pmid-desc": "Esta página usa enlaces mágicos de PMID. Véase [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] sobre cómo migrar.",
+       "magiclink-tracking-isbn": "Páginas que usan enlaces mágicos de ISBN",
+       "magiclink-tracking-isbn-desc": "Esta página usa enlaces mágicos de ISBN. Véase [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] sobre cómo migrar.",
        "specialloguserlabel": "Usuario:",
        "speciallogtitlelabel": "Objetivo (título o {{ns:user}}:nombre de usuario):",
        "log": "Registros",
        "activeusers": "Lista de usuarios activos",
        "activeusers-intro": "Esta es una lista de usuarios que han tenido alguna actividad en los últimos $1 {{PLURAL:$1|día|días}}.",
        "activeusers-count": "$1 {{PLURAL:$1|acción|acciones}} en {{PLURAL:$3|el último día|los últimos $3 días}}",
-       "activeusers-from": "Mostrando a los usuarios empezando por:",
-       "activeusers-hidebots": "Ocultar robots",
-       "activeusers-hidesysops": "Ocultar administradores",
+       "activeusers-from": "Mostrar los usuarios que empiezan por:",
+       "activeusers-groups": "Mostrar los usuarios que pertenecen a los grupos:",
        "activeusers-noresult": "No se encontraron usuarios.",
        "activeusers-submit": "Mostrar usuarios activos",
        "listgrouprights": "Permisos de los grupos de usuarios",
        "modifiedarticleprotection": "cambió el nivel de protección de «[[$1]]»",
        "unprotectedarticle": "desprotegió «[[$1]]»",
        "movedarticleprotection": "cambiadas protecciones de «[[$2]]» a «[[$1]]»",
+       "protectedarticle-comment": "{{GENDER:$2|Protegió}} «[[$1]]»",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Cambió el nivel de protección}} de «[[$1]]»",
+       "unprotectedarticle-comment": "{{GENDER:$2|Eliminó la protección}} de «[[$1]]»",
        "protect-title": "Cambiando el nivel de protección de «$1»",
        "protect-title-notallowed": "Ver el nivel de protección de «$1»",
        "prot_1movedto2": "[[$1]] se trasladó a [[$2]]",
        "undeletehistorynoadmin": "El artículo ha sido borrado. La razón de su eliminación se indica abajo en el resumen, así como los detalles de las ediciones realizadas antes del borrado. El texto completo del artículo está disponible sólo para usuarios con permisos de administrador.",
        "undelete-revision": "Edición borrada de $1 (fechada el $4, a las $5) por $3:",
        "undeleterevision-missing": "Revisión no válida o perdida. Puede deberse a un enlace incorrecto,\no a que la revisión haya sido restaurada o eliminada del archivo.",
+       "undeleterevision-duplicate-revid": "No se {{PLURAL:$1|pudo restaurar una modificación|pudieron restaurar $1 modificaciones}} porque {{PLURAL:$1|su <code>rev_id</code> ya se estaba|sus <code>rev_id</code> ya se estaban}} utilizando.",
        "undelete-nodiff": "No existe una revisión previa.",
        "undeletebtn": "Restaurar",
        "undeletelink": "ver/restaurar",
        "undeletedrevisions": "{{PLURAL:$1|Una revisión restaurada|$1 revisiones restauradas}}",
        "undeletedrevisions-files": "{{PLURAL:$1|1 revisión|$1 revisiones}} y {{PLURAL:$2|1 archivo|$2 archivos}} restaurados",
        "undeletedfiles": "$1 {{PLURAL:$1|archivo restaurado|archivos restaurados}}",
-       "cannotundelete": "Hubo un error durante la restauración:\n$1",
+       "cannotundelete": "Hubo un error en la totalidad o en parte del proceso de la restauración:\n$1",
        "undeletedpage": "<strong>Se ha restaurado $1</strong>\n\nConsulta el [[Special:Log/delete|registro de borrados]] para ver una lista de los últimos borrados y restauraciones.",
        "undelete-header": "En el [[Special:Log/delete|registro de borrados]] se listan las páginas eliminadas.",
        "undelete-search-title": "Buscar páginas borradas",
        "movelogpagetext": "Abajo se encuentra una lista de páginas trasladadas.",
        "movesubpage": "{{PLURAL:$1|Subpágina|Subpáginas}}",
        "movesubpagetext": "Esta página tiene {{PLURAL:$1|la siguiente subpágina|las siguientes $1 subpáginas}}:",
+       "movesubpagetalktext": "La página de discusión tiene $1 {{PLURAL:$1|subpágina que se muestra|subpáginas que se muestran}} a continuación.",
        "movenosubpage": "Esta página no tiene subpáginas.",
        "movereason": "Motivo:",
        "revertmove": "revertir",
        "filemissing": "Falta archivo",
        "thumbnail_error": "Error al crear miniatura: $1",
        "thumbnail_error_remote": "Mensaje de error de $1:\n$2",
-       "djvu_page_error": "Página DjVu fuera de rango",
+       "djvu_page_error": "Página DjVu fuera de los límites",
        "djvu_no_xml": "Imposible obtener XML para el archivo DjVu",
        "thumbnail-temp-create": "No se ha podido crear el archivo temporal de la miniatura",
        "thumbnail-dest-create": "No se ha podido guardar la miniatura",
        "pageinfo-category-pages": "Número de páginas",
        "pageinfo-category-subcats": "Número de subcategorías",
        "pageinfo-category-files": "Número de archivos",
+       "pageinfo-user-id": "Identificador de usuario",
        "markaspatrolleddiff": "Marcar como verificada",
        "markaspatrolledtext": "Marcar esta página como verificada",
        "markaspatrolledtext-file": "Marcar esta versión de archivo como verificada",
        "patrol-log-header": "Este es un registro de revisiones verificadas.",
        "log-show-hide-patrol": "$1 registro de verificación",
        "log-show-hide-tag": "$1 registro de etiquetas",
+       "confirm-markpatrolled-button": "Aceptar",
+       "confirm-markpatrolled-top": "marcar la revisión $3 de $2 como revisada?",
        "deletedrevision": "Borrada revisión antigua $1",
        "filedeleteerror-short": "Error al borrar el archivo: $1",
        "filedeleteerror-long": "Se han producido errores mientras se borraba el archivo:\n\n$1",
        "confirmemail_sendfailed": "No fue posible enviar el correo de confirmación. Por favor, comprueba la validez de la dirección de correo.\n\nEl servidor indicó el error: $1",
        "confirmemail_invalid": "Código de confirmación incorrecto.\nEl código debe haber expirado.",
        "confirmemail_needlogin": "Necesitas $1 para confirmar tu dirección electrónica.",
-       "confirmemail_success": "Su dirección de correo ha sido confirmada\nAhora puedes [[Special:UserLogin|identificarte]] y colaborar en el wiki.",
+       "confirmemail_success": "Se ha confirmado tu dirección de correo electrónico.\nAhora puedes [[Special:UserLogin|acceder]] y disfrutar del wiki.",
        "confirmemail_loggedin": "Tu dirección de correo electrónico ha sido confirmada.",
        "confirmemail_subject": "confirmación de la dirección de correo de {{SITENAME}}",
        "confirmemail_body": "Alguien, probablemente tú mismo, ha registrado desde la dirección IP $1 la cuenta \"$2\" en {{SITENAME}}, utilizando esta dirección de correo.\n\nPara confirmar que esta cuenta realmente te pertenece y activar el correo en {{SITENAME}}, sigue este enlace en tu navegador:\n\n$3\n\nSi la cuenta *no* es tuya, sigue este otro enlace para cancelar la confirmación de la dirección de correo:\n\n$5\n\nEl código de confirmación expirará el $4.",
        "tag-filter": "Filtro de [[Special:Tags|etiquetas]]:",
        "tag-filter-submit": "Filtro",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Etiqueta|Etiquetas}}]]: $2)",
+       "tag-mw-contentmodelchange": "cambio de modelo de contenido",
+       "tag-mw-contentmodelchange-description": "Ediciones que [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel cambian el modelo de contenido] de una página",
        "tags-title": "Etiquetas",
        "tags-intro": "Esta página lista las etiquetas con las que el software puede marcar una edición y su significado.",
        "tags-tag": "Nombre de etiqueta",
        "tags-deactivate": "desactivar",
        "tags-hitcount": "$1 {{PLURAL:$1|cambio|cambios}}",
        "tags-manage-no-permission": "No tienes permiso para gestionar las etiquetas de cambios.",
-       "tags-manage-blocked": "No puedes gestionar el cambio de etiquetas mientras estés bloqueado.",
+       "tags-manage-blocked": "No puedes dirigir etiquetas de cambio mientras {{GÉNERO:$1|tú}} estás bloqueado.",
        "tags-create-heading": "Crear una etiqueta",
        "tags-create-explanation": "De manera predeterminada, las etiquetas nuevas estarán disponibles para su uso por usuarios y bots.",
        "tags-create-tag-name": "Nombre de la etiqueta:",
        "tags-deactivate-not-allowed": "No es posible desactivar la etiqueta «$1».",
        "tags-deactivate-submit": "Desactivar",
        "tags-apply-no-permission": "No tienes permiso para aplicar etiquetas de cambios, junto con tus cambios.",
-       "tags-apply-blocked": "No puedes aplicar etiquetas de cambio con tus cambios mientras estés {{GENDER:|bloqueado|bloqueada}}.",
+       "tags-apply-blocked": "No puedes pedir cambio de etiquetas con tus cambios mientras estés {{GENDER:$1|bloqueado|bloqueada}}.",
        "tags-apply-not-allowed-one": "No se permite aplicar manualmente la etiqueta «$1».",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|La siguiente etiqueta no se puede|Las siguientes etiquetas no se pueden}} aplicar manualmente: $1",
        "tags-update-no-permission": "No tienes permiso para agregar o quitar etiquetas de cambio de las revisiones individuales o las entradas del registro.",
-       "tags-update-blocked": "No puedes añadir o eliminar etiquetas de cambio mientras estés {{GENDER:|bloqueado|bloqueada}}.",
+       "tags-update-blocked": "No puedes añadir o eliminar etiquetas de cambio mientras estés {{GENDER:$1|bloqueado|bloqueada}}.",
        "tags-update-add-not-allowed-one": "No se permite la adición manual de la etiqueta «$1».",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|La siguiente etiqueta no se puede|Las siguientes etiquetas no se pueden}} agregar manualmente: $1",
        "tags-update-remove-not-allowed-one": "No se permite eliminar la etiqueta «$1».",
        "htmlform-cloner-create": "Añadir más",
        "htmlform-cloner-delete": "Eliminar",
        "htmlform-cloner-required": "Se requiere al menos un valor.",
+       "htmlform-date-placeholder": "AAAA-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "AAAA-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "No se reconoció la fecha en el formato proporcionado. Prueba a usar el formato AAAA-MM-DD.",
+       "htmlform-time-invalid": "No se reconoció la hora en el formato proporcionado. Prueba a usar el formato HH:MM:SS.",
+       "htmlform-datetime-invalid": "No se reconoció la fecha y la hora en el formato proporcionado. Prueba a usar el formato AAAA-MM-DD HH:MM:SS.",
+       "htmlform-date-toolow": "El valor especificado es anterior a la fecha más antigua permitida, $1.",
+       "htmlform-date-toohigh": "El valor especificado es posterior a la fecha límite permitida, $1.",
+       "htmlform-time-toolow": "El valor especificado es anterior a la hora más antigua permitida, $1.",
+       "htmlform-time-toohigh": "El valor especificado es posterior a la hora límite permitida, $1.",
+       "htmlform-datetime-toolow": "El valor especificado es anterior a la fecha y hora más antigua permitidas, $1.",
+       "htmlform-datetime-toohigh": "El valor especificado es posterior a la fecha y hora límite permitidas, $1.",
        "htmlform-title-badnamespace": "[[:$1]] no está en el espacio de nombres \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" no es un título de página que se pueda crear",
        "htmlform-title-not-exists": "$1 no existe.",
        "feedback-external-bug-report-button": "Enviar una tarea técnica",
        "feedback-dialog-title": "Enviar comentarios",
        "feedback-dialog-intro": "Puedes usar el formulario sencillo debajo para enviar tus comentarios. Ellos se agregarán a la página \"$1\", junto con tu nombre de usuario.",
-       "feedback-error-title": "Error",
        "feedback-error1": "Error: No se reconoce resultado de API",
        "feedback-error2": "Error: Falló la edición",
        "feedback-error3": "Error: No hay respuesta de la API",
        "feedback-thanks": "¡Gracias! Tus comentarios se han publicado en la página \"[$2 $1]\".",
        "feedback-thanks-title": "¡Muchas gracias!",
        "feedback-useragent": "Agente de usuario:",
-       "searchsuggest-search": "Buscar",
+       "searchsuggest-search": "Buscar en {{SITENAME}}",
        "searchsuggest-containing": "que contiene...",
        "api-error-autoblocked": "Tu dirección IP ha sido bloqueada automáticamente porque fue utilizada por un usuario bloqueado.",
        "api-error-badaccess-groups": "No puedes cargar archivos en este wiki.",
        "authmanager-authn-autocreate-failed": "Falló la creación automática de una cuenta local: $1",
        "authmanager-change-not-supported": "Las credenciales proporcionadas no se pueden cambiar, ya que no hay nada que fuera a hacer uso de ellas.",
        "authmanager-create-disabled": "Está desactivada la creación de cuentas.",
-       "authmanager-create-from-login": "Para crear tu cuenta, completa los campos a continuación.",
+       "authmanager-create-from-login": "Para crear una cuenta, rellena los campos.",
        "authmanager-create-not-in-progress": "El proceso de creación de la cuenta no está en progreso o se perdieron los datos de la sesión. Empieza de nuevo desde el principio.",
        "authmanager-create-no-primary": "Las credenciales suministradas no pueden usarse para la creación de la cuenta.",
        "authmanager-link-no-primary": "Las credenciales proporcionadas no se han podido utilizar para enlazar cuentas.",
        "unlinkaccounts-success": "Se ha desvinculado la cuenta.",
        "authenticationdatachange-ignored": "El cambio den los datos de autentificacion no fue realizado. ¿Tal vez, no se configuró un proveedor?",
        "userjsispublic": "Recuerda: las subpáginas JavaScript no deberían contener datos confidenciales, pues otros usuarios los pueden ver.",
-       "usercssispublic": "Recuerda: las subpáginas CSS no deberían contener datos confidenciales, pues otros usuarios los pueden ver."
+       "usercssispublic": "Recuerda: las subpáginas CSS no deberían contener datos confidenciales, pues otros usuarios los pueden ver.",
+       "restrictionsfield-badip": "Dirección o intervalo IP no válidos: $1",
+       "restrictionsfield-label": "Intervalos de IP permitidos:",
+       "restrictionsfield-help": "Una dirección IP o intervalo de CIDR por renglón. Para activar todo, utiliza<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Error: $1",
+       "edit-error-long": "Errores:\n\n$1"
 }
index f7a01e8..70fca4e 100644 (file)
@@ -28,7 +28,8 @@
                        "Purodha",
                        "Macofe",
                        "Adeliine",
-                       "Metsavend"
+                       "Metsavend",
+                       "Cumbril"
                ]
        },
        "tog-underline": "Linkide allakriipsutus:",
        "talk": "Arutelu",
        "views": "vaatamisi",
        "toolbox": "Tööriistad",
+       "tool-link-userrights": "Muuda {{GENDER:$1|kasutajarühmi}}",
+       "tool-link-emailuser": "Saada {{GENDER:$1|kasutajale}} e-kiri",
        "userpage": "Vaata kasutajalehekülge",
        "projectpage": "Vaata projektilehekülge",
        "imagepage": "Vaata faililehekülge",
        "databaseerror-error": "Tõrge: $1",
        "transaction-duration-limit-exceeded": "Selleks et vältida tiražeerimise suurt mahajäämust, on see tehing katkestatud, kuna kirjutamise kestus ($1) ületas {{PLURAL:$2|$2}} sekundi piirangut.\nKui muudad korraga palju üksusi, siis proovi selle asemel teha mitu väiksemat toimingut.",
        "laggedslavemode": "Hoiatus: Leheküljel võivad puududa viimased uuendused.",
-       "readonly": "Andmebaas on hetkel kirjutuskaitse all",
+       "readonly": "Andmebaas lukustatud",
        "enterlockreason": "Sisesta lukustamise põhjus ning juurdepääsu taastamise ligikaudne aeg",
        "readonlytext": "Andmebaas on praegu lukustatud. Uusi sissekandeid ja muid muudatusi ei saa teha. Tõenäoliselt toimub andmebaasi plaanipärane hooldus, mille järel tavaline olukord taastub.\nSüsteemiadministraator, kes andmebaasi lukustas, andis järgmise selgituse: $1",
        "missing-article": "Andmebaas ei leidnud küsitud lehekülje \"$1\" $2 teksti.\n\nPõhjuseks võib olla võrdlus- või ajaloolink kustutatud leheküljele.\n\nKui tegemist ei ole nimetatud olukorraga, võib tegu olla ka süsteemi veaga.\nSellisel juhul tuleks teavitada [[Special:ListUsers/sysop|administraatorit]], edastades talle ka käesoleva lehe internetiaadressi.",
        "internalerror-fatal-exception": "Saatuslik erandtöötluse tõrge: $1",
        "filecopyerror": "Ei saanud faili \"$1\" kopeerida nimega \"$2\".",
        "filerenameerror": "Ei saanud faili \"$1\" failiks \"$2\" ümber nimetada.",
-       "filedeleteerror": "Faili nimega \"$1\" ei ole võimalik kustutada.",
+       "filedeleteerror": "Faili \"$1\" ei õnnestunud kustutada.",
        "directorycreateerror": "Kataloogi \"$1\" ei saanud luua.",
        "directoryreadonlyerror": "Kataloog \"$1\" on kirjutuskaitstud.",
        "directorynotreadableerror": "Kataloog \"$1\" pole loetav.",
        "myprivateinfoprotected": "Sul pole lubatud oma eraandmeid redigeerida.",
        "mypreferencesprotected": "Sul pole lubatud oma eelistusi muuta.",
        "ns-specialprotected": "Erilehekülgi ei saa redigeerida.",
-       "titleprotected": "Kasutaja [[User:$1|$1]] on selle pealkirjaga lehe loomise keelanud esitades järgmise põhjenduse: <em>$2</em>.",
+       "titleprotected": "Kasutaja [[User:$1|$1]] on selle pealkirjaga lehekülje loomise keelanud, esitades järgmise põhjenduse: <em>$2</em>.",
        "filereadonlyerror": "Faili \"$1\" ei saa muuta, sest hoidla \"$2\" on kirjutuskaitstud.\n\nSüsteemiadministraator lukustas selle järgmisel põhjusel: \"$3\".",
        "invalidtitle-knownnamespace": "Vigane pealkiri nimeruumis \"$2\" tekstiga \"$3\"",
        "invalidtitle-unknownnamespace": "Vigane pealkiri nimeruuminumbriga $1 ja tekstiga \"$2\"",
        "password-change-forbidden": "Selles vikis ei saa paroole muuta.",
        "externaldberror": "Esines autentimistõrge või sul pole õigust konto andmeid muuta.",
        "login": "Sisselogimine",
+       "login-security": "Identsuskontroll",
        "nav-login-createaccount": "Logi sisse või registreeru kasutajaks",
        "userlogin": "Sisselogimine või kasutajakonto loomine",
        "userloginnocreate": "Sisselogimine",
        "userlogin-resetpassword-link": "Kas unustasid parooli?",
        "userlogin-helplink2": "Sisselogimisabi",
        "userlogin-loggedin": "Oled juba sisse logitud nimega {{GENDER:$1|$1}}.\nKasuta allolevat vormi, et logida sisse teise kasutajaga.",
+       "userlogin-reauth": "Pead uuesti sisse logima tõestamaks, et oled {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Loo teine konto",
        "createacct-emailrequired": "E-posti aadress",
        "createacct-emailoptional": "E-posti aadress (valikuline)",
        "eauthentsent": "Määratud e-posti aadressile on saadetud kinnituse e-kiri.\nEnne kui su kontole ükskõik milline muu e-kiri saadetakse, pead e-kirjas olevat juhist järgides kinnitama, et konto on tõepoolest sinu.",
        "throttled-mailpassword": "Parooli lähtestamise e-kiri saadetud viimase {{PLURAL:$1|tunni|$1 tunni}} jooksul.\nVäärtarvitamise vältimiseks saadetakse {{PLURAL:$1|tunni|$1 tunni}} jooksul ainult üks lähtestamise e-kiri.",
        "mailerror": "Viga kirja saatmisel: $1",
-       "acct_creation_throttle_hit": "Selle viki külastajad, kes kasutavad sinu IP-aadressi, on viimase ööpäeva jooksul loonud {{PLURAL:$1|ühe konto|$1 kontot}}, mis on selles ajavahemikus ülemmääraks.\nSeetõttu ei saa seda IP-aadressi kasutades hetkel rohkem kontosid luua.",
+       "acct_creation_throttle_hit": "Selle viki külastajad, kes kasutavad sinu IP-aadressi, on viimase $2 jooksul loonud {{PLURAL:$1|ühe konto|$1 kontot}}, mis on selles ajavahemikus ülemmääraks.\nSeetõttu ei saa seda IP-aadressi kasutades hetkel rohkem kontosid luua.",
        "emailauthenticated": "Sinu e-posti aadressi kinnitamisaeg: $2 kell $3.",
        "emailnotauthenticated": "Sinu e-posti aadress pole veel kinnitatud.\nJärgmiste funktsioonidega seotud e-kirju ei saadeta.",
        "noemailprefs": "Järgmiste võimaluste toimimiseks on vaja määrata e-posti aadress.",
        "resetpass_submit": "Sisesta parool ja logi sisse",
        "changepassword-success": "Sinu parool on muudetud!",
        "changepassword-throttled": "Oled hiljuti proovinud liiga palju kordi sisse logida.\nPalun oota $1, enne kui uuesti proovid.",
+       "botpasswords": "Robotiparoolid",
+       "botpasswords-summary": "<em>Robotiparoolid</em> võimaldavad API-põhist juurdepääsu kasutajakontole, ilma kasutamata konto peamisi autentimisandmeid. Kui konto on sisse logitud robotiparooliga, võivad saadaolevad kasutajaõigused olla piiratud.\n\nKui sa ei tea, miks sul on vaja robotiparooli, siis on parem seda mitte kasutada. Mitte keegi ei peaks paluma sul robotiparooli genereerida ja seda talle edasi anda.",
+       "botpasswords-createnew": "Uue robotiparooli loomine",
+       "botpasswords-label-appid": "Roboti nimi:",
+       "botpasswords-label-create": "Loo",
        "resetpass_forbidden": "Paroole ei saa muuta",
        "resetpass-no-info": "Pead olema sisselogitud, et sellele lehele pääseda.",
        "resetpass-submit-loggedin": "Muuda parool",
        "resetpass-temp-password": "Ajutine parool:",
        "resetpass-abort-generic": "Tarkvaralisa on paroolimuudatuse abortinud.",
        "resetpass-expired": "Sinu parool on iganenud. Palun määra uus parool, et sisse logida.",
-       "resetpass-expired-soft": "Sinu parool on iganenud ja tuleb uuesti määrata. Palun vali kohe uus parool või klõpsa \"{{int:authprovider-resetpass-skip-label}}\", et määrata see hiljem.",
-       "resetpass-validity-soft": "Sinu parool ei sobi: $1\n\nPalun vali kohe uus parool või klõpsa \"{{int:authprovider-resetpass-skip-label}}\", et see hiljem uuesti määrata.",
+       "resetpass-expired-soft": "Sinu parool on iganenud ja tuleb uuesti määrata. Palun vali kohe uus parool või klõpsa nuppu \"{{int:authprovider-resetpass-skip-label}}\", et määrata see hiljem.",
+       "resetpass-validity-soft": "Sinu parool ei sobi: $1\n\nPalun vali kohe uus parool või klõpsa nuppu \"{{int:authprovider-resetpass-skip-label}}\", et see hiljem uuesti määrata.",
        "passwordreset": "Parooli lähtestamine",
        "passwordreset-text-one": "Täida see vorm, et oma parool lähtestada.",
        "passwordreset-text-many": "{{PLURAL:$1|Täida üks väljadest, et saada e-kiri ajutise parooliga.}}",
        "content-model-css": "CSS",
        "content-json-empty-object": "Tühi objekt",
        "content-json-empty-array": "Tühi massiiv",
+       "deprecated-self-close-category": "Vigaste endassesuletud HTML-siltidega leheküljed",
        "duplicate-args-warning": "<strong>Hoiatus:</strong> [[:$1]] kutsub malli [[:$2]] nii, et parameetrile \"$3\" vastab rohkem kui üks väärtus. Väärtustest kasutatakse ainult viimast.",
        "duplicate-args-category": "Leheküljed, kus mallikutses on topeltargument",
        "duplicate-args-category-desc": "Lehekülg sisaldab mallikutseid, kus mõnd argumenti on kasutatud mitu korda, näiteks <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> või <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "searchprofile-advanced-tooltip": "Otsi kohandatud nimeruumidest",
        "search-result-size": "$1 ({{PLURAL:$2|1 sõna|$2 sõna}})",
        "search-result-category-size": "{{PLURAL:$1|1 lehekülg|$1 lehekülge}} ({{PLURAL:$2|1 alamkategooria|$2 alamkategooriat}}, {{PLURAL:$3|1 fail|$3 faili}})",
-       "search-redirect": "(ümbersuunamine $1)",
+       "search-redirect": "(ümbersuunamine lehelt $1)",
        "search-section": "(alaosa $1)",
        "search-category": "(kategooria \"$1\")",
        "search-file-match": "(vastab faili sisule)",
        "right-managechangetags": "Koostada ja (in)aktiveerida [[Special:Tags|märgiseid]]",
        "right-applychangetags": "Rakendada [[Special:Tags|märgiseid]] enda muudatuste suhtes",
        "right-changetags": "Lisada ja eemaldada käsitsi rakendatavaid [[Special:Tags|märgiseid]] üksikute redaktsioonide ja logisissekannete juures",
+       "right-deletechangetags": "Kustutada andmebaasist [[Special:Tags|märgiseid]]",
        "grant-group-page-interaction": "Interaktsioon lehekülgedega",
        "grant-group-file-interaction": "Interaktsioon meediafailidega",
        "grant-group-watchlist-interaction": "Interaktsioon sinu jälgimisloendiga",
        "booksources-search": "Otsi",
        "booksources-text": "Allpool on linke teistele lehekülgedele, kus müüakse uusi ja kasutatud raamatuid. Lehekülgedel võib olla ka lisainfot raamatute kohta:",
        "booksources-invalid-isbn": "Antud ISBN-number ei ole korrektne; kontrolli algallikast kopeerides vigu.",
+       "magiclink-tracking-rfc": "RFC-võlulingiga leheküljed",
+       "magiclink-tracking-pmid": "PMID-võlulingiga leheküljed",
+       "magiclink-tracking-isbn": "ISBN-võlulingiga leheküljed",
        "specialloguserlabel": "Täitja:",
        "speciallogtitlelabel": "Objekt (pealkiri või {{ns:user}}:kasutajanimi):",
        "log": "Logid",
        "activeusers-intro": "See on loetelu kasutajatest, kes on viimase $1 {{PLURAL:$1|päev|päeva}} jooksul midagi teinud.",
        "activeusers-count": "$1 {{PLURAL:$1|toiming|toimingut}} viimase {{PLURAL:$3|päeva|$3 päeva}} jooksul",
        "activeusers-from": "Näita kasutajaid alates:",
-       "activeusers-hidebots": "Peida robotid",
-       "activeusers-hidesysops": "Peida administraatorid",
        "activeusers-noresult": "Kasutajaid ei leidunud.",
        "activeusers-submit": "Kuva aktiivsed kasutajad",
        "listgrouprights": "Kasutajarühma õigused",
        "trackingcategories-msg": "Süsteemikategooria",
        "trackingcategories-name": "Sõnumi nimi",
        "trackingcategories-desc": "Kategooriasse arvamise kriteeriumid",
+       "restricted-displaytitle-ignored": "Eiratava kuvapealkirjaga leheküljed",
        "noindex-category-desc": "Robotid ei indekseeri lehekülge, sest sellel on võlusõna <code><nowiki>__NOINDEX__</nowiki></code> ja lehekülg on nimeruumis, kus see silt on lubatud.",
        "index-category-desc": "Leheküljel on <code><nowiki>__INDEX__</nowiki></code> ja lehekülg on nimeruumis, kus see silt on lubatud ning seetõttu indekseerivad robotid lehekülge seal, kus nad muidu seda ei teeks.",
        "post-expand-template-inclusion-category-desc": "Kõigi mallide hõrendamise järel on lehekülg suurem kui <code>$wgMaxArticleSize</code>, mistõttu jäid mõned mallid hõrendamata.",
        "changecontentmodel-title-label": "Lehekülje pealkiri",
        "changecontentmodel-model-label": "Uus sisumudel",
        "changecontentmodel-reason-label": "Põhjus:",
+       "changecontentmodel-submit": "Muuda",
        "changecontentmodel-success-title": "Sisumudel on muudetud",
        "changecontentmodel-success-text": "Lehekülje [[:$1]] sisumudel on muudetud.",
        "changecontentmodel-cannot-convert": "Lehekülje [[:$1]] sisumudelit ei saa teisendada tüübiks $2.",
        "undeletehistorynoadmin": "See lehekülg on kustutatud.\nKustutamise põhjus ning selle lehekülje kustutamiseelne redigeerimislugu on näha allolevas kokkuvõttes.\nLehekülje kustutamiseelsed redaktsioonid on kättesaadavad ainult administraatoritele.",
        "undelete-revision": "Lehekülje $1 kustutatud redaktsioon, mille autor on $3, seisuga $4, kell $5.",
        "undeleterevision-missing": "Vigane või puuduv redaktsioon.\nLink võib olla kõlbmatu või redaktsioon võib olla taastatud või arhiivist eemaldatud.",
+       "undeleterevision-duplicate-revid": "{{PLURAL:$1|Üht|$1}} redaktsiooni ei saanud taastada, sest {{PLURAL:$1|selle|nende}} <code>rev_id</code> oli juba kasutuses.",
        "undelete-nodiff": "Varasemat redaktsiooni ei leidunud.",
        "undeletebtn": "Taasta",
        "undeletelink": "vaata/taasta",
        "sp-contributions-username": "IP-aadress või kasutajanimi:",
        "sp-contributions-toponly": "Ainult uusimad redaktsioonid",
        "sp-contributions-newonly": "Näita ainult uute lehekülgedega alustamist",
+       "sp-contributions-hideminor": "Peida pisimuudatused",
        "sp-contributions-submit": "Otsi",
        "whatlinkshere": "Lingid siia",
        "whatlinkshere-title": "Leheküljed, mis viitavad lehele \"$1\"",
        "ipb-unblock": "Kasutaja või IP-aadressi vabastamine blokeerimisest",
        "ipb-blocklist": "Vaata kehtivaid blokeeringuid",
        "ipb-blocklist-contribs": "Kasutaja $1 kaastöö",
+       "ipb-blocklist-duration-left": "$1 järel",
        "unblockip": "Blokeerimise eemaldamine",
        "unblockiptext": "Kasuta allpool olevat vormi varem blokeeritud IP-aadressi või kasutaja redigeerimisõiguse taastamiseks.",
        "ipusubmit": "Eemalda see blokeering",
        "block-log-flags-hiddenname": "kasutajanimi peidetud",
        "range_block_disabled": "Administraatori õigus blokeerida IP-aadresside vahemik on ära võetud.",
        "ipb_expiry_invalid": "Vigane aegumise tähtaeg.",
+       "ipb_expiry_old": "Aegumistähtaeg on minevikus.",
        "ipb_expiry_temp": "Peidetud kasutajanime blokeeringud peavad olema alalised.",
        "ipb_hide_invalid": "Seda kontot ei saa varjata, sest sellega on tehtud üle {{PLURAL:$1|ühe|$1}} muudatuse.",
        "ipb_already_blocked": "\"$1\" on juba blokeeritud.",
        "pageinfo-article-id": "Lehekülje identifikaator",
        "pageinfo-language": "Lehekülje sisu keel",
        "pageinfo-content-model": "Lehekülje sisumudel",
+       "pageinfo-content-model-change": "muuda",
        "pageinfo-robot-policy": "Robotindekseering",
        "pageinfo-robot-index": "Lubatud",
        "pageinfo-robot-noindex": "Keelatud",
        "pageinfo-category-pages": "Lehekülgi",
        "pageinfo-category-subcats": "Alamkategooriaid",
        "pageinfo-category-files": "Faile",
+       "pageinfo-user-id": "Kasutaja identifikaator",
        "markaspatrolleddiff": "Märgi kontrollituks",
        "markaspatrolledtext": "Märgi see leht kontrollituks",
+       "markaspatrolledtext-file": "Märgi see failiversioon kontrollituks",
        "markedaspatrolled": "Kontrollituks märgitud",
        "markedaspatrolledtext": "Valitud redaktsioon leheküljel [[:$1]] on kontrollituks märgitud.",
        "rcpatroldisabled": "Viimaste muudatuste kontroll ei toimi",
        "patrol-log-header": "See on kontrollitud redaktsioonide logi.",
        "log-show-hide-patrol": "$1 kontrollimislogi",
        "log-show-hide-tag": "$1 märgiste logi",
+       "confirm-markpatrolled-button": "Sobib",
        "deletedrevision": "Kustutatud vanem versioon $1",
        "filedeleteerror-short": "Tõrge faili kustutamisel: $1",
        "filedeleteerror-long": "Faili kustutamisel esines tõrkeid:\n\n$1",
        "confirm-watch-top": "Kas lisad selle lehekülje oma jälgimisloendisse?",
        "confirm-unwatch-button": "Sobib",
        "confirm-unwatch-top": "Kas eemaldad selle lehekülje oma jälgimisloendist?",
+       "confirm-rollback-button": "Sobib",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← eelmine lehekülg",
        "imgmultipagenext": "järgmine lehekülg →",
        "tag-filter": "[[Special:Tags|Märgisefilter]]:",
        "tag-filter-submit": "Filtri",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Märgis|Märgised}}]]: $2)",
+       "tag-mw-contentmodelchange": "sisumudeli muudatus",
+       "tag-mw-contentmodelchange-description": "Lehekülje [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel sisumudelit muutvad] redaktsioonid",
        "tags-title": "Märgised",
        "tags-intro": "See lehekülg loetleb märgised, millega tarkvara võib muudatused märgistada, ja nende kirjeldused.",
        "tags-tag": "Märgise nimi",
        "feedback-external-bug-report-button": "Koosta tehniline tööülesanne",
        "feedback-dialog-title": "Tagasiside saatmine",
        "feedback-dialog-intro": "Selle lihtsa vormi abil saad tagasisidet saata. Leheküljele \"$1\" lisatakse sinu kommentaar, mille juures on sinu kasutajanimi.",
-       "feedback-error-title": "Tõrge",
        "feedback-error1": "Tõrge: Tundmatu API tulemus",
        "feedback-error2": "Tõrge: Redigeerimine ebaõnnestus",
        "feedback-error3": "Tõrge: API ei vasta",
        "feedback-thanks": "Aitäh! Sinu tagasiside on postitatud leheküljele \"[$2 $1]\".",
        "feedback-thanks-title": "Aitäh!",
        "feedback-useragent": "Kasutajaagent:",
-       "searchsuggest-search": "Otsi",
+       "searchsuggest-search": "Otsi {{GRAMMAR:elative|{{SITENAME}}}}",
        "searchsuggest-containing": "sisalduv...",
        "api-error-badaccess-groups": "Sul pole selles vikis üleslaadimisõigust.",
        "api-error-badtoken": "Sisemine tõrge: Sobimatu nimi.",
        "mediastatistics-header-text": "Tekstifailid",
        "mediastatistics-header-executable": "Täitmisfailid",
        "mediastatistics-header-archive": "Tihendatud vormingud",
+       "mediastatistics-header-total": "Kõik failid",
        "json-warn-trailing-comma": "$1 lõpukoma eemaldati JSON-ist.",
        "json-error-unknown": "JSON-iga oli probleem. Tõrge: $1",
        "json-error-depth": "Suurim võimalik pinusügavus on ületatud.",
        "special-characters-group-ipa": "IPA-laiendid",
        "special-characters-group-symbols": "Sümbolid",
        "special-characters-group-greek": "Kreeka",
+       "special-characters-group-greekextended": "Kreeka (laiendatud)",
        "special-characters-group-cyrillic": "Kirillitsa",
        "special-characters-group-arabic": "Araabia",
        "special-characters-group-arabicextended": "Araabia (laiendatud)",
        "mw-widgets-titleinput-description-new-page": "lehekülge pole veel",
        "mw-widgets-titleinput-description-redirect": "ümbersuunamine leheküljele \"$1\"",
        "randomrootpage": "Juhuslik juurlehekülg",
-       "userjsispublic": "Pea silmas, et JavaScripti alamleheküljed ei tohiks sisaldada konfidentsiaalseid andmeid, kuna neid näevad teised kasutajad."
+       "log-action-filter-block": "Blokeeringu tüüp:",
+       "log-action-filter-all": "Kõik",
+       "log-action-filter-block-block": "Blokeerimine",
+       "log-action-filter-block-reblock": "Blokeeringu muutmine",
+       "log-action-filter-block-unblock": "Blokeeringu tühistamine",
+       "authmanager-provider-password": "Paroolipõhine autentimine",
+       "authmanager-provider-password-domain": "Parooli- ja domeenipõhine autentimine",
+       "authmanager-provider-temporarypassword": "Ajutine parool",
+       "changecredentials": "Autentimisandmete muutmine",
+       "changecredentials-submit": "Muuda autentimisandmed",
+       "changecredentials-success": "Sinu autentimisandmed on muudetud.",
+       "removecredentials": "Autentimisandmete eemaldamine",
+       "removecredentials-submit": "Eemalda autentimisandmed",
+       "removecredentials-success": "Sinu autentimisandmed on eemaldatud.",
+       "credentialsform-provider": "Andmete tüüp:",
+       "credentialsform-account": "Konto nimi:",
+       "userjsispublic": "Pea silmas, et JavaScripti alamleheküljed ei tohiks sisaldada konfidentsiaalseid andmeid, kuna neid näevad teised kasutajad.",
+       "restrictionsfield-badip": "Vigane IP-aadress või -aadressivahemik: $1",
+       "restrictionsfield-label": "Lubatud IP-aadressivahemikud:",
+       "restrictionsfield-help": "Üks IP-aadress või CIDR-vahemik rea kohta. Et lubada kõik, kasuta süntaksit <br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Tõrge: $1",
+       "edit-error-long": "Tõrked:\n\n$1"
 }
index 476e3f1..187d68c 100644 (file)
@@ -25,7 +25,8 @@
                        "Macofe",
                        "Xð",
                        "Asierog",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Gorkaazk"
                ]
        },
        "tog-underline": "Azpimarratu loturak:",
        "talk": "Eztabaida",
        "views": "Ikustaldiak",
        "toolbox": "Tresnak",
+       "tool-link-userrights": "Erabiltzaile {{GENDER:$1|taldea}} aldatu",
+       "tool-link-emailuser": "{{GENDER:$1|Erabiltzale}} honi e-posta bidali",
        "userpage": "Lankide orrialdea ikusi",
        "projectpage": "Proiektuaren orrialdea ikusi",
        "imagepage": "Ikusi fitxategiaren orria",
        "login": "Saioa hasi",
        "nav-login-createaccount": "Saioa hasi / kontua sortu",
        "userlogin": "Saioa hasi / kontua sortu",
-       "userloginnocreate": "Saioa hasi",
+       "userloginnocreate": "Hasi saioa",
        "logout": "Saioa itxi",
        "userlogout": "Saioa itxi",
        "notloggedin": "Saioa hasi gabe",
        "eauthentsent": "Egiaztapen mezu bat bidali da zehaztutako e-posta helbidera.\nHelbide horretara beste edozein mezu bidali aurretik, bertan azaltzen diren argibideak jarraitu behar dituzu, kontua zurea dela egiaztatzeko.",
        "throttled-mailpassword": "Pasahitz gogorarazle bat bidali da jada azken {{PLURAL:$1|orduan|$1 orduetan}}.\nBandalismoa sahiesteko pasahitz eskaera bat baino ezin da egin {{PLURAL:$1|orduan|$1 orduan}} behin.",
        "mailerror": "Errorea mezua bidaltzerakoan: $1",
-       "acct_creation_throttle_hit": "Sentitzen dugu, {{PLURAL:$1|erabiltzaile kontu bat sortu duzu|$1 erabiltzaile kontu sortu dituzu}} dagoeneko.\nOndorioz, ezin duzu kontu gehiago sortu.",
+       "acct_creation_throttle_hit": "Sentitzen dugu, {{PLURAL:$1|erabiltzaile kontu bat sortu duzu|$1 erabiltzaile kontu sortu dituzu}} dagoeneko azken $2(e)tan.\nOndorioz, ezin duzu kontu gehiago sortu.",
        "emailauthenticated": "Zure e-posta helbidea autentifikatu da $2an $3(e)tan.",
        "emailnotauthenticated": "Zure posta helbidea egiaztatu gabe dago. \nEz da mezurik bidaliko hurrengo ezaugarrientzako.",
        "noemailprefs": "Zehaztu e-posta helbide bat ezaugarri hauek erabili ahal izateko.",
        "loginlanguagelabel": "Hizkuntza: $1",
        "suspicious-userlogout": "Saioa amaitzeko egin duzun eskaria ukatu da. Izan ere, ematen du eskari hori gaizki dabilen nabigatzaile edo cache proxy batek bidali duela.",
        "createacct-another-realname-tip": "Benetako izena hautazkoa da.\nEmatea erabakitzen baduzu hori erabiliko da lanaren atribuzioa egiterako garaian.",
-       "pt-login": "Saioa hasi",
-       "pt-login-button": "Saioa hasi",
+       "pt-login": "Hasi saioa",
+       "pt-login-button": "Hasi saioa",
        "pt-login-continue-button": "Konexioa jarraitu",
        "pt-createaccount": "Sortu kontua",
        "pt-userlogout": "Saioa itxi",
        "nosuchsectiontitle": "Atala ez da aurkitu",
        "nosuchsectiontext": "Existitzen ez den atala editatzen saiatu zara.\nBaliteke orrialdea begiratzen zenuen bitartean norbaitek ezabatu edo izenburua aldatu izana.",
        "loginreqtitle": "Saioa hastea beharrezkoa",
-       "loginreqlink": "saioa hasi",
+       "loginreqlink": "hasi saioa",
        "loginreqpagetext": "Beste orrialde batzuk ikusteko $1 beharra daukazu..",
        "accmailtitle": "Pasahitza bidali da.",
        "accmailtext": "[[User talk:$1|$1]]-entzako ausaz sortutako pasahitza $2-(r)a bidali da.\n\n''[[Special:ChangePassword|pasahitz aldaketa]]'' orrialdean alda daiteke, behin barruan sartuta.",
        "preferences": "Hobespenak",
        "mypreferences": "Hobespenak",
        "prefs-edits": "Aldaketa kopurua:",
-       "prefsnologintext2": "Mesedez saioa hasi zure hobespenak aldatzeko.",
+       "prefsnologintext2": "Mesedez hasi saioa zure hobespenak aldatzeko.",
        "prefs-skin": "Itxura",
        "skin-preview": "Aurrebista",
        "datedefault": "Hobespenik ez",
        "gender-female": "Wiki orrialdeak editatzen dituen emakumea",
        "prefs-help-gender": "Hobespen hau jartzea aukerazkoa da.\nSoftwareak bere balioak erabiltzen ditu zu aipatzeko eta beste batzuek genero gramatikala erabiltzeko aukera izan dezaten.\nInformazio hau publikoa da.",
        "email": "E-posta",
-       "prefs-help-realname": "* Benetako izena (aukerakoa): zehaztea erabakiz gero, zure lanarentzako atribuzio bezala balioko du.",
+       "prefs-help-realname": "Benetako izena aukerakoa da. \nZehaztea erabakiz gero, zure lanarentzako atribuzio bezala balioko du.",
        "prefs-help-email": "E-posta helbidea aukerakoa da, baina zure pasahitza ahaztekotan berriro zure e-postara bidaltzeko aukera ematen dizu.",
        "prefs-help-email-others": "Besteak e-mail bidez zurekin harremanetan jartzea ahalbidetu dezakezu, zure lankide- edo eztabaida-orrietako loturaren bidez. Beste lankideak zurekin harremanetan jartzerakoan ez da ikusiko zure e-mail helbidea.",
        "prefs-help-email-required": "E-mail helbidea derrigorrezkoa da.",
        "upload-copy-upload-invalid-domain": "Domeinu honetan ezin dira igoerak kopiatu.",
        "upload-dialog-title": "Igo fitxategia",
        "upload-dialog-button-cancel": "Utzi",
+       "upload-dialog-button-back": "Atzera",
        "upload-dialog-button-done": "Egina",
        "upload-dialog-button-save": "Gorde",
        "upload-dialog-button-upload": "Igo",
        "activeusers": "Lankide aktiboen zerrenda",
        "activeusers-count": "{{PLURAL:$1|Ekintza berri bat|$1 ekintza berri}} azken {{PLURAL:$3|egunean|$3 egunetan}}",
        "activeusers-from": "Bilatu honela hasten diren lankideak:",
-       "activeusers-hidebots": "Ezkutatu bot-ak",
-       "activeusers-hidesysops": "Ezkutatu administratzaileak",
        "activeusers-noresult": "Ez da lankiderik aurkitu.",
        "listgrouprights": "Erabiltzaile talde eskumenak",
        "listgrouprights-summary": "Ondorengo zerrendak wikian dauden lankide taldeak agertzen dira, beraien eskubideekin.\nBadago [[{{MediaWiki:Listgrouprights-helppage}}|informazio osagarria]] banakako eskubideei buruz.",
        "htmlform-chosen-placeholder": "Aukeratu",
        "htmlform-cloner-create": "Gehitu gehiago",
        "htmlform-cloner-delete": "Kendu",
+       "htmlform-date-placeholder": "UUUU-HH-EE",
+       "htmlform-time-placeholder": "OO:MM:SS",
+       "htmlform-datetime-placeholder": "UUUU-HH-EE OO:MM:SS",
+       "htmlform-date-invalid": "Jarri duzun balioak ez du data ezagunik adierazten. Saiatu UUUU-HH-EE formatua erabiltzen.",
+       "htmlform-time-invalid": "Jarri duzun balioak ez du denbora ezagunik adierazten. Saiatu OO:MM:SS formatua erabiltzen.",
+       "htmlform-datetime-invalid": "Jarri duzun balioak ez da data eta denbora bezala ezagutzen. Saitu UUUU-HH-EE OO:MM:SS formatua erabiltzen.",
        "htmlform-title-not-creatable": "\"$1\" ez da sor daitekeen orrialde baten izenburua",
        "htmlform-title-not-exists": "$1 ez da existitzen.",
        "htmlform-user-not-exists": "<strong>$1</strong> ez da existitzen.",
        "feedback-cancel": "Utzi",
        "feedback-close": "Egina",
        "feedback-dialog-title": "Feedbacka bidali",
-       "feedback-error-title": "Errorea",
        "feedback-error1": "Akatsa: APIaren emaitza ez ezagunak",
        "feedback-error2": "Akatsa: Aldaketa ez da egin",
        "feedback-error3": "Akatsa: APIaren erantzunik gabe",
index 302bc58..486fc28 100644 (file)
        "nstab-main": "Artículu",
        "nstab-user": "Páhina d'usuáriu",
        "nstab-media": "Páhina \"Meya\"",
-       "nstab-special": "Artículu especial",
+       "nstab-special": "Páhina especial",
        "nstab-project": "Página el proyeutu",
        "nstab-image": "Archivu",
        "nstab-mediawiki": "Mensahi",
        "undo-norev": "La eición nu pué sel eshecha ebiu a que nu dessisti, u hue esborrá",
        "undo-summary": "Eshazel revisión $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|Caraba]])",
        "cantcreateaccount-text": "La criación de cuentas pol parti e la IP ('''$1''') á siu pará pol el usuáriu [[User:$3|$3]].\n\nLa razón dá pol $3 es ''$2''",
-       "viewpagelogs": "Vel los rustrihus d´esta páhina",
+       "viewpagelogs": "Vel los rustrihus desta páhina",
        "nohistory": "Nu ai dengún estorial d´eicionis pa esta páhina.",
        "currentrev": "Revisión atual",
        "currentrev-asof": "Úrtima revisión: $1",
        "history-feed-title": "Estorial de revisionis",
        "history-feed-description": "Estorial de revisionis pa esta páhina nel güiqui",
        "history-feed-item-nocomment": "$1 en $2",
-       "history-feed-empty": "Esa páhina nu desisti.\nEs posibri qu´aiga siu esborrá e la güiqui, u que s´aiga chambau el su nombri.\nPreba [[Special:Search|landeandu]] entri las nuevas páhinas de la güiqui.",
+       "history-feed-empty": "Esa páhina nu desisti.\nEs posibri qu’aiga siu esborrá e la güiqui, u que s’aiga chambau el su nombri.\nPreba [[Special:Search|landeandu]] entri las nuevas páhinas de la güiqui.",
        "rev-deleted-comment": "(comentáriu esborrau)",
        "rev-deleted-user": "(nombri d´usuáriu esborrau)",
        "rev-deleted-event": "(entrá esborrá)",
        "enhancedrc-history": "Estorial",
        "recentchanges": "Úrtimus chambus",
        "recentchanges-legend": "Ocionis enos úrtimus chambus",
-       "recentchanges-summary": "Sigui los úrtimus chambus d´esti güiqui nesta páhina.",
+       "recentchanges-summary": "Sigui los úrtimus chambus desti güiqui nesta páhina.",
        "recentchanges-feed-description": "Sigui los úrtimus chambus nel güiqui nesti feed.",
        "rcnotefrom": "Embahu se muestran los chambus hechus dendi el '''$2''' (hata el '''$1''').",
        "rclistfrom": "Muestral los chambus hechus dendi el $3 $2",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|usuáriu está|usuárius están}} vehilandu]",
        "rc_categories": "Arrayal a categorias (separás pol \"|\")",
        "rc_categories_any": "Cualisquiá",
-       "rc-change-size-new": "$1{{PLURAL:$1|byte|bytes}} dempués el chambu",
+       "rc-change-size-new": "$1 {{PLURAL:$1|byte|bytes}} dempués el chambu",
        "newsectionsummary": "/* $1 */ seción nueva",
        "rc-enhanced-expand": "muestral detallis (es mestel JavaScript)",
        "rc-enhanced-hide": "Açonchal detallis",
        "filehist-comment": "Comentáriu",
        "imagelinks": "Atihus",
        "linkstoimage": "{{PLURAL:$1|El siguienti artículu atiha|Los siguientis $1 artículus atihan}} a esti archivu:",
-       "nolinkstoimage": "Nu ai denguna páhina qu´atihi a esti archivu.",
+       "nolinkstoimage": "Nu ai denguna páhina quatihi a esti archivu.",
        "morelinkstoimage": "Guipal [[Special:WhatLinksHere/$1|mas atijus]] a esti archivu.",
        "sharedupload": "Esti archivu procei de $1 i puei gastalsi dendi otrus proyeutus.",
        "uploadnewversion-linktext": "Empuntal una nueva velsión d´esti archivu",
        "tooltip-t-print": "Velsión pa imprental desta páhina",
        "tooltip-t-permalink": "Atihu remanenti a esta velsión de la páhina",
        "tooltip-ca-nstab-main": "Vel el artículu",
-       "tooltip-ca-nstab-user": "Vel la páhina d´usuáriu",
+       "tooltip-ca-nstab-user": "Vel la páhina dusuáriu",
        "tooltip-ca-nstab-media": "Vel la páhina e \"meya\"",
        "tooltip-ca-nstab-special": "Esta es una páhina especial, razón pola que nu pueis eitala",
        "tooltip-ca-nstab-project": "Vel la páhina el proyeutu",
        "tooltip-ca-nstab-image": "Vel la páhina el archivu",
        "tooltip-ca-nstab-mediawiki": "Vel el mensahi el sistema",
        "tooltip-ca-nstab-template": "Vel la prantilla",
-       "tooltip-ca-nstab-help": "Vel la páhina d´ayua",
+       "tooltip-ca-nstab-help": "Vel la páhina dayua",
        "tooltip-ca-nstab-category": "Vel la categoria",
        "tooltip-minoredit": "Aseñalal cumu eición chiquenina",
        "tooltip-save": "Emburacal los tus chambus",
index 0fbbe20..4bffbc9 100644 (file)
        "talk": "بحث",
        "views": "بازدیدها",
        "toolbox": "ابزارها",
+       "tool-link-userrights": "تغییر گروه‌های {{GENDER:$1|کاربر}}",
+       "tool-link-emailuser": "فرستادن نامه به {{GENDER:$1|کاربر}}",
        "userpage": "نمایش صفحهٔ کاربر",
        "projectpage": "نمایش صفحهٔ پروژه",
        "imagepage": "نمایش صفحهٔ پرونده",
        "botpasswords-label-resetpassword": "بازگردانی گذرواژه",
        "botpasswords-label-grants": "اعطاهای اجرا شدنی:",
        "botpasswords-help-grants": "هر اجازه به حقوق کاربری که یک حساب کاربری دارد. [[Special:ListGrants|table of grants]] را برای اطلاعات بیشتر مشاهده کنید.",
-       "botpasswords-label-restrictions": "محدودیت استفاده:",
        "botpasswords-label-grants-column": "اعطا شد",
        "botpasswords-bad-appid": "نام ربات \"$1\" معتبر نیست.",
        "botpasswords-insert-failed": "شکست در افزودن نام ربات «$1». در حال حاضر اضافه شده است؟",
        "passwordreset-nocaller": "فراخواننده می‌بايست مشخص شده باشد",
        "passwordreset-nosuchcaller": "اين فراخواننده وجود ندارد:$1",
        "passwordreset-ignored": "به بازنشانی گذرواژه پرداخته نشد. آیا ممکن است که هيچ مهياکننده‌ای برای این کار تنظيم نشده باشد؟",
-       "passwordreset-invalideamil": "آدرس ایمیل نامعتبر",
+       "passwordreset-invalidemail": "آدرس ایمیل نامعتبر",
        "passwordreset-nodata": "یک نام کاربری و یا یک آدرس ايميل، هيچکدام ارائه نشده",
        "changeemail": "تغییر یا حذف نشانی ایمیل",
        "changeemail-header": "برای تغییر ایمیلتان این فرم را کامل کنید. برای حذف ایملیتان کافی است بخش ایمیل را خالی رها کنید و فرم را ارسال کنید.",
        "prefs-advancedwatchlist": "گزینه‌های پیشرفته",
        "prefs-displayrc": "گزینه‌های نمایش",
        "prefs-displaywatchlist": "گزینه‌های نمایش",
-       "prefs-tokenwatchlist": "نشانه",
+       "prefs-tokenwatchlist": "بلیط",
        "prefs-diffs": "تفاوت‌ها",
        "prefs-help-prefershttps": "تأثیر این ترجیح بعد از ورود بعدی شما اعمال خواهد شد.",
        "prefswarning-warning": "تغییراتتان به ترجیحات هنوز ذحیره نشده است.\nاگر این صفحه بدون کلیک بر «$1» ترک کنید ترجیحاتتان ذخیره نخواهد شد.",
        "activeusers-intro": "در زیر فهرستی از کاربرانی را می‌بینید که در $1 {{PLURAL:$1|روز|روز}} گذشته فعالیتی داشته‌اند.",
        "activeusers-count": "$1 {{PLURAL:$1|فعالیت|فعالیت}} در {{PLURAL:$3|روز|$3 روز}} اخیر",
        "activeusers-from": "نمایش کاربران با آغاز از:",
-       "activeusers-hidebots": "نهفتن ربات‌ها",
-       "activeusers-hidesysops": "نهفتن مدیران",
        "activeusers-noresult": "کاربری پیدا نشد.",
        "activeusers-submit": "نمایش کاربران فعال",
        "listgrouprights": "اختیارات گروه‌های کاربری",
        "blocklist-userblocks": "پنهان کردن بسته‌شدن‌های حساب",
        "blocklist-tempblocks": "پنهان کردن بستن‌های موقت",
        "blocklist-addressblocks": "پنهان کردن تک آی‌پی‌های بسته شده",
-       "blocklist-rangeblocks": "پنهان کردنی قطع دسترسی بازه‌ها",
+       "blocklist-rangeblocks": "پنهان کردن قطع دسترسی بازه‌ها",
        "blocklist-timestamp": "برچسب زمان",
        "blocklist-target": "هدف",
        "blocklist-expiry": "زمان سرآمدن",
        "feedback-external-bug-report-button": "پرونده‌سازی یک عمل فنی",
        "feedback-dialog-title": "ارسال یک بازخورد",
        "feedback-dialog-intro": "شما می توانید از فرم زیر برای بازخورد استفاده کنید. متن شما همراه با نام کاربریتان به صفحهٔ \"$1\" افزوده خواهد شد.",
-       "feedback-error-title": "خطا",
        "feedback-error1": "خطا: پاسخ‌های ناشناخته از رابط برنامه‌نویسی نرم‌افزار",
        "feedback-error2": "خطا: شکست در ویرایش",
        "feedback-error3": "خطا: عدم پاسخ از رابط برنامه‌نویسی نرم‌افزار",
index 37a6d51..1a19f65 100644 (file)
@@ -52,7 +52,8 @@
                        "01miki10",
                        "Matma Rex",
                        "BiscuitMan",
-                       "Alluk."
+                       "Alluk.",
+                       "Tumm1"
                ]
        },
        "tog-underline": "Linkkien alleviivaus:",
@@ -60,7 +61,7 @@
        "tog-hidepatrolled": "Piilota tarkastetut muutokset tuoreet muutokset -listasta",
        "tog-newpageshidepatrolled": "Piilota tarkastetut sivut uusien sivujen listalta",
        "tog-hidecategorization": "Piilota sivujen luokittelu",
-       "tog-extendwatchlist": "Laajenna tarkkailulista näyttämään kaikki tehdyt muutokset eikä vain viimeisimmät",
+       "tog-extendwatchlist": "Laajenna tarkkailulista näyttämään kaikki tehdyt muutokset, eikä vain viimeisimmät",
        "tog-usenewrc": "Ryhmittele muutokset sivun mukaan tuoreiden muutosten listalla ja tarkkailulistalla",
        "tog-numberheadings": "Numeroi otsikot automaattisesti",
        "tog-showtoolbar": "Näytä työkalupalkki",
        "talk": "Keskustelu",
        "views": "Näkymät",
        "toolbox": "Työkalut",
+       "tool-link-userrights": "Muokkaa {{GENDER:$1|käyttäjän}} ryhmiä",
+       "tool-link-emailuser": "Lähetä sähköpostia tälle {{GENDER:$1|käyttäjälle}}",
        "userpage": "Näytä käyttäjäsivu",
        "projectpage": "Näytä projektisivu",
        "imagepage": "Näytä tiedostosivu",
        "botpasswords-updated-body": "Bottisalasana käyttäjän \"$2\" bottinimelle \"$1\" päivitettiin.",
        "botpasswords-deleted-title": "Bottisalasana poistettu",
        "botpasswords-deleted-body": "Bottisalasana käyttäjän \"$2\" bottinimelle \"$1\" poistettiin.",
-       "botpasswords-newpassword": "Uusi salasana kirjautumiseen käyttäjällä <strong>$1</strong> on <strong>$2</strong>. <em>Säilytä tämä myöhempää käyttöä varten.</em>",
+       "botpasswords-newpassword": "Uusi salasana kirjautumiseen käyttäjällä <strong>$1</strong> on <strong>$2</strong>. <em>Säilytä tämä myöhempää käyttöä varten.</em> <br> (Vanhoilla boteilla, jotka vaativat kirjautumisnimen olevan sama kuin lopullinen käyttäjänimi, voit myös käyttää nimeä <strong>$3</strong> ja salasanaa <strong>$4</strong>.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider ei ole saatavilla.",
        "botpasswords-restriction-failed": "Bottisalasanan rajoitukset estävät tämän sisäänkirjautumisen.",
        "botpasswords-invalid-name": "Annetussa käyttäjätunnuksessa ei ole bottisalasanan erotinta (\"$1\").",
        "passwordreset-emailsentusername": "Jos on olemassa vastaava rekisteröity sähköpostiosoite, salasanan uudistamisesta kertova viesti lähetetään.",
        "passwordreset-emailsent-capture2": "Salasananpalautus{{PLURAL:$1|sähköposti|sähköpostit}} on lähetetty. {{PLURAL:$1|Käyttäjä ja salasana|Luettelo käyttäjistä ja salasanoista}} näytetään alapuolella.",
        "passwordreset-emailerror-capture2": "Sähköpostin lähettäminen {{GENDER:$2|käyttäjälle}} epäonnistui: $1 {{PLURAL:$3|Käyttäjänimi ja salasana|Luettelo käyttäjänimistä ja salasanoista}} näytetään alla.",
-       "passwordreset-invalideamil": "Virheellinen sähköpostiosoite",
+       "passwordreset-ignored": "Salasanan palauttamista ei käsitelty. Ehkä tarjoajaa ei ollut määritetty?",
+       "passwordreset-invalidemail": "Virheellinen sähköpostiosoite",
        "passwordreset-nodata": "Käyttäjätunnusta ja salasanaa ei annettu",
        "changeemail": "Muuta tai poista sähköpostiosoite",
        "changeemail-header": "Täydennä tämä lomake, jolla voit muuttaa sähköpostiosoitettasi. Jos haluat poistaa sähköpostiosoitteesi kokonaan tunnuksesi yhteydestä, älä kirjoita uudeksi osoitteeksi mitään vaan jätä se tyhjäksi.",
        "invalid-content-data": "Virheellinen sisältö",
        "content-not-allowed-here": "Sivun [[$2]] sisältö ei voi olla tyyppiä $1.",
        "editwarning-warning": "Tältä sivulta poistuminen saattaa aiheuttaa kaikkien tekemiesi muutosten katoamisen.\nJos olet kirjautunut sisään, voit poistaa tämän varoituksen käytöstä omien asetuksien osiossa \"{{int:prefs-editing}}\".",
+       "editpage-invalidcontentmodel-title": "Sisältömalli ei ole tuettu",
+       "editpage-invalidcontentmodel-text": "Sisältömalli \"$1\" ei ole tuettu.",
        "editpage-notsupportedcontentformat-title": "Sisällön muotoa ei tueta",
        "editpage-notsupportedcontentformat-text": "Sisällön muotoa $1 ei tueta sisältömallilla $2.",
        "content-model-wikitext": "wikiteksti",
        "content-model-css": "CSS",
        "content-json-empty-object": "Tyhjä objekti",
        "content-json-empty-array": "Tyhjä array",
+       "deprecated-self-close-category": "Sivut, joissa on virheellisiä itsensäsulkevia HTLM-tageja",
+       "deprecated-self-close-category-desc": "Sivulla on virheellisiä itsensäsulkevia HTML-tageja, kuten <code>&lt;b/></code> tai <code>&lt;span/></code>. Niiden käyttäytyminen muuttuu pian HTLM5:n määritysten mukaiseksi, joten niiden käyttö wikitekstissä on vanhentunut.",
        "duplicate-args-warning": "<strong>Varoitus:</strong> [[:$1]] kutsuu mallinetta [[:$2]] niin, että parametrille \"$3\" on annettu enemmän kuin yksi arvo. Ainoastaan viimeksi annettu arvo otetaan huomioon.",
        "duplicate-args-category": "Sivut, jotka käyttävät kaksinkertaisia argumentteja mallinekutsuissa",
        "duplicate-args-category-desc": "Tämä sivu sisältää sellaisia mallinekutsuja, jotka käyttävät kaksi kertaa samaa argumenttia kuten <nowiki>{{foo|bar=1|bar=2}}</nowiki></code> taikka <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "searchprofile-advanced-tooltip": "Etsi määritellyistä nimiavaruuksista",
        "search-result-size": "$1 ({{PLURAL:$2|1 sana|$2 sanaa}})",
        "search-result-category-size": "{{PLURAL:$1|1 jäsen|$1 jäsentä}} ({{PLURAL:$2|1 alaluokka|$2 alaluokkaa}}, {{PLURAL:$3|1 tiedosto|$3 tiedostoa}})",
-       "search-redirect": "(ohjaus $1)",
+       "search-redirect": "(ohjaus sivulta $1)",
        "search-section": "(osio $1)",
        "search-category": "(luokka $1)",
        "search-file-match": "(vastaa tiedoston sisältöä)",
        "right-changetags": "Lisätä ja poistaa satunnaisia [[Special:Tags|merkkauksia]] yksittäisissä sivuversioissa tai lokimerkinnöissä",
        "right-deletechangetags": "Poistaa [[Special:Tags|merkkauksia]] tietokannasta",
        "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-page-interaction": "Käsitellä sivuja",
+       "grant-group-file-interaction": "Käsitellä mediatiedostoja",
+       "grant-group-watchlist-interaction": "Käsitellä tarkkailulistaasi",
        "grant-group-email": "Lähettää sähköpostia",
        "grant-group-high-volume": "Suorittaa suuri määrä toimintoja",
        "grant-group-customization": "Mukauttaminen ja asetukset",
        "grant-group-administration": "Suorittaa ylläpitoon liittyviä toimintoja",
+       "grant-group-private-information": "Päästä näkemään yksityiset tiedot, jotka koskevat sinua",
        "grant-group-other": "Sekalainen toiminta",
        "grant-blockusers": "Estää käyttäjiä muokkaamasta ja poistaa estoja",
        "grant-createaccount": "Luoda käyttäjätunnuksia",
        "grant-editinterface": "Muokata järjestelmäviesti-nimiavaruutta ja käyttäjien CSS/JavaScript-sivuja",
        "grant-editmycssjs": "Muokata käyttäjän omia CSS/JavaScript-sivuja",
        "grant-editmyoptions": "Muokata käyttäjän omia asetuksia",
-       "grant-editmywatchlist": "Muokata omaa tarkkailulistaa",
+       "grant-editmywatchlist": "Muokata tarkkailulistaasi",
        "grant-editpage": "Muokata olemassa olevia sivuja",
        "grant-editprotected": "Muokata suojattuja sivuja",
        "grant-highvolume": "Suorittaa paljon muokkauksia",
        "grant-oversight": "Piilottaa käyttäjiä ja häivyttää yksittäisiä versioita",
        "grant-patrol": "Partioida sivuihin tehtyjä muutoksia",
+       "grant-privateinfo": "Päästä näkemään yksityiset tiedot",
        "grant-protect": "Suojata sivuja tai poistaa suojauksia",
-       "grant-rollback": "Peräyttää sivuun tehdyt muutokset",
+       "grant-rollback": "Palauttaa sivuun tehtyjä muutoksia",
        "grant-sendemail": "Lähettää sähköpostia toisille käyttäjille",
        "grant-uploadeditmovefile": "Tallentaa, korvata ja siirtää tiedostoja",
        "grant-uploadfile": "Tallentaa uusia tiedostoja",
        "grant-basic": "Perustason oikeudet",
        "grant-viewdeleted": "Nähdä poistettuja sivuja ja tiedostoja",
        "grant-viewmywatchlist": "Nähdä oma tarkkailulista",
+       "grant-viewrestrictedlogs": "Nähdä rajoitettuja lokimerkintöjä",
        "newuserlogpage": "Uudet käyttäjät",
        "newuserlogpagetext": "Tämä on loki luoduista käyttäjätunnuksista.",
        "rightslog": "Käyttöoikeusloki",
        "action-applychangetags": "käyttää merkkauksia muutostesi yhteydessä",
        "action-changetags": "lisätä ja poistaa satunnaisia merkkauksia yksittäisissä sivuversioissa ja lokimerkinnöissä",
        "action-deletechangetags": "poistaa merkkauksia tietokannasta",
+       "action-purge": "päivittää tämän sivun välimuistia",
        "nchanges": "$1 {{PLURAL:$1|muutos|muutosta}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|viimeisen käynnin jälkeen}}",
        "enhancedrc-history": "historia",
        "file-thumbnail-no": "Tiedostonimi alkaa merkkijonolla <strong>$1</strong>. Tiedosto näyttäisi olevan pienennetty kuva.\nJos sinulla on tämän kuvan alkuperäinen versio, tallenna se. Muussa tapauksessa nimeä tiedosto uudelleen.",
        "fileexists-forbidden": "Samanniminen tiedosto on jo olemassa, eikä sen tilalle voi tallentaa uutta. \nJos kuitenkin haluat tallentaa tiedostosi, palaa takaisin ja käytä jotain toista nimeä. \n[[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Samanniminen tiedosto on jo olemassa jaetussa mediavarastossa. Tallenna tiedosto jollakin toisella nimellä. [[File:$1|thumb|center|$1]]",
+       "fileexists-no-change": "Tallennettava tiedosto on tarkka kaksoiskappale tiedoston <strong>[[:$1]]</strong> nykyisestä versiosta.",
+       "fileexists-duplicate-version": "Tallennettava tiedosto on tarkka kaksoiskappale tiedoston <strong>[[:$1]]</strong> {{PLURAL:$2|vanhasta versiosta|vanhoista versioista}}.",
        "file-exists-duplicate": "Tämä tiedosto on kaksoiskappale {{PLURAL:$1|seuraavasta tiedostosta|seuraavista tiedostoista}}:",
        "file-deleted-duplicate": "Tiedosto, joka on identtinen tämän tiedoston kanssa ([[:$1]]) on aiemmin poistettu. Katso kyseisen tiedoston poistoloki ennen kuin jatkat uudelleentallentamista.",
        "file-deleted-duplicate-notitle": "Tämän tiedoston kanssa samanlainen tiedosto on aikaisemmin poistettu ja tiedoston nimi on häivytetty.\nSinun on syytä pyytää jotakuta häivytettyjen tietojen näkemiseen oikeutettua käyttäjää katsomaan tiedoston tiedot asian arvioimiseksi ennen kuin jatkat tiedoston lataamista tietokantaan.",
        "upload-foreign-cant-upload": "Tätä wikiä ei ole konfiguroitu tallentamaan tiedostoja pyydettyyn ulkoiseen tiedostovarastoon.",
        "upload-dialog-title": "Tiedoston tallennus",
        "upload-dialog-button-cancel": "Peru",
+       "upload-dialog-button-back": "Takaisin",
        "upload-dialog-button-done": "Valmis",
        "upload-dialog-button-save": "Tallenna",
        "upload-dialog-button-upload": "Tallenna",
        "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.",
+       "apisandbox-continue": "Jatka",
+       "apisandbox-continue-clear": "Tyhjennä",
        "booksources": "Kirjalähteet",
        "booksources-search-legend": "Etsi kirjalähteitä",
        "booksources-isbn": "ISBN",
        "activeusers": "Aktiivisten käyttäjien lista",
        "activeusers-intro": "Tämä on luettelo käyttäjistä, jotka ovat tehneet jotain viimeisen $1 {{PLURAL:$1|päivän}} sisällä.",
        "activeusers-count": "$1 {{PLURAL:$1|toiminto|toimintoa}} viimeisen {{PLURAL:$3|päivän|$3 päivän}} aikana",
-       "activeusers-from": "Näytä käyttäjät alkaen",
-       "activeusers-hidebots": "Piilota botit",
-       "activeusers-hidesysops": "Piilota ylläpitäjät",
+       "activeusers-from": "Näytä käyttäjät alkaen kohdasta:",
+       "activeusers-groups": "Näytä käyttäjät, jotka kuuluvat ryhmiin:",
        "activeusers-noresult": "Käyttäjiä ei löytynyt.",
        "activeusers-submit": "Hae aktiiviset käyttäjät",
        "listgrouprights": "Käyttäjäryhmien oikeudet",
        "watchnologin": "Et ole kirjautunut sisään",
        "addwatch": "Lisää tarkkailulistalle",
        "addedwatchtext": "\"[[:$1]]\" ja sen keskustelusivu on lisätty [[Special:Watchlist|tarkkailulistallesi]].",
+       "addedwatchtext-talk": "\"[[:$1]]\" ja siihen liittyvä sivu on lisätty [[Special:Watchlist|tarkkailulistallesi]].",
        "addedwatchtext-short": "Sivu ”$1” on lisätty tarkkailulistallesi.",
        "removewatch": "Poista tarkkailulistalta",
        "removedwatchtext": "\"[[:$1]]\" ja sen keskustelusivu on poistettu [[Special:Watchlist|tarkkailulistaltasi]].",
+       "removedwatchtext-talk": "\"[[:$1]]\" ja siihen liittyvä sivu on poistettu [[Special:Watchlist|tarkkailulistaltasi]].",
        "removedwatchtext-short": "Sivu ”$1” on poistettu tarkkailulistaltasi.",
        "watch": "Tarkkaile",
        "watchthispage": "Tarkkaile tätä sivua",
        "rollbacklinkcount-morethan": "palauta yli $1 {{PLURAL:$1|muutos|muutosta}}",
        "rollbackfailed": "Palautus epäonnistui",
        "rollback-missingparam": "Tarvittavat parametrit puuttuvat pyynnöstä.",
+       "rollback-missingrevision": "Ei voitu ladata sivuversiota koskevaa tietoa.",
        "cantrollback": "Aiempaan versioon ei voi palauttaa, koska viimeisin kirjoittaja on sivun ainoa tekijä.",
        "alreadyrolled": "Käyttäjän [[User:$2|$2]] ([[User talk:$2|keskustelu]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) tekemiä muutoksia sivuun [[:$1]] ei voida kumota, koska joku toinen käyttäjä on joko muuttanut sivua tai palauttanut muokkauksen.\n\nViimeisimmän muokkauksen on tehnyt käyttäjä [[User:$3|$3]] ([[User talk:$3|keskustelu]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Muokkauksen yhteenveto oli: <em>$1</em>.",
        "modifiedarticleprotection": "muutti sivun [[$1]] suojausasetuksia",
        "unprotectedarticle": "poisti suojauksen sivulta [[$1]]",
        "movedarticleprotection": "siirsi suojausasetukset sivulta [[$2]] sivulle [[$1]]",
+       "protectedarticle-comment": "{{GENDER:$2|Suojasi}} sivun \"[[$1]]\"",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Muutti suojaustasoa}} sivulla \"[[$1]]\"",
+       "unprotectedarticle-comment": "{{GENDER:$2|Otti pois suojauksen}} sivulta \"[[$1]]\"",
        "protect-title": "Muuta suojausta sivulla ”$1”",
        "protect-title-notallowed": "Katsele kohteen $1 suojauksen tasoa",
        "prot_1movedto2": "siirsi sivun [[$1]] uudelle nimelle [[$2]]",
        "undeletedrevisions": "{{PLURAL:$1|Yksi versio|$1 versiota}} palautettiin",
        "undeletedrevisions-files": "{{PLURAL:$1|Yksi versio|$1 versiota}} ja {{PLURAL:$2|yksi tiedosto|$2 tiedostoa}} palautettiin",
        "undeletedfiles": "{{PLURAL:$1|1 tiedosto|$1 tiedostoa}} palautettiin",
-       "cannotundelete": "Palauttaminen epäonnistui:\n$1",
+       "cannotundelete": "Palauttaminen epäonnistui osittain tai kokonaan:\n$1",
        "undeletedpage": "'''$1 on palautettu.'''\n\n[[Special:Log/delete|Poistolokista]] löydät listan viimeisimmistä poistoista ja palautuksista.",
        "undelete-header": "[[Special:Log/delete|Poistolokissa]] on lista viimeisimmistä poistoista.",
        "undelete-search-title": "Etsi poistettuja sivuja",
        "sp-contributions-newbies-sub": "Uusien käyttäjien muokkaukset",
        "sp-contributions-newbies-title": "Uusien käyttäjien muokkaukset",
        "sp-contributions-blocklog": "estoloki",
-       "sp-contributions-suppresslog": "häivytetyt käyttäjän muokkaukset",
-       "sp-contributions-deleted": "poistetut muokkaukset",
+       "sp-contributions-suppresslog": "häivytetyt {{GENDER:$1|käyttäjän}} muokkaukset",
+       "sp-contributions-deleted": "poistetut {{GENDER:$1|käyttäjän}} muokkaukset",
        "sp-contributions-uploads": "tallennukset",
        "sp-contributions-logs": "lokit",
        "sp-contributions-talk": "keskustelu",
        "movelogpagetext": "Tämä on luettelo kaikista sivujen siirroista.",
        "movesubpage": "{{PLURAL:$1|Alasivu|Alasivut}}",
        "movesubpagetext": "Tällä sivulla on $1 {{PLURAL:$1|alasivu|alasivua}}, jotka näkyvät alla.",
+       "movesubpagetalktext": "Sivuun liittyvällä keskustelusivulla on $1 {{PLURAL:$1|alasivu|alasivua}}, jotka näytetään alla.",
        "movenosubpage": "Tällä sivulla ei ole alasivuja.",
        "movereason": "Syy:",
        "revertmove": "kumoa siirto",
        "pageinfo-article-id": "Sivun tunnistenumero",
        "pageinfo-language": "Sivun sisällön kieli",
        "pageinfo-content-model": "Sivun sisältömalli",
+       "pageinfo-content-model-change": "muuta",
        "pageinfo-robot-policy": "Hakukonemerkinnät",
        "pageinfo-robot-index": "Indeksoitava",
        "pageinfo-robot-noindex": "Ei indeksoitava",
        "pageinfo-category-pages": "Sivujen määrä",
        "pageinfo-category-subcats": "Alaluokkien määrä",
        "pageinfo-category-files": "Tiedostojen määrä",
+       "pageinfo-user-id": "Käyttäjän tunnistenumero",
        "markaspatrolleddiff": "Merkitse tarkastetuksi",
        "markaspatrolledtext": "Merkitse muutos tarkastetuksi",
        "markaspatrolledtext-file": "Merkitse tämä tiedoston versio tarkastetuksi",
        "patrol-log-header": "Tämä on loki tarkastetuista muutoksista.",
        "log-show-hide-patrol": "$1 muutostentarkastusloki",
        "log-show-hide-tag": "$1 merkkausloki",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Merkitäänkö versio $3 kohdesivusta $2 partioiduksi?",
        "deletedrevision": "Poistettiin vanha versio $1",
        "filedeleteerror-short": "Tiedoston $1 poistaminen epäonnistui",
        "filedeleteerror-long": "Tiedoston poistaminen epäonnistui:\n\n$1",
        "newimages-showbots": "Näytä bottien tekemät tallennukset",
        "newimages-hidepatrolled": "Piilota tarkastetut tiedostotallennukset",
        "noimages": "Ei uusia tiedostoja.",
+       "gallery-slideshow-toggle": "Vaihda pienoiskuvaa",
        "ilsubmit": "Hae",
        "bydate": "päiväyksen mukaan",
        "sp-newimages-showfrom": "Näytä uudet tiedostot alkaen $1 kello $2",
        "version-libraries-license": "Lisenssi",
        "version-libraries-description": "Kuvaus",
        "version-libraries-authors": "Tekijät",
-       "redirect": "Ohjaus tiedoston, käyttäjän, sivun, sivuversion tai lokin tunnistenumeron mukaan",
+       "redirect": "Ohjaus kohteen tunnistenumeron mukaan",
        "redirect-summary": "Tämä toimintosivu ohjaa tiedostoon (tiedostonimen mukaan), sivulle (version tunnistenumeron tai sivun tunnistenumeron mukaan), käyttäjäsivulle (käyttäjän tunnistenumeron mukaan) taikka lokimerkintään (lokin tunnistenumeron mukaan). Käytetään seuraavasti: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]],[[{{#Special:Redirect}}/user/101]] tai [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Siirry",
        "redirect-lookup": "Hae:",
        "redirect-value": "Arvo:",
        "redirect-user": "Käyttäjän tunnistenumero",
        "redirect-page": "Sivun tunnistenumero",
-       "redirect-revision": "Sivun versio",
+       "redirect-revision": "Sivun versionumero",
        "redirect-file": "Tiedostonimi",
        "redirect-logid": "Lokin tunnistenumero",
        "redirect-not-exists": "Arvoa ei löytynyt",
        "tag-filter": "[[Special:Tags|Merkkausten]] suodatin:",
        "tag-filter-submit": "Suodata",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Merkkaus|Merkkaukset}}]]: $2)",
+       "tag-mw-contentmodelchange": "sisältömallin muutos",
+       "tag-mw-contentmodelchange-description": "Muokkaukset, jotka [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel muuttavat sivun sisältömallia]",
        "tags-title": "Merkkaukset",
        "tags-intro": "Tämä sivu luetteloi ne merkkaukset (''engl.'' tags), joilla ohjelmisto voi merkitä muokkauksia, ja mitä ne tarkoittavat.",
        "tags-tag": "Merkkauksen nimi",
        "htmlform-cloner-create": "Lisää enemmän",
        "htmlform-cloner-delete": "Poista",
        "htmlform-cloner-required": "Vähintään yksi arvo on pakollinen.",
+       "htmlform-date-placeholder": "VVVV-KK-PP",
+       "htmlform-time-placeholder": "TT:MM:SS",
+       "htmlform-datetime-placeholder": "VVVV-KK-PP TT:MM:SS",
+       "htmlform-date-invalid": "Annettu arvo ei ole tunnistettava päivämäärä. Kokeile muotoa VVVV-KK-PP.",
+       "htmlform-time-invalid": "Annettu arvo ei ole tunnistettava aika. Kokeile muotoa TT:MM:SS.",
+       "htmlform-datetime-invalid": "Annettu arvo ei ole tunnistettava päivämäärä ja aika. Kokeile muotoa VVVV-KK-PP TT:MM:SS.",
+       "htmlform-date-toolow": "Annettu arvo on ennen aikaisinta sallittua päivämäärää $1.",
+       "htmlform-date-toohigh": "Annettu arvo on viimeisen sallitun päivämäärän $1 jälkeen.",
+       "htmlform-time-toolow": "Annettu arvo on ennen aikaisinta sallittua aikaa $1.",
+       "htmlform-time-toohigh": "Annettu arvo on viimeisen sallitun ajan $1 jälkeen.",
+       "htmlform-datetime-toolow": "Annettu arvo on ennen aikaisinta sallittua päivämäärää ja aikaa $1.",
+       "htmlform-datetime-toohigh": "Annettu arvo on viimeisen sallitun päivämäärän ja ajan $1 jälkeen.",
        "htmlform-title-badnamespace": "Sivu [[:$1]] ei ole nimiavaruudessa ”{{ns:$2}}”.",
        "htmlform-title-not-creatable": "”$1” ei kelpaa sivun nimeksi.",
        "htmlform-title-not-exists": "Sivua $1 ei ole olemassa.",
        "feedback-external-bug-report-button": "Lähetä tekninen tehtävä",
        "feedback-dialog-title": "Lähetä palautetta",
        "feedback-dialog-intro": "Voit käyttää tätä helppoa lomaketta palautteesi lähettämiseen. Kommenttisi lisätään sivulle \"$1\" käyttäjätunnuksesi kera.",
-       "feedback-error-title": "Virhe",
        "feedback-error1": "Virhe: Ohjelmointirajapinnan vastausta ei tunnistettu",
        "feedback-error2": "Virhe: Muokkaus epäonnistui",
        "feedback-error3": "Virhe: Ohjelmointirajapinta ei vastaa",
        "feedback-thanks": "Kiitos. Palautteesi on jätetty sivulle [$2 $1].",
        "feedback-thanks-title": "Kiitos!",
        "feedback-useragent": "User agent:",
-       "searchsuggest-search": "Hae",
+       "searchsuggest-search": "Hae {{GRAMMAR:elative|{{SITENAME}}}}",
        "searchsuggest-containing": "sisältää...",
        "api-error-autoblocked": "Sinun IP-osoitteesi on estetty automaattisesti, koska sitä on käyttänyt estetty käyttäjätunnus.",
        "api-error-badaccess-groups": "Sinulla ei ole oikeutta tallentaa tiedostoja tähän wikiin.",
        "authmanager-authn-autocreate-failed": "Paikallisen tunnuksen automaattinen luonti epäonnistui: $1",
        "authmanager-change-not-supported": "Annettuja kirjautumistietoja ei voida muuttaa, koska mikään ei käyttäisi niitä.",
        "authmanager-create-disabled": "Tunnusten luonti ei ole käytössä.",
-       "authmanager-create-from-login": "Luodaksesi tunnuksen täytä alla olevat kentät.",
+       "authmanager-create-from-login": "Luodaksesi tunnuksen kirjoita tiedot kenttiin.",
        "authmanager-create-not-in-progress": "Tunnuksen luonti ei ole käynnissä tai istunnon tiedot ovat hävinneet. Ole hyvä ja aloita uudelleen alusta.",
        "authmanager-create-no-primary": "Annettuja kirjautumistietoja ei voitu käyttää tunnuksen luontiin.",
        "authmanager-link-no-primary": "Annettuja kirjautumistietoja ei voitu käyttää tunnuksen linkittämiseen.",
        "authprovider-resetpass-skip-help": "Ohita salasanan palautus.",
        "authform-nosession-login": "Varmennus onnistui, mutta selaimesi ei pysty \"muistamaan\" sisäänkirjautumista.\n\n$1",
        "authform-nosession-signup": "Tunnus luotiin, mutta selaimesi ei pysty \"muistamaan\" sisäänkirjautumista.\n\n$1",
+       "authform-newtoken": "Puuttuva \"token\". $1",
+       "authform-notoken": "Puuttuva \"token\"",
+       "authform-wrongtoken": "Väärä \"token\"",
        "specialpage-securitylevel-not-allowed-title": "Ei sallittu",
        "specialpage-securitylevel-not-allowed": "Valitettavasti sinulla ei ole oikeutta muokata tätä sivua, koska henkilöllisyyttäsi ei voitu varmentaa.",
        "authpage-cannot-login": "Kirjautumista ei voitu aloittaa.",
        "linkaccounts-submit": "Linkitä tunnuksia",
        "unlinkaccounts": "Poista tunnusten linkityksiä",
        "unlinkaccounts-success": "Tunnuksen linkitys poistettiin.",
-       "authenticationdatachange-ignored": "Varmennustietojen muutosta ei käsitelty. Ehkä palveluntarjoajaa ei määritelty?"
+       "authenticationdatachange-ignored": "Varmennustietojen muutosta ei käsitelty. Ehkä palveluntarjoajaa ei määritelty?",
+       "restrictionsfield-badip": "Virheellinen IP-osoite tai alue: $1",
+       "restrictionsfield-label": "Sallitut IP-alueet:",
+       "edit-error-short": "$1",
+       "edit-error-long": "Virheet:\n\n$1"
 }
index edf9094..19113d8 100644 (file)
@@ -11,7 +11,8 @@
                        "Urhixidur",
                        "לערי ריינהארט",
                        "아라",
-                       "Macofe"
+                       "Macofe",
+                       "Irus"
                ]
        },
        "tog-underline": "Undirstrika leinki:",
        "yourpasswordagain": "Skriva loyniorð umaftur:",
        "createacct-yourpasswordagain": "Váttað loyniorðið",
        "createacct-yourpasswordagain-ph": "Skrivað loyniorðið enn einaferð",
-       "remembermypassword": "Minst til logg inn hjá mær á hesum kaganum (í mesta lagi í $1 {{PLURAL:$1|dag|dagar}})",
        "userlogin-remembermypassword": "Lat meg vera innritaðan",
        "userlogin-signwithsecure": "Nýt trygt samband",
        "yourdomainname": "Títt domene:",
        "passwordreset-emailtext-user": "Brúkari $1 á {{SITENAME}} hevur biðið um eina nullstillan av tínum loyniorði til {{SITENAME}} \n($4). Fylgjandi brúkara {{PLURAL:$3|konta er|kontur eru}} settar í samband við hesa t-post adressuna:\n\n$2\n\n{{PLURAL:$3|Hetta fyribils loyniorðið|Hesi fyribils loyniorðini}} ganga út um {{PLURAL:$5|ein dag|$5 dagar}}.\nTú eigur at rita inn og velja eitt nýtt loyniorð nú. Um onkur annar hevur gjørt hesa umbøn, ella um tú ert komin í tankar um títt uppruna loyniorð, og tú ikki longur ynskir at broyta tað, so kanst tú síggja burtur frá hesum boðum og halda fram at brúka títt gamla loyniorð.",
        "passwordreset-emailelement": "Brúkaranavn: \n$1\n\nFyribils loyniorð: \n$2",
        "passwordreset-emailsentemail": "Ein teldupostur har tú kanst nullstillað loyniorðið er blivin sendur.",
-       "passwordreset-emailsent-capture": "Ein teldupostur, har ið tú kanst nullstilla loyniorðið, er blivin sendur, sum víst niðanfyri.",
-       "passwordreset-emailerror-capture": "Ein teldupostur við nullstillaðum loyniorði var gjørdur, sum víst niðanfyri, men tað miseydnaðist at senda til {{GENDER:$2|brúkaran}}: $1",
        "changeemail": "Broyt teldupost adressu",
        "changeemail-header": "Broyt t-post adressuna hjá kontuni",
        "changeemail-no-info": "Tú mást vera innritað/ur fyri at fáa beinleiðis atgongd til hesa síðu.",
        "undo-norev": "Rættingin kann ikki takast burtur, tí at hon er ikki til ella var strikað.",
        "undo-summary": "Tak burtur versjón $1 hjá [[Special:Contributions/$2|$2]] ([[User talk:$2|kjak]])",
        "undo-summary-username-hidden": "Angra versjón $1 sum ein fjaldur brúkari hevur gjørt",
-       "cantcreateaccounttitle": "Tað ber ikki til at upprætta konto",
        "cantcreateaccount-text": "Upprættan frá hesi IP adressuni ('''$1''') er blivin sperrað av [[User:$3|$3]]. Orsøkin til sperringina sigst vera ''$2''\n\n$3 sigur orsøkina vera ''$2''",
        "cantcreateaccount-range-text": "IP adressur í intervallinum <strong>$1</strong>, sum fevnir um tína IP adressu (<strong>$4</strong>), eru sperraðar fyri upprættan av nýggjari konto av [[User:$3|$3]].\n\n$3 segði orsøkina vera <em>$2</em>",
        "viewpagelogs": "Sí logg fyri hesa grein",
        "activeusers-intro": "Hetta er ein listi yvir brúkarar, ið høvdu okkurt slag av aktiviteti tann seinasta/teir seinastu $1 {{PLURAL:$1|dagin|dagarnar}}.",
        "activeusers-count": "$1 {{PLURAL:$1|handling|handlingar}} tann seinasta/teir seinastu {{PLURAL:$3|dagin|$3 dagarnar}}",
        "activeusers-from": "Vís brúkarar, ið byrja við:",
-       "activeusers-hidebots": "Fjal bottar",
-       "activeusers-hidesysops": "Fjal umboðsstjórar (administratorar)",
        "activeusers-noresult": "Ongir brúkarar funnir.",
        "listgrouprights": "Brúkara bólka rættindi",
        "listgrouprights-summary": "Henda síða vísir ein lista av brúkarabólkum, sum eru útgreinaðir á hesi wiki og rættindini hjá teimum einstøku bólkunum.\nMøguliga er [[{{MediaWiki:Listgrouprights-helppage}}|meira kunning]] um einstøk rættindi.",
        "contributions": "{{GENDER:$1|Brúkaraíkøst}}",
        "contributions-title": "Brúkaraíkøst fyri $1",
        "mycontris": "Íkøst",
+       "anoncontribs": "Íkøst",
        "contribsub2": "Fyri {{GENDER:$3|$1}} ($2)",
        "nocontribs": "Ongar broytingar vóru funnar, sum samsvaraðu hesar treytirnar.",
        "uctop": "(verandi)",
        "import-logentry-upload-detail": "$1 {{PLURAL:$1|versjón|versjónir}}",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|versjón|versjónir}} frá $2",
        "javascripttest": "Royndarkoyring av JavaScript",
-       "tooltip-pt-userpage": "Tín brúkarasíða",
+       "tooltip-pt-userpage": "{{GENDER:|Tín}} brúkarasíða",
        "tooltip-pt-anonuserpage": "Brúkarasíðan fyri IP adressuna, sum tú rættar frá",
        "tooltip-pt-mytalk": "Tín kjaksíða",
        "tooltip-pt-anontalk": "Kjak um rættingar frá hesi IP adressuni",
        "tooltip-pt-logout": "Rita út",
        "tooltip-pt-createaccount": "Vit mæla tær til at upprætta eina konto, tað er tó ikki eitt krav.",
        "tooltip-ca-talk": "Kjak um innihaldssíðuna",
-       "tooltip-ca-edit": "Tú kanst broyta hesa síðuna. Vinarliga nýt forskoðanarknøttin áðrenn tú goymir.",
+       "tooltip-ca-edit": "Rætta hesa síðuna",
        "tooltip-ca-addsection": "Byrja eitt nýtt brot",
        "tooltip-ca-viewsource": "Henda síðan er friðað. Tú kanst síggja keldukotuna.",
        "tooltip-ca-history": "Fyrrverandi útgávur av hesi síðu.",
        "logentry-upload-upload": "$1 {{GENDER:$2|legði út}} $3",
        "rightsnone": "(ongin)",
        "revdelete-summary": "yvirlit yvir broytingar",
-       "searchsuggest-search": "Leita",
+       "searchsuggest-search": "Leita í {{SITENAME}}",
        "api-error-empty-file": "Fílan sum tú sendi inn var tóm.",
        "api-error-file-too-large": "Fílan sum tú sendi inn var óv stór.",
        "api-error-http": "Internur feilur: Kann ikki fáa samband við servaran.",
        "expand_templates_preview": "Forskoðan",
        "mw-widgets-dateinput-placeholder-day": "ÁÁÁÁ-MM-DD",
        "mw-widgets-dateinput-placeholder-month": "ÁÁÁÁ-MM",
-       "mw-widgets-titleinput-description-new-page": "síðan er ikki til enn",
-       "api-error-blacklisted": "Vinarliga vel ein annarleiðis tittul, sum lýsir fíluna betri."
+       "mw-widgets-titleinput-description-new-page": "síðan er ikki til enn"
 }
index cb79079..7df0354 100644 (file)
        "loginerror": "Erreur de connexion",
        "createacct-error": "Erreur lors de la création du compte",
        "createaccounterror": "Impossible de créer le compte : $1",
-       "nocookiesnew": "Le compte utilisateur a été créé, mais vous n’êtes pas connecté{{GENDER:||e|(e)}}.\n{{SITENAME}} utilise des cookies pour conserver la connexion mais vous les avez désactivés.\nVeuillez les activer et vous reconnecter avec le même nom et le même mot de passe.",
-       "nocookieslogin": "{{SITENAME}} utilise des cookies pour conserver la connexion mais vous les avez désactivés.\nVeuillez les activer et vous reconnecter.",
-       "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.",
+       "nocookiesnew": "Le compte utilisateur a été créé, mais vous n’êtes pas connecté{{GENDER:||e|(e)}}.\n{{SITENAME}} utilise des témoins (''cookies'') pour conserver la connexion mais vous les avez désactivés.\nVeuillez les activer et vous reconnecter avec le même nom et le même mot de passe.",
+       "nocookieslogin": "{{SITENAME}} utilise des témoins (''cookies'') pour conserver la connexion mais vous les avez désactivés.\nVeuillez les activer et vous reconnecter.",
+       "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 témoins (''cookies''), rechargez la page et essayez à nouveau.",
        "createacct-loginerror": "Le compte a bien été créé mais vous ne pouvez pas vous connecter automatiquement. Veuillez vous [[Special:UserLogin|connecter manuellement]].",
        "noname": "Vous n’avez pas saisi un nom d’utilisateur valide.",
        "loginsuccesstitle": "Connecté",
        "botpasswords-label-delete": "Supprimer",
        "botpasswords-label-resetpassword": "Réinitialiser le mot de passe",
        "botpasswords-label-grants": "Droits applicables :",
-       "botpasswords-help-grants": "Chaque droit accordé donne accès à la liste des droits utilisateurs dont l’utilisateur dispose déjà. Voyez le [[Special:ListGrants|tableau des droits]] pour plus d’informations.",
+       "botpasswords-help-grants": "Les autorisations permettent d’accéder aux droits déjà accordés à votre compte utilisateur. Activer une autorisation ici ne fournit l’accès à aucun droit que votre compte utilisateur n’aurait pas par ailleurs. Voyez le [[Special:ListGrants|tableau des autorisations]] pour plus d’information.",
        "botpasswords-label-grants-column": "Accordé",
        "botpasswords-bad-appid": "Le nom de robot « $1 » n’est pas valide.",
        "botpasswords-insert-failed": "Échec de l’ajout du nom de robot « $1 ». A-t-il déjà été ajouté ?",
        "passwordreset-capture-help": "Si vous cochez cette case, le courriel (avec le mot de passe temporaire) vous sera affiché en même temps qu’il sera envoyé à l’utilisateur.",
        "passwordreset-email": "Adresse de courriel :",
        "passwordreset-emailtitle": "Détails du compte sur {{SITENAME}}",
-       "passwordreset-emailtext-ip": "Quelqu’un (probablement vous, depuis l’adresse IP $1) a demandé un réinitialisation de votre mot de passe pour {{SITENAME}} ($4). {{PLURAL:$3|Le compte utilisateur suivant est associé|Les comptes utilisateurs suivants sont associés}} à cette adresse de courriel :\n\n$2\n\n{{PLURAL:$3|Ce mot de passe temporaire expirera|Ces mots de passe temporaires expireront}} dans {{PLURAL:$5|un jour|$5 jours}}. \nVous devez maintenant vous connecter et choisir un nouveau mot de passe. Si cette demande ne provient pas de vous, ou que vous avez retrouvé votre mot de passe initial, et ne souhaitez plus le modifier, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.",
+       "passwordreset-emailtext-ip": "Quelqu’un (probablement vous, depuis l’adresse IP $1) a demandé une réinitialisation de votre mot de passe pour {{SITENAME}} ($4). {{PLURAL:$3|Le compte utilisateur suivant est associé|Les comptes utilisateurs suivants sont associés}} à cette adresse de courriel :\n\n$2\n\n{{PLURAL:$3|Ce mot de passe temporaire expirera|Ces mots de passe temporaires expireront}} dans {{PLURAL:$5|un jour|$5 jours}}. \nVous devez maintenant vous connecter et choisir un nouveau mot de passe. Si cette demande ne provient pas de vous, ou si vous avez retrouvé votre mot de passe initial, et ne souhaitez plus le modifier, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.",
        "passwordreset-emailtext-user": "L’utilisateur $1 sur {{SITENAME}} a demandé une réinitialisation de votre mot de passe pour {{SITENAME}} ($4). {{PLURAL:$3|Le compte utilisateur suivant est associé|Les comptes utilisateurs suivants sont associés}} à cette adresse de courriel :\n\n$2\n\n{{PLURAL:$3|Ce mot de passe temporaire expirera|Ces mots de passe temporaires expireront}} dans {{PLURAL:$5|un jour|$5 jours}}. \nVous devez maintenant vous connecter et choisir un nouveau mot de passe. Si cette demande ne provient pas de vous, ou si vous avez retrouvé votre mot de passe initial, et ne souhaitez plus le modifier, vous pouvez ignorer ce message et continuer à utiliser votre ancien mot de passe.",
        "passwordreset-emailelement": "Nom d’utilisateur : \n$1\n\nMot de passe temporaire : \n$2",
        "passwordreset-emailsentemail": "Si cette adresse de courriel est associée à votre compte, alors un courriel de réinitialisation de mot de passe sera envoyé.",
        "passwordreset-nocaller": "Un appelant doit être fourni",
        "passwordreset-nosuchcaller": "L’appelant n’existe pas : $1",
        "passwordreset-ignored": "La réinitialisation du mot de passe n’a pas été gérée. Peut-être qu’aucun fournisseur n’a été configuré ?",
-       "passwordreset-invalideamil": "Adresse de messagerie non valide",
+       "passwordreset-invalidemail": "Adresse de messagerie non valide",
        "passwordreset-nodata": "Aucun nom d’utilisateur ou adresse de messagerie n’a été fourni",
        "changeemail": "Changer ou supprimer l’adresse de courriel",
        "changeemail-header": "Complétez ce formulaire pour modifier votre adresse de courriel. Si vous voulez supprimer l’association d’une adresse de courriel avec votre compte, laissez la nouvelle adresse de courriel vide lors de la soumission du formulaire.",
        "previewnote": "<strong>Rappelez-vous que ce n’est qu’une prévisualisation.</strong>\nVos modifications n’ont pas encore été enregistrées !",
        "continue-editing": "Aller à la zone de modification",
        "previewconflict": "Cette prévisualisation montre le texte de la boîte supérieure de modification tel qu’il apparaîtra si vous choisissez de le publier.",
-       "session_fail_preview": "Désolé, nous ne pouvons enregistrer votre modification à cause d’une perte d’informations concernant votre session.\n\nVous avez peut-être été déconnecté. <strong>Veuillez vérifier que vous êtes toujours connecté et réessayer.</strong>\nSi cela échoue de nouveau, essayez en vous [[Special:UserLogout|déconnectant]], puis en vous reconnectant, et vérifiez que votre navigateur accepte les cookies de ce site.",
-       "session_fail_preview_html": "Désolé, nous ne pouvons enregistrer votre modification à cause d’une perte d’informations concernant votre session.\n\n<em>Parce que {{SITENAME}} a activé le HTML brut, la prévisualisation est masquée afin de prévenir les attaques par JavaScript.</em>\n\n<strong>Si la tentative de modification est légitime, veuillez réessayer.</strong>\nSi cela échoue de nouveau, [[Special:UserLogout|déconnectez-vous]], puis reconnectez-vous, et vérifiez que votre navigateur accepte les cookies de ce site.",
+       "session_fail_preview": "Désolé, nous ne pouvons enregistrer votre modification à cause d’une perte d’informations concernant votre session.\n\nVous avez peut-être été déconnecté. <strong>Veuillez vérifier que vous êtes toujours connecté et réessayer.</strong>\nSi cela échoue de nouveau, essayez en vous [[Special:UserLogout|déconnectant]], puis en vous reconnectant, et vérifiez que votre navigateur accepte les témoins (''cookies'') de ce site.",
+       "session_fail_preview_html": "Désolé, nous ne pouvons enregistrer votre modification à cause d’une perte d’informations concernant votre session.\n\n<em>Parce que {{SITENAME}} a activé le HTML brut, la prévisualisation est masquée afin de prévenir les attaques par JavaScript.</em>\n\n<strong>Si la tentative de modification est légitime, veuillez réessayer.</strong>\nSi cela échoue de nouveau, [[Special:UserLogout|déconnectez-vous]], puis reconnectez-vous, et vérifiez que votre navigateur accepte les témoins (''cookies'') de ce site.",
        "token_suffix_mismatch": "<strong>Votre modification n’a pas été acceptée car votre navigateur a mal codé les caractères de ponctuation dans l’identifiant de modification.</strong>\nCe rejet est nécessaire pour empêcher la corruption du texte de la page.\nCe problème se produit parfois lorsque vous utilisez un serveur mandataire anonyme problématique basé sur le web.",
        "edit_form_incomplete": "<strong>Certaines parties du formulaire de modification n’ont pas atteint le serveur, vérifiez que vos modifications sont intactes et essayez à nouveau.</strong>",
        "editing": "Modification de $1",
        "editingsection": "Modification de $1 (section)",
        "editingcomment": "Modification de $1 (nouvelle section)",
        "editconflict": "Conflit de modification : $1",
-       "explainconflict": "Cette page a été changée après que vous ayez commencé à la modifier.\nLa zone de modification supérieure contient le texte tel qu’il est actuellement enregistré dans la base de données.\nVos modifications apparaissent dans la zone de modification inférieure.\nVous allez devoir fusionner vos modifications dans le texte existant.\n<strong>Seul</strong> le texte de la zone supérieure sera sauvegardé si vous cliquez sur « {{int:savearticle}} ».",
+       "explainconflict": "Cette page a été changée après que vous avez commencé à la modifier.\nLa zone de modification supérieure contient le texte tel qu’il est actuellement enregistré dans la base de données.\nVos modifications apparaissent dans la zone de modification inférieure.\nVous allez devoir fusionner vos modifications dans le texte existant.\n<strong>Seul</strong> le texte de la zone supérieure sera sauvegardé si vous cliquez sur « {{int:savearticle}} ».",
        "yourtext": "Votre texte",
        "storedversion": "La version enregistrée",
        "nonunicodebrowser": "<strong>Attention : votre navigateur ne prend pas en charge l’Unicode.</strong>\nUn palliatif est en place vous permettant de modifier les pages en toute sécurité, faisant apparaître les caractères non-ASCII sous forme hexadécimale dans la boîte de modification.",
        "revdelete-radio-same": "(ne pas changer)",
        "revdelete-radio-set": "Masqué",
        "revdelete-radio-unset": "Visible",
-       "revdelete-suppress": "Supprimer également les données des administrateurs",
+       "revdelete-suppress": "Masquer également les données pour les administrateurs",
        "revdelete-unsuppress": "Enlever les restrictions sur les versions restaurées",
        "revdelete-log": "Motif :",
        "revdelete-submit": "Appliquer {{PLURAL:$1|à la révision sélectionnée|aux révisions sélectionnées}}",
        "prefs-emailconfirm-label": "Confirmation du courriel :",
        "youremail": "Courriel :",
        "username": "{{GENDER:$1|Nom d'utilisateur|Nom d'utilisatrice}} :",
-       "prefs-memberingroups": "{{GENDER:$2|Membre}} {{PLURAL:$1|du groupe|des groupes}}:",
+       "prefs-memberingroups": "{{GENDER:$2|Membre}} {{PLURAL:$1|du groupe|des groupes}} :",
        "prefs-registration": "Date d'inscription :",
        "yourrealname": "Nom réel :",
        "yourlanguage": "Langue :",
        "grant-basic": "Droits de base",
        "grant-viewdeleted": "Afficher les fichiers et pages supprimés",
        "grant-viewmywatchlist": "Afficher votre liste de suivi",
+       "grant-viewrestrictedlogs": "Afficher les entrées de journal confidentielles",
        "newuserlogpage": "Journal des créations de comptes utilisateur",
        "newuserlogpagetext": "Cette page affiche l’historique des créations de comptes utilisateur.",
        "rightslog": "Journal des modifications de droits d’utilisateurs",
        "upload-dialog-disabled": "Les téléversements de fichier utilisant cette boîte de dialogue sont désactivés sur ce wiki.",
        "upload-dialog-title": "Téléverser un fichier",
        "upload-dialog-button-cancel": "Annuler",
+       "upload-dialog-button-back": "Retour",
        "upload-dialog-button-done": "Terminé",
        "upload-dialog-button-save": "Enregistrer",
        "upload-dialog-button-upload": "Téléverser",
        "apisandbox-results-fixtoken-fail": "Impossible de récupérer le jeton \"$1\"",
        "apisandbox-alert-page": "Les champs de cette page ne sont pas valides.",
        "apisandbox-alert-field": "La valeur de ce champ n'est pas valide.",
+       "apisandbox-continue": "Continuer",
+       "apisandbox-continue-clear": "Effacer",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries continuera] la dernière requête ; {{int:apisandbox-continue-clear}} effacera les paramètres relatifs à la continuation.",
+       "apisandbox-param-limit": "Saisir <kbd>max</kbd> pour utiliser la limite maximale.",
        "booksources": "Ouvrages de référence",
        "booksources-search-legend": "Rechercher parmi des ouvrages de référence",
        "booksources-isbn": "ISBN :",
        "booksources-search": "Rechercher",
        "booksources-text": "Voici une liste indicative de liens vers d’autres sites vendant des livres neufs et d’occasion et sur lesquels vous trouverez peut-être des informations sur les ouvrages que vous cherchez :",
        "booksources-invalid-isbn": "L’ISBN donné ne semble pas être correct ; vérifiez si vous avez fait une erreur en copiant la source originale.",
+       "magiclink-tracking-rfc": "Pages utilisant des liens magiques RFC",
+       "magiclink-tracking-rfc-desc": "Cette page utilise des liens magiques RFC. Voyez [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] sur la manière de migrer.",
+       "magiclink-tracking-pmid": "Pages utilisant des liens magiques PMID",
+       "magiclink-tracking-pmid-desc": "Cette page utilise des liens magiques PMID. Voyez [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] sur la manière de migrer.",
+       "magiclink-tracking-isbn": "Pages utilisant des liens magiques ISBN",
+       "magiclink-tracking-isbn-desc": "Cette page utilise des liens magiques ISBN. Voyez [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] sur la manière de migrer.",
        "specialloguserlabel": "Auteur :",
        "speciallogtitlelabel": "Cible (titre ou {{ns:user}}:nom d'utilisateur) :",
        "log": "Journaux d’opérations",
        "activeusers-intro": "Ceci est une liste des utilisateurs qui ont exercé une quelconque activité au cours {{PLURAL:$1|de la dernière journée|des $1 derniers jours}}.",
        "activeusers-count": "$1 {{PLURAL:$1|action|actions}} lors {{PLURAL:$3|du dernier jour|des $3 derniers jours}}",
        "activeusers-from": "Afficher les utilisateurs depuis :",
-       "activeusers-hidebots": "Masquer les robots",
-       "activeusers-hidesysops": "Masquer les administrateurs",
+       "activeusers-groups": "Afficher les utilisateurs appartenant aux groupes :",
        "activeusers-noresult": "Aucun utilisateur trouvé.",
        "activeusers-submit": "Afficher les utilisateurs actifs",
        "listgrouprights": "Droits des groupes d'utilisateurs",
-       "listgrouprights-summary": "Cette page contient une liste des groupes définis sur ce wiki ainsi que les droits d'accès qui leur sont associés.\nDes [[{{MediaWiki:Listgrouprights-helppage}}|informations additionnelles]] peuvent exister au sujet des droits individuels.",
+       "listgrouprights-summary": "Cette page contient une liste des groupes définis sur ce wiki ainsi que les droits d'accès qui leur sont associés.\nDes [[{{MediaWiki:Listgrouprights-helppage}}|renseignements complémentaires]] peuvent exister au sujet des droits individuels.",
        "listgrouprights-key": "Légende :\n*<span class=\"listgrouprights-granted\">Droit octroyé</span>\n*<span class=\"listgrouprights-revoked\">Droit révoqué</span>",
        "listgrouprights-group": "Groupe",
        "listgrouprights-rights": "Droits associés",
        "modifiedarticleprotection": "a modifié le niveau de protection de « [[$1]] »",
        "unprotectedarticle": "a supprimé la protection de « [[$1]] »",
        "movedarticleprotection": "a déplacé les paramètres de protection depuis « [[$2]] » vers « [[$1]] »",
+       "protectedarticle-comment": "{{GENDER:$2|A protégé}} « [[$1]] »",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|A changé le niveau de protection}} pour « [[$1]] »",
+       "unprotectedarticle-comment": "{{GENDER:$2|A supprimé la protection}} de « [[$1]] »",
        "protect-title": "Changer le niveau de protection pour « $1 »",
        "protect-title-notallowed": "Voir le niveau de protection de « $1 »",
        "prot_1movedto2": "[[$1]] renommé en [[$2]]",
        "movelogpagetext": "Voici la liste de toutes les pages renommées ou déplacées.",
        "movesubpage": "Sous-page{{PLURAL:$1||s}}",
        "movesubpagetext": "Cette page a $1 {{PLURAL:$1|sous-page affichée|sous-pages affichées}} ci-dessous.",
+       "movesubpagetalktext": "La page de discussion correspodnante a $1 {{PLURAL:$1|sous-page|sous-pages}} affichées ci-dessous.",
        "movenosubpage": "Cette page n'a aucune sous-page.",
        "movereason": "Motif :",
        "revertmove": "rétablir",
        "import-nonewrevisions": "Aucune révision importée (toutes étaient soit déjà présentes, soit ignorées du fait d’erreurs).",
        "xml-error-string": "$1 à la ligne $2, colonne $3 (octet $4) : $5",
        "import-upload": "Import de données XML",
-       "import-token-mismatch": "Perte des données de session.\n\nVous avez peut-être été déconnecté. <strong>Veuillez vérifier que vous êtes toujours connecté et réessayez</strong>.\nSi cela ne fonctionne toujours pas, essayez de [[Special:UserLogout|vous déconnecter]] et reconnectez-vous, et vérifiez que votre navigateur accepte les cookies de ce site.",
+       "import-token-mismatch": "Perte des données de session.\n\nVous avez peut-être été déconnecté. <strong>Veuillez vérifier que vous êtes toujours connecté et réessayez</strong>.\nSi cela ne fonctionne toujours pas, essayez de [[Special:UserLogout|vous déconnecter]] et de vous reconnecter, et vérifiez que votre navigateur accepte les témoins (''cookies'') de ce site.",
        "import-invalid-interwiki": "Impossible d'importer depuis le wiki spécifié.",
        "import-error-edit": "La page « $1 » n’a pas été importée parce que vous n’êtes pas autorisé à la modifier.",
        "import-error-create": "La page « $1 » n’a pas été importée parce que vous n’êtes pas autorisé à la créer.",
        "pageinfo-category-pages": "Nombre de pages",
        "pageinfo-category-subcats": "Nombre de sous-catégories",
        "pageinfo-category-files": "Nombre de fichiers",
+       "pageinfo-user-id": "ID de l’utilisateur",
        "markaspatrolleddiff": "Marquer comme relue",
        "markaspatrolledtext": "Marquer cette page comme relue",
        "markaspatrolledtext-file": "Marquer cette version de fichier comme relue",
        "patrol-log-header": "Voici l’historique des versions relues.",
        "log-show-hide-patrol": "$1 l’historique des relectures",
        "log-show-hide-tag": "$1 le journal des balises",
+       "confirm-markpatrolled-button": "Valider",
+       "confirm-markpatrolled-top": "Marquer la révision de $3 de $2 comme prise en compte ?",
        "deletedrevision": "Ancienne version $1 supprimée",
        "filedeleteerror-short": "Erreur lors de la suppression du fichier : $1",
        "filedeleteerror-long": "Des erreurs ont été rencontrées lors de la suppression du fichier :\n\n$1",
        "newimages-showbots": "Afficher les imports faits par des robots",
        "newimages-hidepatrolled": "Masquer les téléchargements patrouillés",
        "noimages": "Aucune image à afficher.",
+       "gallery-slideshow-toggle": "Basculer les vignettes",
        "ilsubmit": "Rechercher",
        "bydate": "par date",
        "sp-newimages-showfrom": "Afficher les nouveaux fichiers à partir du $1 à $2",
        "namespacesall": "Tous",
        "monthsall": "tous",
        "confirmemail": "Confirmer l’adresse de courriel",
-       "confirmemail_noemail": "Vous n’avez pas défini une adresse de courriel valide dans vos [[Special:Preferences|préférences]].",
+       "confirmemail_noemail": "Vous n’avez pas défini une adresse de courriel valide dans vos [[Special:Preferences|préférences utilisateur]].",
        "confirmemail_text": "Ce wiki nécessite la vérification de votre adresse de courriel avant de pouvoir utiliser toute fonction de messagerie.\nUtilisez le bouton ci-dessous pour envoyer un courriel de confirmation à votre adresse.\nLe courriel inclura un lien comportant un code à usage unique et limité dans le temps ;\nchargez ce lien dans votre navigateur pour confirmer que votre adresse de courriel est valide.",
        "confirmemail_pending": "Un code de confirmation vous a déjà été envoyé par courriel ;\nsi vous venez de créer votre compte, veuillez attendre quelques minutes que le courriel arrive avant de demander un nouveau code.",
        "confirmemail_send": "Envoyer un code de confirmation",
        "confirmemail_success": "Votre adresse de courriel a été confirmée.\nVous pouvez maintenant vous [[Special:UserLogin|{{MediaWiki:Loginreqlink}}]] et profiter du wiki.",
        "confirmemail_loggedin": "Votre adresse de courriel est maintenant confirmée.",
        "confirmemail_subject": "Confirmation d’adresse de courriel pour {{SITENAME}}",
-       "confirmemail_body": "Quelqu’un, probablement vous, à partir de l’adresse IP $1,\na enregistré un compte « $2 » avec cette adresse de courriel\nsur le site {{SITENAME}}.\n\nPour confirmer que ce compte vous appartient vraiment et afin\nd’activer les fonctions de messagerie sur {{SITENAME}},\nveuillez suivre ce lien dans votre navigateur :\n\n$3\n\nSi vous n’avez *pas* enregistré ce compte, n’ouvrez pas ce lien ;\nvous pouvez suivre l’autre lien ci-dessous pour annuler la\nconfirmation de votre adresse courriel :\n\n$5\n\nCe code de confirmation expirera le $4.",
+       "confirmemail_body": "Quelqu’un, probablement vous, à partir de l’adresse IP $1,\na créé un compte « $2 » avec cette adresse de courriel sur le site {{SITENAME}}.\n\nPour confirmer que ce compte vous appartient vraiment et afin\nd’activer les fonctions de messagerie sur {{SITENAME}},\nveuillez suivre ce lien dans votre navigateur :\n\n$3\n\nSi vous n’avez *pas* créé ce compte, suivez le lien ci-dessous \npour annuler la confirmation de votre adresse courriel :\n\n$5\n\nCe code de confirmation expirera le $4.",
        "confirmemail_body_changed": "Quelqu’un, probablement vous, à partir de l’adresse IP $1,\na modifié l’adresse de courriel associée au compte « $2 » de {{SITENAME}}\nen cette adresse.\n\nPour confirmer que ce compte vous appartient vraiment et afin\nde réactiver les fonctions de messagerie sur {{SITENAME}},\nveuillez suivre ce lien dans votre navigateur :\n\n$3\n\nSi ce compte ne vous appartient *pas*, n’ouvrez pas ce lien ;\nvous pouvez suivre l’autre lien ci-dessous pour annuler la\nconfirmation de votre adresse courriel :\n\n$5\n\nCe code de confirmation expirera le $4.",
        "confirmemail_body_set": "Quelqu’un, probablement vous, depuis l’adresse IP $1, a modifié l’adresse de courriel du compte « $2 » en celle-ci sur {{SITENAME}}.\n\nPour confirmer que ce compte vous appartient et réactiver les fonctions de courriel sur {{SITENAME}}, ouvrez ce lien dans votre navigateur Web :\n\n$3\n\nCe code de confirmation expirera le $4.\n\nSi le compte ne vous appartient *pas*, suivez plutôt ce lien pour annuler la confirmation de l’adresse de courriel :\n\n$5",
        "confirmemail_invalidated": "Confirmation de l’adresse courriel annulée",
        "scarytranscludefailed": "[La récupération de modèle a échoué pour $1]",
        "scarytranscludefailed-httpstatus": "[Échec de la récupération du modèle pour  $1 : HTTP  $2 ]",
        "scarytranscludetoolong": "[L'URL est trop longue]",
-       "deletedwhileediting": "'''Attention''' : cette page a été supprimée après que vous ayez commencé à la modifier !",
+       "deletedwhileediting": "<strong>Attention</strong> : cette page a été supprimée après que vous ayez commencé à la modifier !",
        "confirmrecreate": "L’utilisat{{GENDER:$1|eur|rice}} [[User:$1|$1]] ([[User talk:$1|Discussion]]) a supprimé cette page, alors que vous aviez commencé à la modifier, pour le motif suivant :\n: <em>$2</em>\nVeuillez confirmer que vous désirez réellement recréer cette page.",
        "confirmrecreate-noreason": "L’utilisat{{GENDER:$1|eur|rice}} [[User:$1|$1]] ([[User talk:$1|Discussion]]) a supprimé cette page, alors que vous aviez commencé à la modifier. Veuillez confirmer que vous désirez réellement recréer cette page.",
        "recreate": "Recréer",
        "watchlistedit-clear-removed": "{{PLURAL:$1|Un titre a été|$1 titres ont été}} retirés :",
        "watchlistedit-too-many": "Il y a trop de pages à afficher ici.",
        "watchlisttools-clear": "Effacer la liste de suivi",
-       "watchlisttools-view": "Liste de suivi",
+       "watchlisttools-view": "Afficher les modifications associées",
        "watchlisttools-edit": "Voir et modifier la liste de suivi",
        "watchlisttools-raw": "Modifier la liste de suivi en mode brut",
        "iranian-calendar-m1": "Farvardin",
        "hebrew-calendar-m12-gen": "eloul",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|discussion]])",
        "timezone-local": "Local",
-       "duplicate-defaultsort": "Attention : la clé de tri par défaut « $2 » écrase la précédente clé « $1 ».",
+       "duplicate-defaultsort": "<strong>Attention :</strong> la clé de tri par défaut « $2 » écrase la précédente clé « $1 ».",
        "duplicate-displaytitle": "<strong>Attention :</strong> Le titre d'affichage « $2 » remplace l'ancien titre d'affichage « $1 ».",
        "restricted-displaytitle": "<strong>Avertissement :</strong> le titre d’affichage \"$1\" a été ignoré car il n'est pas équivalent au titre effectif de la page.",
        "invalid-indicator-name": "<strong>Erreur :</strong> L’attribut <code>name</code> des indicateurs d’état de la page ne doit pas être vide.",
        "version-license-not-found": "Aucune information détaillée de la licence n'a été trouvée pour cette extension.",
        "version-credits-title": "Remerciements pour $1",
        "version-credits-not-found": "Aucune information détaillée des remerciements n'a été trouvée pour cette extension.",
-       "version-poweredby-credits": "Ce wiki fonctionne grâce à '''[https://www.mediawiki.org/ MediaWiki]''', copyright © 2001-$1 $2.",
+       "version-poweredby-credits": "Ce wiki fonctionne grâce à <strong>[https://www.mediawiki.org/ MediaWiki]</strong>, copyright © 2001-$1 $2.",
        "version-poweredby-others": "autres",
        "version-poweredby-translators": "traducteurs de translatewiki.net",
        "version-credits-summary": "Nous tenons à remercier les personnes suivantes pour leur contribution à  [[Special:Version|MediaWiki]].",
-       "version-license-info": "MediaWiki est un logiciel libre, vous pouvez le redistribuer ou le modifier selon les termes de la Licence Publique Générale GNU telle que publiée par la Free Software Foundation ; soit la version 2 de la Licence, ou (à votre choix) toute version ultérieure.\n\nMediaWiki est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE, sans même la garantie implicite de COMMERCIALISATION ou D'ADAPTATION À UN USAGE PARTICULIER. Voir la Licence Publique Générale GNU pour plus de détails.\n\nVous devriez avoir reçu [{{SERVER}}{{SCRIPTPATH}}/COPYING une copie de la Licence Publique Générale GNU] avec ce programme, sinon, écrivez à la Free Software Foundation, Inc., 51, rue Franklin, cinquième étage, Boston, MA 02110-1301, États-Unis ou [//www.gnu.org/licenses/old-licenses/gpl-2.0.html lisez-la en ligne].",
+       "version-license-info": "MediaWiki est un logiciel libre, vous pouvez le redistribuer ou le modifier selon les termes de la Licence Publique Générale GNU telle que publiée par la Free Software Foundation ; soit la version 2 de la Licence, ou (à votre choix) toute version ultérieure.\n\nMediaWiki est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE, sans même la garantie implicite de COMMERCIALISATION ou D'ADAPTATION À UN USAGE PARTICULIER. Voir la Licence Publique Générale GNU pour plus de détails.\n\nVous devriez avoir reçu [{{SERVER}}{{SCRIPTPATH}}/COPYING une copie de la Licence Publique Générale GNU] avec ce programme, sinon, écrivez à la Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, États-Unis ou [//www.gnu.org/licenses/old-licenses/gpl-2.0.html lisez-la en ligne].",
        "version-software": "Logiciels installés",
        "version-software-product": "Produit",
        "version-software-version": "Version",
        "tags-deactivate": "désactiver",
        "tags-hitcount": "$1 modification{{PLURAL:$1||s}}",
        "tags-manage-no-permission": "Vous n'avez pas la permission de gérer les modifications de balises.",
-       "tags-manage-blocked": "Vous ne pouvez pas accéder à l’interface de modification des balises lorsque vous êtes bloqué{{GENDER:||e}}.",
+       "tags-manage-blocked": "Vous ne pouvez pas accéder à l’interface de modification des balises lorsque vous êtes bloqué{{GENDER:$1||e}}.",
        "tags-create-heading": "Créer une nouvelle balise",
        "tags-create-explanation": "Par défaut, les nouvelles balises créées seront disponibles pour les utilisateurs et les robots.",
        "tags-create-tag-name": "Nom de la balise :",
        "tags-create-reason": "Raison :",
        "tags-create-submit": "Créer",
        "tags-create-no-name": "Vous devez spécifier un nom de balise.",
-       "tags-create-invalid-chars": "Les noms de balise ne doivent pas contenir de virgules (<code>,</code>) ou des barres obliques (<code>/</code>).",
+       "tags-create-invalid-chars": "Les noms de balise ne doivent pas contenir de virgules (<code>,</code>) ni de barres obliques (<code>/</code>).",
        "tags-create-invalid-title-chars": "Les noms de balise ne doivent pas contenir de caractères qui ne peuvent pas être utilisés dans les titres des pages.",
        "tags-create-already-exists": "La balise « $1 » existe déjà.",
        "tags-create-warnings-above": "{{PLURAL:$2|L'avertissement suivant|Les avertissements suivants}} ont été rencontrés lors de la tentative de création de la balise « $1 » :",
        "tags-delete-title": "Supprimer la balise",
        "tags-delete-explanation-initial": "Vous êtes sur le point de supprimer la balise « $1 » de la base de données.",
        "tags-delete-explanation-in-use": "Elle sera supprimée de {{PLURAL:$2|$2 révision ou entrée de journal à laquelle|toutes les $2 révisions et/ou entrées de journal auxquelles}} elle est actuellement appliquée.",
-       "tags-delete-explanation-warning": "Cette action est <strong>irréversible</strong> et <strong>ne peut pas être annulée</strong>, même pas par les administrateurs de base de données. Soyez certain que c'est la balise que vous voulez supprimer.",
+       "tags-delete-explanation-warning": "Cette action est <strong>irréversible</strong> et <strong>ne peut pas être annulée</strong>, même pas par les administrateurs de base de données. Soyez certain que c'est cette balise que vous voulez supprimer.",
        "tags-delete-explanation-active": "<strong>La balise « $1 » est toujours active, et continuera à être appliquée dans le futur. </strong> Pour arrêter cela, allez à l'endroit (ou aux endroits) où la balise est appliquée, et désactivez la.",
        "tags-delete-reason": "Motif :",
        "tags-delete-submit": "Supprimer cette balise de manière irréversible",
        "tags-deactivate-reason": "Motif :",
        "tags-deactivate-not-allowed": "Il n'est pas possible de désactiver la balise « $1 ».",
        "tags-deactivate-submit": "Désactiver",
-       "tags-apply-no-permission": "Vous n’avez pas le droit d’appliquer des balises de changement avec vos modifications.",
-       "tags-apply-blocked": "Vous ne pouvez pas appliquer les modifications de balises lorsque vous êtes bloqué{{GENDER:||e}}.",
+       "tags-apply-no-permission": "Vous n’avez pas le droit d’appliquer des balises de changement en même temps que vos modifications.",
+       "tags-apply-blocked": "Vous ne pouvez pas appliquer les modifications de balises et vos modifications lorsque vous êtes bloqué{{GENDER:$1||e}}.",
        "tags-apply-not-allowed-one": "La balise « $1 » n’est pas autorisée à être appliquée manuellement.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|La balise suivante n’est pas autorisée à être appliquée|Les balises suivantes ne sont pas autorisées à être appliquées}} manuellement : $1",
        "tags-update-no-permission": "Vous n’avez pas le droit d’ajouter ou de supprimer des balises de modification des révisions individuelles ou des entrées de journal.",
-       "tags-update-blocked": "Vous ne pouvez pas ajouter ou supprimer des balises de modifications lorsque vous êtes bloqué{{GENDER:||e}}.",
+       "tags-update-blocked": "Vous ne pouvez pas ajouter ou supprimer des balises de modifications lorsque vous êtes bloqué{{GENDER:$1||e}}.",
        "tags-update-add-not-allowed-one": "La balise « $1 » ne peut pas être ajoutée manuellement.",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|La balise suivante ne peut pas être ajoutée|Les balises suivantes ne peuvent pas être ajoutées}} manuellement : $1",
        "tags-update-remove-not-allowed-one": "La balise « $1 » ne peut pas être enlevée.",
        "tags-edit-failure": "Les modifications n’ont pas pu être appliquées :\n$1",
        "tags-edit-nooldid-title": "Version cible non valide",
        "tags-edit-nooldid-text": "Vous n’avez soit pas spécifié de version cible sur laquelle exécuter cette fonction, soit la version spécifiée n’existe pas.",
-       "tags-edit-none-selected": "Veuillez sélectionner au moins une balise à ajouter ou enlever.",
+       "tags-edit-none-selected": "Veuillez sélectionner au moins une balise à ajouter ou à enlever.",
        "comparepages": "Comparer des pages",
        "compare-page1": "Page 1",
        "compare-page2": "Page 2",
        "htmlform-cloner-create": "Ajouter encore",
        "htmlform-cloner-delete": "Supprimer",
        "htmlform-cloner-required": "Une valeur au moins est obligatoire.",
+       "htmlform-date-placeholder": "AAAA-MM-JJ",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "AAAA-MM-JJ HH:MM:SS",
+       "htmlform-date-invalid": "La valeur que vous avez spécifiée n’est pas une date reconnue. Essayez en utilisant le format AAAA-MM-JJ.",
+       "htmlform-time-invalid": "La valeur que vous avez spécifiée n’est pas une heure reconnue. Essayez en utilisant le format HH:MM:SS.",
+       "htmlform-datetime-invalid": "La valeur que vous avez spécifiée n’est pas un horodatage reconnu. Essayez en utilisant le format AAAA-MM-JJ HH:MM:SS.",
+       "htmlform-date-toolow": "La valeur que vous avez spécifiée est antérieure à la date autorisée la plus ancienne, qui est $1.",
+       "htmlform-date-toohigh": "La valeur que vous avez spécifiée est postérieure à la date autorisée la plus lointaine, qui est $1.",
+       "htmlform-time-toolow": "La valeur que vous avez spécifiée est antérieure à la plus petite heure autorisée, qui est $1.",
+       "htmlform-time-toohigh": "La valeur que vous avez spécifiée est postérieure à la plus grande heure autorisée, qui est $1.",
+       "htmlform-datetime-toolow": "La valeur que vous avez spécifiée est antérieure à l’horodatage autorisé le plus ancien, qui est $1.",
+       "htmlform-datetime-toohigh": "La valeur que vous avez spécifiée est postérieure à l’horodatage autorisé le plus lointain, qui est $1.",
        "htmlform-title-badnamespace": "[[:$1]] n'est pas dans l’espace de noms « {{ns:$2}} ».",
        "htmlform-title-not-creatable": "« $1 » n’est pas un titre de page pouvant être créée",
        "htmlform-title-not-exists": "$1 n’existe pas",
        "log-description-managetags": "Cette page recense les tâches de maintenance liées aux [[Special:Tags|balises]]. Le journal contient uniquement les actions faites manuellement par un administrateur ; les balises peuvent être créées ou supprimées par le logiciel wiki sans que cette action ne soit inscrite dans ce journal.",
        "logentry-managetags-create": "$1 {{GENDER:$2|a créé}} la balise « $4 ».",
        "logentry-managetags-delete": "$1 {{GENDER:$2|a supprimé}} la balise « $4 » (retirée {{PLURAL:$5|d'une révision ou entrée de journal|de $5 révisions ou entrées de journal}})",
-       "logentry-managetags-activate": "$1 {{GENDER:$2|a activé}} la balise \"$4\" pour l’usage des utilisateurs et des robots",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|a activé}} la balise « $4 » pour l’usage des utilisateurs et des robots",
        "logentry-managetags-deactivate": "$1 {{GENDER:$2|a désactivé}} la balise « $4 » pour l’usage des utilisateurs et des robots",
        "log-name-tag": "Journal des balises",
        "log-description-tag": "Cette page montre quand des utilisateurs ont ajouté ou supprimé des [[Special:Tags|balises]] de révisions individuelles ou d’entrées de journal. Le journal ne liste pas les actions de marquage quand elles ont lieu au cours d’une modification, d’une suppression, ou d’une action semblable.",
        "feedback-external-bug-report-button": "Signaler un bogue technique",
        "feedback-dialog-title": "Soumettre un commentaire",
        "feedback-dialog-intro": "Vous pouvez utiliser le simple formulaire ci-dessous pour faire parvenir vos commentaires. Votre commentaire sera ajouté à la page « $1 », ainsi que votre nom d’utilisateur.",
-       "feedback-error-title": "Erreur",
        "feedback-error1": "Erreur : Résultat de l'IPA non reconnu",
        "feedback-error2": "Erreur : la modification a échoué",
        "feedback-error3": "Erreur : aucune réponse de l'API",
        "feedback-thanks": "Merci ! Votre commentaire a été publié sur la page « [$2 $1] ».",
        "feedback-thanks-title": "Merci !",
        "feedback-useragent": "Agent utilisateur :",
-       "searchsuggest-search": "Rechercher",
+       "searchsuggest-search": "Rechercher sur {{SITENAME}}",
        "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-hookaborted": "La modification que vous avez essayé de faire a été annulée par une extension.",
        "api-error-http": "Erreur interne : ne peut se connecter au serveur.",
        "api-error-illegal-filename": "Le nom du fichier n'est pas autorisé.",
-       "api-error-internal-error": "Erreur interne : Quelque chose s'est mal passé lors du traitement de votre import sur le wiki.",
-       "api-error-invalid-file-key": "Erreur interne : aucun fichier trouvé dans le stockage temporaire.",
+       "api-error-internal-error": "Erreur interne : quelque chose s'est mal passé lors du traitement de votre import sur le wiki.",
+       "api-error-invalid-file-key": "Erreur interne : fichier non trouvé dans l'espace de stockage temporaire.",
        "api-error-missingparam": "Erreur interne : Il manque des paramètres dans la requête.",
        "api-error-missingresult": "Erreur interne : Nous n'avons pas pu déterminer si la copie avait réussi.",
        "api-error-mustbeloggedin": "Vous devez être connecté pour télécharger des fichiers.",
        "api-error-timeout": "Le serveur n'a pas répondu dans le délai imparti.",
        "api-error-unclassified": "Une erreur inconnue s'est produite",
        "api-error-unknown-code": "Erreur inconnue : « $1 »",
-       "api-error-unknown-error": "Erreur interne : Quelque chose a mal tourné lors du versement de votre fichier.",
-       "api-error-unknown-warning": "Avertissement inconnu : $1",
+       "api-error-unknown-error": "Erreur interne : quelque chose s'est mal passé lors du téléversement de votre fichier.",
+       "api-error-unknown-warning": "Avertissement inconnu : « $1 ».",
        "api-error-unknownerror": "Erreur inconnue : « $1 ».",
        "api-error-uploaddisabled": "Le téléversement est désactivé sur ce wiki.",
-       "api-error-verification-error": "Ce fichier peut être corrompu, ou son extension est incorrecte.",
+       "api-error-verification-error": "Ce fichier est peut-être corrompu, ou son extension est incorrecte.",
        "api-error-was-deleted": "Un fichier portant ce nom a déjà été importé puis supprimé.",
        "duration-seconds": "$1 seconde{{PLURAL:$1||s}}",
        "duration-minutes": "$1 minute{{PLURAL:$1||s}}",
        "expand_templates_generate_xml": "Voir l’arborescence d’analyse XML",
        "expand_templates_generate_rawhtml": "Afficher le HTML brut",
        "expand_templates_preview": "Aperçu du rendu",
-       "expand_templates_preview_fail_html": "<em>Comme {{SITENAME}} a HTML brut activé et qu’il y a eu une perte de données de session, l’aperçu est masqué par précaution contre les attaques JavaScript.</em>\n\n<strong>Si c’est une demande d’aperçu légitime, veuillez réessayer.</strong>\nSi cela ne fonctionne toujours pas, essayez de [[Special:UserLogout|vous déconnecter]] et vous reconnecter, et vérifiez que votre navigateur accepte les cookies de ce site.",
+       "expand_templates_preview_fail_html": "<em>Comme {{SITENAME}} a l’HTML brut activé et qu’il y a eu une perte de données de session, l’aperçu est masqué par précaution contre les attaques JavaScript.</em>\n\n<strong>Si c’est une demande d’aperçu légitime, veuillez réessayer.</strong>\nSi cela ne fonctionne toujours pas, essayez de [[Special:UserLogout|vous déconnecter]] et de vous reconnecter, et vérifiez que votre navigateur accepte les témoins (''cookies'') de ce site.",
        "expand_templates_preview_fail_html_anon": "<em>Comme {{SITENAME}} a HTML brut activé et que vous n’êtes pas connecté, l’aperçu est masqué par précaution contre les attaques JavaScript.</em>\n\n<strong>Si c’est une demande d’aperçu légitime, veuillez [[Special:UserLogin|vous connecter]] et réessayer.</strong>",
        "expand_templates_input_missing": "Vous devez fournir au moins un texte d’entrée.",
        "pagelanguage": "Modifier la langue de la page",
        "json-error-state-mismatch": "JSON non valide ou mal formé",
        "json-error-ctrl-char": "Erreur de caractères de contrôle, peut-être mal encodé",
        "json-error-syntax": "Erreur de syntaxe",
-       "json-error-utf8": "Caractères UTF-8 mal formés, peut-être mal encodé",
+       "json-error-utf8": "Caractères UTF-8 mal formés, peut-être mal encodés",
        "json-error-recursion": "Une ou plusieurs références récursives dans la valeur à encoder",
        "json-error-inf-or-nan": "Une une plusieurs valeurs NaN ou INF dans la valeur à encoder",
        "json-error-unsupported-type": "Une valeur a été donnée dans un type ne pouvant pas être encodé",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-new-page": "la page n’existe pas encore",
        "mw-widgets-titleinput-description-redirect": "redirection vers $1",
-       "sessionmanager-tie": "Impossible de combiner les demandes multiples de types d’authentification : $1.",
+       "sessionmanager-tie": "Impossible de combiner des types multiples de demandes d’authentification : $1.",
        "sessionprovider-generic": "sessions $1",
-       "sessionprovider-mediawiki-session-cookiesessionprovider": "sessions basées sur les cookies",
-       "sessionprovider-nocookies": "Les cookies peuvent être désactivés. Assurez-vous que vous avez activé les cookies et recommencez.",
+       "sessionprovider-mediawiki-session-cookiesessionprovider": "sessions basées sur les témoins (''cookies'')",
+       "sessionprovider-nocookies": "Il est possible que les témoins (''cookies'') soient désactivés. Assurez-vous que vous avez activé les témoins et recommencez.",
        "randomrootpage": "Page racine aléatoire",
        "log-action-filter-block": "Type de blocage :",
        "log-action-filter-contentmodel": "Type de modification de modèle de contenu :",
        "authmanager-authn-autocreate-failed": "La création automatique d’un compte local a échoué : $1",
        "authmanager-change-not-supported": "Les informations d’identification fournies ne peuvent pas être modifiées, car rien ne les utiliserait.",
        "authmanager-create-disabled": "La création de compte est désactivée.",
-       "authmanager-create-from-login": "Pour créer votre compte, veuillez remplir les champs ci-dessous.",
+       "authmanager-create-from-login": "Pour créer votre compte, veuillez remplir les champs.",
        "authmanager-create-not-in-progress": "La création de compte n’est pas en cours, ou les données de session ont été perdues. Veuillez recommencer depuis le début.",
        "authmanager-create-no-primary": "Les informations d’identification fournies n’ont pas pu être utilisées pour la création de compte.",
        "authmanager-link-no-primary": "Les informations d’identification fournies n’ont pas pu être utilisées pour lier un compte.",
        "usercssispublic": "Veuillez noter: les sous-pages CSS ne doivent pas contenir de données confidentielles parce qu'elles sont visibles des autres utilisateurs.",
        "restrictionsfield-badip": "Adresse IP ou plage non valide : $1",
        "restrictionsfield-label": "Plages IP autorisées :",
-       "restrictionsfield-help": "Une adresse IP ou une plage CIDR par ligne. Pour tout activer, utiliser <br><code>0.0.0.0/0</code><br><code>::/0</code>"
+       "restrictionsfield-help": "Une adresse IP ou une plage CIDR par ligne. Pour tout activer, utiliser <br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Erreur : $1",
+       "edit-error-long": "Erreurs :\n\n$1"
 }
index 8e542fb..3ae9648 100644 (file)
        "yourpasswordagain": "Mot de passe encore:",
        "createacct-yourpasswordagain": "Confirmes le mot de passe",
        "createacct-yourpasswordagain-ph": "Entres à nouveau le mot de passe",
-       "remembermypassword": "Garder mon mot de passe dans cette browser (pour un maximum of $1 {{PLURAL:$1|jour|jours}})",
        "yourdomainname": "Votre domaine:",
        "externaldberror": "Soit y avait une erreur avec la base d'information de certification extérieur, soit vous avez pas la permission de renouveler votre compte extérieur.",
        "login": "Connecter",
        "undo-success": "Le changement peut être renversé.  Regardez donc la comparaison en bas pour être sûr que c'est comme vous voulez, et puis sauvez les changements en bas pour finir le renversage du changement.",
        "undo-failure": "Le changement pouvait pas être renversé à cause d'une dispute de changements.",
        "undo-summary": "Défaire la révision $1 par [[Special:Contributions/$2|$2]] ([[User talk:$2|Discussion]])",
-       "cantcreateaccounttitle": "Impossible de créer le compte",
        "viewpagelogs": "Voir les notes pour cette page",
        "nohistory": "Y a pas de changements pour cette page.",
        "currentrev": "Version courante",
index d3828ca..006492e 100644 (file)
        "yourpasswordagain": "Confirmâd lo contresegno :",
        "createacct-yourpasswordagain": "Confirmâd lo contresegno",
        "createacct-yourpasswordagain-ph": "Tornâd buchiér lo contresegno",
-       "remembermypassword": "Sè rapelar de mon contresegno sur cél navegator (por lo més $1 jorn{{PLURAL:$1||s}})",
        "userlogin-remembermypassword": "Gouardar ma sèssion activa",
        "userlogin-signwithsecure": "Empleyér un branchement sècurisâ",
        "cannotloginnow-title": "Ora y at pas moyen de sè branchiér",
        "botpasswords-label-resetpassword": "Rebetar a zérô lo contresegno",
        "botpasswords-label-grants": "Drêts aplicâblos :",
        "botpasswords-help-grants": "Châque drêt balye accès ux drêts d’utilisator listâs qu’at ja un comptio. Vêde la [[Special:ListGrants|grelye des drêts]] por més d’enformacions.",
-       "botpasswords-label-restrictions": "Rèstriccions d’usâjo :",
        "botpasswords-label-grants-column": "Acordâ",
        "botpasswords-bad-appid": "Lo nom de robot « $1 » est pas justo.",
        "botpasswords-insert-failed": "Falyita de l’aponsa du nom de robot « $1 ». Est-o qu’il est ja étâ apondu ?",
        "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â.",
-       "passwordreset-emailsent-capture": "Un mèssâjo de remês’a zérô de contresegno est étâ mandâ, qu’il est montrâ ce-desot.",
-       "passwordreset-emailerror-capture": "Un mèssâjo de remês’a zérô de contresegno est étâ fêt, qu’il est montrâ ce-desot, mas l’èxpèdicion a l’utilisat{{GENDER:$2|or|rice}} at pas reussi : $1",
        "changeemail": "Changiér enlevar l’adrèce èlèctronica",
        "changeemail-header": "Complètâd cél formulèro por changiér voutron adrèce èlèctronica. Se vos voléd enlevar l’associacion d’un’adrèce èlèctronica avouéc voutron comptio, lèssiéd la novèl’adrèce èlèctronica voueda pendent la somission du formulèro.",
-       "changeemail-passwordrequired": "Vos devréd buchiér voutron contresegno por confirmar cél changement.",
        "changeemail-no-info": "Vos dête étre branchiê por arrevar tot drêt a cela pâge.",
        "changeemail-oldemail": "Adrèce èlèctronica d’ora :",
        "changeemail-newemail": "Novèl’adrèce èlèctronica :",
        "undo-nochange": "Semble que lo changement seye ja étâ dèfêt.",
        "undo-summary": "Dèfêta du changement $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|discutar]])",
        "undo-summary-username-hidden": "Dèfêta du changement $1 d’un utilisator cachiê",
-       "cantcreateaccounttitle": "Y at pas moyen de fâre lo comptio",
        "cantcreateaccount-text": "La crèacion de comptio dês cel’adrèce IP (<strong>$1</strong>) est étâye blocâye per [[User:$3|$3]].\n\nLa rêson balyêe per $3 ére <em>$2</em>",
        "cantcreateaccount-range-text": "La crèacion de comptio dês les adrèces IP dedens la plage <strong>$1</strong>, que comprend voutron adrèce IP (<strong>$4</strong>), sont étâye blocâyes per [[User:$3|$3]].\n\nLa rêson balyêe per $3 ére <em>$2</em>",
        "viewpagelogs": "Vêde los jornâls de cela pâge",
        "activeusers-intro": "O est na lista des utilisators qu’ant ègzèrciê un’activitât quinta que seye pendent {{PLURAL:$1|lo jorn passâ|los $1 jorns passâs}}.",
        "activeusers-count": "$1 accion{{PLURAL:$1||s}} pendent {{PLURAL:$3|lo jorn passâ|los $3 jorns passâs}}",
        "activeusers-from": "Fâre vêre los utilisators dês :",
-       "activeusers-hidebots": "Cachiér los robots",
-       "activeusers-hidesysops": "Cachiér los administrators",
        "activeusers-noresult": "Nion utilisator est étâ trovâ.",
        "activeusers-submit": "Fâre vêre los utilisators actifs",
        "listgrouprights": "Drêts de les tropes d’utilisators",
        "htmlform-submit": "Sometre",
        "htmlform-reset": "Dèfâre los changements",
        "htmlform-selectorother-other": "Ôtro",
-       "sqlite-has-fts": "$1 avouéc rechèrche en tèxto complèt recognua",
-       "sqlite-no-fts": "$1 sen rechèrche en tèxto complèt recognua",
        "logentry-delete-delete": "$1 {{GENDER:$2|at suprimâ}} la pâge $3",
        "logentry-delete-restore": "$1 at refêt la pâge $3",
        "logentry-delete-event": "$1 at changiê la visibilitât {{PLURAL:$5|d’un èvènement|de $5 èvènements}} du jornal dessus $3 : $4",
index d361eae..a9446ce 100644 (file)
        "yourpasswordagain": "Skriiw det paaswurd noch ans weder hen:",
        "createacct-yourpasswordagain": "Paaswurd gudkään",
        "createacct-yourpasswordagain-ph": "Du det paaswurd noch ans iin",
-       "remembermypassword": "Üüb diheer reegner üüb düür uunmelde (maksimaal för $1 {{PLURAL:$1|dai|daar}})",
        "userlogin-remembermypassword": "Uunmeldet bliiw",
        "userlogin-signwithsecure": "Seeker ferbinjang brük",
        "yourdomainname": "Din domain:",
        "botpasswords-label-resetpassword": "Paaswurd turagsaat",
        "botpasswords-label-grants": "Mögelk brükerrochten:",
        "botpasswords-help-grants": "Mä arke brükerrocht könst dü üüb ööder brükerrochten faan en brükerkonto tugrip. Luke iin uun det [[Special:ListGrants|tabel]] am muar informatjuun.",
-       "botpasswords-label-restrictions": "Kört brükerrochten:",
        "botpasswords-label-grants-column": "Tugestenen",
        "botpasswords-bad-appid": "Di bot-nööm \"$1\" gongt ei.",
        "botpasswords-insert-failed": "Di bot-nööm \"$1\" küd ei apnimen wurd. Ferlicht as hi al diar?",
        "passwordreset-emailtext-user": "Di brüker $1 üüb {{SITENAME}} hää am brükerinformatsjuunen för {{SITENAME}} uunfraaget ($4). {{PLURAL:$3|Detdiar brükerkonto as|Jodiar brükerkontos san}} mä detdiar E-Mail-Adres ferbünjen:\n\n$2\n\n{{PLURAL:$3|Detheer tidjwiis paaswurd lääpt|Joheer tidjwiis paaswurden luup}} efter {{PLURAL:$5|ään dai|$5 daar}} uf. Dü skulst di uunmelde an en nei paaswurd iinracht. Wan hoker ööders detheer uunfraag steld hää of dü din ual paaswurd käänst, säärst dü niks widjer onernem. Melde di ianfach mä din ual paaswurd uun.",
        "passwordreset-emailelement": "Brükernööm: \n$1\n\nTidjwiis paaswurd: \n$2",
        "passwordreset-emailsentemail": "Diar as en E-Mail tu di onerwais.",
-       "passwordreset-emailsent-capture": "Detdiar E-Mail, wat oner uunwiset woort, as tu di onerwais.",
-       "passwordreset-emailerror-capture": "Detdiar E-Mail, wat oner uunwiset woort, wiar tu di onerwais, oober küd ei tu di {{GENDER:$2|brüker}} ufsjüürd wurd: $1",
        "changeemail": "Feranre det E-Mail-adres",
        "changeemail-header": "Feranre det E-Mail-adres",
        "changeemail-no-info": "Dü möist önjmälded weese am ju sid diräkt tu tu gripen.",
        "undo-nochange": "Detdiar feranrang as wel al ans turagsaat wurden.",
        "undo-summary": "Feranrang $1 faan [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskuschuun]]) turagsaat.",
        "undo-summary-username-hidden": "Feranrang $1 faan en ferbürgenen brüker turagsaat",
-       "cantcreateaccounttitle": "Det brükerkonto koon ei iinracht wurd",
        "cantcreateaccount-text": "Det iinrachten faan en brükerkonto faan det IP-adres '''($1)''' as faan [[User:$3|$3]] speret wurden.\n\nGrünj för det sper: ''$2''",
        "cantcreateaccount-range-text": "Det iinrachten faan brükerkontos uun det IP-adresfial <strong>$1</strong>, huar uk din IP (<strong>$4</strong>) uun as, as faan [[User:$3|$3]] speret wurden.\n\nDi grünj faan $3 wiar: <em>$2</em>",
        "viewpagelogs": "Logbuken faan detdiar sidj uunwise",
        "activeusers-intro": "Jodiar brükern wiar {{PLURAL:$1|di leetst dai| a leetst $1 daar}} aktiif.",
        "activeusers-count": "$1 {{PLURAL:$1|aktjuun|aktjuunen}} uun a {{PLURAL:$3|leetst 24 stünj|leetst $3 daar}}",
        "activeusers-from": "Wise brükern mä began üüb:",
-       "activeusers-hidebots": "Bots fersteeg",
-       "activeusers-hidesysops": "Administratooren fersteeg",
        "activeusers-noresult": "Nään brükern fünjen.",
        "listgrouprights": "Brükersköölrochten",
        "listgrouprights-summary": "Jodiar brükersköölen an hör rochten san uun detheer Wiki fäästlaanj wurden.\nMuar diartu fanjst dü üüb  [[{{MediaWiki:Listgrouprights-helppage}}|detdiar sidj]].",
        "htmlform-title-not-exists": "$1 jaft at ei.",
        "htmlform-user-not-exists": "<strong>$1</strong> jaft at ei.",
        "htmlform-user-not-valid": "<strong>$1</strong> as nään tuläät brükernööm",
-       "sqlite-has-fts": "Werjuun $1 mä halep för't schüken uun di hialer tekst.",
-       "sqlite-no-fts": "Werjuun $1 saner halep för't schüken uun di hialer tekst.",
        "logentry-delete-delete": "$1 {{Gender:$2}} hää det sidj $3 stregen",
        "logentry-delete-restore": "$1 {{GENDER:$2}} hää det sidj $3 weder iinsteld",
        "logentry-delete-event": "$1 {{GENDER:$2}} hää det uunsicht feranert faan {{PLURAL:$5|en logbuk iindrach|$5 logbuk iindracher}} üüb $3: $4",
        "feedback-external-bug-report-button": "En technisk apgoow iinschüür",
        "feedback-dialog-title": "Komentaar ufsjüür",
        "feedback-dialog-intro": "Dü könst det ianfach formulaar diar oner för dan komentaar brük. Dan komentaar komt tuup mä dan brükernööm tu det sidj „$1“.",
-       "feedback-error-title": "Diar as wat skiaf gingen",
        "feedback-error1": "Feeler: Ünbekäänd API-bööd",
        "feedback-error2": "Feeler: Bewerkin as skiaf gingen.",
        "feedback-error3": "Feeler: Nian API-oonswaar",
index 20c4d1c..159834d 100644 (file)
        "yourpasswordagain": "Torne a scrivile",
        "createacct-yourpasswordagain": "Conferme la password",
        "createacct-yourpasswordagain-ph": "Torne a scrivi la tô password",
-       "remembermypassword": "Visiti di me di une session a chê altre (fin a $1 {{PLURAL:$1|zornade|zornadis}})",
        "userlogin-remembermypassword": "Tegnimi colegât",
        "yourdomainname": "Il to domini",
        "login": "Jentre",
        "activeusers-intro": "Cheste e je une liste dai utents che a àn vût cualchi gjenar di ativitât {{PLURAL:$1|te ultime dì|tai ultins $1 diis}}.",
        "activeusers-count": "$1 {{PLURAL:$1|cambiament|cambiaments}} {{PLURAL:$3|te ultime dì|tai ultins $3 diis}}",
        "activeusers-from": "Mostre i utents scomençant di:",
-       "activeusers-hidebots": "Plate i bots",
-       "activeusers-hidesysops": "Plate i aministradôrs",
        "activeusers-noresult": "Nissun utent cjatât.",
        "listgrouprights": "Dirits dai grups di utents",
        "listgrouprights-group": "Grup",
index 93caec8..e10b921 100644 (file)
        "yourpasswordagain": "Jo wachtwurd (nochris)",
        "createacct-yourpasswordagain": "Befêstigje wachtwurd",
        "createacct-yourpasswordagain-ph": "Befêstigje wachtwurd nochris",
-       "remembermypassword": "Oare kear fansels oanmelde (maksimaal $1 {{PLURAL:$1|dei|dagen}})",
        "userlogin-remembermypassword": "Ynlogd bliuwe",
        "userlogin-signwithsecure": "Feilige ferbining brûke",
        "yourdomainname": "Jo domein:",
        "undo-failure": "De feroarings kinne net werom set wurde troch in konflikt mei oare feroarings tuskentroch.",
        "undo-norev": "De feroaring kin werom set wurde, omdat it net bestiet of is wiske.",
        "undo-summary": "Werom sette fan ferzje $1 fan [[Special:Contributions/$2|$2]] ([[User talk:$2|Oerlis]])",
-       "cantcreateaccounttitle": "Registrearjen is mislearre.",
        "cantcreateaccount-text": "Registraasje fan in brûker fia dit IP-adres ('''$1''') is blokkearre troch [[User:$3|$3]].\n\nDe fan $3 opjûne reden is ''$2''",
        "viewpagelogs": "Lochboek foar dizze side sjen litte",
        "nohistory": "Dit is de earste ferzje fan de side.",
        "listusers-blocked": "(blokkearre)",
        "activeusers": "Aktive meidoggers",
        "activeusers-count": "$1 {{PLURAL:$1|aksje|aksjes}} yn de lêste {{PLURAL:$3|dei|$3 dagen}}",
-       "activeusers-hidebots": "Bots ferbergje",
-       "activeusers-hidesysops": "Behearders ferbergje",
        "activeusers-noresult": "Gjin meidoggers fûn.",
        "listgrouprights": "Rjochten fan brûkersgroepen",
        "listgrouprights-summary": "Op dizze side steane de brûkersgroepen yn dizze wiki beskreaun, mei har derby hearrende rjochten.\nDer kin [[{{MediaWiki:Listgrouprights-helppage}}|ekstra ynformaasje]] oer yndividuele rjochten oanwêzich wêze.",
        "feedback-back": "Foarige",
        "feedback-cancel": "Annulearje",
        "feedback-close": "Dien",
-       "feedback-error-title": "Flater",
        "feedback-message": "Berjocht:",
        "feedback-subject": "Ûnderwerp:",
        "feedback-submit": "Ferstjoere",
index 2765143..8509a8a 100644 (file)
        "tog-hidepatrolled": "Folaigh giotaí eagartha smachtaithe sna athruithe is déanaí",
        "tog-newpageshidepatrolled": "Folaigh leathanaigh smachtaithe ó liosta leathanaigh úire",
        "tog-extendwatchlist": "Leathnaigh an liosta faire chun gach athrú cuí a thaispeáint",
-       "tog-usenewrc": "Stíl nua do na hathruithe is déanaí (JavaScript riachtanach)",
+       "tog-usenewrc": "Athruithe a ghrúpáil de réir leathanaigh sna hathruithe le déanaí agus sa liosta faire",
        "tog-numberheadings": "Uimhrigh ceannteidil go huathoibríoch",
-       "tog-showtoolbar": "Taispeáin an barra uirlisí eagair (JavaScript)",
-       "tog-editondblclick": "Déghliogáil chun leathanaigh a chur in eagar (JavaScript)",
-       "tog-editsectiononrightclick": "Cumasaigh mír-eagarthóireacht le deaschliceáil<br /> ar cheannteidil (JavaScript)",
+       "tog-showtoolbar": "Taispeáin an barra uirlisí eagair",
+       "tog-editondblclick": "Déchliceáil chun leathanaigh a chur in eagar",
+       "tog-editsectiononrightclick": "Cumasaigh mír-eagarthóireacht le deaschliceáil ar cheannteidil",
        "tog-watchcreations": "Cuir ar mo liosta faire leathanaigh a chruthaím",
-       "tog-watchdefault": "Déan faire ar leathanaigh a athraím",
-       "tog-watchmoves": "Cuir ar mo liosta faire leathanaigh a athainmnaím",
-       "tog-watchdeletion": "Cuir ar mo liosta faire leathanaigh a scriosaim",
+       "tog-watchdefault": "Cuir leathanaigh agus comhaid a athraím le mo liosta faire",
+       "tog-watchmoves": "Cuir ar mo liosta faire leathanaigh agus comhaid a bhogaim",
+       "tog-watchdeletion": "Cuir ar mo liosta faire leathanaigh agus comhaid a scriosaim",
        "tog-minordefault": "Déan mionathruithe de gach aon athrú, mar réamhshocrú",
        "tog-previewontop": "Cuir an réamhamharc os cionn an bhosca eagair, <br />agus ná cuir é taobh thíos de",
        "tog-previewonfirst": "Taispeáin réamhamharc don chéad athrú",
-       "tog-enotifwatchlistpages": "Cuir ríomhphost chugam nuair a athraítear leathanaigh",
+       "tog-enotifwatchlistpages": "Cuir ríomhphost chugam nuair a athraítear leathanach nó comhad atá ar mo liosta faire",
        "tog-enotifusertalkpages": "Cuir ríomhphost chugam nuair a athraítear mo leathanach phlé úsáideora",
        "tog-enotifminoredits": "Cuir ríomhphost chugam nuair a dhéantar mionathruithe chomh maith",
        "tog-enotifrevealaddr": "Taispeáin mo sheoladh ríomhphoist i dteachtaireachtaí fógra",
        "tog-shownumberswatching": "Taispeán an méid úsáideoirí atá ag faire",
-       "tog-oldsig": "Réamhamharc ar an síniú atá ann:",
+       "tog-oldsig": "An síniú atá agat faoi láthair:",
        "tog-fancysig": "Sínithe bunúsacha mar vicítéacs (gan nasc uathoibríoch)",
-       "tog-uselivepreview": "Bain úsáid as réamhamharc beo (JavaScript) (Turgnamhach)",
+       "tog-uselivepreview": "Bain úsáid as réamhamharc beo",
        "tog-forceeditsummary": "Cuir in iúl dom nuair a chuirim isteach achoimre eagair folamh",
        "tog-watchlisthideown": "Folaigh mo chuid athruithe ón liosta faire",
        "tog-watchlisthidebots": "Folaigh athruithe de chuid róbat ón liosta faire",
        "moredotdotdot": "Tuilleadh...",
        "mypage": "Leathanach",
        "mytalk": "Plé",
-       "anontalk": "Plé don seoladh IP seo",
+       "anontalk": "Plé",
        "navigation": "Nascleanúint",
        "and": "&#32;agus",
        "qbfind": "Aimsigh",
        "protect": "Glasáil",
        "protect_change": "athraigh",
        "protectthispage": "Glasáil an lch seo",
-       "unprotect": "Díghlasáil",
-       "unprotectthispage": "Díghlasáil an lch seo",
+       "unprotect": "Athraigh an chosaint",
+       "unprotectthispage": "Athraigh an chosaint atá ag an lch seo",
        "newpage": "Leathanach nua",
        "talkpage": "Pléigh an lch seo",
        "talkpagelinktext": "Plé",
        "pool-errorunknown": "Earráid anaithnid",
        "aboutsite": "Maidir leis an {{SITENAME}}",
        "aboutpage": "Project:Maidir leis",
-       "copyright": "Tá an t-ábhar le fáil faoin $1.",
+       "copyright": "Tá an t-ábhar le fáil faoin $1 mura sonraítear a mhalairt.",
        "copyrightpage": "{{ns:project}}:Cóipchearta",
        "currentevents": "Cúrsaí reatha",
        "currentevents-url": "Project:Cúrsaí reatha",
        "laggedslavemode": "Rabhadh: B'fhéidir nach bhfuil na nuashonrúcháin is déanaí le feiceáil ar an leathanach seo.",
        "readonly": "Bunachar sonraí faoi ghlas",
        "enterlockreason": "Iontráil cúis don glasáil, agus meastachán\nden uair a díghlasálfar an bunachar sonraí.",
-       "readonlytext": "Tá an bunachar sonraí {{GRAMMAR:genitive|{{SITENAME}}}} glasáilte anois do iontráilí agus athruithe nua\n(is dócha go bhfuil sé do gnáthchothabháil).\nTar éis seo, díghlasálfar an bunachar sonraí arís.\nTugadh an míniú seo ag an riarthóir a ghlasáil é:\n$1",
+       "readonlytext": "Tá an bunachar sonraí glasáilte anois agus ní féidir iontrálacha nua ná athruithe eile a dhéanamh. Gach seans go bhfuil gnáthchothabháil ar siúl, agus beidh gach rud ar ais mar a bhí nuair a bheidh sin thart.\n\nThug an riarthóir a ghlasáil é an míniú seo:\n$1",
        "missing-article": "Ní bhfuarthas téacs an leathanaigh ceart, darbh ainm \"$1\" $2.\n\nDe ghnáth, tarlaíonn sé seo nuair a leantar nasc stáire nó difr chuig leathanach a scriosadh.\n\nMurab fhíor é seo, is féidir go bhfuair tú fabht sa bhogearraí. Beimid buíoch duit é a chur in iúl do [[Special:ListUsers/sysop|riarthóir]], chomh maith le URL an suíoimh.",
        "missingarticle-rev": "(leagan#: $1)",
        "missingarticle-diff": "(Dif: $1, $2)",
        "cannotdelete": "Ní féidir an leathanach nó comhad \"$1\" a scriosadh.\nB'fhéidir gur scrios duine eile é cheana féin.",
        "badtitle": "Teideal neamhbhailí",
        "badtitletext": "Bhí teideal an leathanaigh a d'iarr tú ar neamhbhailí, folamh, nó\nteideal idirtheangach nó idirvicí nasctha go mícheart.",
-       "perfcached": "Fuarthas na sonraí a leanas as taisce, agus is dócha go bhfuil siad as dáta. A maximum of {{PLURAL:$1|one result is|$1 results are}} available in the cache.",
+       "perfcached": "Fuarthas na sonraí a leanas as taisce, agus seans go bhfuil siad as dáta. Tá {{PLURAL:$1|aon toradh amháin|$1 thoradh}} ar fáil sa taisce.",
        "perfcachedts": "Tá na sonraí seo a leanas sa taisce, nuashonraithe $1. A maximum of {{PLURAL:$4|one result is|$4 results are}} available in the cache.",
        "viewsource": "Féach ar fhoinse",
        "actionthrottled": "Gníomh scóigthe",
-       "actionthrottledtext": "Mar theicníc frithurscair, ní féidir lear an gníomh seo a dhéanamh barraíocht taobh istigh de thréimhse ghairid ama, agus tá an méid sáraithe agat.\nBain trial arís as i gcionn cúpla bomaite más é do thoil é.",
+       "actionthrottledtext": "Mar theicníc frithurscair, ní féidir lear an gníomh seo a dhéanamh barraíocht taobh istigh de thréimhse ghairid ama, agus tá an méid sáraithe agat.\nBain triail arís as i gcionn cúpla bomaite más é do thoil é.",
        "protectedpagetext": "Tá an leathanach seo glasáilte chun coisc ar eagarthóireacht.",
        "viewsourcetext": "Is féidir foinse an leathanach seo a fheiceáil ná a cóipeáil:",
        "editinginterface": "'''Rabhadh:''' Tá tú ag athrú leathanaigh a bhfuil téacs comhéadain do na bogearraí air. Cuirfear athruithe ar an leathanach seo i bhfeidhm ar an gcomhéadan úsáideora.\nMás maith leat MediaWiki a aistriú, cuimhnigh ar [https://translatewiki.net/wiki/Main_Page?setlang=ga translatewiki.net] (tionscadal logánaithe MediaWiki) a úsáid.",
        "yourpasswordagain": "Athiontráil d'fhocal faire",
        "createacct-yourpasswordagain": "Deimhnigh an pasfhocal",
        "createacct-yourpasswordagain-ph": "Iontráil an pasfhocal arís",
-       "remembermypassword": "Cuimhnigh ar m'fhocal faire ar an ríomhaire seo (ar feadh uastréimhse de $1 {{PLURAL:$1|lá|lá}})",
        "userlogin-remembermypassword": "Coinnigh logáilte isteach mé",
        "yourdomainname": "D'fhearann",
        "externaldberror": "Bhí earráid bhunachair sonraí ann maidir le fíordheimhniú seachtrach, nóThere was either an external authentication database error or you are not allowed to update your external account.",
        "createacct-reason": "Cúis",
        "createacct-submit": "Cruthaigh do chuntas",
        "createacct-another-submit": "Cruthaigh cuntas eile",
+       "createacct-benefit-heading": "Daoine cosúil leatsa a dhéanann {{SITENAME}}.",
        "badretype": "D'iontráil tú dhá fhocal faire difriúla.",
        "userexists": "Tá an ainm úsáideora sin in úsáid cheana féin.<br />\nRoghnaigh ainm eile agus bain triail eile as.",
        "loginerror": "Earráid leis an logáil isteach",
        "nocookieslogin": "Úsáideann {{SITENAME}} fianáin chun úsáideoirí a logáil isteach.\nTá fianáin díchumasaithe agat.\nCumasaigh iad agus bain triail eile as, le do thoil.",
        "nocookiesforlogin": "{{int:nocookieslogin}}",
        "noname": "Níor thug tú ainm úsáideora bailí.",
-       "loginsuccesstitle": "Logáladh isteach thú",
+       "loginsuccesstitle": "Logáilte isteach",
        "loginsuccess": "'''Tá tú logáilte isteach anois sa {{SITENAME}} mar \"<nowiki>$1</nowiki>\".'''",
-       "nosuchuser": "Níl aon úsáideoir ann leis an ainm \"$1\".\nTá ainmneacha úsáideoir cásíogair.\nCinntigh do litriú, nó [[Special:CreateAccount|bain úsáid as an foirm thíos]] chun cuntas úsáideora nua a chruthú.",
+       "nosuchuser": "Níl aon úsáideoir ann darb ainm \"$1\".\nTá ainmneacha úsáideoir cásíogair.\nSeiceáil an litriú, nó [[Special:CreateAccount|cruthaigh cuntas nua]].",
        "nosuchusershort": "Níl aon úsáideoir ann leis an ainm \"$1\". Cinntigh do litriú.",
        "nouserspecified": "Caithfidh ainm úsáideoir a shonrú.",
        "login-userblocked": "Tá an t-úsáideoir seo faoi bhac. Níl cead aige/aici logáil isteach.",
        "wrongpassword": "D'iontráil tú focal faire mícheart.<br />\nBain triail eile as.",
        "wrongpasswordempty": "Níor iontráil tú focal faire. Bain triail eile as.",
        "passwordtooshort": "Is riachtanach go bhfuil {{PLURAL:$1|carachtar amháin|$1 carachtair}} ann ar a laghad i bhfocal faire.",
-       "mailmypassword": "Seol m'fhocal faire chugam.",
+       "mailmypassword": "Focal faire a athshocrú",
        "passwordremindertitle": "Cuimneachán an fhocail faire ó {{SITENAME}}",
        "passwordremindertext": "D'iarr duine éigin (tusa de réir cosúlachta, ón seoladh IP $1) go sheolfaimis focal faire {{GRAMMAR:genitive|{{SITENAME}}}} nua  ($4).\n\"$3\" an focal faire don úsáideoir \"$2\" anois. Ba chóir duit lógail isteach anois agus d'fhocal faire a athrú.\n\nRachaidh d'fhocail faire sealadach as feidhm i gceann {{PLURAL:$5|lá amháin|$5 lae}}.",
        "noemail": "Níl aon seoladh ríomhphoist i gcuntas don úsáideoir \"$1\".",
        "mergehistory-reason": "Fáth:",
        "revertmerge": "Díchumaisc",
        "history-title": "Stair leasú \"$1\"",
+       "difference-title": "An difríocht idir athruithe ar: \"$1\"",
        "lineno": "Líne $1:",
        "compareselectedversions": "Cuir na leagain roghnaithe i gcomparáid",
        "editundo": "cealaigh",
        "search-section": "(gearradh $1)",
        "search-suggest": "An raibh $1 á lorg agat?",
        "search-interwiki-caption": "Comhthionscadail",
-       "search-interwiki-default": "$1 torthaí:",
+       "search-interwiki-default": "Torthaí ó $1:",
        "search-interwiki-more": "(níos mó)",
        "search-relatedarticle": "Gaolmhar",
        "searchrelated": "gaolmhara",
        "prefs-rc": "Athruithe is déanaí",
        "prefs-watchlist": "Liosta faire",
        "prefs-watchlist-days": "Líon na laethanta le taispeáint sa liosta faire:",
-       "prefs-watchlist-days-max": "Maximum $1 {{PLURAL:$1|day|days}}",
+       "prefs-watchlist-days-max": "$1 {{PLURAL:$1|lá}} ar a mhéad",
        "prefs-watchlist-edits": "Líon na n-athruithe le taispeáint sa liosta leathnaithe faire:",
        "prefs-watchlist-edits-max": "Uasmhéid: 1000",
        "prefs-misc": "Éagsúla",
        "savedprefs": "Sábháladh do chuid sainroghanna.",
        "timezonelegend": "Crios ama:",
        "localtime": "An t-am áitiúil:",
-       "timezoneuseserverdefault": "Úsáid am réamhshocraithe an fhreastalaí",
+       "timezoneuseserverdefault": "Úsáid am réamhshocraithe an vicí ($1)",
        "timezoneuseoffset": "Eile (cuir isteach an difear)",
        "servertime": "Am an fhreastalaí:",
        "guesstimezone": "Líon ón mbrabhsálaí",
        "anoncontribs": "Dréachtaí",
        "contribsub2": "Do $1 ($2)",
        "nocontribs": "Ní bhfuarthas aon athrú a bhí cosúil le na crítéir seo.",
-       "uctop": " (barr)",
+       "uctop": "(reatha)",
        "month": "Ón mhí seo (agus níos luaithe):",
        "year": "Ón bhliain seo (agus níos luaithe):",
        "sp-contributions-newbies": "Taispeáin dréachtaí ó chuntais nua amháin",
        "sp-contributions-newbies-sub": "Le cuntais nua",
        "sp-contributions-newbies-title": "Dréachtaí úsáideora do chuntasaí nua",
        "sp-contributions-blocklog": "Log coisc",
-       "sp-contributions-deleted": "dréachtaí úsáideora scriosta",
+       "sp-contributions-deleted": "dréachtaí {{GENDER:$1|úsáideora}} scriosta",
        "sp-contributions-uploads": "uaslódálacha",
        "sp-contributions-logs": "logaí",
        "sp-contributions-talk": "plé",
        "whatlinkshere-prev": "{{PLURAL:$1|roimhe|$1 roimhe}}",
        "whatlinkshere-next": "{{PLURAL:$1|ar aghaidh|$1 ar aghaidh}}",
        "whatlinkshere-links": "← naisc",
-       "whatlinkshere-hideredirs": "$1 athsheolaidh",
+       "whatlinkshere-hideredirs": "$1 an t-athsheoladh",
        "whatlinkshere-hidetrans": "$1 trasiamh",
        "whatlinkshere-hidelinks": "$1 nasc",
        "whatlinkshere-hideimages": "$1 naisc comhad",
        "movepagetalktext": "Aistreofar an leathanach plé go huathoibríoch '''ach ní tharlófar sin''':\n* má tá leathanach plé neamhfholamh ann cheana leis an teideal nua, nó\n* má bhaineann tú an tic den bhosca thíos.\n\nSna cásanna sin, caithfidh tú an leathanach a aistrigh nó a chumasc tú féin más maith leat.",
        "movenologintext": "Ní mór duit bheith i d'úsáideoir cláraithe agus [[Special:UserLogin|logáilte isteach]] chun leathanach a hathainmniú.",
        "movenotallowed": "Níl cead agat leathanaigh a athainmniú.",
-       "newtitle": "Go teideal nua",
+       "newtitle": "Teideal nua:",
        "move-watch": "Déan faire an leathanach seo",
        "movepagebtn": "Athainmnigh an leathanach",
        "pagemovedsub": "D'éirigh leis an athainmniú",
        "movelogpagetext": "Liosta is ea seo thíos de leathanaigh athainmnithe.",
        "movereason": "Fáth:",
        "revertmove": "athúsáid",
-       "delete_and_move_text": "==Tá scriosadh riachtanach==\nTá an leathanach sprice (\"[[:$1]]\") ann cheana féin.\nAr mhaith leat é a scriosadh chun áit a dhéanamh don athainmniú?",
+       "delete_and_move_text": "Tá an leathanach sprice (\"[[:$1]]\") ann cheana féin.\nAr mhaith leat é a scriosadh chun áit a dhéanamh don bhogadh?",
        "delete_and_move_confirm": "Tá, scrios an leathanach",
-       "delete_and_move_reason": "Scriosta chun áit a dhéanamh d'athainmniú",
+       "delete_and_move_reason": "Scriosta chun áit a dhéanamh do bhogadh ó [[$1]]",
        "selfmove": "Tá an ainm céanna ag an bhfoinse mar atá ar an ainm sprice; ní féidir leathanach a athainmniú bheith é féin.",
        "export": "Easportáil leathanaigh",
        "exporttext": "Is féidir an téacs agus an stair athraithe de leathanach áirithe nó sraith leathanach a easpórtáil, fillte i bpíosa XML.\nIs féidir é seo a iompórtáil i vicí eile MediaWiki trí úsáid an [[Special:Import|leathanach iompórtála]].\n\nChun leathanaigh a easpórtáil, cuir isteach na teidil sa bhosca thíos, gach teideal ar a líne féin, agus roghnaigh an leagan reatha in éineacht leis na sean-leaganacha agus stair an leathanaigh, nó an leagan reatha in éineacht le faisnéis faoin athrú deireanach.\n\nSa dara cás, is féidir leat nasc a úsáid, mar shampla [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] le haghaidh an leathanaigh \"[[{{MediaWiki:Mainpage}}]]\".",
        "filemissing": "Comhad ar iarraidh",
        "thumbnail_error": "Earráid agus mionsamhail a chruthú: $1",
        "import": "Iompórtáil leathanaigh",
-       "importinterwiki": "Iompórtáil trasna vicithe",
+       "importinterwiki": "Iompórtáil ó vicí eile",
        "import-interwiki-submit": "iompórtáil",
        "import-comment": "Nóta tráchta:",
-       "importtext": "Easportáil an comhad ón vici-fhoinse (le húsáid na [[Special:Export|tréithe easportáil]]), sábháil ar do dhíosca é agus uaslódáil anseo é.",
+       "importtext": "Easpórtáil an comhad ón vicí-fhoinse tríd an[[Special:Export|uirlis easpórtála]] a úsáid. Sábháil ar do ríomhaire é agus uaslódáil anseo é.",
        "import-revision-count": "{{PLURAL:$1|Leagan amháin|$1 leagain}}",
        "importnopages": "Níl aon leathanaigh chun iompórtáil",
        "importfailed": "Theip ar an iompórtáil: $1",
        "exif-orientation-3": "Rothlaithe trí 180°",
        "exif-orientation-4": "Iompaithe go hingearach",
        "exif-orientation-5": "Rothlaithe trí 90° CCW agus iompaithe go hingearach",
-       "exif-orientation-6": "Rothlaithe trí 90° CW",
+       "exif-orientation-6": "Rothlaithe trí 90° tuathalach",
        "exif-orientation-7": "Rothlaithe trí 90° CW agus iompaithe go hingearach",
-       "exif-orientation-8": "Rothlaithe trí 90° CCW",
+       "exif-orientation-8": "Rothlaithe trí 90° deiseal",
        "exif-planarconfiguration-1": "Formáid shmutánach",
        "exif-planarconfiguration-2": "Formáid phlánach",
        "exif-componentsconfiguration-0": "níl a leithéid ann",
        "watchlisttools-view": "Féach ar na hathruithe ábhartha",
        "watchlisttools-edit": "Féach ar do liosta faire ná cuir in eagar é",
        "watchlisttools-raw": "Cuir do amhliosta faire in eagar",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|plé]])",
        "version": "Leagan",
        "version-other": "Eile",
        "version-version": "($1)",
-       "version-license": "Ceadúnas",
+       "version-license": "Ceadúnas MediaWiki",
        "version-software": "Bogearraí suiteáilte",
        "version-software-version": "Leagan",
        "version-entrypoints-header-url": "URL",
        "fileduplicatesearch-info": "$1 × $2 picteillín<br />Méid comhad: $3<br />Saghas MIME: $4",
        "specialpages": "Leathanaigh speisialta",
        "specialpages-group-other": "Leathanaigh speisialta eile",
-       "specialpages-group-login": "Logáil isteach / cruthaigh cuntas",
+       "specialpages-group-login": "Logáil isteach / Cuntas a chruthú",
        "specialpages-group-changes": "Athruithe is déanaí agus logaí",
        "specialpages-group-users": "Úsáideoirí agus cearta",
        "specialpages-group-pages": "Liostaí leathanaigh",
        "specialpages-group-pagetools": "Uirslí leathanach",
-       "specialpages-group-wiki": "Sonraí vicí agus uirslí",
+       "specialpages-group-wiki": "Sonraí agus uirlisí",
        "specialpages-group-spam": "Uirlisí turscar",
        "blankpage": "Leathanach bán",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|chlib amháin|clib}}]]: $2)",
        "logentry-move-move": "{{GENDER:$2|Bhog}} $1 an leathanach $3 go $4",
        "feedback-cancel": "Cealaigh",
        "feedback-message": "Teachtaireacht:",
-       "searchsuggest-search": "Cuardaigh",
+       "searchsuggest-search": "Cuardaigh {{SITENAME}}",
        "expand_templates_remove_comments": "Scrios nótaí tráchta",
        "expand_templates_preview": "Réamhamharc"
 }
index e6cbbcb..42b617f 100644 (file)
        "yourname": "Kullanıcı adınız",
        "yourpassword": "Parol",
        "yourpasswordagain": "Parolu enidän yaz",
-       "remembermypassword": "Parolu hatırla (en fazla $1 {{PLURAL:$1|gün|gün}} için)",
        "yourdomainname": "Domen adınız",
        "login": "Gir",
        "nav-login-createaccount": "Gir / esap yarat",
        "permissionserrors": "İzin yannışları",
        "permissionserrorstext-withaction": "Aşaadaki {{PLURAL:$1|sebep|sebepler}}ä deyni yok $2 kuvediniz:",
        "recreate-moveddeleted-warn": "'''Bak: Siz yarattınız o sayfayı angısı ilerdän silindi.'''\n\nLäazım düşünmää bu sayfayı redaktat etmää devam etmää deyni.\nSayfanın silmää jurnalı raatlık için yazılêr burada:",
-       "cantcreateaccounttitle": "Yok nicä esap yaratılsın",
        "viewpagelogs": "Bu yaprak için jurnalları göster",
        "currentrev": "Şindiki versiya",
        "currentrev-asof": "$1 sayfanın şindiki halı",
index d6b8a34..e3a2daf 100644 (file)
        "yourname": "用户名:",
        "yourpassword": "密码:",
        "yourpasswordagain": "输过道密码:",
-       "remembermypassword": "记定我𠮶密码(顶多$1{{PLURAL:$1|日|日}})",
        "yourdomainname": "倷𠮶域名:",
        "externaldberror": "外部验证数据库出错,或倷更新伓正倷𠮶外部帐户。",
        "login": "登入",
        "undo-success": "个只编辑可以拖取销。请检查吖以确定个系倷想扤𠮶,接到保存修改去完成撤销编辑。",
        "undo-failure": "半中𠮶编辑有人挭仗,个只编辑伓可以拖取销。",
        "undo-summary": "取消由[[Special:Contributions/$2|$2]] ([[User talk:$2|对话]])所修订𠮶 $1",
-       "cantcreateaccounttitle": "新开伓正帐户",
        "cantcreateaccount-text": "IP 地址伓能 ('''$1''') 新开帐户。个可能系因为经常有来自倷𠮶学堂或网络供应商 (ISP)故意𠮶破坏扤得。",
        "viewpagelogs": "眵吖个页𠮶日志",
        "nohistory": "个页冇修改历史。",
index 1cb2ad7..3a58c92 100644 (file)
        "yourname": "用戶名:",
        "yourpassword": "密碼:",
        "yourpasswordagain": "輸過道密碼:",
-       "remembermypassword": "記定我嗰密碼(頂多$1{{PLURAL:$1|日|日}})",
        "yourdomainname": "倷嗰域名:",
        "externaldberror": "外部驗證資料庫出錯,或倷更新伓正倷嗰外部帳戶。",
        "login": "登入",
        "undo-success": "箇隻編輯可以拕取銷。請檢查吖以確定箇係倷想扤嗰,接到保存修改去完成撤銷編輯。",
        "undo-failure": "半中嗰編輯有人挭仗,箇隻編輯伓可以拕取銷。",
        "undo-summary": "取消由[[Special:Contributions/$2|$2]] ([[User talk:$2|對話]])所修訂嗰 $1",
-       "cantcreateaccounttitle": "新開伓正帳戶",
        "cantcreateaccount-text": "IP 位址伓能 ('''$1''') 新開帳戶。箇可能係因為經常有來自倷嗰學堂或網絡供應商 (ISP)故意嗰破壞扤得。",
        "viewpagelogs": "眵吖箇頁嗰日誌",
        "nohistory": "箇頁冇修改歷史。",
index c658811..93fb479 100644 (file)
        "yourpasswordagain": "Ath-sgrìobh facal-faire",
        "createacct-yourpasswordagain": "Dearbhaich am facal-faire",
        "createacct-yourpasswordagain-ph": "Cuir a-steach am facal-faire a-rithist",
-       "remembermypassword": "Cuimhnich gu bheil mi air logadh a-steach air a' choimpiutair seo (suas gu $1 {{PLURAL:$1|latha|latha|làithean|latha}})",
        "userlogin-remembermypassword": "Cum air logadh a-steach mi",
        "userlogin-signwithsecure": "Cleachd ceangal tèarainte",
        "yourdomainname": "An àrainn-lìn agad:",
        "activeusers-intro": "Seo liosta dhe na cleachdaichean a rinn gnìomh air choireigin am broinn {{PLURAL:$1|an $1 latha|an $1 latha|nan $1 làithean|an $1 latha}} mu dheireadh.",
        "activeusers-count": "$1 {{PLURAL:$1|ghnìomh|ghnìomh|gnìomhan|gnìomh}} am broinn {{PLURAL:$3|an $3 latha|an $3 latha|nan $3 làithean|an $3 latha}} mu dheireadh.",
        "activeusers-from": "Seall cleachdaichean o seo a-mach:",
-       "activeusers-hidebots": "Falaich na botaichean",
-       "activeusers-hidesysops": "Falaich na rianairean",
        "activeusers-noresult": "Cha deach cleachdaiche a lorg.",
        "listgrouprights": "Ceadan nam buidhnean chleachdaichean",
        "listgrouprights-summary": "chì thu liosta dhe na buidhnean chleachdaichean a tha san uicidh seo 's na ceadan inntrigidh aca.\nDh'fhaoidte gu bheil [[{{MediaWiki:Listgrouprights-helppage}}|barrachd fiosrachaidh]] mu cheadan fa leth ann.",
        "htmlform-cloner-create": "Cuir barrachd ris",
        "htmlform-cloner-delete": "Thoir air falbh",
        "htmlform-cloner-required": "Tha luach a dhìth.",
-       "sqlite-has-fts": "$1 le taic ri lorg teacsa shlàin",
-       "sqlite-no-fts": "$1 gun taic ri lorg teacsa shlàin",
        "logentry-delete-delete": "Sguab $1 às duilleag $3",
        "logentry-delete-restore": "Dh'aisig $1 duilleag $3",
        "logentry-delete-event": "Dh'atharraich $1 an fhaicsinneachd aig $5 {{PLURAL:$5|tachartas|thachartas|tachartasan|tachartas}} an loga air $3: $4",
index c1dcd52..8579fd8 100644 (file)
        "laggedslavemode": "'''Aviso:''' A páxina pode non conter as actualizacións recentes.",
        "readonly": "Base de datos pechada",
        "enterlockreason": "Dea unha razón para o peche, incluíndo unha estimación de até cando se manterá",
-       "readonlytext": "Nestes intres a base de datos está pechada a novas entradas e outras modificacións, probablemente debido a procesos de mantemento, tras os que volverá á normalidade.\n\nO administrador de sistemas que a pechou deu esta explicación: $1",
+       "readonlytext": "Nestes intres a base de datos está pechada a novas entradas e outras modificacións, probablemente debido a procesos de mantemento, tralos que volverá á normalidade.\n\nO administrador do sistema que a pechou deu esta explicación: $1",
        "missing-article": "A base de datos non atopou o texto da páxina chamada \"$1\" $2, que debera ter atopado.\n\nNormalmente, isto está causado por seguir unha ligazón cara a unha diferenza vella ou a unha páxina que foi borrada.\n\nSe este non é o caso, poida que atopase un erro no software.\nPor favor, comuníquello a un [[Special:ListUsers/sysop|administrador]] tomando nota do enderezo URL.",
        "missingarticle-rev": "(nº de revisión: $1)",
        "missingarticle-diff": "(dif: $1, $2)",
        "readonly_lag": "A base de datos bloqueouse automaticamente mentres os servidores levan a cabo a sincronización co servidor principal",
-       "nonwrite-api-promise-error": "A cabeceira HTTP  'Promise-Non-Write-API-Action' foi enviada pero a petición foi feita a un módulo de escritura da API.",
+       "nonwrite-api-promise-error": "Enviouse a cabeceira HTTP \"Promise-Non-Write-API-Action\", pero a petición fíxose a un módulo de escritura da API.",
        "internalerror": "Erro interno",
        "internalerror_info": "Erro interno: $1",
        "internalerror-fatal-exception": "Excepción grave de tipo \"$1\"",
        "no-null-revision": "Non se puido crear a nova revisión nula para a páxina \"$1\"",
        "badtitle": "Título incorrecto",
        "badtitletext": "O título da páxina pedida non era válido, estaba baleiro ou proviña dunha ligazón interlingüística ou interwiki incorrecta.\nPoida que conteña un ou máis caracteres dos que non se poden empregar nos títulos.",
-       "title-invalid-empty": "O título de páxina solicitado está baleiro ou só contén o nome do espazo de nomes.",
+       "title-invalid-empty": "O título de páxina solicitado está baleiro ou só contén o nome dun espazo de nomes.",
        "title-invalid-utf8": "O título de páxina solicitado contén unha secuencia UTF-8 inválida.",
-       "title-invalid-interwiki": "O título da páxina solicitada contén unha ligazón interwiki que non pode usarse nos títulos.",
-       "title-invalid-talk-namespace": "O título de páxina solicitado refírese a unha páxina de conversa que pode non existir.",
+       "title-invalid-interwiki": "O título de páxina solicitado contén unha ligazón interwiki que non se pode utilizar nos títulos.",
+       "title-invalid-talk-namespace": "O título de páxina solicitado fai referencia a unha páxina de conversa que pode non existir.",
        "title-invalid-characters": "O título de páxina solicitado contén caracteres inválidos: \"$1\".",
-       "title-invalid-relative": "O título ten unha ruta relativa. Os títulos de páxina relativos (./, ../) son inválidos, porque non van ser accesibles cando se consulten co navegador do usuario.",
+       "title-invalid-relative": "O título ten unha ruta relativa. Os títulos de páxina relativos (./, ../) son inválidos, porque a miúdo non son accesibles cando se consultan desde o navegador do usuario.",
        "title-invalid-magic-tilde": "O título de páxina solicitado contén unha secuencia con tiles inválida (<nowiki>~~~</nowiki>).",
-       "title-invalid-too-long": "O título de páxina solicitado é moi longo. Non pode ser maior de {{PLURAL:$1|byte|bytes}} en codificación UTF-8.",
-       "title-invalid-leading-colon": "O título de páxina solicitado contén un punto e coma inválido ó comezo.",
+       "title-invalid-too-long": "O título de páxina solicitado é moi longo. Non pode ser maior de $1 {{PLURAL:$1|byte|bytes}} en codificación UTF-8.",
+       "title-invalid-leading-colon": "O título de páxina solicitado contén un carácter de dous puntos non permitido ao comezo.",
        "perfcached": "Esta información é da memoria caché e pode ser que non estea completamente actualizada. Hai un máximo de {{PLURAL:$1|$1 resultado dispoñible|$1 resultados dispoñibles}} na caché.",
        "perfcachedts": "Esta información é da memoria caché. Última actualización: $2 ás $3. Hai un máximo de {{PLURAL:$4|$4 resultado dispoñible|$4 resultados dispoñibles}} na caché.",
        "querypage-no-updates": "Neste momento están desactivadas as actualizacións nesta páxina. O seu contido non se modificará.",
        "viewsource": "Ver o código fonte",
        "viewsource-title": "Ver o código fonte de \"$1\"",
        "actionthrottled": "Acción limitada",
-       "actionthrottledtext": "Como medida contra os abusos, a acción que está realizando está limitada a un número determinado de veces nun periodo curto de tempo, e superou ese límite.\nInténteo de novo nuns minutos.",
+       "actionthrottledtext": "Como medida contra os abusos, ten limitada a acción que está realizando a un número determinado de veces nun período curto de tempo, e vostede superou ese límite.\nInténteo de novo nuns minutos.",
        "protectedpagetext": "Esta páxina foi protexida para evitar a edición e outras accións.",
        "viewsourcetext": "Pode ver e copiar o código fonte desta páxina.",
        "viewyourtext": "Pode ver e copiar o código fonte <strong>das súas edicións</strong> nesta páxina.",
        "mypreferencesprotected": "Non ten os permisos necesarios para editar as súas preferencias.",
        "ns-specialprotected": "Non se poden editar as páxinas no espazo de nomes \"{{ns:special}}\".",
        "titleprotected": "Este título foi protexido da creación por [[User:$1|$1]].\nO motivo achegado é <em>$2</em>.",
-       "filereadonlyerror": "Non se puido modificar o ficheiro \"$1\" porque o repositorio \"$2\" está en modo de só lectura.\n\nO administrador de sistemas que bloqueou o repositorio achegou este motivo: \"$3\".",
+       "filereadonlyerror": "Non se puido modificar o ficheiro \"$1\" porque o repositorio \"$2\" está en modo de só lectura.\n\nO administrador do sistema que bloqueou o repositorio achegou este motivo: \"$3\".",
        "invalidtitle-knownnamespace": "Título inválido co espazo de nomes \"$2\" e o texto \"$3\"",
        "invalidtitle-unknownnamespace": "Título inválido cun número de espazo de nomes, $1, descoñecido e o texto \"$2\"",
        "exception-nologin": "Non accedeu ao sistema",
        "exception-nologin-text": "Acceda ao sistema para poder realizar esa acción ou acceder a esa páxina.",
        "exception-nologin-text-manual": "Debe $1 para poder realizar esa acción ou acceder a esa páxina.",
-       "virus-badscanner": "Configuración errónea: escáner de virus descoñecido: ''$1''",
+       "virus-badscanner": "Configuración errónea: Escáner de virus descoñecido: <em>$1</em>",
        "virus-scanfailed": "fallou o escaneado (código $1)",
        "virus-unknownscanner": "antivirus descoñecido:",
        "logouttext": "'''Agora está fóra do sistema.'''\n\nTeña en conta que algunhas páxinas poden continuar aparecendo como se aínda estivese dentro do sistema, ata que limpe a caché do seu navegador.",
        "cannotlogoutnow-title": "Non se pode saír da sesión agora mesmo",
        "cannotlogoutnow-text": "Non é posible saír da sesión cando se usa $1.",
        "welcomeuser": "Reciba a nosa benvida, $1!",
-       "welcomecreation-msg": "A súa conta foi creada correctamente.\nNon esqueza personalizar as súas [[Special:Preferences|preferencias de {{SITENAME}}]].",
+       "welcomecreation-msg": "A súa conta creouse correctamente.\nNon esqueza personalizar as súas [[Special:Preferences|preferencias]] de {{SITENAME}}.",
        "yourname": "Nome de usuario:",
        "userlogin-yourname": "Nome de usuario",
        "userlogin-yourname-ph": "Insira o seu nome de usuario",
        "createacct-yourpasswordagain-ph": "Insira o contrasinal outra vez",
        "userlogin-remembermypassword": "Manter a miña conexión",
        "userlogin-signwithsecure": "Utilizar a conexión segura",
-       "cannotlogin-title": "Non se pode acceder ó sistema",
-       "cannotlogin-text": "O acceso ó sistema non está dispoñible.",
+       "cannotlogin-title": "Non se pode acceder ao sistema",
+       "cannotlogin-text": "O acceso ao sistema non está dispoñible.",
        "cannotloginnow-title": "Non se pode iniciar a sesión agora mesmo",
        "cannotloginnow-text": "Non é posible iniciar a sesión cando se usa $1.",
        "cannotcreateaccount-title": "Non se poden crear contas de usuario",
-       "cannotcreateaccount-text": "A creación directa de contas de usuario non está habilitada nesta wiki.",
+       "cannotcreateaccount-text": "A creación directa de contas de usuario non está activada neste wiki.",
        "yourdomainname": "O seu dominio:",
        "password-change-forbidden": "Non pode mudar os contrasinais neste wiki.",
        "externaldberror": "Ou ben se produciu un erro da base de datos na autenticación externa ou ben non se lle permite actualizar a súa conta externa.",
        "userlogin-resetpassword-link": "Esqueceu o contrasinal?",
        "userlogin-helplink2": "Axuda co rexistro",
        "userlogin-loggedin": "Xa accedeu ao sistema como {{GENDER:$1|$1}}.\nUtilice o formulario inferior para acceder como outro usuario.",
-       "userlogin-reauth": "Debe conectarse de novo para verificar que é {{GENDER:$1|$1}}.",
+       "userlogin-reauth": "Debe conectarse de novo para verificar que vostede é {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Crear outra conta",
        "createacct-emailrequired": "Enderezo de correo electrónico",
        "createacct-emailoptional": "Enderezo de correo electrónico (opcional)",
        "createaccountreason": "Motivo:",
        "createacct-reason": "Motivo",
        "createacct-reason-ph": "Por que crea outra conta?",
-       "createacct-reason-help": "Mensaxe que se mostra no rexistro de creación de contas",
+       "createacct-reason-help": "Mensaxe mostrada no rexistro de creación de contas",
        "createacct-submit": "Crear a conta",
        "createacct-another-submit": "Crear a conta",
        "createacct-continue-submit": "Continuar a creación da conta",
        "nocookiesnew": "A conta de usuario foi creada, pero non accedeu ao sistema.\n{{SITENAME}} para rexistrar os usuarios.\nVostede ten as cookies deshabilitadas.\nPor favor, habilíteas e logo acceda ao sistema co seu novo nome de usuario e contrasinal.",
        "nocookieslogin": "{{SITENAME}} usa cookies para rexistrar os usuarios.\nVostede ten as cookies deshabilitadas.\nPor favor, habilíteas e inténteo de novo.",
        "nocookiesfornew": "Non se creou a conta de usuario porque non puidemos confirmar a súa orixe.\nAsegúrese de que ten as cookies habilitadas, volva cargar a páxina e inténteo de novo.",
-       "createacct-loginerror": "A conta creouse correctamente, pero non se puido conectar automaticamente. Proceda ó [[Special:UserLogin|acceso manual]].",
+       "createacct-loginerror": "A conta creouse correctamente, pero non se puido conectar automaticamente. Vaia ao [[Special:UserLogin|acceso manual]].",
        "noname": "Non especificou un nome de usuario válido.",
-       "loginsuccesstitle": "Conectado",
+       "loginsuccesstitle": "Accedeu ao sistema",
        "loginsuccess": "<strong>Accedeu ao sistema de {{SITENAME}} como \"$1\".</strong>",
        "nosuchuser": "Non existe ningún usuario chamado \"$1\".\nOs nomes de usuario diferencian entre maiúsculas e minúsculas.\nVerifique a ortografía ou [[Special:CreateAccount|cree unha nova conta]].",
        "nosuchusershort": "Non existe ningún usuario chamado \"$1\".\nVerifique o nome que inseriu.",
        "wrongpassword": "O contrasinal escrito é incorrecto.\nPor favor, insira outro.",
        "wrongpasswordempty": "O campo do contrasinal estaba en branco.\nPor favor, inténteo de novo.",
        "passwordtooshort": "Os contrasinais deben conter, como mínimo, {{PLURAL:$1|1 carácter|$1 caracteres}}.",
-       "passwordtoolong": "Os contrasinais non deben ser máis longo de {{PLURAL:$1|1 carácter|$1 caracteres}}.",
-       "passwordtoopopular": "Os contrasinais escollidos máis habitualmente non poden usarse. Por favor, escolle un contrasinal máis único.",
+       "passwordtoolong": "Os contrasinais non poden ser máis longo de {{PLURAL:$1|1 carácter|$1 caracteres}}.",
+       "passwordtoopopular": "Non pode utilizar un contrasinal dos habitualmente elixidos pola xente. Por favor, escolla un contrasinal máis orixinal.",
        "password-name-match": "O seu contrasinal debe ser diferente do seu nome de usuario.",
        "password-login-forbidden": "O uso deste nome de usuario e contrasinal foi prohibido.",
        "mailmypassword": "Restablecer o contrasinal",
        "passwordremindertitle": "Novo contrasinal temporal para {{SITENAME}}",
-       "passwordremindertext": "Alguén (probablemente vostede, desde o enderezo IP $1) solicitou un novo\ncontrasinal para acceder a {{SITENAME}} ($4). Un contrasinal temporal para o usuario\n\"$2\" foi creado e fixado como \"$3\". Se esa foi a súa\nintención, necesitará acceder ao sistema e escoller un novo contrasinal agora.\nO seu contrasinal temporal caducará {{PLURAL:$5|nun día|en $5 días}}.\n\nSe foi alguén diferente o que fixo esta solicitude ou se xa se lembra do seu contrasinal\ne non o quere modificar, pode ignorar esta mensaxe e\ncontinuar a utilizar o seu contrasinal vello.",
+       "passwordremindertext": "Alguén (probablemente vostede, desde o enderezo IP $1) solicitou un novo\ncontrasinal para acceder a {{SITENAME}} ($4). Creouse un contrasinal temporal para o usuario\n\"$2\" e quedou establecido como \"$3\". Se esa foi a súa\nintención, terá que acceder ao sistema e escoller un novo contrasinal agora.\nO seu contrasinal temporal caducará {{PLURAL:$5|nun día|en $5 días}}.\n\nSe foi outra persoa a que fixo esta solicitude ou se xa se lembra do seu contrasinal\ne non o quere modificar, pode ignorar esta mensaxe e\ncontinuar a utilizar o seu contrasinal vello.",
        "noemail": "O usuario \"$1\" non posúe ningún enderezo de correo electrónico rexistrado.",
        "noemailcreate": "Ten que proporcionar un enderezo de correo electrónico válido",
        "passwordsent": "Enviouse un contrasinal novo ao enderezo de correo electrónico rexistrado de \"$1\".\nPor favor, acceda ao sistema de novo tras recibilo.",
-       "blocked-mailpassword": "O seu enderezo IP está bloqueado para editar. Tampouco se lle permite usar a función de recuperación do contrasinal para evitar abusos do sistema.",
+       "blocked-mailpassword": "O seu enderezo IP está bloqueado fronte á edición. Tampouco se lle permite usar a función de recuperación do contrasinal para evitar abusos do sistema.",
        "eauthentsent": "Envióuselle un correo electrónico de confirmación ao enderezo especificado.\nAntes de que se lle envíe calquera outro correo a esta conta terá que seguir as instrucións que aparecen nesa mensaxe para confirmar que a conta é realmente súa.",
        "throttled-mailpassword": "Enviouse un correo electrónico de restablecemento do contrasinal {{PLURAL:$1|na última hora|nas últimas $1 horas}}.\nPara evitar o abuso do sistema só se enviará unha mensaxe de restablecemento cada {{PLURAL:$1|hora|$1 horas}}.",
        "mailerror": "Produciuse un erro ao enviar o correo electrónico: $1",
-       "acct_creation_throttle_hit": "Alguén que visitou este wiki co seu enderezo IP creou {{PLURAL:$1|unha conta|$1 contas}} nos últimos ̩$2 días, que é o máximo permitido neste período de tempo.\nComo resultado, os visitantes que usen este enderezo IP non poden crear máis contas nestes intres.",
+       "acct_creation_throttle_hit": "Alguén que visitou este wiki co seu enderezo IP creou {{PLURAL:$1|unha conta|$1 contas}} nun breve período de tempo ($2), que é o máximo permitido neste período de tempo.\nComo resultado, os visitantes que usen este enderezo IP non poden crear máis contas nestes intres.",
        "emailauthenticated": "O seu enderezo de correo electrónico foi confirmado o $2 ás $3.",
        "emailnotauthenticated": "O seu enderezo de correo electrónico aínda non foi confirmado.\nNon se enviará ningunha mensaxe por ningunha das seguintes características.",
        "noemailprefs": "Especifique un enderezo de correo electrónico se quere que funcione esta opción.",
        "createacct-another-realname-tip": "O nome real é opcional.\nSe escolle dalo utilizarase para atribuír ao usuario o seu traballo.",
        "pt-login": "Acceder ao sistema",
        "pt-login-button": "Acceder ao sistema",
-       "pt-login-continue-button": "Continuar a conexión",
+       "pt-login-continue-button": "Continuar co inicio de sesión",
        "pt-createaccount": "Crear unha conta",
        "pt-userlogout": "Saír",
        "php-mail-error-unknown": "Erro descoñecido na función mail() do PHP.",
        "newpassword": "Contrasinal novo:",
        "retypenew": "Insira outra vez o novo contrasinal:",
        "resetpass_submit": "Establecer o contrasinal e acceder ao sistema",
-       "changepassword-success": "O seu contrasinal foi modificado!",
+       "changepassword-success": "Modificouse o seu contrasinal!",
        "changepassword-throttled": "Fixo demasiados intentos de acceder ao sistema.\nPor favor, agarde $1 antes de probar outra vez.",
        "botpasswords": "Contrasinais de bots",
        "botpasswords-summary": "Os <em>contrasinais de bots</em> permiten acceder a unha conta de usuario por medio da API sen usar as crecenciais de acceso da conta principal. Os dereitos de usuario dispoñibles cando se accede ao sistema cun contrasinal de bot poden estar restrinxidos.\n\nSe non sabe por que quere facer isto, probablemente signifique que non o queira facer. Ningunha persoa debería pedirlle a vostede que xere unha destas claves para entregarlla.",
        "botpasswords-label-delete": "Borrar",
        "botpasswords-label-resetpassword": "Restablecer o contrasinal",
        "botpasswords-label-grants": "Permisos aplicables:",
-       "botpasswords-help-grants": "Cada permiso dá acceso aos permisos de usuario listados que a conta xa teña. Consulte a [[Special:ListGrants|táboa de permisos]] para obter máis información.",
+       "botpasswords-help-grants": "As concesións permiten o acceso aos dereitos que xa teña a conta de usuario. A activación dunha concesión non dá acceso a ningún dereito que a súa conta de usuario non tivese doutro xeito. Consulte a [[Special:ListGrants|táboa de permisos]] para obter máis información.",
        "botpasswords-label-grants-column": "Concedido",
        "botpasswords-bad-appid": "O nome de bot \"$1\" non é válido.",
        "botpasswords-insert-failed": "Erro ao engadir o nome de bot \"$1\". Revise se xa foi engadido previamente.",
        "resetpass-abort-generic": "Unha extensión cancelou a modificación do contrasinal.",
        "resetpass-expired": "O seu contrasinal caducou. Defina un novo contrasinal para acceder.",
        "resetpass-expired-soft": "O seu contrasinal caducou e debe restablecelo. Escolla un novo contrasinal ou prema en \"{{int:authprovider-resetpass-skip-label}}\" para restablecelo máis tarde.",
-       "resetpass-validity-soft": "O seu contrasinal non é válido: $1\n\nEscolla un novo contrasinal ou prema en \"{{int:authprovider-resetpass-skip-label}}\" para restablecelo máis tarde.",
+       "resetpass-validity-soft": "O seu contrasinal non é válido: $1\n\nEscolla un novo contrasinal agora ou prema en \"{{int:authprovider-resetpass-skip-label}}\" para restablecelo máis tarde.",
        "passwordreset": "Restablecer o contrasinal",
        "passwordreset-text-one": "Encha este formulario para restablecer o seu contrasinal.",
        "passwordreset-text-many": "{{PLURAL:$1|Encha un dos campos para recibir por correo electrónico un contrasinal temporal.}}",
        "passwordreset-emailtext-ip": "Alguén (probablemente vostede, desde o enderezo IP $1) solicitou o restablecemento do seu\ncontrasinal de {{SITENAME}} ($4). {{PLURAL:$3|A seguinte conta de usuario está asociada|As seguintes contas de usuarios están asociadas}}\na este enderezo de correo electrónico:\n\n$2\n\n{{PLURAL:$3|Este contrasinal temporal caducará|Estes contrasinais temporais caducarán}} {{PLURAL:$5|nun día|en $5 días}}.\nDebería acceder ao sistema e elixir un novo contrasinal agora. Se outra persoa fixo esta\nsolicitude ou se lembrou o seu contrasinal orixinal e xa non o quere cambiar,\nignore esta mensaxe e continúe empregando o seu contrasinal vello.",
        "passwordreset-emailtext-user": "O usuario $1 solicitou o restablecemento do contrasinal de {{SITENAME}}\n($4). {{PLURAL:$3|A seguinte conta de usuario está asociada|As seguintes contas de usuarios están asociadas}}\na este enderezo de correo electrónico:\n\n$2\n\n{{PLURAL:$3|Este contrasinal temporal caducará|Estes contrasinais temporais caducarán}} {{PLURAL:$5|nun día|en $5 días}}.\nDebería acceder ao sistema e elixir un novo contrasinal agora. Se outra persoa fixo esta\nsolicitude ou se lembrou o seu contrasinal orixinal e xa non o quere cambiar,\nignore esta mensaxe e continúe empregando o seu contrasinal vello.",
        "passwordreset-emailelement": "Nome de usuario: \n$1\n\nContrasinal temporal: \n$2",
-       "passwordreset-emailsentemail": "Se esta é unha dirección de correo electrónico asociada á súa conta, entón enviarase un correo electrónico para o restablecemento do seu contrasinal.",
-       "passwordreset-emailsentusername": "Se hai unha dirección de correo electrónico asociada con este nome de usuario, entón enviarase un correo electrónico para o restablecemento do contrasinal.",
-       "passwordreset-emailsent-capture2": "{{PLURAL:$1|O correo de reinicialización do contrasinal foi enviado|Os correos de reinicialización do contrasinal foron enviados}}. {{PLURAL:$1|O nome de usuario e contrasinal móstrase aquí|A lista de nomes de usuarios e contrasinais móstranse aquí}}.",
-       "passwordreset-emailerror-capture2": "O envío do correo {{GENDER:$2|ó usuario|á usuaria}} fallou: $1 {{PLURAL:$3|O nome de usuario e contrasinal móstrase aquí|A lista de usuarios e contrasinais móstranse aquí}}.",
+       "passwordreset-emailsentemail": "Se este enderezo de correo electrónico está asociado á súa conta, entón enviarase un correo electrónico para o restablecemento do seu contrasinal.",
+       "passwordreset-emailsentusername": "Se hai un enderezo de correo electrónico asociado a este nome de usuario, entón enviarase un correo electrónico para o restablecemento do contrasinal.",
+       "passwordreset-emailsent-capture2": "{{PLURAL:$1|Enviouse o correo electrónico co restablecemento do contrasinal. O nome de usuario e o contrasinal móstranse aquí.|Enviáronse os correos electrónicos cos restablecementos dos contrasinais. A lista de nomes de usuario e contrasinais móstrase aquí.}}",
+       "passwordreset-emailerror-capture2": "O envío do correo {{GENDER:$2|ao usuario|á usuaria}} fallou: $1 {{PLURAL:$3|O nome de usuario e o contrasinal móstranse aquí.|A lista de nomes de usuario e contrasinais móstrase aquí.}}",
        "passwordreset-nocaller": "Cómpre proporcionar un chamador",
        "passwordreset-nosuchcaller": "O chamador non existe: $1",
-       "passwordreset-ignored": "A reinicialización do contrasinal non puido realizarse. Quizais non configurou o provedor?",
-       "passwordreset-invalideamil": "O enderezo de correo electrónico non é válido",
-       "passwordreset-nodata": "Non se indicou o nome de usuario ou a dirección de correo electrónico",
+       "passwordreset-ignored": "Non se puido completar o restablecemento do contrasinal. Quizais non configurou o provedor?",
+       "passwordreset-invalidemail": "O enderezo de correo electrónico non é válido",
+       "passwordreset-nodata": "Non se indicou nin un nome de usuario nin un enderezo de correo electrónico",
        "changeemail": "Cambiar ou eliminar o enderezo de correo electrónico",
-       "changeemail-header": "Encha este formulario para cambiar o seu enderezo de correo electrónico. Se vostede quere eliminar a asociación da dirección de correo electrónico da súa conta, deixe en branco a nova dirección de correo electrónico cando envíe o formulario.",
+       "changeemail-header": "Encha este formulario para cambiar o seu enderezo de correo electrónico. Se quere eliminar a asociación do enderezo de correo electrónico á súa conta, deixe en branco o novo enderezo de correo electrónico cando envíe o formulario.",
        "changeemail-no-info": "Debe rexistrarse para acceder directamente a esta páxina.",
        "changeemail-oldemail": "Enderezo de correo electrónico actual:",
        "changeemail-newemail": "Novo enderezo de correo electrónico:",
-       "changeemail-newemail-help": "Este campo debe deixarse en branco se quere eliminar o seu enderezo de correo electrónico. Non será capaz de redefinir a súa clave nin recibir mensaxes electrónicas desta wiki se elimina o correo electrónico.",
+       "changeemail-newemail-help": "Este campo debe deixarse en branco se quere eliminar o seu enderezo de correo electrónico. Non poderá restablecer o seu contrasinal se o esquece nin recibir mensaxes de correo electrónico desde este wiki se elimina o enderezo.",
        "changeemail-none": "(ningún)",
        "changeemail-password": "O seu contrasinal en {{SITENAME}}:",
        "changeemail-submit": "Cambiar o correo electrónico",
        "anoneditwarning": "<strong>Aviso:</strong> Non accedeu ao sistema. O seu enderezo IP será visible se fai algunha edición. Se <strong>[$1 accede ao sistema]</strong> ou <strong>[$2 crea unha conta]</strong>, as súas edicións serán atribuídas ao seu nome de usuario e obterá outros beneficios.",
        "anonpreviewwarning": "''Non accedeu ao sistema. Se garda a páxina, o seu enderezo IP quedará rexistrado no historial de edicións.''",
        "missingsummary": "'''Aviso:''' Esqueceu incluír o texto do campo resumo.\nSe preme en \"{{int:savearticle}}\" a súa edición gardarase sen ningunha descrición da edición.",
-       "selfredirect": "<strong>Atención:</strong> Está redirecionando esta páxina a ela mesma. Vostede pode ter especificado a páxina incorrecta para a redireción, ou pode que estea a editar a páxina incorrecta. Se preme \"{{int:savearticle}}\" de novo, crearase a redireción de tódolos xeitos.",
+       "selfredirect": "<strong>Atención:</strong> Está redirixindo esta páxina a si mesma.\nQuizais especificou incorrectamente a páxina de destino ou poida que estea a editar unha páxina errónea.\nSe preme en \"{{int:savearticle}}\" de novo, crearase a redireción de calquera xeito.",
        "missingcommenttext": "Por favor, escriba un comentario a continuación.",
-       "missingcommentheader": "<strong>Aviso:</strong> Non escribiu ningún texto no asunto deste comentario.\nSe preme sobre \"{{int:savearticle}}\", a súa edición gardarase sen el.",
+       "missingcommentheader": "<strong>Aviso:</strong> Non escribiu ningún texto no asunto deste comentario.\nSe preme en \"{{int:savearticle}}\" de novo, a súa edición gardarase sen el.",
        "summary-preview": "Vista previa do resumo:",
        "subject-preview": "Vista previa do asunto:",
        "previewerrortext": "Produciuse un erro ao intentar previsualizar os cambios.",
        "blockedtitle": "O usuario está bloqueado",
-       "blockedtext": "'''O seu nome de usuario ou enderezo IP foi bloqueado.'''\n\nO bloqueo foi realizado por $1.\nA razón que deu foi ''$2''.\n\n* Inicio do bloqueo: $8\n* Caducidade do bloqueo: $6\n* Pretendeuse bloquear: $7\n\nPode contactar con $1 ou con calquera outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir este bloqueo.\nNon pode empregar a característica \"Enviar un correo electrónico a este usuario\" a non ser que dispoña dun enderezo electrónico válido rexistrado nas súas [[Special:Preferences|preferencias de usuario]] e que o seu uso non fose bloqueado.\nO seu enderezo IP actual é $3 e o ID do bloqueo é #$5.\nPor favor, inclúa eses datos nas consultas que faga.",
+       "blockedtext": "<strong>Bloqueouse o seu nome de usuario ou enderezo IP.</strong>\n\n$1 estableceu o bloqueo.\nO motivo que achegou foi <em>$2</em>.\n\n* Inicio do bloqueo: $8\n* Caducidade do bloqueo: $6\n* Pretendeuse bloquear: $7\n\nPode contactar con $1 ou con calquera outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir este bloqueo.\nNon pode empregar a característica \"Enviar un correo electrónico a este usuario\" a non ser que dispoña dun enderezo electrónico válido rexistrado nas súas [[Special:Preferences|preferencias de usuario]] e que o seu uso non fose bloqueado.\nO seu enderezo IP actual é $3 e o identificador do bloqueo é #$5.\nPor favor, inclúa todos estes datos nas consultas que faga.",
        "autoblockedtext": "O seu enderezo IP foi bloqueado automaticamente porque foi empregado por outro usuario que foi bloqueado por $1.\nA razón que deu foi a seguinte:\n\n:''$2''\n\n* Inicio do bloqueo: $8\n* Caducidade do bloqueo: $6\n* Pretendeuse bloquear: $7\n\nPode contactar con $1 ou con calquera outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir este bloqueo.\n\nTeña en conta que non pode empregar a característica \"Enviar un correo electrónico a este usuario\" a non ser que dispoña dun enderezo electrónico válido rexistrado nas súas [[Special:Preferences|preferencias de usuario]] e e que o seu uso non fose bloqueado.\n\nO seu enderezo IP actual é $3 e o ID do bloqueo é #$5.\nPor favor, inclúa eses datos nas consultas que faga.",
        "blockednoreason": "non se deu ningunha razón",
        "whitelistedittext": "Debe $1 para poder editar páxinas.",
        "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": "<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>.",
+       "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> nos Mac) e logo a <em>Privacidade e seguridade → Limpar os 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!'''",
        "userinvalidcssjstitle": "<strong>Aviso:</strong> Non hai ningunha aparencia chamada \"$1\".\nLembre que as páxinas .css e .js personalizadas utilizan un título en minúsculas, como por exemplo \"{{ns:user}}:Exemplo/vector.css\" no canto de \"{{ns:user}}:Exemplo/Vector.css\".",
        "updated": "(Actualizado)",
        "note": "'''Nota:'''",
-       "previewnote": "'''Lembre que esta é só unha vista previa e que aínda non gardou os seus cambios!'''",
+       "previewnote": "<strong>Lembre que esta é só unha vista previa.</strong>\nAínda non gardou os seus cambios!",
        "continue-editing": "Ir ata a caixa de edición",
        "previewconflict": "Esta vista previa mostra o texto na área superior tal e como aparecerá se escolle gardar.",
-       "session_fail_preview": "Sentímolo! Non podemos procesar a súa edición porque se perderon os datos de inicio da sesión.\n\nA súa sesión pode que fose pechada. <strong> Por favor, verifique se aínda está conectado e probe de novo</strong>. En caso de que siga sen funcionar, intente [[Special:UserLogout|saír]] e volver a entrar na súa conta, e verifique que o seu navegador permite o uso de \"cookies\" neste sitio.",
-       "session_fail_preview_html": "Sentímolo! Non foi posible procesar a edición debido á pérdida de datos da súa sesión.\n\n<em>Como a wiki {{SITENAME}} posibilita o uso de HTML puro, a vista previa está oculta por precaución contra ataques con JavaScript.</em>\n\n<strong>Se este é un intento lexítimo de edición probe de novo, por favor</strong>. \nEn caso de que continúe sen funcionar, intente [[Special:UserLogout|saír]] e volver a entrar na súa conta, e verifique se o seu navegador permite o uso de ''cookies'' deste sitio.",
+       "session_fail_preview": "Sentímolo! Non puidemos procesar a súa edición porque se perderon os datos de inicio da sesión.\n\nPoida que se pechase a súa sesión. <strong>Por favor, verifique que ten a sesión aberta e probe de novo.</strong>\nEn caso de que siga sen funcionar, intente [[Special:UserLogout|saír]] e volver entrar na súa conta e verifique que o seu navegador permite o uso de cookies neste sitio.",
+       "session_fail_preview_html": "Sentímolo! Non foi posible procesar a edición debido á perda dos datos da súa sesión.\n\n<em>Dado que {{SITENAME}} ten activado o uso de HTML puro, a vista previa está oculta por precaución contra ataques mediante JavaScript.</em>\n\n<strong>Se este é un intento lexítimo de edición, probe de novo.</strong>\nEn caso de que continúe sen funcionar, intente [[Special:UserLogout|saír]] e volver entrar na súa conta. Verifique tamén se o seu navegador permite o uso de cookies deste sitio.",
        "token_suffix_mismatch": "'''Rexeitouse a súa edición porque o seu cliente confundiu os signos de puntuación na edición.'''\nRexeitouse a edición para evitar que se corrompa o texto do artigo.\nIsto pode acontecer porque estea a empregar un servizo de proxy anónimo defectuoso baseado na web.",
        "edit_form_incomplete": "'''Algunhas partes do formulario de edición non chegaron ao servidor; comprobe que a súa modificación está intacta e inténteo de novo.'''",
        "editing": "Editando \"$1\"",
        "nonunicodebrowser": "'''Atención: O seu navegador non soporta o Unicode.'''\nExiste unha solución que lle permite editar páxinas con seguridade: os caracteres non incluídos no ASCII aparecerán na caixa de edición como códigos hexadecimais.",
        "editingold": "'''Atención: Está editando unha revisión vella desta páxina.'''\nSe a garda, perderanse os cambios realizados tras esta revisión.",
        "yourdiff": "Diferenzas",
-       "copyrightwarning": "Por favor, teña en conta que todas as contribucións a {{SITENAME}} considéranse publicadas baixo a $2 (vexa $1 para máis detalles). Se non quere que o que escriba se edite sen piedade e se redistribúa sen límites, entón non o envíe aquí.<br />\nAo mesmo tempo, prométanos que o que escribiu é da súa autoría ou que está copiado dun recurso do dominio público ou que permite unha liberdade semellante.\n'''NON ENVÍE MATERIAL CON DEREITOS DE AUTOR SEN PERMISO!'''",
-       "copyrightwarning2": "Por favor, decátese de que todas as súas contribucións a {{SITENAME}} poden ser editadas, alteradas ou eliminadas por outras persoas. Se non quere que os seus escritos sexan editados sen piedade, non os publique aquí.<br />\nDo mesmo xeito, comprométese a que o que vostede escriba sexa da súa autoría ou copiado dunha fonte de dominio público ou recurso público semellante (vexa $1 para detalles).\n'''NON ENVÍE SEN PERMISO TRABALLOS CON DEREITOS DE COPIA!'''",
+       "copyrightwarning": "Por favor, teña en conta que todas as contribucións feitas en {{SITENAME}} se consideran publicadas baixo a $2 (consulte $1 para obter máis detalles).\nSe non quere que os seus escritos sexan editados sen piedade e redistribuídos sen límites, entón non os publique aquí.<br />\nDo mesmo xeito, comprométese a que o que vostede escriba é da súa autoría ou está copiado dun recurso de dominio público ou que procede dunha fonte libre.\n<strong>Non envíe material con dereitos de autoría sen permiso!</strong>",
+       "copyrightwarning2": "Por favor, teña en conta que todas as contribucións feitas en {{SITENAME}} poden ser editadas, alteradas ou eliminadas por outras persoas.\nSe non quere que os seus escritos sexan editados sen piedade, entón non os publique aquí.<br />\nDo mesmo xeito, comprométese a que o que vostede escriba é da súa autoría ou está copiado dun recurso de dominio público ou que procede dunha fonte libre (consulte $1 para obter máis detalles).\n<strong>Non envíe material con dereitos de autoría sen permiso!</strong>",
        "editpage-cannot-use-custom-model": "O modelo de contido desta páxina non se pode modificar.",
        "longpageerror": "'''Erro: O texto que pretende gardar ocupa {{PLURAL:$1|$1 kilobyte|$1 kilobytes}}, e existe un límite dun máximo de {{PLURAL:$2|$2 kilobyte|$2 kilobytes}}.'''\nPolo tanto, non se pode gardar.",
        "readonlywarning": "<strong>Atención: A base de datos foi pechada para facer mantemento, polo que non vai poder gardar as súas edicións polo de agora.</strong>\nSe cadra, pode cortar e pegar o texto nun ficheiro de texto e gardalo para despois.\n\nO administrador de sistemas que a pechou deu esta explicación: $1",
        "invalid-content-data": "Datos de contido inválidos",
        "content-not-allowed-here": "O contido \"$1\" non está permitido na páxina \"[[$2]]\"",
        "editwarning-warning": "Deixar esta páxina pode causar a perda de calquera cambio feito.\nSe accedeu ao sistema, pode desactivar esta mensaxe de advertencia na sección \"{{int:prefs-editing}}\" das súas preferencias.",
-       "editpage-invalidcontentmodel-title": "Modelo de contido non válido",
-       "editpage-invalidcontentmodel-text": "O modelo de contido \"$1\" non é válido.",
+       "editpage-invalidcontentmodel-title": "O modelo de contido non está soportado",
+       "editpage-invalidcontentmodel-text": "O modelo de contido \"$1\" non está soportado.",
        "editpage-notsupportedcontentformat-title": "Formato de contido non admitido",
        "editpage-notsupportedcontentformat-text": "O formato de contido $1 non é compatible co modelo de contido $2.",
        "content-model-wikitext": "texto wiki",
        "searchprofile-advanced-tooltip": "Procurar nos espazos de nomes elixidos",
        "search-result-size": "$1 ({{PLURAL:$2|1 palabra|$2 palabras}})",
        "search-result-category-size": "{{PLURAL:$1|1 membro|$1 membros}} ({{PLURAL:$2|1 subcategoría|$2 subcategorías}}, {{PLURAL:$3|1 ficheiro|$3 ficheiros}})",
-       "search-redirect": "(redirixido desde \"$1\")",
+       "search-redirect": "(redirección desde \"$1\")",
        "search-section": "(sección \"$1\")",
        "search-category": "(categoría $1)",
        "search-file-match": "(coincide co contido do ficheiro)",
        "rows": "Filas:",
        "columns": "Columnas:",
        "searchresultshead": "Procurar",
-       "stub-threshold": "Límite superior de tamaño para o formato das ligazóns cara bosquexos ($1):",
+       "stub-threshold": "Límite superior de tamaño para o formato das ligazóns cara bosquexos ($1):",
        "stub-threshold-sample-link": "exemplo",
        "stub-threshold-disabled": "Desactivado",
        "recentchangesdays": "Número de días a mostrar nos cambios recentes:",
        "prefs-help-recentchangescount": "Isto inclúe os cambios recentes, os historiais e mais os rexistros.",
        "prefs-help-watchlist-token2": "Esta é a clave secreta da fonte de novas web para a súa lista de vixilancia.\nCalquera persoa que a saiba poderá ler a súa lista de vixilancia; non comparta esta clave.\n[[Special:ResetTokens|Prema aquí se necesita restablecela]].",
        "savedprefs": "Gardáronse as súas preferencias.",
-       "savedrights": "Gardáronse os permisos de {{GENDER:$1|$1}}.",
+       "savedrights": "Gardáronse os dereitos de {{GENDER:$1|usuario|usuaria}} de $1.",
        "timezonelegend": "Fuso horario:",
        "localtime": "Hora local:",
        "timezoneuseserverdefault": "Usar a hora do servidor por defecto ($1)",
        "prefs-help-variant": "A variante ou ortografía preferida na que mostrar o contido das páxinas deste wiki.",
        "yournick": "Sinatura:",
        "prefs-help-signature": "Os comentarios feitos nas páxinas de conversa deben asinarse con catro tiles (\"<nowiki>~~~~</nowiki>\"), que se converterán na súa sinatura con data e hora.",
-       "badsig": "Sinatura non válida; comprobe o código HTML utilizado.",
+       "badsig": "A sinatura non é válida.\nComprobe as etiquetas HTML.",
        "badsiglength": "A súa sinatura é demasiado longa.\nHa de ter menos {{PLURAL:$1|dun carácter|de $1 caracteres}}.",
        "yourgender": "Cal das seguintes oracións referidas a vostede é a máis axeitada?",
        "gender-unknown": "Ao facer mención á súa persoa, o software empregará verbas de xénero neutro sempre que sexa posible",
        "userrights-groupsmember-auto": "Membro implícito de:",
        "userrights-groups-help": "Pode cambiar os grupos aos que {{GENDER:$1|o usuario|a usuaria}} pertence:\n* Se a caixa ten un sinal (✓) significa que {{GENDER:$1|o usuario|a usuaria}} pertence a ese grupo.\n* Se, pola contra, non o ten, significa que non pertence.\n* Un asterisco (*) indica que non pode eliminar o grupo unha vez que o engadiu, e viceversa.",
        "userrights-reason": "Motivo:",
-       "userrights-no-interwiki": "Non dispón de permiso para editar dereitos de usuarios noutros wikis.",
-       "userrights-nodatabase": "A base de datos $1 non existe ou non é local.",
+       "userrights-no-interwiki": "Non ten os permisos necesarios para editar os dereitos de usuario noutros wikis.",
+       "userrights-nodatabase": "A base de datos \"$1\" non existe ou non é local.",
        "userrights-nologin": "Debe [[Special:UserLogin|acceder ao sistema]] cunta conta de administrador para asignar dereitos de usuario.",
        "userrights-notallowed": "Non dispón dos permisos necesarios para asignar ou retirar dereitos de usuario.",
        "userrights-changeable-col": "Os grupos que pode cambiar",
        "right-autoconfirmed": "Non ser afectado polos límites de frecuencia ligados aos enderezos IP",
        "right-bot": "Ser tratado coma un proceso automatizado",
        "right-nominornewtalk": "As edicións pequenas nas páxinas de conversa non lanzan o aviso de mensaxes novas",
-       "right-apihighlimits": "Usar os límites superiores nas peticións API",
+       "right-apihighlimits": "Usar os límites superiores nas peticións á API",
        "right-writeapi": "Usar a API para modificar o wiki",
        "right-delete": "Borrar páxinas",
        "right-bigdelete": "Borrar páxinas con historiais grandes",
        "right-protect": "Cambiar os niveis de protección e editar páxinas protexidas coa opción \"protección en serie\"",
        "right-editprotected": "Editar páxinas protexidas con \"{{int:protect-level-sysop}}\"",
        "right-editsemiprotected": "Editar páxinas protexidas con \"{{int:protect-level-autoconfirmed}}\"",
-       "right-editcontentmodel": "Editar o modelo de contido dunha páxina.",
+       "right-editcontentmodel": "Editar o modelo de contido dunha páxina",
        "right-editinterface": "Editar a interface de usuario",
        "right-editusercssjs": "Editar os ficheiros CSS e JavaScript doutros usuarios",
        "right-editusercss": "Editar os ficheiros CSS doutros usuarios",
        "right-patrol": "Marcar edicións como patrulladas",
        "right-autopatrol": "Ter as edicións marcadas automaticamente como patrulladas",
        "right-patrolmarks": "Ver os cambios que están marcados coma patrullados",
-       "right-unwatchedpages": "Ver unha lista de páxinas que non están vixiadas",
+       "right-unwatchedpages": "Ver unha lista das páxinas que non están vixiadas",
        "right-mergehistory": "Fusionar o historial das páxinas",
        "right-userrights": "Editar todos os dereitos de usuario",
        "right-userrights-interwiki": "Editar os dereitos de usuario dos usuarios doutros wikis",
        "right-override-export-depth": "Exportar páxinas incluíndo as páxinas ligadas ata unha profundidade de 5",
        "right-sendemail": "Enviar correos electrónicos a outros usuarios",
        "right-passwordreset": "Ver os correos electrónicos de restablecemento de contrasinais",
-       "right-managechangetags": "Crear e (des)activar [[Special:Tags|tags]]",
-       "right-applychangetags": "Aplicar [[Special:Tags|etiquetas]] xunto cos cambios propios",
+       "right-managechangetags": "Crear e (des)activar [[Special:Tags|etiquetas]]",
+       "right-applychangetags": "Aplicar [[Special:Tags|etiquetas]] xunto coas modificacións propias",
        "right-changetags": "Engadir e quitar [[Special:Tags|etiquetas]] arbitrarias a revisións individuais e entradas do rexistro",
-       "right-deletechangetags": "Suprimir as [[Special:Tags|etiquetas]] da base de datos",
-       "grant-generic": "conxunto de dereitos \"$1\"",
+       "right-deletechangetags": "Suprimir [[Special:Tags|etiquetas]] da base de datos",
+       "grant-generic": "Conxunto de dereitos \"$1\"",
        "grant-group-page-interaction": "Interactuar con páxinas",
        "grant-group-file-interaction": "Interactuar con ficheiros multimedia",
        "grant-group-watchlist-interaction": "Interactuar coa súa lista de vixilancia",
        "grant-group-high-volume": "Realizar actividades de alto volume",
        "grant-group-customization": "Personalización e preferencias",
        "grant-group-administration": "Realizar accións administrativas",
-       "grant-group-private-information": "Acceder a datos privados sobre ti",
+       "grant-group-private-information": "Acceder a datos privados sobre vostede",
        "grant-group-other": "Outras actividades",
        "grant-blockusers": "Bloquear e desbloquear usuarios",
        "grant-createaccount": "Crear contas",
        "grant-protect": "Protexer e desprotexer páxinas",
        "grant-rollback": "Reverter os cambios feitos nas páxinas",
        "grant-sendemail": "Enviar correos electrónicos a outros usuarios",
-       "grant-uploadeditmovefile": "Cargar, substituír e mover ficheiros",
-       "grant-uploadfile": "Cargar ficheiros novos",
+       "grant-uploadeditmovefile": "Subir, substituír e mover ficheiros",
+       "grant-uploadfile": "Subir ficheiros novos",
        "grant-basic": "Dereitos básicos",
-       "grant-viewdeleted": "Ver ficheiros e páxinas eliminadas",
+       "grant-viewdeleted": "Ver ficheiros e páxinas eliminados",
        "grant-viewmywatchlist": "Ver a súa lista de vixilancia",
+       "grant-viewrestrictedlogs": "Ver as entradas de rexistro restrinxidas",
        "newuserlogpage": "Rexistro de creación de usuarios",
        "newuserlogpagetext": "Este é un rexistro de creación de contas de usuario.",
        "rightslog": "Rexistro de dereitos de usuario",
        "action-editmyprivateinfo": "editar a súa información privada",
        "action-editcontentmodel": "editar o modelo de contido dunha páxina",
        "action-managechangetags": "crear e (des)activar etiquetas",
-       "action-applychangetags": "aplicar etiquetas xunto cos cambios",
+       "action-applychangetags": "aplicar etiquetas xunto coas súas modificacións",
        "action-changetags": "engadir e quitar etiquetas arbitrarias a revisións individuais e entradas do rexistro",
        "action-deletechangetags": "borrar etiquetas da base de datos",
        "action-purge": "purgar esta páxina",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|desde a última visita}}",
        "enhancedrc-history": "historial",
        "recentchanges": "Cambios recentes",
-       "recentchanges-legend": "Opcións dos cambios",
-       "recentchanges-summary": "Nesta páxina podes seguir as modificacións máis recentes feitas no wiki.",
+       "recentchanges-legend": "Opcións dos cambios recentes",
+       "recentchanges-summary": "Nesta páxina pode seguir as modificacións máis recentes feitas no wiki.",
        "recentchanges-noresult": "Non se produciron cambios que coincidisen con eses criterios durante o período especificado.",
        "recentchanges-feed-description": "Nesta fonte de novas pode seguir as modificacións máis recentes feitas no wiki.",
        "recentchanges-label-newpage": "Esta edición creou unha nova páxina",
        "recentchanges-page-removed-from-category-bundled": "[[:$1]] eliminada da categoría [[Special:WhatLinksHere/$1||esta páxina está incluída noutras páxinas]]",
        "autochange-username": "Cambio automático de MediaWiki",
        "upload": "Subir un ficheiro",
-       "uploadbtn": "Subir un ficheiro",
-       "reuploaddesc": "Cancelar a carga e volver ao formulario de carga",
+       "uploadbtn": "Subir o ficheiro",
+       "reuploaddesc": "Cancelar a subida e volver ao formulario de subidas",
        "upload-tryagain": "Enviar a descrición do ficheiro modificada",
        "uploadnologin": "Non accedeu ao sistema",
        "uploadnologintext": "Debe $1 para poder cargar ficheiros.",
        "filesource": "Fonte:",
        "ignorewarning": "Ignorar a advertencia e gardar o ficheiro de calquera xeito",
        "ignorewarnings": "Ignorar as advertencias",
-       "minlength1": "Os nomes dos ficheiros deben ter cando menos unha letra.",
+       "minlength1": "Os nomes dos ficheiros deben ter como mínimo unha letra.",
        "illegalfilename": "O nome de ficheiro \"$1\" contén caracteres que non están permitidos nos títulos das páxinas.\nPor favor, cambie o nome do ficheiro e intente cargalo de novo.",
        "filename-toolong": "Os nomes dos ficheiros non poden superar os 240 bytes.",
        "badfilename": "O nome deste ficheiro cambiouse a \"$1\".",
        "filetype-mime-mismatch": "A extensión do ficheiro \".$1\" non coincide co tipo MIME detectado ($2).",
-       "filetype-badmime": "Non se permite enviar ficheiros de tipo MIME \"$1\".",
+       "filetype-badmime": "Non se permite a subida de ficheiros de tipo MIME \"$1\".",
        "filetype-bad-ie-mime": "Non se pode cargar este ficheiro porque o Internet Explorer detectaríao como \"$1\", o cal é un tipo de ficheiro non permitido e potencialmente perigoso.",
        "filetype-unwanted-type": "'''\".$1\"''' é un tipo de ficheiro non desexado.\n{{PLURAL:$3|O tipo de ficheiro preferido é|Os tipos de ficheiro preferidos son}} $2.",
        "filetype-banned-type": "'''\".$1\"''' non {{PLURAL:$4|é un tipo de ficheiro permitido|son tipos de ficheiro permitidos}}.\n{{PLURAL:$3|O tipo de ficheiro permitido é|Os tipos de ficheiro permitidos son}} $2.",
        "file-thumbnail-no": "O nome do ficheiro comeza por <strong>$1</strong>.\nParece tratarse dunha imaxe de tamaño reducido ''(miniatura)''.\nSe dispón dunha versión desta imaxe de maior resolución cárguea; se non, múdelle o nome ao ficheiro.",
        "fileexists-forbidden": "Xa existe un ficheiro co mesmo nome e este non pode ser sobrescrito.\nSe aínda quere cargar o seu ficheiro, por favor, retroceda e use un novo nome. [[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Xa existe un ficheiro con este nome no repositorio de ficheiros compartidos.\nSe aínda quere cargar o seu ficheiro, volva atrás e use outro nome.\n[[File:$1|thumb|center|$1]]",
-       "fileexists-no-change": "O ficheiro cargado é un duplicado exacto da versión actual de <strong>[[:$1]]</strong>.",
-       "fileexists-duplicate-version": "O ficheiro cargado é un duplicado exacto {{PLURAL:$2|dunha versión vella|de varias versións vellas}} de <strong>[[:$1]]</strong>.",
+       "fileexists-no-change": "O ficheiro subido é un duplicado exacto da versión actual de \"<strong>[[:$1]]</strong>\".",
+       "fileexists-duplicate-version": "O ficheiro subido é un duplicado exacto {{PLURAL:$2|dunha versión vella|de varias versións vellas}} de \"<strong>[[:$1]]</strong>\".",
        "file-exists-duplicate": "Este ficheiro é un duplicado {{PLURAL:$1|do seguinte|dos seguintes}}:",
-       "file-deleted-duplicate": "Un ficheiro idéntico a este (\"[[:$1]]\") foi borrado previamente. Debería comprobar o historial de borrados do ficheiro antes de proceder a cargalo de novo.",
+       "file-deleted-duplicate": "Un ficheiro idéntico a este (\"[[:$1]]\") foi borrado previamente. Debería comprobar o historial de borrados do ficheiro antes de proceder a subilo de novo.",
        "file-deleted-duplicate-notitle": "Un ficheiro idéntico a este foi borrado con anterioridade e o título foi suprimido.\nDebería contactar con alguén capaz de ver os datos de ficheiros borrados para que revise esta situación antes de subilo de novo.",
        "uploadwarning": "Advertencia ao cargar o ficheiro",
        "uploadwarning-text": "Por favor, modifique a descrición do ficheiro e inténteo de novo.",
        "savefile": "Gardar o ficheiro",
-       "uploaddisabled": "Sentímolo, a subida de ficheiros está desactivada.",
+       "uploaddisabled": "A subida de ficheiros está desactivada.",
        "copyuploaddisabled": "A carga mediante URL está desactivada.",
        "uploaddisabledtext": "A carga de ficheiros está desactivada.",
        "php-uploaddisabledtext": "As cargas de ficheiros PHP están desactivadas. Por favor, comprobe a característica file_uploads.",
        "uploadscripted": "Este ficheiro contén código HTML ou script que pode producir erros ao ser interpretado polo navegador.",
-       "upload-scripted-pi-callback": "Non se pode subir un ficheiro que conteña instruccións de proceso de folla de estilo XML.",
-       "uploaded-script-svg": "Atopado elemento de comandos \"$1\" no ficheiro SVG subido.",
-       "uploaded-hostile-svg": "Atopado CSS non seguro no elemento de estilo do ficheiro SVG subido.",
-       "uploaded-event-handler-on-svg": "Fixar atributos de xestión de eventos <code>$1=\"$2\"</code> no está permitido en ficheiros SVG.",
-       "uploaded-href-attribute-svg": "os atributos href nos ficheiros SVG só están autorizados a ligar a direccións http:// ou https://, atopado <code>&lt;$1 $2=\"$3\"&gt;</code>.",
-       "uploaded-href-unsafe-target-svg": "Atopado href a datos non seguros: dirección URI <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG subido.",
-       "uploaded-animate-svg": "Atopada etiqueta \"animate\" que podería estar cambiando a href, usando o atributo \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG subido.",
-       "uploaded-setting-event-handler-svg": "Fichar os atributos de xestión de eventos non está permitido, atopado <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG subido.",
-       "uploaded-setting-href-svg": "Usar a etiqueta \"set\" para engadir o atributo \"href\" ó elemento pai non está permitido.",
-       "uploaded-wrong-setting-svg": "Usar a etiqueta \"set\" para engadir un obxectivo remoto/datos/secuencia de comandos a calquera atributo non está permitido. Atopado <code>&lt;set to=\"$1\"&gt;</code> no ficheiro SVG subido.",
-       "uploaded-setting-handler-svg": "SVG que fixa o atributo \"handler\" con remoto/datos/secuencia de comandos non está permitido. Atopado <code>$1=\"$2\"</code> no ficheiro SVG subido.",
-       "uploaded-remote-url-svg": "SVG que fixa calquera atributo de estilo con URL remota non está permitido. Atopado <code>$1=\"$2\"</code> no ficheiro SVG subido.",
-       "uploaded-image-filter-svg": "Atopado filtro de imaxe con URL: <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG subido.",
+       "upload-scripted-pi-callback": "Non se pode subir un ficheiro que conteña instrucións de procesamento de follas de estilo XML.",
+       "uploaded-script-svg": "Atopouse un elemento de comandos \"$1\" no ficheiro SVG subido.",
+       "uploaded-hostile-svg": "Atopouse CSS non seguro no elemento de estilo do ficheiro SVG subido.",
+       "uploaded-event-handler-on-svg": "Non está permitido fixar atributos de xestión de eventos <code>$1=\"$2\"</code> nos ficheiros SVG.",
+       "uploaded-href-attribute-svg": "Os atributos href nos ficheiros SVG só están autorizados a ligar con enderezos http:// ou https://, mais atopouse <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "Atopouse un href a datos non seguros: un enderezo URI <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG subido.",
+       "uploaded-animate-svg": "Atopouse unha etiqueta \"animate\", que podería cambiar o seu href, usando o atributo \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG subido.",
+       "uploaded-setting-event-handler-svg": "Non está permitido fixar os atributos de xestión de eventos, mais atopouse <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG subido.",
+       "uploaded-setting-href-svg": "Non está permitido usar a etiqueta \"set\" para engadir o atributo \"href\" ao elemento pai.",
+       "uploaded-wrong-setting-svg": "Non está permitido usar a etiqueta \"set\" para engadir un obxectivo remoto/datos/secuencia de comandos a calquera atributo. Atopouse <code>&lt;set to=\"$1\"&gt;</code> no ficheiro SVG subido.",
+       "uploaded-setting-handler-svg": "Non están permitidos os ficheiros SVG que fixen o atributo \"handler\" cun obxectivo remoto/datos/secuencia de comandos. Atopouse <code>$1=\"$2\"</code> no ficheiro SVG subido.",
+       "uploaded-remote-url-svg": "Non están permitidos os ficheiros SVG que fixen calquera atributo de estilo con enderezos URL remotos. Atopouse <code>$1=\"$2\"</code> no ficheiro SVG subido.",
+       "uploaded-image-filter-svg": "Atopouse un filtro de imaxe con URL: <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG subido.",
        "uploadscriptednamespace": "Este ficheiro SVG contén o espazo de nomes non permitido \"$1\"",
        "uploadinvalidxml": "Non se puido analizar o XML do ficheiro cargado.",
-       "uploadvirus": "O ficheiro contén un virus! Detalles: $1",
+       "uploadvirus": "O ficheiro contén un virus!\nDetalles: $1",
        "uploadjava": "O ficheiro é un ZIP que contén un ficheiro .class de Java.\nNon están permitidas as cargas de ficheiros Java, dado que poden causar restricións de seguridade.",
        "upload-source": "Ficheiro de orixe",
        "sourcefilename": "Nome do ficheiro a cargar:",
        "upload-proto-error-text": "A carga remota require enderezos URL que comecen por <code>http://</code> ou <code>ftp://</code>.",
        "upload-file-error": "Erro interno",
        "upload-file-error-text": "Produciuse un erro interno ao intentar crear un ficheiro temporal no servidor.\nPor favor, póñase en contacto cun [[Special:ListUsers/sysop|administrador]].",
-       "upload-misc-error": "Erro de carga descoñecido",
+       "upload-misc-error": "Erro de subida descoñecido",
        "upload-misc-error-text": "Ocorreu un erro descoñecido durante a carga.\nComprobe que o enderezo URL é válido e accesible e, despois, inténteo de novo.\nSe o problema persiste, póñase en contacto cun [[Special:ListUsers/sysop|administrador]].",
        "upload-too-many-redirects": "O enderezo URL contiña moitas redireccións",
        "upload-http-error": "Produciuse un erro HTTP: $1",
        "upload-dialog-disabled": "As cargas de ficheiros usando esta pantalla están desactivadas neste wiki.",
        "upload-dialog-title": "Subir un ficheiro",
        "upload-dialog-button-cancel": "Cancelar",
+       "upload-dialog-button-back": "Volver",
        "upload-dialog-button-done": "Feito",
        "upload-dialog-button-save": "Gardar",
        "upload-dialog-button-upload": "Subir",
        "uploadstash-badtoken": "A acción fallou, probablemente porque caducou a información de acceso. Por favor, inténteo de novo.",
        "uploadstash-errclear": "Fallou o borrado de ficheiros.",
        "uploadstash-refresh": "Actualizar a lista de ficheiros",
-       "uploadstash-thumbnail": "ver miniatura",
+       "uploadstash-thumbnail": "ver miniatura",
        "uploadstash-exception": "Imposible gardar a subida na reserva ($1): \"$2\".",
        "invalid-chunk-offset": "Desprazamento inválido do fragmento",
        "img-auth-accessdenied": "Acceso rexeitado",
        "http-bad-status": "Houbo un problema durante a solicitude HTTP: $1 $2",
        "upload-curl-error6": "Non se puido acceder ao enderezo URL",
        "upload-curl-error6-text": "Non se puido acceder ao enderezo URL especificado.\nComprobe que ese enderezo URL é correcto e que o sitio está activo.",
-       "upload-curl-error28": "Rematou o tempo de espera",
+       "upload-curl-error28": "Rematou o tempo de espera da subida",
        "upload-curl-error28-text": "O sitio tardou demasiado en responder.\nPor favor, comprobe que está activo, agarde un anaco e inténteo de novo.\nTamén pode reintentalo cando haxa menos actividade.",
        "license": "Licenza:",
        "license-header": "Licenza",
        "filerevert-defaultcomment": "Volveuse á versión do $1 ás $2 ($3)",
        "filerevert-submit": "Reverter",
        "filerevert-success": "Reverteuse \"'''[[Media:$1|$1]]'''\" á [$4 versión do $2 ás $3].",
-       "filerevert-badversion": "Non existe unha versión local anterior deste ficheiro coa data e hora indicadas.",
-       "filerevert-identical": "A versión actual do ficheiro é igual á seleccionada.",
+       "filerevert-badversion": "Non existe ningunha versión local anterior deste ficheiro coa data e hora indicadas.",
+       "filerevert-identical": "A versión actual do ficheiro é idéntica á seleccionada.",
        "filedelete": "Borrar \"$1\"",
        "filedelete-legend": "Eliminar un ficheiro",
        "filedelete-intro": "Está a piques de eliminar o ficheiro \"'''[[Media:$1|$1]]'''\" xunto con todo o seu historial.",
        "statistics-edits-average": "Media de edicións por páxina",
        "statistics-users": "[[Special:ListUsers|Usuarios]] rexistrados",
        "statistics-users-active": "Usuarios activos",
-       "statistics-users-active-desc": "Usuarios que teñen levado a cabo unha acción {{PLURAL:$1|no último día|nos últimos $1 días}}",
+       "statistics-users-active-desc": "Usuarios que levaron a cabo unha acción {{PLURAL:$1|no último día|nos últimos $1 días}}",
        "pageswithprop": "Páxinas cunha propiedade de páxina",
        "pageswithprop-legend": "Páxinas cunha propiedade de páxina",
        "pageswithprop-text": "Esta páxina lista aquelas páxinas que utilizan unha propiedade de páxina determinada.",
        "apisandbox-jsonly": "É preciso activar o JavaScript para usar a zona de probas.",
        "apisandbox-api-disabled": "API está desactivado neste sitio.",
        "apisandbox-intro": "Use esta páxina para experimentar co <strong>servizo web da API de MediaWiki</strong>.\nConsulte a [[mw:API:Main page| documentación da API]] para obter máis información sobre o uso da API. Exemplo: [https://www.mediawiki.org/wiki/API#A_simple_example obter o contido dunha páxina de inicio]. Seleccione unha acción para ollar máis exemplos.\n\nTeña en conta que, aínda que esta é unha páxina de probas, as accións que realice nesta páxina poden modificar o wiki.",
-       "apisandbox-fullscreen": "Expandir panel",
+       "apisandbox-fullscreen": "Expandir panel",
        "apisandbox-fullscreen-tooltip": "Expande o panel da zona de probas para encher a pantalla do navegador.",
        "apisandbox-unfullscreen": "Mostrar a páxina",
-       "apisandbox-unfullscreen-tooltip": "Reduce o panel da zona de probas, así as ligazóns de navegación MediaWiki están dispoñibles.",
+       "apisandbox-unfullscreen-tooltip": "Reduce o panel da zona de probas para que as ligazóns de navegación de MediaWiki estean dispoñibles.",
        "apisandbox-submit": "Facer a solicitude",
        "apisandbox-reset": "Limpar",
        "apisandbox-retry": "Reintentar",
-       "apisandbox-loading": "Cargando información para módulo de API \"$1\"...",
-       "apisandbox-load-error": "Houbo un erro mentres se cargaba a información do módulo API \"$1\": $2",
-       "apisandbox-no-parameters": "O módulo de API non ten parámetros.",
+       "apisandbox-loading": "Cargando a información para módulo \"$1\" da API...",
+       "apisandbox-load-error": "Produciuse un erro mentres se cargaba a información do módulo \"$1\" da API: $2",
+       "apisandbox-no-parameters": "Este módulo da API non ten parámetros.",
        "apisandbox-helpurls": "Ligazóns de axuda",
        "apisandbox-examples": "Exemplos",
        "apisandbox-dynamic-parameters": "Parámetros adicionais",
-       "apisandbox-dynamic-parameters-add-label": "Engadir parámetro:",
+       "apisandbox-dynamic-parameters-add-label": "Engadir un parámetro:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nome do parámetro",
        "apisandbox-dynamic-error-exists": "Xa existe un parámetro co nome \"$1\".",
        "apisandbox-deprecated-parameters": "Parámetros obsoletos",
-       "apisandbox-fetch-token": "Auto-enchido do identificador",
+       "apisandbox-fetch-token": "Encher automaticamente o identificador",
        "apisandbox-submit-invalid-fields-title": "Algúns campos non son válidos",
        "apisandbox-submit-invalid-fields-message": "Por favor, amañe os campos marcados e inténteo de novo.",
        "apisandbox-results": "Resultados",
        "apisandbox-sending-request": "Enviando a petición á API...",
        "apisandbox-loading-results": "Recibindo os resultados da API...",
-       "apisandbox-results-error": "Houbo un erro mentres se cargaba a resposta á consulta da API: $1.",
+       "apisandbox-results-error": "Produciuse un erro mentres se cargaba a resposta da petición á API: $1.",
        "apisandbox-request-url-label": "URL da solicitude:",
        "apisandbox-request-time": "Duración da solicitude: {{PLURAL:$1|$1 ms}}",
-       "apisandbox-results-fixtoken": "Correxir identificador e reenviar",
-       "apisandbox-results-fixtoken-fail": "Erro ó recuperar o identificador \"$1\".",
-       "apisandbox-alert-page": "Os campos nesta páxina non son válidos.",
+       "apisandbox-results-fixtoken": "Corrixir o identificador e reenviar",
+       "apisandbox-results-fixtoken-fail": "Erro ao recuperar o identificador \"$1\".",
+       "apisandbox-alert-page": "Os campos desta páxina non son válidos.",
        "apisandbox-alert-field": "O valor deste campo non é válido.",
+       "apisandbox-continue": "Continuar",
+       "apisandbox-continue-clear": "Limpar",
+       "apisandbox-continue-help": "\"{{int:apisandbox-continue}}\" [https://www.mediawiki.org/wiki/API:Query#Continuing_queries continuará] a última petición; \"{{int:apisandbox-continue-clear}}\" limpará os parámetros relativos á continuación.",
+       "apisandbox-param-limit": "Indicar <kbd>max</kbd> para usar o límite máximo.",
        "booksources": "Fontes bibliográficas",
        "booksources-search-legend": "Procurar fontes bibliográficas",
        "booksources-search": "Procurar",
-       "booksources-text": "A continuación aparece unha lista de ligazóns cara a outros sitios web que venden libros novos e usados, neles tamén pode obter máis información sobre as obras que está a buscar:",
-       "booksources-invalid-isbn": "O ISBN inserido parece non ser válido; comprobe que non haxa erros ao copialo da fonte orixinal.",
+       "booksources-text": "A continuación aparece unha lista de ligazóns cara a outros sitios web que venden libros novos e usados; neles tamén pode obter máis información sobre as obras que está a buscar:",
+       "booksources-invalid-isbn": "O ISBN inserido semella non ser válido; comprobe que non se producisen erros ao copialo da fonte orixinal.",
+       "magiclink-tracking-rfc": "Páxinas que usan ligazóns máxicas RFC",
+       "magiclink-tracking-rfc-desc": "Esta páxina utiliza ligazóns máxicas RFC. Consulte [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] para descubrir como facer a migración.",
+       "magiclink-tracking-pmid": "Páxinas que usan ligazóns máxicas PMID",
+       "magiclink-tracking-pmid-desc": "Esta páxina utiliza ligazóns máxicas PMID. Consulte [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] para descubrir como facer a migración.",
+       "magiclink-tracking-isbn": "Páxinas que usan ligazóns máxicas ISBN",
+       "magiclink-tracking-isbn-desc": "Esta páxina utiliza ligazóns máxicas ISBN. Consulte [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] para descubrir como facer a migración.",
        "specialloguserlabel": "Executante:",
-       "speciallogtitlelabel": "Obxectivo (título ou {{ns:user}}:nome de usuario):",
+       "speciallogtitlelabel": "Obxectivo (título ou \"{{ns:user}}:nome de usuario\" para un usuario):",
        "log": "Rexistros",
        "logeventslist-submit": "Mostrar",
        "all-logs-page": "Todos os rexistros públicos",
        "logempty": "Non se atopou ningún elemento relacionado no rexistro.",
        "log-title-wildcard": "Procurar os títulos que comecen con este texto",
        "showhideselectedlogentries": "Mostrar/agochar as entradas do rexistro seleccionadas",
-       "log-edit-tags": "Editar as etiquetas das entradas do registro seleccionadas",
+       "log-edit-tags": "Editar as etiquetas das entradas de rexistro seleccionadas",
        "checkbox-select": "Seleccionar: $1",
        "checkbox-all": "Todos",
        "checkbox-none": "Ningún",
        "activeusers-intro": "Esta é unha lista cos usuarios que tiveron algún tipo de actividade {{PLURAL:$1|no último día|nos últimos $1 días}}.",
        "activeusers-count": "$1 {{PLURAL:$1|acción|accións}} {{PLURAL:$3|no último día|nos últimos $3 días}}",
        "activeusers-from": "Mostrar os usuarios que comecen por:",
-       "activeusers-hidebots": "Agochar os bots",
-       "activeusers-hidesysops": "Agochar os administradores",
+       "activeusers-groups": "Mostrar os usuarios que pertencen aos grupos:",
        "activeusers-noresult": "Non se atopou ningún usuario.",
-       "activeusers-submit": "Mostrar usuarios activos",
+       "activeusers-submit": "Mostrar os usuarios activos",
        "listgrouprights": "Dereitos dun usuario segundo o seu grupo",
        "listgrouprights-summary": "A seguinte lista mostra os grupos de usuario definidos neste wiki, cos seus dereitos de acceso asociados.\nSe quere máis información acerca dos dereitos individuais, pode atopala [[{{MediaWiki:Listgrouprights-helppage}}|aquí]].",
        "listgrouprights-key": "Lenda:\n* <span class=\"listgrouprights-granted\">Dereito concedido</span>\n* <span class=\"listgrouprights-revoked\">Dereito revogado</span>",
        "listgrouprights-namespaceprotection-namespace": "Espazo de nomes",
        "listgrouprights-namespaceprotection-restrictedto": "Dereito(s) que permite(n) ao usuario editar",
        "listgrants": "Permisos",
-       "listgrants-summary": "Esta é unha lista de permisos cos seus accesos asoaciados aos permisos de usuario. Os usuarios poden autorizar aplicacións para usar a súa conta, pero con permisos limitados baseados nos permisos que o usuario dá á aplicación. Porén, unha aplicación que actúa no lugar do usuario non pode empregar permisos que o propio usuario non posúe.\nPode ver máis información sobre dereitos individuais [[{{MediaWiki:Listgrouprights-helppage}}|aquí]].",
+       "listgrants-summary": "Esta é unha lista de permisos cos seus accesos asociados aos permisos de usuario. Os usuarios poden autorizar aplicacións para que usen a súa conta, pero con acceso limitado en función dos permisos que o usuario concede á aplicación. Porén, unha aplicación que actúa no nome dun usuario non pode empregar permisos que o propio usuario non posúe.\nPode obter máis información sobre os dereitos individuais [[{{MediaWiki:Listgrouprights-helppage}}|nesta páxina]].",
        "listgrants-grant": "Outorgar",
        "listgrants-rights": "Dereitos",
        "trackingcategories": "Categorías de seguimento",
        "hidden-category-category-desc": "A categoría contén a palabra máxica <code><nowiki>__HIDDENCAT__</nowiki></code>, que impide que se mostre por defecto na caixa de categorías das páxinas.",
        "trackingcategories-nodesc": "Non hai ningunha descrición dispoñible.",
        "trackingcategories-disabled": "A categoría está desactivada",
-       "mailnologin": "Non existe enderezo para o envío",
+       "mailnologin": "Non hai enderezo de envío",
        "mailnologintext": "Debe [[Special:UserLogin|acceder ao sistema]] e ter rexistrado un enderezo de correo electrónico válido nas súas [[Special:Preferences|preferencias]] para enviar correos electrónicos a outros usuarios.",
        "emailuser": "Enviar un correo electrónico a {{GENDER:{{BASEPAGENAME}}|este usuario|esta usuaria}}",
        "emailuser-title-target": "Enviar un correo electrónico a {{GENDER:$1|este usuario|esta usuaria}}",
        "defemailsubject": "Correo electrónico do usuario $1 de {{SITENAME}}",
        "usermaildisabled": "O correo electrónico do usuario está desactivado",
        "usermaildisabledtext": "Non pode enviar correos electrónicos a outros usuarios deste wiki",
-       "noemailtitle": "Sen enderezo de correo electrónico",
+       "noemailtitle": "Non hai enderezo de correo electrónico",
        "noemailtext": "Este usuario non especificou un enderezo de correo electrónico válido.",
        "nowikiemailtext": "Este usuario elixiu non recibir correos electrónicos doutros usuarios.",
        "emailnotarget": "O nome de usuario do destinatario non existe ou é incorrecto.",
        "emailsubject": "Asunto:",
        "emailmessage": "Mensaxe:",
        "emailsend": "Enviar",
-       "emailccme": "Enviar unha copia da mensaxe para min.",
+       "emailccme": "Enviar unha copia da mensaxe ao meu enderezo de correo electrónico.",
        "emailccsubject": "Copia da súa mensaxe para $1: $2",
        "emailsent": "Mensaxe enviada",
        "emailsenttext": "A súa mensaxe de correo electrónico foi enviada.",
-       "emailuserfooter": "Este correo electrónico foi {{GENDER:$1|enviado}} por $1 a {{GENDER:$2|$2}} mediante a función \"{{int:emailuser}}\" en {{SITENAME}}.",
+       "emailuserfooter": "$1 {{GENDER:$1|enviou}} este correo electrónico a {{GENDER:$2|$2}} mediante a función \"{{int:emailuser}}\" de {{SITENAME}}.",
        "usermessage-summary": "Mensaxe deixada polo sistema.",
        "usermessage-editor": "Editor das mensaxes do sistema",
        "watchlist": "Lista de vixilancia",
        "watchnologin": "Non accedeu ao sistema",
        "addwatch": "Engadir á lista vixilancia",
        "addedwatchtext": "A páxina \"[[:$1]]\" e mais a súa conversa foron engadidas á súa [[Special:Watchlist|lista de vixilancia]].",
-       "addedwatchtext-talk": "\"[[:$1]]\" xunto coa súa páxina asociada foron engadidas á túa [[Special:Watchlist|lista de vixilancia]].",
+       "addedwatchtext-talk": "\"[[:$1]]\" e a súa páxina asociada engadíronse á súa [[Special:Watchlist|lista de vixilancia]].",
        "addedwatchtext-short": "A páxina \"$1\" foi engadida á súa lista de vixilancia.",
        "removewatch": "Eliminar da lista de vixilancia",
        "removedwatchtext": "A páxina \"[[:$1]]\" e mais a súa conversa foron eliminadas da súa [[Special:Watchlist|lista de vixilancia]].",
-       "removedwatchtext-talk": "\"[[:$1]]\" xunto coa súa páxina asociada foron eliminadas da túa [[Special:Watchlist|lista de vixilancia]].",
+       "removedwatchtext-talk": "\"[[:$1]]\" e a súa páxina asociada elimináronse da súa [[Special:Watchlist|lista de vixilancia]].",
        "removedwatchtext-short": "A páxina \"$1\" foi eliminada da súa lista de vixilancia.",
        "watch": "Vixiar",
        "watchthispage": "Vixiar esta páxina",
        "wlshowlast": "Mostrar as últimas $1 horas e os últimos $2 días",
        "watchlist-hide": "Agochar",
        "watchlist-submit": "Mostrar",
-       "wlshowtime": "Periodo de tempo a amosar:",
+       "wlshowtime": "Período de tempo a mostrar:",
        "wlshowhideminor": "edicións menores",
        "wlshowhidebots": "bots",
        "wlshowhideliu": "usuarios rexistrados",
        "deletepage": "Borrar a páxina",
        "confirm": "Confirmar",
        "excontent": "o contido era: \"$1\"",
-       "excontentauthor": "o contido era: \"$1\", e o único editor foi \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|conversa]])",
+       "excontentauthor": "o contido era \"$1\", e o único editor foi [[Special:Contributions/$2|$2]] ([[User talk:$2|conversa]])",
        "exbeforeblank": "o contido antes do baleirado era: \"$1\"",
        "delete-confirm": "Borrar \"$1\"",
        "delete-legend": "Borrar",
        "historywarning": "<strong>Atención:</strong> A páxina que está a piques de borrar ten un historial con $1 {{PLURAL:$1|revisión|revisións}}:",
        "historyaction-submit": "Mostrar",
-       "confirmdeletetext": "Está a piques de borrar de xeito permanente unha páxina ou imaxe con todo o seu historial na base de datos.\nPor favor, confirme que é realmente a súa intención, que comprende as consecuencias e que está obrando de acordo coas regras [[{{MediaWiki:Policy-url}}|da política e normas]].",
+       "confirmdeletetext": "Está a piques de borrar de xeito permanente unha páxina con todo o seu historial.\nPor favor, confirme que é realmente a súa intención, que comprende as consecuencias e que está obrando de acordo coas [[{{MediaWiki:Policy-url}}|políticas]].",
        "actioncomplete": "Completouse a acción",
        "actionfailed": "Fallou a acción",
        "deletedtext": "Borrouse a páxina \"$1\".\nNo $2 pode ver unha lista cos borrados máis recentes.",
        "rollbacklinkcount-morethan": "reverter máis de $1 {{PLURAL:$1|edición|edicións}}",
        "rollbackfailed": "Houbo un erro ao reverter as edicións",
        "rollback-missingparam": "Faltan parámetros obrigatorios na solicitude.",
-       "rollback-missingrevision": "Non se poden cargar datos da revisión.",
+       "rollback-missingrevision": "Non se poden cargar os datos da revisión.",
        "cantrollback": "Non se pode desfacer a edición; o último colaborador é o único autor desta páxina.",
        "alreadyrolled": "Non se pode desfacer a edición en \"[[:$1]]\" feita por [[User:$2|$2]] ([[User talk:$2|conversa]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); alguén máis editou ou desfixo os cambios desta páxina.\n\nA última edición fíxoa [[User:$3|$3]] ([[User talk:$3|conversa]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "O resumo de edición foi: <em>$1</em>.",
        "revertpage": "Desfixéronse as edicións de [[Special:Contributions/$2|$2]] ([[User talk:$2|conversa]]); cambiado á última versión feita por [[User:$1|$1]]",
        "revertpage-nouser": "Desfixéronse as edicións dun usuario agochado; cambiado á última versión feita por {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Desfixéronse as edicións de $1;\nvolveuse á última edición, feita por $2.",
-       "rollback-success-notify": "Modificacións anuladas por $1; restaurado á última revisión de $2. [$3 Mostrar os cambios]",
+       "rollback-success-notify": "Revertéronse as edicións de $1;\nrestaurouse a última revisión de $2. [$3 Mostrar os cambios]",
        "sessionfailure-title": "Erro de sesión",
        "sessionfailure": "Parece que hai un problema co rexistro da súa sesión;\nesta acción cancelouse como precaución fronte ao secuestro de sesións.\nPrema no botón \"atrás\", volva cargar a páxina da que proviña e inténteo de novo.",
-       "changecontentmodel": "Cambiar o modelo do contido dunha páxina",
-       "changecontentmodel-legend": "Cambiar o modelo do contido",
+       "changecontentmodel": "Cambiar o modelo de contido dunha páxina",
+       "changecontentmodel-legend": "Cambiar o modelo de contido",
        "changecontentmodel-title-label": "Título da páxina",
        "changecontentmodel-model-label": "Novo modelo de contido",
        "changecontentmodel-reason-label": "Motivo:",
        "changecontentmodel-submit": "Cambiar",
-       "changecontentmodel-success-title": "O modelo de contido foi modificado",
-       "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-success-title": "Modificouse o modelo de contido",
+       "changecontentmodel-success-text": "Modificouse o tipo de contido de \"[[:$1]]\".",
+       "changecontentmodel-cannot-convert": "O contido de \"[[:$1]]\" non se pode converter ao tipo \"$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",
+       "changecontentmodel-emptymodels-text": "O contido de \"[[:$1]]\" non se pode converter a ningún tipo.",
+       "log-name-contentmodel": "Rexistro de cambios no 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\"",
-       "logentry-contentmodel-change": "$1 {{GENDER:$2|cambiou}} o modelo de contido da páxina $3 de \"$4\" a \"$5\"",
+       "logentry-contentmodel-new": "$1 {{GENDER:$2|creou}} a páxina \"$3\" usando o modelo de contido non predeterminado \"$5\"",
+       "logentry-contentmodel-change": "$1 {{GENDER:$2|cambiou}} o modelo de contido da páxina \"$3\" de \"$4\" a \"$5\"",
        "logentry-contentmodel-change-revertlink": "reverter",
        "logentry-contentmodel-change-revert": "reverter",
        "protectlogpage": "Rexistro de proteccións",
        "modifiedarticleprotection": "modificou o nivel de protección de \"[[$1]]\"",
        "unprotectedarticle": "eliminou a protección de \"[[$1]]\"",
        "movedarticleprotection": "cambiou as características da protección de \"[[$2]]\" a \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|Protexo}} \"[[$1]]\"",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Cambio o nivel de protección}} de \"[[$1]]\"",
+       "unprotectedarticle-comment": "{{GENDER:$2|Elimino a protección}} de \"[[$1]]\"",
        "protect-title": "Cambiar o nivel de protección de \"$1\"",
        "protect-title-notallowed": "Ollar o nivel de protección de \"$1\"",
        "prot_1movedto2": "moveu \"[[$1]]\" a \"[[$2]]\"",
        "protectcomment": "Motivo:",
        "protectexpiry": "Caducidade:",
        "protect_expiry_invalid": "O tempo de duración da protección non é válido.",
-       "protect_expiry_old": "O momento de remate da protección corresponde ao pasado.",
+       "protect_expiry_old": "A data de caducidade da protección corresponde ao pasado.",
        "protect-unchain-permissions": "Desbloquear as opcións de protección adicionais",
-       "protect-text": "Aquí é onde pode ver e cambiar os niveis de protección da páxina chamada \"'''$1'''\".",
-       "protect-locked-blocked": "Non pode modificar os niveis de protección mentres exista un bloqueo. Velaquí a configuración actual da páxina  '''$1''':",
-       "protect-locked-dblock": "Os niveis de protección non se poden modificar debido a un bloqueo da base de datos activa.\nVelaquí a configuración actual da páxina '''$1''':",
-       "protect-locked-access": "A súa conta non dispón de permisos para mudar os niveis de protección.\nVelaquí a configuración actual da páxina '''$1''':",
+       "protect-text": "Aquí pode ver e modificar o nivel de protección da páxina \"<strong>$1</strong>\".",
+       "protect-locked-blocked": "Non pode modificar o nivel de protección durante un bloqueo.\nVelaquí está a configuración actual da páxina \"<strong>$1</strong>\":",
+       "protect-locked-dblock": "Os niveis de protección non se poden modificar debido a un bloqueo activo da base de datos.\nVelaquí está a configuración actual da páxina \"<strong>$1</strong>\":",
+       "protect-locked-access": "A súa conta non dispón dos permisos necesarios para modificar os niveis de protección.\nVelaquí está a configuración actual da páxina \"<strong>$1</strong>\":",
        "protect-cascadeon": "Esta páxina está protexida actualmente porque está transcluída {{PLURAL:$1|na seguinte páxina, que foi protexida|nas seguintes páxinas, que foron protexidas}} coa opción \"protección en serie\" activada.\nOs cambios no nivel de protección desta páxina non afectarán á protección en serie.",
        "protect-default": "Permitir a todos os usuarios",
        "protect-fallback": "Permitir só aos usuarios con permisos de \"$1\"",
        "sp-contributions-username": "Enderezo IP ou nome de usuario:",
        "sp-contributions-toponly": "Mostrar só as últimas revisións",
        "sp-contributions-newonly": "Mostrar só as edicións que crearon páxinas",
-       "sp-contributions-hideminor": "Ocultar edicións menores",
+       "sp-contributions-hideminor": "Agochar as edicións pequenas",
        "sp-contributions-submit": "Procurar",
        "whatlinkshere": "Páxinas que ligan con esta",
        "whatlinkshere-title": "Páxinas que ligan con \"$1\"",
        "whatlinkshere-hideredirs": "$1 as redireccións",
        "whatlinkshere-hidetrans": "$1 as inclusións",
        "whatlinkshere-hidelinks": "$1 as ligazóns",
-       "whatlinkshere-hideimages": "$1 ligazóns ao ficheiro",
+       "whatlinkshere-hideimages": "$1 as ligazóns ao ficheiro",
        "whatlinkshere-filters": "Filtros",
        "whatlinkshere-submit": "Ir",
        "autoblockid": "Bloqueo automático nº$1",
        "unblock-hideuser": "Non pode desbloquear o usuario porque o seu nome foi agochado.",
        "ipb_cant_unblock": "Erro: Non se atopa o identificador do bloqueo $1. Posiblemente xa foi desbloqueado.",
        "ipb_blocked_as_range": "Erro: O enderezo IP $1 non está bloqueado directamente e non se pode desbloquear. Porén, está bloqueado por estar no rango $2, que si se pode desbloquear.",
-       "ip_range_invalid": "Rango IP non válido.",
+       "ip_range_invalid": "Rango de enderezos IP non válido.",
        "ip_range_toolarge": "Non están permitidos os rangos de bloqueo maiores que /$1.",
        "proxyblocker": "Bloqueador de proxy",
        "proxyblockreason": "O seu enderezo IP foi bloqueado porque é un proxy aberto.\nPor favor, contacte co seu fornecedor de acceso á Internet ou co seu soporte técnico e informe deste grave problema de seguridade.",
        "movelogpagetext": "A continuación móstrase a lista con todas as páxinas trasladadas.",
        "movesubpage": "{{PLURAL:$1|Subpáxina|Subpáxinas}}",
        "movesubpagetext": "Esta páxina ten $1 {{PLURAL:$1|subpáxina|subpáxinas}}.",
+       "movesubpagetalktext": "A páxina de conversa correspondente ten $1 {{PLURAL:$1|subpáxina, mostrada|subpáxinas, mostradas}} abaixo.",
        "movenosubpage": "Esta páxina non ten subpáxinas.",
        "movereason": "Motivo:",
        "revertmove": "reverter",
        "pageinfo-category-pages": "Número de páxinas",
        "pageinfo-category-subcats": "Número de subcategorías",
        "pageinfo-category-files": "Número de ficheiros",
+       "pageinfo-user-id": "ID do usuario",
        "markaspatrolleddiff": "Marcar como revisada",
        "markaspatrolledtext": "Marcar esta páxina como revisada",
        "markaspatrolledtext-file": "Marcar esta versión de ficheiro como verificada",
        "patrol-log-page": "Rexistro de revisións patrulladas",
        "patrol-log-header": "Este é un rexistro das revisións patrulladas.",
        "log-show-hide-patrol": "$1 o rexistro de patrullas",
-       "log-show-hide-tag": "$1 rexistro de etiquetas",
-       "deletedrevision": "A revisión vella $1 foi borrada.",
+       "log-show-hide-tag": "$1 o rexistro de etiquetas",
+       "confirm-markpatrolled-button": "Aceptar",
+       "confirm-markpatrolled-top": "Quere marcar a revisión $3 de \"$2\" como patrullada?",
+       "deletedrevision": "Revisión vella e borrada de \"$1\"",
        "filedeleteerror-short": "Erro ao eliminar o ficheiro: $1",
        "filedeleteerror-long": "Atopáronse erros ao eliminar o ficheiro:\n\n$1",
        "filedelete-missing": "Non se pode eliminar o ficheiro \"$1\" porque non existe.",
        "svg-long-error": "Ficheiro SVG non válido: $1",
        "show-big-image": "Ficheiro orixinal",
        "show-big-image-preview": "Tamaño desta vista previa: $1.",
-       "show-big-image-preview-differ": "Tamaño desta revisión $3 do ficheiro $2: $1.",
+       "show-big-image-preview-differ": "Tamaño desta vista previa en $3 do ficheiro en formato $2: $1.",
        "show-big-image-other": "{{PLURAL:$2|Outra resolución|Outras resolucións}}: $1.",
        "show-big-image-size": "$1 × $2 píxeles",
        "file-info-gif-looped": "en bucle",
        "newimages-legend": "Filtro",
        "newimages-label": "Nome do ficheiro (ou parte del):",
        "newimages-showbots": "Mostrar as cargas feitas por bots",
-       "newimages-hidepatrolled": "Ocultar as subas verificadas",
-       "noimages": "Non hai imaxes para ver.",
+       "newimages-hidepatrolled": "Agochar as subidas patrulladas",
+       "noimages": "Non hai imaxes que mostrar.",
+       "gallery-slideshow-toggle": "Intercambiar as miniaturas",
        "ilsubmit": "Procurar",
        "bydate": "por data",
        "sp-newimages-showfrom": "Mostrar os novos ficheiros comezando polo $1 ás $2",
        "exif-imagelength": "Alto",
        "exif-bitspersample": "Bits por compoñente",
        "exif-compression": "Esquema de compresión",
-       "exif-photometricinterpretation": "Composición do píxel",
+       "exif-photometricinterpretation": "Composición de píxeles",
        "exif-orientation": "Orientación",
        "exif-samplesperpixel": "Número de compoñentes",
        "exif-planarconfiguration": "Disposición dos datos",
        "exif-stripoffsets": "Localización dos datos da imaxe",
        "exif-rowsperstrip": "Número de filas por tira",
        "exif-stripbytecounts": "Bytes por tira comprimida",
-       "exif-jpeginterchangeformat": "Distancia ao inicio (SOI) do JPEG",
+       "exif-jpeginterchangeformat": "Desprazamento do SOI do JPEG",
        "exif-jpeginterchangeformatlength": "Bytes de datos JPEG",
-       "exif-whitepoint": "Coordenadas cromáticas de referencia do branco",
+       "exif-whitepoint": "Cromacidade do punto branco",
        "exif-primarychromaticities": "Cromacidades primarias",
        "exif-ycbcrcoefficients": "Coeficientes da matriz de transformación do espazo de cores",
        "exif-referenceblackwhite": "Par de valores de referencia branco e negro",
        "exif-relatedsoundfile": "Ficheiro de son relacionado",
        "exif-datetimeoriginal": "Data e hora de xeración do ficheiro",
        "exif-datetimedigitized": "Data e hora de dixitalización",
-       "exif-subsectime": "DataHora subsegundos",
-       "exif-subsectimeoriginal": "DataHoraOrixinal subsegundos",
-       "exif-subsectimedigitized": "DataHoraDixitalización subsegundos",
+       "exif-subsectime": "Subsegundo da data e hora",
+       "exif-subsectimeoriginal": "Subsegundo da data e hora orixinais",
+       "exif-subsectimedigitized": "Subsegundo da data e hora de dixitalización",
        "exif-exposuretime": "Tempo de exposición",
        "exif-exposuretime-format": "$1 segundos ($2)",
        "exif-fnumber": "Número f",
        "exif-exposureprogram": "Programa de exposición",
        "exif-spectralsensitivity": "Sensibilidade espectral",
-       "exif-isospeedratings": "Relación da velocidade ISO",
+       "exif-isospeedratings": "Relación de velocidade ISO",
        "exif-shutterspeedvalue": "Velocidade de obturación APEX",
        "exif-aperturevalue": "Apertura APEX",
        "exif-brightnessvalue": "Brillo APEX",
-       "exif-exposurebiasvalue": "Corrección da exposición",
+       "exif-exposurebiasvalue": "Corrección da exposición mediante APEX",
        "exif-maxaperturevalue": "Máxima apertura do diafragma",
        "exif-subjectdistance": "Distancia do suxeito",
        "exif-meteringmode": "Modo de medida da exposición",
        "exif-sensingmethod": "Tipo de sensor",
        "exif-filesource": "Fonte do ficheiro",
        "exif-scenetype": "Tipo de escena",
-       "exif-customrendered": "Procesamento da imaxe personalizado",
+       "exif-customrendered": "Procesamento de imaxe personalizado",
        "exif-exposuremode": "Modo de exposición",
        "exif-whitebalance": "Balance de brancos",
        "exif-digitalzoomratio": "Valor do zoom dixital",
        "exif-saturation": "Saturación",
        "exif-sharpness": "Nitidez",
        "exif-devicesettingdescription": "Descrición da configuración do dispositivo",
-       "exif-subjectdistancerange": "Distancia ao suxeito",
+       "exif-subjectdistancerange": "Rango de distancia ao suxeito",
        "exif-imageuniqueid": "ID único da imaxe",
        "exif-gpsversionid": "Versión da etiqueta GPS",
        "exif-gpslatituderef": "Latitude norte ou sur",
        "exif-gpstrack": "Dirección do movemento",
        "exif-gpsimgdirectionref": "Referencia para a dirección da imaxe",
        "exif-gpsimgdirection": "Dirección da imaxe",
-       "exif-gpsmapdatum": "Usados datos xeodésicos de enquisas",
+       "exif-gpsmapdatum": "Datos xeodésicos usados",
        "exif-gpsdestlatituderef": "Referencia para a latitude do destino",
        "exif-gpsdestlatitude": "Latitude do destino",
        "exif-gpsdestlongituderef": "Referencia para a lonxitude do destino",
        "exif-gpsdestlongitude": "Lonxitude do destino",
-       "exif-gpsdestbearingref": "Referencia para a coordenada de destino",
-       "exif-gpsdestbearing": "Coordenada de destino",
+       "exif-gpsdestbearingref": "Referencia para a orientación de destino",
+       "exif-gpsdestbearing": "Orientación de destino",
        "exif-gpsdestdistanceref": "Referencia para a distancia ao destino",
        "exif-gpsdestdistance": "Distancia ao destino",
        "exif-gpsprocessingmethod": "Nome do método de procesamento GPS",
        "exif-orientation-6": "Rotada 90° en sentido antihorario",
        "exif-orientation-7": "Rotada 90° en sentido horario e volteada verticalmente",
        "exif-orientation-8": "Rotada 90° en sentido horario",
-       "exif-planarconfiguration-1": "Formato de paquete de píxeles",
-       "exif-planarconfiguration-2": "Formato de planos",
+       "exif-planarconfiguration-1": "formato de paquete de píxeles",
+       "exif-planarconfiguration-2": "formato de planos",
        "exif-colorspace-65535": "Sen calibrar",
-       "exif-componentsconfiguration-0": "non hai",
+       "exif-componentsconfiguration-0": "non existe",
        "exif-exposureprogram-0": "Sen definir",
        "exif-exposureprogram-1": "Manual",
        "exif-exposureprogram-2": "Programa normal",
        "exif-exposureprogram-3": "Prioridade da apertura",
-       "exif-exposureprogram-4": "Prioridade da obturación",
+       "exif-exposureprogram-4": "Prioridade do obturador",
        "exif-exposureprogram-5": "Programa creativo (preferencia pola profundidade de campo)",
-       "exif-exposureprogram-6": "Programa de acción (preferencia por unha velocidade de exposición máis rápida)",
+       "exif-exposureprogram-6": "Programa de acción (preferencia por unha velocidade do obturador máis rápida)",
        "exif-exposureprogram-7": "Modo retrato (para primeiros planos co fondo desenfocado)",
        "exif-exposureprogram-8": "Modo paisaxe (para paisaxes co fondo enfocado)",
        "exif-subjectdistance-value": "$1 metros",
        "exif-meteringmode-0": "Descoñecido",
        "exif-meteringmode-1": "Media",
-       "exif-meteringmode-2": "Ponderado no centro",
-       "exif-meteringmode-3": "Un punto",
-       "exif-meteringmode-4": "Varios puntos",
-       "exif-meteringmode-5": "Patrón de medición",
+       "exif-meteringmode-2": "Media ponderada no centro",
+       "exif-meteringmode-3": "Puntual",
+       "exif-meteringmode-4": "Multipuntual",
+       "exif-meteringmode-5": "Patrón",
        "exif-meteringmode-6": "Parcial",
        "exif-meteringmode-255": "Outro",
        "exif-lightsource-0": "Descoñecida",
        "exif-lightsource-9": "Bo tempo",
        "exif-lightsource-10": "Tempo anubrado",
        "exif-lightsource-11": "Sombra",
-       "exif-lightsource-12": "Fluorescente luz de día (D 5700 – 7100K)",
-       "exif-lightsource-13": "Fluorescente branco día (N 4600 – 5400K)",
-       "exif-lightsource-14": "Fluorescente branco frío (W 3900 – 4500K)",
+       "exif-lightsource-12": "Fluorescente de luz de día (D 5700 – 7100K)",
+       "exif-lightsource-13": "Fluorescente de branco diurno (N 4600 – 5400K)",
+       "exif-lightsource-14": "Fluorescente de branco frío (W 3900 – 4500K)",
        "exif-lightsource-15": "Fluorescente branco (WW 3200 – 3700K)",
        "exif-lightsource-17": "Luz estándar A",
        "exif-lightsource-18": "Luz estándar B",
        "exif-sensingmethod-2": "Sensor da área de cor dun chip",
        "exif-sensingmethod-3": "Sensor da área de cor de dous chips",
        "exif-sensingmethod-4": "Sensor da área de cor de tres chips",
-       "exif-sensingmethod-5": "Sensor secuencial da área de cor",
-       "exif-sensingmethod-7": "Sensor trilineal",
-       "exif-sensingmethod-8": "Sensor secuencial da liña de cor",
+       "exif-sensingmethod-5": "Sensor da área de cor secuencial",
+       "exif-sensingmethod-7": "Sensor trilinear",
+       "exif-sensingmethod-8": "Sensor da cor linear secuencial",
        "exif-filesource-3": "Cámara fotográfica dixital",
        "exif-scenetype-1": "Unha imaxe fotografada directamente",
        "exif-customrendered-0": "Procesamento normal",
        "exif-customrendered-1": "Procesamento personalizado",
        "exif-exposuremode-0": "Exposición automática",
        "exif-exposuremode-1": "Exposición manual",
-       "exif-exposuremode-2": "Compensación de exposición automática",
+       "exif-exposuremode-2": "Compensación automática da exposición",
        "exif-whitebalance-0": "Balance de brancos automático",
        "exif-whitebalance-1": "Balance de brancos manual",
        "exif-scenecapturetype-0": "Estándar",
        "exif-subjectdistancerange-0": "Descoñecida",
        "exif-subjectdistancerange-1": "Macro",
        "exif-subjectdistancerange-2": "Primeiro plano",
-       "exif-subjectdistancerange-3": "Paisaxe",
+       "exif-subjectdistancerange-3": "Vista distante",
        "exif-gpslatitude-n": "Latitude norte",
        "exif-gpslatitude-s": "Latitude sur",
        "exif-gpslongitude-e": "Lonxitude leste",
        "confirmemail_body_set": "Alguén, probablemente vostede, desde o enderezo IP $1,\nestableceu este enderezo de correo electrónico como o da conta \"$2\" en {{SITENAME}}.\n\nPara confirmar que realmente esta conta lle pertence a vostede e activar\nas características do correo electrónico en {{SITENAME}}, abra esta ligazón no seu navegador:\n\n$3\n\nSe a conta *non* é súa, siga estoutra ligazón\npara cancelar a confirmación do enderezo de correo electrónico:\n\n$5\n\nO código de confirmación caduca o $6 ás $7.",
        "confirmemail_invalidated": "A confirmación do enderezo de correo electrónico foi cancelada",
        "invalidateemail": "Cancelar a confirmación do correo electrónico",
-       "notificationemail_subject_changed": "A dirección de correo rexistrada en {{SITENAME}} foi modificada",
-       "notificationemail_subject_removed": "A dirección de correo rexistrada en {{SITENAME}} foi eliminada",
-       "notificationemail_body_changed": "Alguén, probablemente vostede, dende a dirección IP $1, cambiou a dirección de correo electrónico da conta \"$2\" a \"$3\" en {{SITENAME}}.\n\nSe non foi vostede, contacte cun administrador inmediatamente.",
-       "notificationemail_body_removed": "Alguén, probablemente vostede, dende a dirección IP $1, eliminou a dirección de correo electrónico da conta \"$2\" en {{SITENAME}}.\n\nSe non foi vostede, contacte cun administrador inmediatamente.",
+       "notificationemail_subject_changed": "Modificouse o enderezo de correo electrónico rexistrado en {{SITENAME}}",
+       "notificationemail_subject_removed": "Eliminouse o enderezo de correo electrónico rexistrado en {{SITENAME}}",
+       "notificationemail_body_changed": "Alguén, probablemente vostede, dende o enderezo IP $1,\ncambiou o enderezo de correo electrónico da conta \"$2\" a \"$3\" en {{SITENAME}}.\n\nSe non foi vostede, contacte cun administrador inmediatamente.",
+       "notificationemail_body_removed": "Alguén, probablemente vostede, dende o enderezo IP $1,\neliminou o enderezo de correo electrónico da conta \"$2\" en {{SITENAME}}.\n\nSe non foi vostede, contacte cun administrador inmediatamente.",
        "scarytranscludedisabled": "[A transclusión interwiki está desactivada]",
        "scarytranscludefailed": "[Fallou a busca do modelo \"$1\"]",
        "scarytranscludefailed-httpstatus": "[Fallou a busca do modelo \"$1\": HTTP $2]",
        "scarytranscludetoolong": "[O enderezo URL é demasiado longo]",
        "deletedwhileediting": "'''Aviso:''' Esta páxina foi borrada despois de que comezase a editala!",
-       "confirmrecreate": "O usuario [[User:$1|$1]] ([[User talk:$1|conversa]]) {{GENDER:$1|borrou}} esta páxina despois de que vostede comezara a editala, dando o seguinte motivo:\n: <em>$2</em>\nPor favor, confirme que realmente quere recrear esta páxina.",
-       "confirmrecreate-noreason": "O usuario [[User:$1|$1]] ([[User talk:$1|conversa]]) {{GENDER:$1|borrou}} esta páxina despois de que vostede comezara a editala. Por favor, confirme que realmente quere recrear esta páxina.",
+       "confirmrecreate": "O usuario [[User:$1|$1]] ([[User talk:$1|conversa]]) {{GENDER:$1|borrou}} esta páxina despois de que vostede comezase a editala, achegando o seguinte motivo:\n: <em>$2</em>\nPor favor, confirme que realmente quere recrear esta páxina.",
+       "confirmrecreate-noreason": "O usuario [[User:$1|$1]] ([[User talk:$1|conversa]]) {{GENDER:$1|borrou}} esta páxina despois de que vostede comezase a editala. Por favor, confirme que realmente quere recrear esta páxina.",
        "recreate": "Recrear",
        "confirm_purge_button": "Aceptar",
        "confirm-purge-top": "Quere limpar a memoria caché desta páxina?",
        "confirm-unwatch-button": "Aceptar",
        "confirm-unwatch-top": "Quere eliminar esta páxina da lista de vixilancia?",
        "confirm-rollback-button": "Aceptar",
-       "confirm-rollback-top": "Reverter as edicións desta páxina?",
+       "confirm-rollback-top": "Quere reverter as edicións desta páxina?",
        "colon-separator": ":&#32;",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← páxina anterior",
        "version-variables": "Variables",
        "version-antispam": "Prevención contra spam",
        "version-other": "Outros",
-       "version-mediahandlers": "Executadores de multimedia",
+       "version-mediahandlers": "Manipuladores de ficheiros multimedia",
        "version-hooks": "Asociadores",
        "version-parser-extensiontags": "Etiquetas das extensións do analizador",
-       "version-parser-function-hooks": "Asociadores da función do analizador",
+       "version-parser-function-hooks": "Asociadores das funcións do analizador",
        "version-hook-name": "Nome do asociador",
        "version-hook-subscribedby": "Subscrito por",
        "version-version": "($1)",
        "version-software": "Software instalado",
        "version-software-product": "Produto",
        "version-software-version": "Versión",
-       "version-entrypoints": "Enderezos URL de punto de entrada",
+       "version-entrypoints": "Enderezos URL do punto de entrada",
        "version-entrypoints-header-entrypoint": "Punto de entrada",
        "version-entrypoints-header-url": "URL",
        "version-entrypoints-articlepath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgArticlePath Ruta dos artigos]",
        "version-libraries-license": "Licenza",
        "version-libraries-description": "Descrición",
        "version-libraries-authors": "Autores",
-       "redirect": "Redirixir por nome de ficheiro, usuario, páxina, modificación ou identificador de rexistro",
-       "redirect-summary": "Esta páxina especial redirixe cara a un ficheiro (dado o nome), unha páxina (dado o ID da páxina ou o dunha revisión) ou unha páxina de usuario (dado o ID dun usuario), ou unha entrada do rexistro (dada polo ID do rexistro). Utilización: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]] ou [[{{#Special:Redirect}}/user/101]], ou [[{{#Special:Redirect}}/logid/186]].",
+       "redirect": "Redirixir por nome de ficheiro, ID de usuario, ID de páxina, ID de revisión ou ID de rexistro",
+       "redirect-summary": "Esta páxina especial redirixe cara a un ficheiro (dado o nome), unha páxina (dado o ID da páxina ou o dunha revisión), unha páxina de usuario (dado o ID dun usuario) ou unha entrada do rexistro (dada o ID do rexistro). Utilización: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]] ou [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "Continuar",
        "redirect-lookup": "Procurar:",
        "redirect-value": "Valor:",
-       "redirect-user": "ID de usuario",
-       "redirect-page": "ID de páxina",
+       "redirect-user": "Identificador de usuario",
+       "redirect-page": "Identificador de páxina",
        "redirect-revision": "Revisión de páxina",
        "redirect-file": "Nome de ficheiro",
        "redirect-logid": "Identificador de rexistro",
        "tags-deactivate": "desactivar",
        "tags-hitcount": "$1 {{PLURAL:$1|modificación|modificacións}}",
        "tags-manage-no-permission": "Non ten os permisos necesarios para modificar etiquetas.",
-       "tags-manage-blocked": "Non pode acceder á interface de modificación de etiquetas mentres estea bloqueado.",
+       "tags-manage-blocked": "Non pode acceder á interface de modificación de etiquetas mentres {{GENDER:$1|estea}} bloqueado.",
        "tags-create-heading": "Crear unha nova etiqueta",
        "tags-create-explanation": "Por defecto, as etiquetas creadas recentemente poderán ser empregadas polos usuarios e os bots.",
        "tags-create-tag-name": "Nome da etiqueta:",
        "tags-deactivate-not-allowed": "Non é posible reactivar a páxina \"$1\".",
        "tags-deactivate-submit": "Desactivar",
        "tags-apply-no-permission": "Non ten permisos para aplicar etiquetas de cambios xunto cos seus tus cambios.",
-       "tags-apply-blocked": "Non pode aplicar os cambios das etiquetas cos seus cambios mentras estea bloqueado.",
+       "tags-apply-blocked": "Non pode aplicar os cambios das etiquetas cos seus cambios mentras {{GENDER:$1|estea}} bloqueado.",
        "tags-apply-not-allowed-one": "A etiqueta \"$1\" non se puede aplicar manualmente.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|A seguinte etiqueta non se pode|As seguintes etiquetas non se poden}} aplicar manualmente: $1",
        "tags-update-no-permission": "Non ten permisos para engadir ou quitar etiquetas de cambio das revisións individuais ou das entradas do rexistro.",
-       "tags-update-blocked": "Non pode engadir nin quitar de modificación etiquetas mentras estea bloqueado.",
+       "tags-update-blocked": "Non pode engadir nin quitar de modificación etiquetas mentras {{GENDER:$1|estea}} bloqueado.",
        "tags-update-add-not-allowed-one": "A etiqueta \"$1\" non se pode engadir manualmente.",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|A seguinte etiqueta non se pode|As seguintes etiquetas non se poden}} engadir manualmente: $1",
        "tags-update-remove-not-allowed-one": "A etiqueta \"$1\" non se pode eliminar.",
        "htmlform-cloner-create": "Engadir máis",
        "htmlform-cloner-delete": "Eliminar",
        "htmlform-cloner-required": "Necesítase, polo menos, un valor.",
+       "htmlform-date-placeholder": "AAAA-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "AAAA-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "O valor especificado non é unha data recoñedica. Probe usando o formato AAAA-MM-DD.",
+       "htmlform-time-invalid": "O valor especificado non é unha hora recoñedica. Probe usando o formato HH:MM:SS.",
+       "htmlform-datetime-invalid": "O valor especificado non é unha data e hora recoñedica. Probe usando o formato AAAA-MM-DD HH:MM:SS.",
+       "htmlform-date-toolow": "O valor especificado é anterior á data máis antiga permitida: $1",
+       "htmlform-date-toohigh": "O valor especificado é posterior á data máis nova permitida: $1",
+       "htmlform-time-toolow": "O valor especificado é anterior ó tempo máis antigo permitido: $1",
+       "htmlform-time-toohigh": "O valor especificado é posterior ó tempo máis novo permitido: $1",
+       "htmlform-datetime-toolow": "O valor especificado é anterior á data e tampo máis antigo permitido: $1",
+       "htmlform-datetime-toohigh": "O valor especificado é posterior á data e tempo máis novo permitido: $1",
        "htmlform-title-badnamespace": "\"[[:$1]]\" non está no espazo de nomes \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" non é un título de páxina que se poida crear",
        "htmlform-title-not-exists": "\"$1\" non existe.",
        "feedback-external-bug-report-button": "Enviar unha tarefa técnica",
        "feedback-dialog-title": "Enviar comentarios",
        "feedback-dialog-intro": "Pode usar o formulario simple de abaixo para enviar os seus comentarios sobre o editor visual. O seu comentario será engadido á páxina \"$1\", xunto co seu nome de usuario.",
-       "feedback-error-title": "Erro",
        "feedback-error1": "Erro: Resultado da API non recoñecido",
        "feedback-error2": "Erro: Fallo de edición",
        "feedback-error3": "Erro: Non hai resposta da API",
        "feedback-thanks": "Grazas! Os seus comentarios publicáronse na páxina \"[$2 $1]\".",
        "feedback-thanks-title": "Grazas!",
        "feedback-useragent": "Axente de usuario:",
-       "searchsuggest-search": "Procurar",
+       "searchsuggest-search": "Procurar en {{SITENAME}}",
        "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.",
        "authmanager-authn-autocreate-failed": "A creación automatica dunha conta local fallou: $1",
        "authmanager-change-not-supported": "As credenciais proporcionadas non se poden modificar, xa que ninguén as utilizará.",
        "authmanager-create-disabled": "A creación de contas está desactivada.",
-       "authmanager-create-from-login": "Para crear a súa conta, complete os campos a continuación.",
+       "authmanager-create-from-login": "Para crear a súa conta, complete os campos.",
        "authmanager-create-not-in-progress": "O proceso de creación da conta non está en progreso ou perdéronse os datos da sesión. Empece de novo desde o principio.",
        "authmanager-create-no-primary": "As credenciais subministradas non poden usarse para a creación da conta.",
        "authmanager-link-no-primary": "As credenciais subministradas non poden usarse para a ligazón da conta.",
        "usercssispublic": "Lembre: As subpáxinas CSS non deberían conter datos confidenciais porque outros usuarios poden velos.",
        "restrictionsfield-badip": "Enderezo IP ou rango de IP non válido: $1",
        "restrictionsfield-label": "Rangos de IP permitidos:",
-       "restrictionsfield-help": "Un único enderezo IP ou rango CIDR por liña. Para habilitalos todos, utilice<br><code>0.0.0.0/0</code><br><code>::/0</code>"
+       "restrictionsfield-help": "Un único enderezo IP ou rango CIDR por liña. Para habilitalos todos, utilice<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Erro: $1",
+       "edit-error-long": "Erros:\n\n$1"
 }
index 2dc66a3..4e4e804 100644 (file)
        "yourpasswordagain": "رمزه دۊمارته بنويس",
        "createacct-yourpasswordagain": "رمزه تأىيد بکۊن",
        "createacct-yourpasswordagain-ph": "هندئه رمزه بنويس",
-       "remembermypassword": "رمزه (تا حدأکثر $1 {{PLURAL:$1|رۊز|رۊزؤن}}) اي وبمجˇ مئن ىاد بدأر.",
        "userlogin-remembermypassword": "مره دۊيرين بمأ بدأر",
        "cannotloginnow-title": "هسأ دۊيرين أمأ منين",
        "cannotloginnow-text": "وختي $1 کاردره، نشأنه دۊيرين أمأن.",
        "categories": "جرگه'ن",
        "listusers-noresult": "هيچ کارگيري پىدا نۊبؤ.",
        "activeusers": "فعال کارگيرؤنˇ ليست",
-       "activeusers-hidesysops": "کيا'نه جيگا دأن",
        "activeusers-noresult": "هيچ کارگيري پىدا نۊبؤ.",
        "listgrouprights": "کارگيري پأره دسفأرسؤن",
        "listgrouprights-group": "پأره",
index d4040cb..a12ef51 100644 (file)
        "yourpasswordagain": "गुपीत उतर परतें टायप करात",
        "createacct-yourpasswordagain": "गुपीतउतराची खात्री कर",
        "createacct-yourpasswordagain-ph": "गुपितउतर परत घालात",
-       "remembermypassword": "ह्या ब्राउजराचेर म्हजें लॉग इन याद दवरात (चडांतचड $1 {{PLURAL:$1|दिस|दिसां}} खातीर)",
        "userlogin-remembermypassword": "म्हजें सत्र चालू दवर",
        "userlogin-signwithsecure": "सुरक्षित कनेक्शन वापर",
        "yourdomainname": "तुमचो डोमेन:",
index 975cb88..a3d9b83 100644 (file)
        "yourpasswordagain": "Gupit utor porot boroi:",
        "createacct-yourpasswordagain": "Gupitutrachi khatri kor",
        "createacct-yourpasswordagain-ph": "Gupitutor porot boroi",
-       "remembermypassword": "Hea internet browseran mhojem sotrachem ugdas dovor (chodan chod $1 {{PLURAL:$1|disak|disank}})",
        "userlogin-remembermypassword": "Mhojem sotr chalu dovor",
        "userlogin-signwithsecure": "Surokxit onubondh vapor",
        "yourdomainname": "Tuzo domain:",
index 432338d..2aa61b6 100644 (file)
        "print": "Cetaki",
        "view": "Bilohi",
        "view-foreign": "Bilohi to $1",
-       "edit": "Momoli'o",
+       "edit": "Boli'o",
        "edit-local": "Ubawa deskripsi lokal",
        "create": "Mohutu",
        "create-local": "Duhengi deskripsi lokal",
        "lastmodifiedat": "Halaman botiye biloli'o pulitiyo $1, $2.",
        "viewcount": "Halaman botiye ma hilu'o {{PLURAL:$1|$1 kali}}.<br />",
        "protectedpage": "Halaman udaha-daha",
-       "jumpto": "Lumanti'a ode",
-       "jumptonavigation": "Navigasi",
+       "jumpto": "Lumanti'a ode:",
+       "jumptonavigation": "navigasi",
        "jumptosearch": "lolohe",
        "view-pool-error": "Ma'apu, server onggo sibuk sa'ati boti.\nNgohuntuwa pengguna mocoba momilehe halaman boti.\nWulatipo ngope'e to'u yi'o dipo mocoba momilehe halaman boti pooli.\n\n\n$1",
        "generic-pool-error": "Ma'apu, server onggo sibuk sa'ati boti.\nNgohuntuwa pengguna mocoba momilohe halaman boti.\nWulatipo ngope'e to'u  yi'u dipo mocoba momilehe halaman boti pooli.",
        "newmessageslinkplural": "{{PLURAL:$1|tuwawu tahuli bohu|999=tahuli bohu}}",
        "newmessagesdifflinkplural": "{{PLURAL:$1|iluba|999=u iluba}} pulitiyo",
        "youhavenewmessagesmulti": "Yio lootapu tahuli bohu to $1",
-       "editsection": "boli'a",
+       "editsection": "boli'o",
        "editold": "boli'a",
        "viewsourceold": "Bilohi bungoliyo",
        "editlink": "boli'a",
        "nstab-template": "Templat",
        "nstab-help": "Halaman tulungi",
        "nstab-category": "Kategori",
-       "mainpage-nstab": "Halamani bungaliyo",
+       "mainpage-nstab": "Halaman Bungaliyo",
        "nosuchaction": "Diya'a huhutu boyito",
        "nosuchactiontext": "Huhutu u hepohile lo URL ja valid.\nYi'o lotalawa lopomaso lo URL, meyalo lodudu'a pranala u ja banari.\nUtiye olo kira-kira tuwotiyo woluwo bug to pilaakasi u hepomake {{SITENAME}}",
        "nosuchspecialpage": "Diya'a halaman istimewa boyito",
        "yourpasswordagain": "Ulangiya tahe u'unti",
        "createacct-yourpasswordagain": "Konfirmasi tahe u'unti",
        "createacct-yourpasswordagain-ph": "Tuwota pooli tahe u'unti",
-       "remembermypassword": "Eelayi tahe u'unti'u to komputer botiye (to delomo $1 {{PLURAL:$1|huyi}})",
        "userlogin-remembermypassword": "Hulima'o wa'u tuwo-tuwoto",
        "userlogin-signwithsecure": "Popohunawa server aamani",
        "cannotloginnow-title": "Ja mowali tumuwoto log sa'ati botiya",
        "tooltip-invert": "Centang kotak botiye u mopowanto'o halaman yiloboli'a to delomo huwali lo tanggulo tilulawoto (wawu huwali lo tanggulo a'ayita wanu dicentang)",
        "namespace_association": "Huwali lo tanggulo a'aayita",
        "tooltip-namespace_association": "Centang halaman botiye u mopowayito huwali lo tanggulo lo'iyawa meyalo subjek u a'ayita wolo huwali lo tanggulo u tilulawoto.",
-       "blanknamespace": "Bungaliyo",
+       "blanknamespace": "(Bungaliyo)",
        "contributions": "Kontribusi {{GENDER:$1|Ta ohu'uwo}}",
        "mycontris": "Kontribusi",
        "anoncontribs": "Kontribusi",
index 0f3e624..6220a07 100644 (file)
        "disclaimers": "𐌲𐌰𐍂𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐍂𐌰𐌹𐌷𐍄𐌰𐌹𐍃",
        "disclaimerpage": "Project:𐌲𐌰𐌼𐌰𐌹𐌽𐌰 𐌲𐌰𐍂𐌰𐌹𐌳𐌴𐌹𐌽𐍃 𐍂𐌰𐌹𐌷𐍄𐌰𐌹𐍃",
        "edithelp": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌹𐌷𐌹𐌻𐍀𐌰",
+       "helppage-top-gethelp": "𐌷𐌹𐌻𐍀𐌰",
        "mainpage": "𐌰𐌽𐌰𐍃𐍄𐍉𐌳𐌴𐌹𐌽𐌹𐌻𐌰𐌿𐍆𐍃",
        "mainpage-description": "𐌰𐌽𐌰𐍃𐍄𐍉𐌳𐌴𐌹𐌽𐌹𐌻𐌰𐌿𐍆𐍃",
-       "portal": "ð\90\8c±ð\90\8c°ð\90\8c¿ð\90\8d\82ð\90\8c²ð\90\8d\83 ð\90\8c²ð\90\8c°ð\90\8d\85ð\90\8c¹",
-       "portal-url": "Project:ð\90\8c±ð\90\8c°ð\90\8c¿ð\90\8d\82ð\90\8c²ð\90\8d\83 ð\90\8c²ð\90\8c°ð\90\8d\85ð\90\8c¹",
+       "portal": "ð\90\8c²ð\90\8c°ð\90\8cµð\90\8c¿ð\90\8c¼ð\90\8c¸ð\90\8d\83 ð\90\8c²ð\90\8c°ð\90\8c¼ð\90\8c°ð\90\8c¹ð\90\8c½ð\90\8c³ð\90\8c¿ð\90\8c¸ð\90\8c°ð\90\8c¹ð\90\8d\83",
+       "portal-url": "Project:ð\90\8c²ð\90\8c°ð\90\8cµð\90\8c¿ð\90\8c¼ð\90\8c¸ð\90\8d\83 ð\90\8c²ð\90\8c°ð\90\8c¼ð\90\8c°ð\90\8c¹ð\90\8c½ð\90\8c³ð\90\8c¿ð\90\8c¸ð\90\8c°ð\90\8c¹ð\90\8d\83",
        "privacy": "𐌲𐌰𐍂𐌴𐌳𐌴𐌹𐌽𐍉𐍃 𐍃𐌿𐌽𐌳𐍂𐍉𐍅𐌹𐍃𐌰𐌽𐌰",
        "privacypage": "Project:𐌲𐌰𐍂𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐍃𐌿𐌽𐌳𐍂𐍉𐍅𐌹𐍃𐌰𐌽𐌰",
        "retrievedfrom": "𐌲𐌰𐌽𐌿𐌼𐌰𐌽 𐍆𐍂𐌰𐌼 \"$1\"",
        "error": "𐌰𐌹𐍂𐌶𐌴𐌹",
        "databaseerror-error": "𐌰𐌹𐍂𐌶𐌴𐌹: $1",
        "missing-article": "𐌳𐌰𐍄𐌰𐌱𐌴𐍃 𐌽𐌹 𐌱𐌹𐌲𐌰𐍄 𐌱𐍉𐌺𐍉𐍃 𐌻𐌰𐌿𐌱𐌹𐍃 𐌸𐌹𐌶𐌴𐌹 𐍃𐌺𐌿𐌻𐌳𐌴𐌳𐌹 𐌱𐌹𐌲𐌹𐍄𐌰𐌽, 𐌷𐌰𐌹𐍄𐌰𐌽𐍃 \"$1\" $2. \n\n𐌸𐌰𐍄𐌰 𐌿𐍆𐍄𐌰 𐍅𐌰𐌹𐍂𐌸𐌹𐌸 𐌾𐌰𐌱𐌰𐌹 𐌻𐌰𐌹𐍃𐍄𐌾𐌰𐌳𐌰 𐍆𐌰𐌹𐍂𐌽𐌾𐌰 𐌳𐌹𐍆𐍆 𐌸𐌰𐌿 𐍃𐍀𐌹𐌻𐌻𐌰𐌲𐌰𐍅𐌹𐍃𐍃 𐍃𐌴𐌹 𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌹𐌳𐌰 𐌹𐍃𐍄. 𐌽𐌹𐌱𐌰𐌹 𐌹𐍃𐍄, 𐌼𐌰𐌷𐍄𐍃 𐌹𐍃𐍄 𐌴𐌹 𐌱𐌹𐌲𐌴𐍄𐌴𐌹𐍃 𐌰𐌹𐍂𐌶𐌴𐌹𐌽 𐌹𐌽 𐍃𐌰𐌿𐍆𐍄𐍅𐌰𐌹𐍂𐌰. \n\n𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺, 𐌼𐌴𐍂𐌴𐌹 𐌸𐌰𐍄𐌰 𐌳𐌿 [[Special:ListUsers/sysop\n|𐍂𐌴𐌹𐌺]] 𐌲𐌹𐍆𐌿𐌷 𐌲𐌰𐍅𐌹𐍃𐍃.",
+       "cannotdelete-title": "𐌽𐌹 𐌼𐌰𐌲 𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌾𐌰𐌽 𐌻𐌰𐌿𐌱𐌰 \"$1\"",
        "badtitle": "𐌿𐌽𐍂𐌰𐌹𐌷𐍄𐌰𐍄𐌰 𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹",
        "badtitletext": "𐍆𐍂𐌰𐌹𐌷𐌰𐌽𐍃 𐌻𐌰𐌿𐍆𐍃 𐍅𐌰𐍃 𐌿𐌽𐌲𐌰𐌼𐌰𐌲𐌰𐌽𐌳𐍃, 𐌻𐌰𐌿𐍃, 𐌰𐌹𐌸𐌸𐌰𐌿 𐌿𐌽𐍂𐌰𐌹𐌷𐍄𐌰𐌱𐌰 𐌲𐌰𐍅𐌹𐌳𐌰𐌽𐍃 𐌼𐌹𐌸𐍂𐌰𐌶𐌳𐌰 𐌸𐌰𐌿 𐌼𐌹𐌸-𐍅𐌹𐌺𐌹 𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹. 𐌼𐌰𐌲𐌹 𐌷𐌰𐌱𐌰𐌽 𐌰𐌹𐌽𐌰 𐌸𐌰𐌿 𐌼𐌰𐌽𐌰𐌲𐌹𐌶𐍉𐍃 𐌱𐍉𐌺𐍉𐍃 𐌱𐍂𐌿𐌺𐌹𐌳𐍉𐍃 𐌹𐌽 𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌾𐌰𐌼.",
        "viewsource": "𐍃𐌰𐌹𐍈 𐌱𐍂𐌿𐌽𐌽𐌰𐌽",
+       "mycustomjsprotected": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐌳𐌿 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 JavaScript 𐌻𐌰𐌿𐍆.",
        "yourname": "𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉:",
        "userlogin-yourname": "𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉",
        "userlogin-yourname-ph": "𐌼𐌴𐌻𐌴𐌹 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉 𐌸𐌴𐌹𐌽",
        "createacct-yourpasswordagain": "𐌲𐌰𐍃𐌹𐌲𐌻𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳",
        "createacct-yourpasswordagain-ph": "𐌼𐌴𐌻𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐌰𐍆𐍄𐍂𐌰",
        "userlogin-remembermypassword": "𐌲𐌰𐍆𐌰𐍃𐍄 𐌼𐌹𐌺 {{GENDER:𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌽𐌰|𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰}}",
+       "cannotloginnow-title": "𐌽𐌿 𐌽𐌹 𐌼𐌰𐌲𐍄 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽",
        "login": "𐌰𐍄𐌲𐌰𐌲𐌲",
        "nav-login-createaccount": "𐌰𐍄𐌲𐌰𐌲𐌲 / 𐍃𐌺𐌰𐍀𐌴𐌹 𐌺𐌰𐍅𐍄𐍃𐌾𐍉𐌽",
        "userlogin": "𐌰𐍄𐌲𐌰𐌲𐌲 / 𐍃𐌺𐌰𐍀𐌴𐌹 𐌺𐌰𐍅𐍄𐍃𐌾𐍉𐌽",
        "pt-login": "𐌰𐍄𐌲𐌰𐌲𐌲",
        "pt-login-button": "𐌰𐍄𐌲𐌰𐌲𐌲",
        "pt-createaccount": "𐍃𐌺𐌰𐍀𐌴𐌹 𐌺𐌰𐍅𐍄𐍃𐌾𐍉𐌽",
+       "pt-userlogout": "𐌰𐍆𐌻𐌴𐌹𐌸",
        "passwordreset": "𐌰𐍆𐍄𐍂𐌰 𐍃𐌰𐍄𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳",
        "bold_sample": "𐍃𐍅𐌹𐌽𐌸𐍉𐍃 𐌱𐍉𐌺𐍉𐍃",
        "bold_tip": "𐍃𐍅𐌹𐌽𐌸𐍉𐍃 𐌱𐍉𐌺𐍉𐍃",
        "showpreview": "𐌰𐍄𐌰𐌿𐌲𐌴𐌹 𐍆𐌰𐌿𐍂𐌰𐍃𐌹𐌿𐌽",
        "showdiff": "𐌰𐍄𐌰𐌿𐌲𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌽𐌹𐌽𐍃",
        "loginreqlink": "𐌰𐍄𐌲𐌰𐌲𐌲",
-       "newarticle": "(ð\90\8c½ð\90\8c¹ð\90\8c¿ð\90\8c¾ð\90\8c°ð\90\8d\84ð\90\8c°)",
+       "newarticle": "(ð\90\8c½ð\90\8c¹ð\90\8d\85ð\90\8c¹)",
        "newarticletext": "𐌻𐌰𐌹𐍃𐍄𐌹𐌳𐌴𐍃 𐌲𐌰𐍅𐌹𐍃 𐌳𐌿 𐌻𐌰𐌿𐌱𐌰 𐍃𐌰𐌴𐌹 𐌽𐌹𐍃𐍄. 𐌳𐌿 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆, 𐌰𐌽 𐌰𐍃𐍄𐍉𐌳𐌴𐌹 𐌼𐌴𐌻𐌾𐌰𐌽 𐌹𐌽 𐌰𐍂𐌺𐌰𐌹 𐌿𐍆 (𐍃𐌰𐌹𐍈 [$1 𐌷𐌹𐌻𐍀𐌰𐌻𐌰𐌿𐍆] 𐌼𐌰𐌽𐌰𐌲𐌹𐌶𐌹𐌽 𐌺𐌿𐌽𐌸𐌾𐌰). 𐌾𐌰𐌱𐌰𐌹 𐌹𐍃 𐌷𐌴𐍂 𐌹𐌽 𐌰𐌹𐍂𐌶𐌴𐌹𐌽𐍃, 𐌲𐌰𐌲𐌲 𐌳𐌿 <𐍃𐍄𐍂𐍉𐌽𐌲>𐌹𐌱𐌿𐌺𐌰𐌷𐌰𐌿𐌱𐌹𐌳𐌹𐌻𐍉𐌽.",
        "noarticletext": "𐌽𐌿 𐌽𐌹 𐍃𐌹𐌽𐌳 𐌱𐍉𐌺𐍉𐍃 𐌹𐌽 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰.\n𐌼𐌰𐌲𐍄 [[Special:Search/{{PAGENAME}}|𐍃𐍉𐌺𐌾𐌰𐌽 𐌸𐌰𐍄𐌰 𐌻𐌰𐌿𐌱𐌰-𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹]] 𐌹𐌽 𐌰𐌽𐌸𐌰𐍂𐌰𐌹𐌼 𐌻𐌰𐌿𐌱𐌰𐌼,  <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 𐍃𐍉𐌺𐌾𐌰𐌽 𐌲𐌰𐌷𐌰𐌷𐌾𐍉 𐌲𐌰𐍆𐌰𐍃𐍄𐍉𐍃], 𐌰𐌹𐌸𐌸𐌰𐌿 [{{fullurl:{{FULLPAGENAME}}|action=edit}} 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆.]</ span>",
        "noarticletext-nopermission": "𐌽𐌿 𐌽𐌹 𐍃𐌹𐌽𐌳 𐌱𐍉𐌺𐍉𐍃 𐌹𐌽 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰.\n𐌼𐌰𐌲𐍄 [[Special:Search/{{PAGENAME}}|𐍃𐍉𐌺𐌾𐌰𐌽 𐌸𐌰𐍄𐌰 𐌻𐌰𐌿𐌱𐌰-𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹]] 𐌹𐌽 𐌰𐌽𐌸𐌰𐍂𐌰𐌹𐌼 𐌻𐌰𐌿𐌱𐌰𐌼, 𐌸𐌰𐌿 <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 𐍃𐍉𐌺𐌾𐌰𐌽 𐌲𐌰𐌷𐌰𐌷𐌾𐍉 𐌲𐌰𐍆𐌰𐍃𐍄𐍉𐍃]</span>, 𐌹𐌸 𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆.",
        "updated": "(𐌰𐌽𐌰𐌽𐌹𐍅𐌹𐌸)",
        "previewnote": "<strong>𐌲𐌰𐌼𐌹𐌽𐌸𐌴𐌹 𐌸𐌰𐍄𐌴𐌹 𐌸𐌰𐍄𐌰 𐌹𐍃𐍄 𐌸𐌰𐍄𐌰𐌹𐌽𐌴𐌹 𐍆𐌰𐌿𐍂𐌰𐍃𐌹𐌿𐌽𐍃.</strong>\n𐌸𐌴𐌹𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌽𐌰𐌿𐌷 𐌽𐌹 𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌽𐍉𐍃 𐍃𐌹𐌽𐌳!",
-       "editing": "{{GENDER:𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐍃|𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐌴𐌹}} $1",
-       "creating": "{{GENDER:𐍃𐌺𐌰𐍀𐌾𐌰𐌽𐌳𐍃|𐍃𐌺𐌰𐍀𐌾𐌰𐌽𐌳𐌴𐌹}} $1",
+       "editing": "{{GENDER:𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐍃|𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐌴𐌹|𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐍃}} $1",
+       "creating": "{{GENDER:𐍃𐌺𐌰𐍀𐌾𐌰𐌽𐌳𐍃|𐍃𐌺𐌰𐍀𐌾𐌰𐌽𐌳𐌴𐌹|𐍃𐌺𐌰𐍀𐌾𐌰𐌽𐌳𐍃\n}} $1",
        "editingsection": "{{GENDER:𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐍃|𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐌴𐌹}} $1 (𐌳𐌰𐌹𐌻)",
        "editingcomment": "{{GENDER:𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐍃|𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐌴𐌹}} $1 (𐌽𐌹𐌿𐌾𐌰 𐌳𐌰𐌹𐌻)",
        "yourdiff": "𐌲𐌰𐍃𐌺𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
        "hiddencategories": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌹𐍃𐍄 𐌲𐌰𐌳𐌰𐌹𐌻𐌰 {{PLURAL:$1|1 𐌰𐌽𐌰𐌻𐌰𐌿𐌲𐌽𐌹𐍃 𐌺𐌿𐌽𐌾𐌹𐍃|$1 𐌰𐌽𐌰𐌻𐌰𐌿𐌲𐌽𐌰𐌹𐌶𐌴 𐌺𐌿𐌽𐌾𐌴}}:‎",
        "permissionserrorstext-withaction": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐌳𐌿 $2, 𐌹𐌽 {{PLURAL:$1|𐌹𐍆𐍄𐌿𐌼𐌰𐌹𐌶𐍉𐍃 𐍅𐌰𐌹𐌷𐍄𐌰𐌹𐍃|𐌹𐍆𐍄𐌿𐌼𐌰𐌹𐌶𐍉 𐍅𐌰𐌹𐌷𐍄𐌴}}:",
        "moveddeleted-notice": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌿𐍃𐌽𐌿𐌼𐌰𐌽𐍃 𐌹𐍃𐍄. 𐌿𐍃𐌽𐌿𐌼𐍄𐍃 𐌾𐌰𐌷 𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌹𐌽𐍃 𐌼𐌹𐌸𐍃𐌰𐍄𐌴𐌹𐌽𐌰𐌹𐍃 𐌿𐍆 𐍃𐌹𐌽𐌳 𐌿𐍃𐍄𐌰𐌹𐌺𐌽𐌴𐌹𐌽𐌰𐌹.",
+       "postedit-confirmation-created": "𐌻𐌰𐌿𐍆𐍃 𐌲𐌰𐍃𐌺𐌰𐍀𐌰𐌽𐍃 𐌹𐍃𐍄.",
+       "edit-already-exists": "𐌽𐌹 𐍅𐌰𐍃 𐌼𐌰𐌷𐍄𐍃 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆. \n𐌾𐌿 𐌹𐍃𐍄.",
        "post-expand-template-inclusion-warning": "'''𐌷𐍅𐍉𐍄𐌾𐌰𐌽𐌳𐍃:''' 𐍆𐌰𐌿𐍂𐌰𐌼𐌴𐌻𐌴𐌹𐌽𐍃 𐍃𐌹𐌽𐌳 𐌿𐍆𐌰𐍂𐌼𐌹𐌺𐌹𐌻𐍃. 𐍃𐌿𐌼𐍃 𐍆𐌰𐌿𐍂𐌴𐌼𐌴𐌻𐌴𐌹𐌽𐍉𐍃 𐌽𐌹 𐌼𐌰𐌲 𐍅𐌹𐍃𐌰𐌽 𐌸𐌰𐍂",
        "post-expand-template-inclusion-category": "𐍃𐌴𐌹𐌳𐍉𐌽𐍃 𐌸𐌰𐍂 𐍆𐌰𐌿𐍂𐌰𐌼𐌴𐌻𐌴𐌹𐌽𐍃 𐍃𐌹𐌽𐌳 𐌿𐍆𐌰𐍂𐌼𐌹𐌺𐌹𐌻𐍃",
        "viewpagelogs": "𐌰𐍄𐌰𐌿𐌲𐌴𐌹 𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌹𐌽𐌹𐌽𐍃 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰",
        "history-feed-item-nocomment": "$1 𐌰𐍄 $2",
        "rev-delundel": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐌰𐌽𐌰𐍃𐌹𐌿𐌽",
        "revdel-restore": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹 𐌰𐌽𐌰𐍃𐌹𐌿𐌽",
-       "revertmerge": "ð\90\8c¿ð\90\8c½ð\90\8c²ð\90\8c°ð\90\8d\84ð\90\8c¹ð\90\8c»ð\90\8d\89ð\90\8d\83",
+       "revertmerge": "ð\90\8c¿ð\90\8c½ð\90\8c²ð\90\8c°ð\90\8c±ð\90\8c»ð\90\8c°ð\90\8c½ð\90\8c³",
        "history-title": "𐌰𐍆𐍄𐍂𐌰𐍃𐌹𐌿𐌽𐌹𐍃𐍀𐌹𐌻𐌻 𐌻𐌰𐌿𐌱𐌹𐍃 \"$1\"",
        "difference-title": "𐌲𐌰𐍃𐌺𐌰𐌹𐌳𐌴𐌹𐌽𐍃 𐌼𐌹𐌸 𐌰𐍆𐍄𐍂𐌰𐍃𐌹𐌿𐌽𐍉𐌼 𐌻𐌰𐌿𐌱𐌹𐍃 \"$1\"",
+       "difference-multipage": "(𐌰𐌽𐌸𐌰𐍂𐌻𐌴𐌹𐌺𐌾𐌰 𐌼𐌹𐌸 𐌻𐌰𐌿𐌱𐌰𐌼)",
        "lineno": "𐍃𐍄𐍂𐌹𐌺𐍃 $1:",
        "editundo": "𐍃𐌺𐌰𐍀𐌴𐌹 𐌰𐍆𐍄𐍂𐌰",
        "diff-multi-sameuser": "({{PLURAL:$1|𐌰𐌹𐌽𐌰 𐌼𐌹𐌳𐌿𐌼𐌰𐌲𐌰𐌱𐍉𐍄𐌴𐌹𐌽𐍃|$1 𐌼𐌹𐌳𐌿𐌼𐌰 𐌲𐌰𐌱𐍉𐍄𐌴𐌹𐌽𐍉𐍃}} 𐍆𐍂𐌰𐌼 𐍃𐌰𐌼𐌹𐌽 𐌱𐍂𐌿𐌺𐌾𐌹𐌽 𐌽𐌹 𐌰𐍄𐌰𐌿𐌲𐌹𐌳𐌰/𐌰𐍄𐌰𐌿𐌲𐌹𐌳𐍉𐍃)",
        "search-showingresults": "{{ZPLURAL:$4|𐍄𐌰𐌿𐌹 <strong>$1 𐍅𐌰𐌹𐌷𐍄𐌰𐌹𐍃 <strong>$3|𐍄𐍉𐌾𐌰 <strong>$1 - $2 𐍅𐌰𐌹𐌷𐍄𐌰𐌹𐍃 <strong>$3}}",
        "search-nonefound": "𐌽𐌹 𐍄𐌰𐌿𐌹 𐍅𐌰𐍃 𐍃𐌰𐌼𐌰𐌽𐌰 𐍃𐍅𐌰 𐍃𐍉𐌺𐌴𐌹𐌽.",
        "powersearch-legend": "𐍃𐍉𐌺𐌴𐌹",
-       "preferences": "ð\90\8c¼ð\90\8c´ð\90\8c¹ð\90\8c½ð\90\8d\89ð\90\8d\83 ð\90\8c±ð\90\8d\82ð\90\8c¿ð\90\8cºð\90\8c¾ð\90\8c°ð\90\8c¼ð\90\8c°ð\90\8c¹ð\90\8c³ð\90\8c´ð\90\8c¹ð\90\8c½ð\90\8c´ð\90\8c¹𐍃",
-       "mypreferences": "ð\90\8c²ð\90\8c°ð\90\8c»ð\90\8c´ð\90\8c¹ð\90\8cºð\90\8c°ð\90\8c½ð\90\8c³ð\90\8c´ð\90\8c¹ð\90\8c½𐍃 𐍅𐌰𐌹𐌷𐍄𐍃",
+       "preferences": "ð\90\8c¼ð\90\8c´ð\90\8c¹ð\90\8c½ð\90\8d\89ð\90\8d\83 ð\90\8d\86ð\90\8d\82ð\90\8c¹ð\90\8c¾ð\90\8d\89ð\90\8c½ð\90\8d\89ð\90\8d\83 ð\90\8d\85ð\90\8c°ð\90\8c¹ð\90\8c·ð\90\8d\84𐍃",
+       "mypreferences": "ð\90\8c¼ð\90\8c´ð\90\8c¹ð\90\8c½ð\90\8d\89ð\90\8d\83 ð\90\8d\86ð\90\8d\82ð\90\8c¹ð\90\8c¾ð\90\8d\89ð\90\8c½ð\90\8d\89𐍃 𐍅𐌰𐌹𐌷𐍄𐍃",
        "prefs-skin": "𐍆𐌹𐌻𐌻",
        "skin-preview": "𐍆𐌰𐌿𐍂𐌰𐍃𐌰𐌹𐍈",
        "saveprefs": "𐌲𐌰𐍆𐌰𐍃𐍄",
        "minoreditletter": "l",
        "newpageletter": "N",
        "boteditletter": "b",
-       "recentchangeslinked": "ð\90\8c²ð\90\8c°ð\90\8d\85ð\90\8c¹𐌳𐌰𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
-       "recentchangeslinked-feed": "Máideinlieks",
-       "recentchangeslinked-toolbox": "ð\90\8c²ð\90\8c°ð\90\8d\85ð\90\8c¹𐌳𐌰𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
-       "recentchangeslinked-title": "ð\90\8c¹ð\90\8c½ð\90\8c¼ð\90\8c°ð\90\8c¹ð\90\8c³ð\90\8c´ð\90\8c¹ð\90\8c½ð\90\8d\89ð\90\8d\83 ð\90\8c²ð\90\8c°ð\90\8d\85ð\90\8c¹𐌳𐌰𐌽𐍉𐍃 𐌼𐌹𐌸 \"$1\"",
-       "recentchangeslinked-summary": "𐍃𐍉 𐌹𐍃𐍄 𐌻𐌴𐌹𐍃𐍄𐌰 𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐌴 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐍃 𐍃𐌺𐍉𐍀 𐌰𐌽𐌰 𐍃𐌴𐌹𐌳𐍉𐌽𐍃 𐌻𐌴𐌹𐌽𐌺𐍉𐌽𐌳 𐌿𐍃 𐌿𐍃𐍃𐌹𐌽𐌳𐌰𐌹 𐍃𐌴𐌹𐌳𐍉𐌽 (𐌰𐌹𐌸𐌸𐌰𐌿 𐌻𐌹𐌸𐌰𐌿𐍃 𐌿𐍃𐍃𐌹𐌽𐌳𐌰𐌹𐌶𐍉𐍃 𐌷𐌰𐌽𐍃𐍉𐍃). 𐍃𐌴𐌹𐌳𐍉𐌽𐍃 [[Special:Watchlist|𐍅𐌹𐍄𐌰𐌽𐌳𐌻𐌴𐌹𐍃𐍄𐍉𐍃 𐌸𐌴𐌹𐌽𐍉𐍃]] 𐍃𐌹𐌽𐌳 '''𐌳𐌹𐌲𐍂𐍃𐍄𐌰𐍆𐍃'''.",
+       "recentchangeslinked": "ð\90\8c²ð\90\8c°ð\90\8c±ð\90\8c¿ð\90\8c½𐌳𐌰𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
+       "recentchangeslinked-feed": "𐌲𐌰𐌱𐌿𐌽𐌳𐌰𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
+       "recentchangeslinked-toolbox": "ð\90\8c²ð\90\8c°ð\90\8c±ð\90\8c¿ð\90\8c½𐌳𐌰𐌽𐍉𐍃 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃",
+       "recentchangeslinked-title": "ð\90\8c¹ð\90\8c½ð\90\8c¼ð\90\8c°ð\90\8c¹ð\90\8c³ð\90\8c´ð\90\8c¹ð\90\8c½ð\90\8d\89ð\90\8d\83 ð\90\8c²ð\90\8c°ð\90\8c±ð\90\8c¿ð\90\8c½𐌳𐌰𐌽𐍉𐍃 𐌼𐌹𐌸 \"$1\"",
+       "recentchangeslinked-summary": "A𐌸𐌰𐍄𐌰 𐌹𐍃𐍄 𐍅𐌹𐌺𐍉 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉 𐌽𐌹𐌿𐌾𐌰𐌱𐌰 𐌲𐌰𐍄𐌰𐍅𐌹𐌳𐍉𐍃 𐌻𐌰𐌿𐌱𐌰𐌼 𐌲𐌰𐌱𐌿𐌽𐌳𐌰𐌹 𐍃𐌿𐌼𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰 (𐌸𐌰𐌿 𐌲𐌰𐌳𐌰𐌹𐌻𐌰𐌼 𐍃𐌿𐌼𐌹𐍃 𐌺𐌿𐌽𐌾𐌹𐍃). <strong>𐌻𐌰𐌿𐌱𐍉𐍃 𐌰𐌽𐌰 [[Special:Watchist|your]] 𐍃𐌹𐌽𐌳 </strong>𐍃𐍅𐌹𐌽𐌸𐌰𐌹.",
        "recentchangeslinked-page": "𐌻𐌰𐌿𐌱𐌰𐌽𐌰𐌼𐍉:",
        "recentchangeslinked-to": "𐌰𐍄𐌰𐌿𐌲𐌴𐌹 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌻𐌰𐌿𐌱𐌴 𐌸𐌰𐌹𐌴𐌹 𐌲𐌰𐍅𐌹𐌳𐌰𐌽𐌰𐌹 𐌳𐌿 𐌲𐌹𐌱𐌰𐌽𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰.",
        "upload": "𐌿𐍃𐌷𐌻𐌰𐌸𐌰𐌽 𐍆𐌴𐌹𐌻𐌰𐌽𐍃",
        "brokenredirects-edit": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹",
        "brokenredirects-delete": "𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌴𐌹",
        "nbytes": "$1 {{PLURAL:$1|𐌱𐌹𐍄|𐌱𐌰𐍄𐌰}}",
-       "ncategories": "$1 {{PLURAL:$1|ð\90\8cºð\90\8c¿ð\90\8c½ð\90\8c¾ð\90\8c°|ð\90\8cºð\90\8c¿ð\90\8c½ð\90\8c¾ð\90\8d\89ð\90\8d\83}}",
+       "ncategories": "$1 {{PLURAL:$1|ð\90\8cºð\90\8c¿ð\90\8c½ð\90\8c¹|ð\90\8cºð\90\8c¿ð\90\8c½ð\90\8c¾ð\90\8c°}}",
        "nlinks": "$1 {{PLURAL:$1|𐌲𐌰𐍅𐌹𐍃𐍃|𐌲𐌰𐍅𐌹𐍃𐍃𐌴𐌹𐍃}}",
        "nmembers": "$1 {{PLURAL:$1|𐌲𐌰𐌳𐌰𐌹𐌻𐌰|𐌲𐌰𐌳𐌰𐌹𐌻𐌰𐌽𐍃}}",
        "wantedpages": "𐌲𐌰𐌹𐍂𐌽𐌹𐌳𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃",
        "longpages": "𐌻𐌰𐌲𐌲𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃",
        "listusers": "𐍂𐌴𐌲𐌹𐍃𐍄𐍂𐌴𐍂𐌰𐌳𐌴 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐍃",
        "newpages": "𐌽𐌹𐌿𐌾𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃",
-       "move": "ð\90\8c½ð\90\8c°ð\90\8c¼ð\90\8c¾ð\90\8c°ð\90\8c½ ð\90\8c°ð\90\8d\86ð\90\8d\84ð\90\8d\82ð\90\8c°",
+       "move": "ð\90\8c¼ð\90\8c¹ð\90\8c¸ð\90\8d\83ð\90\8c°ð\90\8d\84ð\90\8c´ð\90\8c¹",
        "movethispage": "𐌼𐌹𐌸𐍃𐌰𐍄𐌴𐌹 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆",
        "booksources": "𐌱𐍉𐌺𐌰𐌱𐍂𐌿𐌽𐌽𐌰𐌽𐍃",
        "booksources-search-legend": "𐍃𐍉𐌺𐌴𐌹 𐌱𐍉𐌺𐌰𐌱𐍂𐌿𐌽𐌽𐌰𐌽𐍃",
        "log": "𐌻𐍉𐌲𐌱𐍉𐌺𐍉𐍃",
        "all-logs-page": "𐌰𐌻𐌻𐌰 𐌻𐍉𐌲𐍉𐍃",
        "allpages": "𐌰𐌻𐌻𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃",
-       "nextpage": "ð\90\8c¹ð\90\8d\86ð\90\8d\84ð\90\8c¿ð\90\8c¼ð\90\8c° ð\90\8d\83ð\90\8c´ð\90\8c¹ð\90\8c³ð\90\8d\89 ($1)",
+       "nextpage": "ð\90\8c¹ð\90\8d\86ð\90\8d\84ð\90\8c¿ð\90\8c¼ð\90\8c° ð\90\8c»ð\90\8c°ð\90\8c¿ð\90\8d\86ð\90\8d\83 ($1)",
        "prevpage": "𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄𐍃 𐌻𐌰𐌿𐍆𐍃 ($1)",
        "allarticles": "𐌰𐌻𐌻𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃",
        "allpagessubmit": "𐌲𐌰𐌲𐌲",
        "unwatch": "𐌽𐌹𐍅𐌰𐍂𐌰𐌽",
        "watchlist-details": "{{PLURAL:$1|$1 𐌻𐌰𐌿𐍆𐍃|$1 𐌻𐌰𐌿𐌱𐍉𐍃}} 𐌰𐌽𐌰 𐌸𐌴𐌹𐌽𐌰𐌹 𐍅𐌹𐍄𐌰𐍅𐌹𐌺𐍉𐌽, 𐌽𐌹 𐍃𐌿𐌽𐌳𐍂𐍉 𐍂𐌰𐌷𐌽𐌾𐌰𐌽𐌳𐌰 𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌰𐌻𐌰𐌿𐌱𐍉𐍃.",
        "watching": "Wita...",
-       "unwatching": "Niwita...",
+       "unwatching": "𐌿𐌽𐍅𐌹𐍄𐌰𐌽𐌳𐍉...",
        "created": "𐌲𐌰𐍃𐌺𐌰𐍀𐌾𐌰𐌽",
        "deletepage": "𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌴𐌹 𐌻𐌰𐌿𐌱𐌰",
        "delete-legend": "𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌴𐌹",
        "prot_1movedto2": "[[$1]] 𐌼𐌹𐌸𐍃𐌰𐍄𐌹𐌸 𐌳𐌿 [[$2]]",
        "protect-level-sysop": "𐌰𐌽𐌳𐌻𐌴𐍄𐌹𐌸 𐌸𐌰𐍄𐌰𐌹𐌽𐌴𐌹 𐍂𐌴𐌹𐌺𐍃",
        "protect-expiring": "𐌿𐍃𐍄𐌹𐌿𐌷𐌹𐌸 $1 (UTC)",
-       "restriction-type": "Freihals:",
+       "restriction-type": "𐌰𐌽𐌳𐌻𐌴𐍄",
        "restriction-edit": "𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹",
-       "restriction-move": "ð\90\8d\83ð\90\8cºð\90\8c¹ð\90\8c¿ð\90\8c±ð\90\8c°ð\90\8c½",
+       "restriction-move": "ð\90\8c¼ð\90\8c¹ð\90\8c¸ð\90\8d\83ð\90\8c°ð\90\8d\84ð\90\8c´ð\90\8c¹",
        "undeletebtn": "𐌰𐍆𐍄𐍂𐌰 𐌲𐌰𐌱𐍉𐍄𐌾𐌰𐌽",
        "undeletelink": "𐍃𐌰𐌹𐍈𐌰𐌽/𐌰𐍆𐍄𐍂𐌰𐌲𐌰𐍃𐌰𐍄𐌾𐌰𐌽",
        "undeleteviewlink": "𐍃𐌰𐌹𐍈𐌹𐍃",
        "blocklogentry": "𐌰𐍆𐌳𐍂𐌰𐌿𐍃𐌹𐌸 [[$1]] 𐍆𐌰𐌿𐍂 $2 $3",
        "newtitle": "𐌽𐌹𐌿𐌾𐌹 𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹:",
        "move-watch": "𐌰𐍄𐍅𐌹𐍄 𐌱𐍂𐌿𐌽𐌽𐌰𐌻𐌰𐌿𐌱𐌰 𐌾𐌰𐌷 𐌼𐌿𐌽𐌳𐍂𐌴𐌹𐌻𐌰𐌿𐌱𐌰",
-       "movepagebtn": "ð\90\8d\83ð\90\8cºð\90\8c¹ð\90\8c¿ð\90\8c±ð\90\8c° ð\90\8d\83ð\90\8c´ð\90\8c¹ð\90\8c³ð\90\8d\89",
+       "movepagebtn": "ð\90\8c¼ð\90\8c¹ð\90\8c¸ð\90\8d\83ð\90\8c°ð\90\8d\84ð\90\8c´ð\90\8c¹ ð\90\8c»ð\90\8c°ð\90\8c¿ð\90\8d\86",
        "movelogpage": "𐌼𐌹𐌸𐍃𐌰𐍄𐌴𐌹 𐌲𐌰𐍆𐌰𐍃𐍄𐌰𐌹𐌽",
        "movereason": "𐍆𐌰𐌹𐍂𐌹𐌽𐌰:",
        "revertmove": "𐍂𐌰𐌹𐌳𐌾𐌰𐌽",
        "export": "𐌿𐍄𐌱𐌰𐌹𐍂 𐌻𐌰𐌿𐌱𐌰𐌽𐍃",
+       "allmessages-filter-translate": "𐌲𐌰𐍃𐌺𐌴𐌹𐍂𐌴𐌹",
        "thumbnail-more": "\n𐌼𐌹𐌺𐌹𐌻𐌴𐌹",
        "tooltip-pt-userpage": "{{GENDER:|Your user}} 𐌻𐌰𐌿𐍆𐍃",
        "tooltip-pt-mytalk": "{{GENDER:|𐌸𐌴𐌹𐌽𐍃}} 𐌻𐌰𐌿𐍆𐍃 𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌹𐍃",
        "table_pager_limit_submit": "Affgaggan",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌰]])",
        "version-other": "Anþar",
+       "version-poweredby-translators": "translatewiki.net 𐌲𐌰𐍃𐌺𐌴𐌹𐍂𐌾𐌰𐌽𐍃",
        "specialpages": "𐌿𐍃𐍃𐌹𐌽𐌳𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃",
        "tag-filter": "[[Special:Tags|𐍄𐌰𐌹𐌺𐌽𐍉𐍃]] 𐍆𐌹𐌻𐌷𐌰",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|𐍃𐍉𐌺𐌴𐌹𐌽𐌹𐍅𐌰𐌿𐍂𐌳|𐍃𐍉𐌺𐌴𐌹𐌽𐌹𐍅𐌰𐌿𐍂𐌳𐌰}}]]: $2)",
        "tags-source-header": "𐌱𐍂𐌿𐌽𐌽𐌰",
-       "tags-actions-header": "ð\90\8c³ð\90\8c´ð\90\8c³ð\90\8c´ð\90\8c¹ð\90\8d\83",
+       "tags-actions-header": "ð\90\8d\84ð\90\8d\89ð\90\8c¾ð\90\8c°",
        "tags-source-none": "𐌽𐌹 𐌾𐌿 𐌱𐍂𐌿𐌺𐌾𐌰𐌳𐌰",
        "tags-delete": "𐌿𐍃𐌽𐌹𐌼",
        "tags-activate": "𐌲𐌰𐌵𐌹𐌿𐌴𐌹",
index 06bfece..99c0a74 100644 (file)
        "yourpasswordagain": "Ἀνατυπῶσαι σύνθημα:",
        "createacct-yourpasswordagain": "Ἐπιβεβαιώσειν σῆμα",
        "createacct-yourpasswordagain-ph": "Παρέχειν σῆμα πάλιν",
-       "remembermypassword": "Μίμνῃσκε ἐνθάδε συνδεῖσθαι (μέγιστον $1 {{PLURAL:$1|ἡμέρα|ἡμέραι}})",
        "userlogin-remembermypassword": "Διατήρησις συνδέσεως",
        "yourdomainname": "Ὁ τομεύς σου:",
        "externaldberror": "Συνέβη εἴτε σφάλμα τι πιστοποιήσεως τῆς βάσεως δεδομένων εἴτε οὐκ ἔξεστί σοι ἐνημεροῦν τὸν ἐξωτερικὸν λογισμόν σου.",
        "undo-failure": "Ἀδύνατος ἡ μεταστροφὴ λόγῳ ἀντικρουομένων ἐνδιαμέσων μεταγραφῶν.",
        "undo-norev": "Ἀδύνατος ἡ μεταστροφὴ τῆσδε τῆς μεταγραφῆς λόγῳ μὴ ὑπάρξεως ἢ προτέρας διαγραφῆς ταύτης.",
        "undo-summary": "Ἀναίρεσις μεταγραφῆς $1 ὑπὸ τὸν/τὴν [[Special:Contributions/$2|$2]] ([[User talk:$2|Διάλεξις]])",
-       "cantcreateaccounttitle": "Μὴ δυνατὴ ἡ ποίησις λογισμοῦ",
        "viewpagelogs": "Ὁρᾶν καταλόγους διὰ ταύτην τὴν δέλτον",
        "nohistory": "Οὐκ ἔστι ἱστορικὸν μεταγραφῶν διὰ τήνδε τὴν δέλτον.",
        "currentrev": "Τὸ νῦν",
        "activeusers": "Κατάλογος ἐνεργῶν χρωμένων",
        "activeusers-count": "$1 {{PLURAL:$1|μεταγραφή|μεταγραφαὶ}} κατὰ {{PLURAL:$3|τὴν πρόσφατον ἡμέραν|τὰς προσφάτους $3 ἡμέρας}}",
        "activeusers-from": "Δεικνύειν χρωμένους ἐκκινήσει ἐκ:",
-       "activeusers-hidebots": "Κρύπτειν αὐτόματα",
-       "activeusers-hidesysops": "Κρύπτειν ἐπιτρόπους",
        "activeusers-noresult": "Οὐδεὶς χρώμενος εὑρέθη.",
        "listgrouprights": "Δικαιώματα ὁμάδος χρωμένου",
        "listgrouprights-group": "Ὁμάς",
index 7639217..4a3207f 100644 (file)
        "activeusers-intro": "Des isch e Lischt vu Benutzer, wu irgedebis bearbeitet hän {{PLURAL:$1|am letschte Tag|in dr letschte $1 Täg}}.",
        "activeusers-count": "$1 {{PLURAL:$1|Aktion|Aktione}} {{PLURAL:$3|am letschte Tag|in dr letschte $3 Täg}}",
        "activeusers-from": "Zeig Benutzer ab:",
-       "activeusers-hidebots": "Bötli uusblände",
-       "activeusers-hidesysops": "Ammanne (Administratore) uusblände",
        "activeusers-noresult": "Kei Benutzer gfunde.",
        "listgrouprights": "Benutzergruppe-Rächt",
        "listgrouprights-summary": "Des isch e Liste vu dr Benutzergruppe, wu in däm Wiki definiert sin, un dr Rächt, wu dermit verbunde sin.\nZuesätzligi Informatione iber einzelni Rächt git s [[{{MediaWiki:Listgrouprights-helppage}}|doo]].",
        "feedback-external-bug-report-button": "E technischi Ufgab yreiche",
        "feedback-dialog-title": "Rückmäldig gä",
        "feedback-dialog-intro": "Du chasch ds eifache Formular unde bruuche, für’ne Rückmäldig z gä. Dy Kommentar chunt zäme mit dym Benutzernamen uf d Syte «$1».",
-       "feedback-error-title": "Fähler",
        "feedback-error1": "Fäälermäldig: Unbekannts Ergebniss vo de API",
        "feedback-error2": "Fääler: Bearbeitig fehlgschlo",
        "feedback-error3": "Fäälermäldig: Kei Antwort vo de API",
index adaaab4..458d0e5 100644 (file)
        "searchprofile-advanced-tooltip": "સ્થાનીય નામસ્થળોમાં શોધો",
        "search-result-size": "$1 ({{PLURAL:$2|૧ શબ્દ|$2 શબ્દો}})",
        "search-result-category-size": "{{PLURAL:$1|1 સભ્ય|$1 સભ્યો}} ({{PLURAL:$2|1 ઉપ શ્રેણી|$2 ઉપ શ્રેણીઓ}}, {{PLURAL:$3|1 ફાઇલ|$3 ફાઇલો}})",
-       "search-redirect": "(અન્યત્ર પ્રસ્થાન $1)",
+       "search-redirect": "($1થી વાળેલું)",
        "search-section": "(વિભાગ $1)",
        "search-category": "(શ્રેણી $1)",
        "search-suggest": "શું તમે $1 કહેવા માંગો છો?",
        "file-thumbnail-no": "ફાઇલનું નામ <strong>$1</strong>થી શરૂ થાય છે.\nલાગે છે કે આ ઘટાડેલા કદનું ચિત્ર  ''(thumbnail)'' છે..\nજો તમારી સાથે પૂર્ણ ઘનત્વ ધરાવતી ચિત્રની ફાઇલ હોય તો જ આ ફાઇલ ચડાવશો, અન્યથા ફાઇલનું નામ બદલશો.",
        "fileexists-forbidden": "આ નામની ફાઇલ પહેલેથી મોજુદ છે અને તેના ઉપર લેખન કરી શકાશે નહી.\nતેમ છતાં પણ તમે ફાઇલ ચડાવવા માંગતા હોવ તો ફાઇલનું નામ બદલો અને નવા નામે ફરીથી ચડાવો.\n[[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "સર્વસામાન્ય ફાઇલ સંગ્રહમાં આ નામની ફાઇલ મોજુદ છે.\nતેમ છતાં પણ તમે ફાઇલ ચડાવવા માંગતા હોવ તો ફાઇલનું નામ બદલો અને નવા નામે ફરીથી ચડાવો.\n[[File:$1|thumb|center|$1]]",
-       "file-exists-duplicate": "આ ફાઇલ {{PLURAL:$1|ફાઇલ|ફાઇલો}} ની પ્રત છે.",
+       "file-exists-duplicate": "આ ફાઇલ નીચેની {{PLURAL:$1|ફાઇલ|ફાઇલો}}ની નકલ છે:",
        "file-deleted-duplicate": "ફાઇલ ([[:$1]]) ને સમાન ફાઇલ પહેલાં ભૂંસાડી દેવાઇ છે.\nઆ ફાઇલને ચડાવત પહેલાં હટાવ ઇતિહાસ ચકાસી લો.",
        "uploadwarning": "ફાઇલ ચઢાવ ચેતવણી",
        "uploadwarning-text": "કૃપયા ફાઈલ સંબધી વર્ણન સુધારો અને ફરી પ્રયત્ન કરો",
        "activeusers-intro": "છેલ્લા  $1 {{PLURAL:$1|દિવસ|દિવસો}}માં જે સભ્યોએ કંઈક યોગદાન કર્યું હોય તેમની યાદી.",
        "activeusers-count": "$1 {{PLURAL:$1|ફેરફાર|ફેરફારો}} છેલ્લા {{PLURAL:$3|દિવસ |$3 દિવસો }}માં",
        "activeusers-from": "આનાથી શરૂ થતા સભ્યો દર્શાવો:",
-       "activeusers-hidebots": "બોટને છુપાવો",
-       "activeusers-hidesysops": "પ્રબંધકો છુપાવો",
        "activeusers-noresult": "કોઇ સક્રીય સભ્ય ન મળ્યો",
        "listgrouprights": "સભ્ય જૂથ ના હક્કો",
        "listgrouprights-summary": "નીચે આ વિકિ પર વ્યાખ્યાયિત સભ્ય જૂથોની યાદી, તેમની સાથે સંકળાયેલા હક્કો સાથે આપી છે.\nવ્યક્તિગત હક્કો માટે [[{{MediaWiki:Listgrouprights-helppage}}|વધારાની માહિતી]].",
        "emailsubject": "વિષય:",
        "emailmessage": "સંદેશો:",
        "emailsend": "મોકલો",
-       "emailccme": "મારા ઈ-મેલની પ્રત મને મોકલો",
+       "emailccme": "મારા ઈમેલની પ્રત મને મોકલો",
        "emailccsubject": "$1ને તમે મોકલેલા સંદેશાની પ્રત: $2",
        "emailsent": "ઈ-મેલ મોકલી દેવાયો",
        "emailsenttext": "તમારો ઈ-મેલ મોકલી દેવાયો છે",
        "articleexists": "આ નામનું પાનું અસ્તિત્વમાં છે, અથવાતો તમે પસંદ કરેલું નામ અસ્વિકાર્ય છો.\nકૃપા કરી અન્ય નામ પસંદ કરો.",
        "cantmove-titleprotected": "આ સ્થાને તમે પાનું નહીં હટાવી શકો કેમ કે નવું શીર્ષક રચના કરવા પહેલેથી આરક્ષીત છે",
        "movetalk": "સંલગ્ન ચર્ચાનું પાનું પણ ખસેડો",
-       "move-subpages": "($1 સુધી) ઉપ-પાના હટાવાયા",
+       "move-subpages": "પેટાપાનાં પણ ખસેડો ($1 સુધીના)",
        "move-talk-subpages": "ઉપપાનને ચર્ચાના પાના પર ખસેડો ( $1 સુધે)",
        "movepage-page-exists": "પાનું  $1 પહેલેથી અસ્તિત્વમાં છે તેના પર સ્વયં ચલિત રીતે નવું લેખન ન થાય.",
        "movepage-page-moved": "પાના $1 ને $2 પર ખસેડાયું",
        "dberr-usegoogle": "તેસમયા દરમ્યાન તમે ગુગલ દ્વારા શોધી શકો",
        "dberr-outofdate": "આપણી માહિતી સંબંધી તેમની સૂચિ કાલાતિત હોઇ શકે.",
        "dberr-cachederror": "વિનંતિ કરેલ પાનાની આ એક સંગ્રહીત પ્રત માત્ર છે અને તે અધ્યતન ન પણ હોય.",
-       "htmlform-invalid-input": "તમારા અમુક ઉમેરા માંઅમુક તકલીફ છે",
+       "htmlform-invalid-input": "તમારા અમુક ઉમેરામાં ક્ષતિઓ છે.",
        "htmlform-select-badoption": "તમે બતાવેલ વિકલ્પ અવૈધ છે",
        "htmlform-int-invalid": "તમે લખેલ વિકલ્પ અંક નથી",
        "htmlform-float-invalid": "તમે લખેલ વિકલ્પ અંક નથી",
        "feedback-submit": "જમા કરો",
        "feedback-thanks": "આભર! તમારા પ્રતિભાવને \"[$2 $1]\" પાના પર મુકાયા છે.",
        "feedback-thanks-title": "આભાર !",
-       "searchsuggest-search": "શોધો",
+       "searchsuggest-search": "{{SITENAME}} શોધો",
        "searchsuggest-containing": "આ શબ્દ ધરાવતા...",
        "api-error-badaccess-groups": "આ વિકિ પર ફાઈલ ચઢાવવાની પરવાનગી તમને નથી.",
        "api-error-badtoken": "આંતરીક ત્રુટી: ખરાબ ટોકન",
index c1757c9..7c47068 100644 (file)
        "yourname": "Dt'ennym ymmydeyr:",
        "yourpassword": "Fockle yn arrey:",
        "yourpasswordagain": "Aascreeu dt'ockle arrey:",
-       "remembermypassword": "Cooinnee m'ockle arrey (rish wheesh as $1 {{PLURAL:$1|laa|laa|laa|laaghyn}})",
        "login": "Log stiagh",
        "nav-login-createaccount": "Log stiagh / croo coontys",
        "userlogin": "Log stiagh / croo coontys",
        "passwordreset-email": "Enmys post-L:",
        "passwordreset-emailelement": "Ennym ymmydeyr: \n$1\n\nFockle arrey shallidagh: \n$2",
        "passwordreset-emailsentemail": "Ta post-l cur gys cooinaghtyn er ny chur dhyt.",
-       "passwordreset-emailsent-capture": "Ta post-l cur gys cooinaghtyn er ny chur dhyt, as eshyn heese.",
-       "passwordreset-emailerror-capture": "Ta post-l cur gys cooinaghtyn er ny chur dhyt, as eshyn heese, agh cha rosh eh yn ymmydeyr: $1",
        "changeemail-none": "(gyn)",
        "bold_sample": "Clou trome",
        "bold_tip": "Clou trome",
        "permissionserrorstext-withaction": "Cha nel kiart ayd $2, er {{PLURAL:$1|y fa|y fa|y fa|ny faghyn}} heese:",
        "recreate-moveddeleted-warn": "'''Raaue: T’ou aachroo duillag as eh er ve scrysst hannah hene.'''\n\nBy chair dhyt smooinagh vel eh kiart goll er oai lesh reaghey yn duillag shoh.<br />\nTa lioar ny scryssaghyn magh kiarit ayns shoh rere dty chaays hene:",
        "editwarning-warning": "My faagys oo y duillag, hed caghlaaghyn erbee er coayl, foddee.\nMy t'ou uss loggalt stiagh, foddee oo lhiettal y raaue shoh 'sy tosheeaghtyn ayd, 'sy rheynn \"Reaghey\".",
-       "cantcreateaccounttitle": "Cha nod coontys y chroo",
        "viewpagelogs": "Jeeagh er ny lioaryn cooishyn son y duillag shoh",
        "currentrev": "Aavriwnys roie",
        "currentrev-asof": "Aavriwnys s'noa er $1",
index f1cf530..93ba9a2 100644 (file)
                ]
        },
        "tog-underline": "Lièn-chiap kâ-tái sien:",
-       "tog-hideminor": "Yún-chhông chui-khiûn kiên-kói tú ke se-mì phiên-siá",
-       "tog-hidepatrolled": "Yún-chhông chui-khiûn kiên-kói tú sùn-chhà ko ke phiên-siá",
-       "tog-newpageshidepatrolled": "Yún-chhông sîn ya̍p-mien chhîn-tân tú sùn-chhà ko ke ya̍p-mien",
+       "tog-hideminor": "Ám-hí chui-khiûn kiên-kói tú ke se-mì phiên-siá",
+       "tog-hidepatrolled": "Ám-hí chui-khiûn kiên-kói tú sùn-chhà ko ke phiên-siá",
+       "tog-newpageshidepatrolled": "Ám-hí sîn ya̍p-mien chhîn-tân tú sùn-chhà ko ke ya̍p-mien",
        "tog-extendwatchlist": "Chán-khôi kâm-sṳ lie̍t-péu lòi hién-sṳ só-yû kiên-kói, m̀  tân-chhiang he chui-khiûn ke",
        "tog-usenewrc": "Chhai chui-khiûn kiên-kói lâu kâm-sṳ lie̍t-péu tú cháng-ha̍p thùng yit-ya̍p ke siû-kói",
-       "tog-numberheadings": "Phiêu-thì chhṳ-thûng phiên-ho",
+       "tog-numberheadings": "Phiêu-thì chhṳ-thung phiên-ho",
        "tog-showtoolbar": "Chán-sṳ phiên-siá kûng-khí-làn",
        "tog-editondblclick": "Sûng-khim phiên-siá ya̍p-mien",
        "tog-editsectiononrightclick": "Yún-hí yu-khim phiêu-thì phiên-siá thon-lo̍k",
        "october-date": "10-ngie̍t $1-ngit",
        "november-date": "11-ngie̍t $1-ngit",
        "december-date": "12-ngie̍t $1-ngit",
-       "pagecategories": "{{PLURAL:$1|Category|$1-chak fûn-lui}}",
+       "pagecategories": "{{PLURAL:$1|Fûn-lui}}",
        "category_header": "\"$1\" fûn-lui tú ke ya̍p-mien",
        "subcategories": "Chṳ́ fûn-lui",
        "category-media-header": "\"$1\" fûn-lui tú ke mòi-thí",
        "category-empty": "<em>Liá-chak fûn-lui muk-chhièn hàn-mò pâu-hàm ya̍p-mien fe̍t-chá mòi-thí vùn-khien.</em>",
-       "hidden-categories": "$1-chak yún-chhông fûn-lui",
-       "hidden-category-category": "Yún-chhông fûn-lui",
+       "hidden-categories": "{{PLURAL:$1|Ám-hí ke fûn-lui}}",
+       "hidden-category-category": "Ám-hí ke fûn-lui",
        "category-subcat-count": "{{PLURAL:$2|Liá-chak fûn-lui yû hâ-poi yit-chak chṳ́ fûn-lui.|Liá-chak fûn-lui yû $2-chak chṳ́ fûn-lui, hâ-poi lie̍t-chhut yí $1-chak.}}",
        "category-subcat-count-limited": "邇隻分類有下背$1隻子分類。",
        "category-article-count": "{{PLURAL:$2|本分類有下背一隻頁面。|本分類有$2隻頁面,下背列出矣$1隻。}}",
        "editsectionhint": "Phiên-siá chông-chiet: $1",
        "toc": "Muk-liu̍k",
        "showtoc": "Chán-sṳ",
-       "hidetoc": "yún-chhông",
+       "hidetoc": "ám",
        "collapsible-collapse": "Chap-thia̍p",
        "collapsible-expand": "Chán-khôi",
        "thisisdeleted": "Chhà-khon fe̍t-chá fî-fu̍k $1?",
        "viewsource-title": "Khon $1 ke ngièn-sṳ́-mâ",
        "actionthrottled": "動作已經壓制",
        "actionthrottledtext": "基於反垃圾嘅考量,短時間內毋可以多次重複某操作,今下汝已經超過邇隻上限。\n請在數分鐘後再嘗試。",
-       "protectedpagetext": "邇隻頁面已經分人保護以防止編輯或其他操作。",
-       "viewsourcetext": "汝做得查看並複製本頁面嘅源碼:",
+       "protectedpagetext": "Liá ya̍p yí-kîn pûn ngìn pó-fu, kim-chṳ́ siû-kói fe̍t-chá khì-thâ chhâu-chok.",
+       "viewsourcetext": "Ngì cho-tet khon fe̍t-chá copy liá ya̍p ke ngièn-sṳ́-mâ:",
        "viewyourtext": "汝可以查看並複製'''汝對邇隻頁面作出編寫後'''嘅源代碼:",
        "protectedinterface": "邇頁提供此wiki軟體嘅介面文字,其已畀保護以防止惡意修改。\n假使想修改所有wiki嘅翻譯,請到[https://translatewiki.net/ translatewiki.net]上嘅MediaWiki本地化計畫。",
        "editinginterface": "'''警告:'''汝今下編寫緊嘅頁面係用於提供軟件嘅界面文字。\n改變邇頁將影響其他在邇隻wiki上嘅用戶界面外觀。\n假使愛修改所有wiki嘅翻譯,請到[https://translatewiki.net/ translatewiki.net]上嘅MediaWiki本地化計劃。",
        "yourpasswordagain": "Chai yit-pái sû-ngi̍p me̍t-ma:",
        "createacct-yourpasswordagain": "Khok-ngin me̍t-ma",
        "createacct-yourpasswordagain-ph": "Chai yit-pái sû-ngi̍p me̍t-ma",
-       "remembermypassword": "Chhai liá-chak liù-lám-hi sông ki-hâ ngài-ke tên-ngi̍p chhong-thai (chui-chhòng $1-ngit)",
        "userlogin-remembermypassword": "Pó-chhṳ̀ ngài-ke tên-ngi̍p chhong-thai",
        "userlogin-signwithsecure": "使用安全連線",
        "yourdomainname": "Ngì ke vet-miàng:",
        "password-change-forbidden": "汝做毋得更改本wiki上嘅密碼。",
-       "externaldberror": "Liá khó-nèn he yù-yî ngiam-chṳn sú-kí-khù chhâ-chho fe̍t-chá ngì fûn hì-thúng kim-chṳ́ kiên-sîn ngì ke ngoi-phu chòng-ho.",
+       "externaldberror": "Liá khó-nèn he yù-yî ngiam-chṳn sú-kí-khù chhâ-chho fe̍t-chá ngì fûn hì-thúng kim-chṳ́ kiên-sîn ngì ke ngoi-phu fu-thèu.",
        "login": "Tên-ngi̍p",
-       "nav-login-createaccount": "Tên-ngi̍p / kien-li̍p sîn chong-ho",
-       "userlogin": "Tên-ngi̍p / kien-li̍p sîn chong-ho",
+       "nav-login-createaccount": "Tên-ngi̍p / khôi sîn fu-thèu",
+       "userlogin": "Tên-ngi̍p / khôi sîn fu-thèu",
        "userloginnocreate": "Tên-ngi̍p",
        "logout": "Tên-chhut",
        "userlogout": "Tên-chhut",
        "notloggedin": "Hàn-mò tên-ngi̍p",
-       "userlogin-noaccount": "Hàn-mò chong-fu he mò?",
+       "userlogin-noaccount": "Hàn-mò fu-thèu he mò?",
        "userlogin-joinproject": "Chhâm-yi  {{SITENAME}}",
-       "nologin": "Hàn-mò chong-ho he-mò? $1.",
-       "nologinlink": "Kien-li̍p chong-ho",
-       "createaccount": "Kien-li̍p chong-ho",
-       "gotaccount": "Yí-kîn yúng-yû chong-ho he-mò? $1.",
+       "nologin": "Hàn-mò fu-thèu he-mò? $1.",
+       "nologinlink": "Khôi fu-thèu",
+       "createaccount": "Khôi fu-thèu",
+       "gotaccount": "Yí-kîn yû fu-thèu he-mò? $1.",
        "gotaccountlink": "Tên-ngi̍p",
        "userlogin-resetlink": "M̀-ki-tet ngì-ke tên-ngi̍p sin-sit?",
        "userlogin-resetpassword-link": "Thiâm mong-ki ngì ke me̍t-ma?",
        "createaccountreason": "Ngièn-yîn:",
        "createacct-reason": "Ngièn-yîn:",
        "createacct-reason-ph": "汝做麽嘅愛創建另一隻帳號",
-       "createacct-submit": "Kien-li̍p chong-ho",
+       "createacct-submit": "Khôi fu-thèu",
        "createacct-benefit-heading": "{{SITENAME}} he yù lâu Ngì khiung-ngióng ke ngìn kien-li̍p.",
        "createacct-benefit-body1": "$1-chhṳ phiên-siá",
        "createacct-benefit-body2": "$1-ya̍p",
        "badretype": "Ngì só khim-ngi̍p ke me̍t-ma pin m̀  siông-thùng.",
        "userexists": "汝所填入嘅用戶名稱已經存在。\n請另選一隻名稱。",
        "loginerror": "Tên-ngi̍p chhâ-chho",
-       "createacct-error": "Chong-fu kien-li̍p chhâ-chho",
-       "createaccounterror": "Mò phan-fap kien-li̍p chong-ho: $1",
+       "createacct-error": "Khôi fu-thèu chhut chhâ-chho",
+       "createaccounterror": "Mò-fap-thu khôi sîn fu-thèu: $1",
        "nocookiesnew": "本用戶賬號已分建立,但係汝登入失敗。{{SITENAME}}使用cookie登入。汝已停用cookie。請啓用cookie,之後使用汝嘅新用戶名和密碼登入。",
        "nocookieslogin": "{{SITENAME}}用cookie登入。汝已停用cookie。請啓用cookie後再試一擺。",
        "nocookiesfornew": "邇隻用戶嘅賬戶未建立,亻厓兜無法度確認其嘅來源。\n請確定汝已經開啟cookies,重新載入後再試一擺。",
        "noname": "汝還吂輸入一隻有效嘅用戶名。",
        "loginsuccesstitle": "Yí-kîn tên-ngi̍p",
        "loginsuccess": "Ngì kîm-hâ yî \"$1\"-ke sṳ̂n-fun chhai {{SITENAME}} tên-ngi̍p.",
-       "nosuchuser": "Chhìm m̀ -to yung-fu \"$1\". \nYung-fu miàng-chhṳ̂n he yû thai-séu siá khî-fûn ke . \nKiám-chhà ngì ke piâng-siá, fe̍t-chá yung hâ-mien ke péu-kak [[Special:CreateAccount|kien-li̍p yit-chak sîn chòng-ho]].",
+       "nosuchuser": "Chhìm m̀ -to yung-fu \"$1\". \nYung-fu miàng-chhṳ̂n he yû thai-séu siá khî-fûn ke . \nKiám-chhà ngì ke piâng-siá, fe̍t-chá yung hâ-mien ke péu-kak [[Special:CreateAccount|khôi yit-chak sîn fu-thèu]].",
        "nosuchusershort": "無有喊做“$1”嘅用戶。請檢查汝輸入嘅文字係毋係有差錯。",
        "nouserspecified": "汝愛指定一隻用戶名。",
        "login-userblocked": "邇隻用戶已分封鎖。毋做得登入。",
        "suspicious-userlogout": "汝登出嘅要求已經分拒絕,因為其可能係由已損壞嘅瀏覽器或者緩存代理傳送。",
        "pt-login": "Tên-ngi̍p",
        "pt-login-button": "Tên-ngi̍p",
-       "pt-createaccount": "Kien-li̍p chong-ho",
+       "pt-createaccount": "Khôi fu-thèu",
        "pt-userlogout": "Tên-chhut",
        "php-mail-error-unknown": "在PHP嘅mail()參數肚嘅未知錯誤",
        "user-mail-no-addy": "嘗試毋帶電郵地址發送電郵。",
        "preview": "預覽",
        "showpreview": "Chán-sṳ yi-lám",
        "showdiff": "Chán-sṳ chhâ-phe̍t",
-       "anoneditwarning": "<strong>Kín-ko : </strong>Ngì hàn-m̀ tên-ngi̍p. Ngì ke IP thi-chí chiông ki-liu̍k chhai liá-ya̍p ke phiên-siá li̍t-sṳ́ tú. Ká-sṳ́ ngì  <strong>[$1 tên-ngi̍p]</strong> fe̍t  <strong>[$2 kien-li̍p chong-ho]</strong>, ngì ke phiên-si̍p chiông-fi yî ngì ke sṳ́-yung-chá miàng-chhṳ̂n phiêu-sṳ, yúng-yû khì-thâ yù-tiám.",
+       "anoneditwarning": "<strong>Kín-ko:</strong> Ngì hàn-m̀ tên-ngi̍p. Ngì ke IP vi-chí voi ki-liu̍k chhai liá ya̍p ke phiên-siá li̍t-sṳ́ tú. Na-he ngì <strong>[$1 tên-ngi̍p]</strong> fe̍t-chá <strong>[$2 khôi fu-thèu]</strong>, ngì ke phiên-siá voi hién-sṳ ngì ke yung-fu miàng-sṳ, pin-chhiâ yû khì-thâ ke yù-tiám.",
        "anonpreviewwarning": "“警告:汝還吂登入。汝嘅IP地址將會記錄在邇頁嘅編輯歷史中”",
        "missingsummary": "'''提示:''' 汝無提供一隻編寫摘要。假使汝再次單擊「{{int:savearticle}}」,汝嘅編寫將毋帶編寫摘要保存。",
        "missingcommenttext": "請在下背輸入評論。",
        "subject-preview": "主題/標題預覽:",
        "blockedtitle": "用戶分查封",
        "blockedtext": "Ngì-ke yung-fu-miàng fe̍t-chá IP thi-tiám yí-kîn pûn $1 chhà-fûng.\n\nLiá-chhṳ chhà-fûng he yù $1 só fûng ke. Tông-chûng ke ngièn-yîn he ''$2''. Ngì khó-yî lièn-lo̍k $1 fe̍t-chá khì-thâ ke [[{{MediaWiki:Grouppage-sysop}}|Kón-lî-yèn]], thó-lun liá-chhṳ ke chhà-fûng. Chhù-fî ngì yí-kîn chhai ngì-ke [[Special:Preferences|Chong-ho chhâm-su sat-chṳ]] chûng sat-thin liáu yit-ke yû-háu ke email, féu-chet ngì-he put-nèn sṳ́-yung “email liá-vi yung-fu” ke kûng-yung. Ngì-ke IP thi-tiám he $3, yì-yèn ke chhà-fûng ID he #$5. Chhiáng ngì chhai só-yû chhà-chhìm chûng chu-mìn liá-ke thi-tiám khi̍p/fe̍t-he chhà-fûng ID.",
-       "autoblockedtext": "Ngì-ke IP thi-tiám yí-kîn pûn chhṳ-thung chhà-fûng, lî-yù he siên-chhièn ke nang yit-vi yung-fu pûn $1 só chhà-fûng. Yì-yèn chhà-fûng ke ngièn-yîn he: ''$2'' liá-chhṳ chhà-fûng ke khì-kiên he: $6 ngì khó-yî lièn-lo̍k $1 fe̍t-chá khì-thâ ke [[{{MediaWiki:Grouppage-sysop}}|kón-lî-yèn]], thó-lun liá-chhṳ chhà-fûng. Chhù-fî ngì yí-kîn chhai ngì-ke [[Special:Preferences|chong-ho chhâm-su sat-chṳ]] chûng sat-thin yit-ke yû-háu ke email thi-tiám, féu-chet ngì-he put-nèn sṳ́-yung \"email liá-vi yung-fu\" ke kûng-nèn. Ngì-ke chhà-fûng ID he $5. Chhiáng ngì chhai só-yû thiàu-chhà chûng chu-mìn liá-ke chhà-fûng ID.",
+       "autoblockedtext": "Ngì-ke IP thi-tiám yí-kîn pûn chhṳ-thung chhà-fûng, lî-yù he siên-chhièn ke nang yit-vi yung-fu pûn $1 só chhà-fûng. Yì-yèn chhà-fûng ke ngièn-yîn he: ''$2'' liá-chhṳ chhà-fûng ke khì-kiên he: $6 ngì khó-yî lièn-lo̍k $1 fe̍t-chá khì-thâ ke [[{{MediaWiki:Grouppage-sysop}}|kón-lî-yèn]], thó-lun liá-chhṳ chhà-fûng. Chhù-fî ngì yí-kîn chhai ngì-ke [[Special:Preferences|fu-thèu chhâm-su sat-chṳ]] chûng sat-thin yit-ke yû-háu ke email thi-tiám, féu-chet ngì-he put-nèn sṳ́-yung \"email liá-vi yung-fu\" ke kûng-nèn. Ngì-ke chhà-fûng ID he $5. Chhiáng ngì chhai só-yû thiàu-chhà chûng chu-mìn liá-ke chhà-fûng ID.",
        "whitelistedittext": "汝必須先$1正做得編寫頁面。",
        "confirmedittext": "在編寫邇頁之前汝必須確認汝嘅郵箱地址。請通過[[Special:Preferences|偏好設定]]設定並驗證汝嘅郵箱地址。",
        "nosuchsectiontitle": "Mò-yû liá-ke thon-lo̍k",
        "templatesusedsection": "Chhai liá-ke thon-lo̍k song sṳ́-yung ke mù-pán yû:",
        "template-protected": "(Pó-fu)",
        "template-semiprotected": "(Pan pó-fu)",
-       "hiddencategories": "Liá-ya̍p su̍k-yî $1-chak yún-chhông fûn-lui ke sṳ̀n-yèn:",
+       "hiddencategories": "Liá ya̍p su̍k-yî {{PLURAL:$1|1 ke ám-hí ke fûn-lui|$1 ke ám-hí ke fûn-lui}} ke sṳ̀n-yèn:",
        "edittools": "<!-- 邇肚嘅文字將分展示在編寫撈上傳表單以下。 -->\n<div id=\"editpage-specialchars\" class=\"plainlinks edittools-version-test003\" style=\"margin-top: 15px; border-width: 1px; border-style: solid; border-color: #aaaaaa; padding: 2px;\"> <span id=\"edittools_main\">'''Insert:''' <charinsert>– — … ‘ “ ’ ” ° ″ ′ ≈ ≠ ≤ ≥ ± − × ÷ ← → · § </charinsert></span><span id=\"edittools_name\">&nbsp;&nbsp;'''Sign your username:''' <charinsert>--~~&#126;~</charinsert> <small>(on [[Help:Talk pages|talk pages]])</small></span> ---- <small id=\"edittools_newsectionshere\"><span id=\"edittools_hide_for_script_test\"><span id=\"edittools_wikimarkup\">'''Wiki markup:''' <charinsert><nowiki>{{</nowiki>+<nowiki>}}</nowiki> </charinsert> &nbsp; <charinsert><nowiki>{{{</nowiki>+<nowiki>}}}</nowiki> </charinsert> &nbsp; <charinsert><nowiki>|</nowiki></charinsert> &nbsp; <charinsert>[+]</charinsert> &nbsp; <charinsert>[[+]]</charinsert> &nbsp; <charinsert>[[Category:+]]</charinsert> &nbsp; <charinsert>#REDIRECT&#32;[[+]]</charinsert> &nbsp; <charinsert>{{Subst:Fôn-ngiàng}}</charinsert> &nbsp; <charinsert>{{Subst:PAGENAME}}</charinsert> &nbsp; <charinsert>&nbsp;</charinsert> &nbsp; <charinsert><s>+</s></charinsert> &nbsp; <charinsert><sup>+</sup></charinsert> &nbsp; <charinsert><sub>+</sub></charinsert> &nbsp; <charinsert><code>+</code></charinsert> &nbsp; <charinsert><blockquote>+</blockquote></charinsert> &nbsp; <charinsert><ref>+</ref></charinsert> &nbsp; <charinsert><nowiki>{{</nowiki>Reflist<nowiki>}}</nowiki></charinsert> &nbsp; <charinsert><references/></charinsert> &nbsp; <charinsert><includeonly>+</includeonly></charinsert> &nbsp; <charinsert><noinclude>+</noinclude></charinsert> &nbsp; <charinsert><nowiki>{{</nowiki>DEFAULTSORT:+<nowiki>}}</nowiki></charinsert> &nbsp; <charinsert>&lt;nowiki>+</nowiki></charinsert> &nbsp; <charinsert><nowiki><!-- </nowiki>+<nowiki> --></nowiki></charinsert>&nbsp; <charinsert><nowiki><span class=\"plainlinks\"></nowiki>+<nowiki></span></nowiki></charinsert>&nbsp;&nbsp;&bull;&nbsp; ([[Wikipedia:Template messages|templates]])<br/></span> <span id=\"edittools_symbols\">'''Symbols:''' <charinsert> ~ | ¡ ¿ † ‡ ↔ ↑ ↓ • ¶</charinsert> &nbsp; <charinsert> # ½ ⅓ ⅔ ¼ ¾ ⅛ ⅜ ⅝ ⅞ ∞ </charinsert> &nbsp; <charinsert> ‘ “ ’ ” «+»</charinsert> &nbsp; <charinsert> ¤ ₳ ฿ ₵ ¢ ₡ ₢ $ ₫ ₯ € ₠ ₣ ƒ ₴ ₭ ₤ ℳ ₥ ₦ № ₧ ₰ £ ៛ ₨ ₪ ৳ ₮ ₩ ¥ </charinsert> &nbsp; <charinsert> ♠ ♣ ♥ ♦ </charinsert>&nbsp; <charinsert>m²</charinsert>&nbsp;<charinsert>m³</charinsert><br/></span> <span id=\"edittools_characters\">'''Characters:''' <span class=\"latinx\"> <charinsert> Á á Ć ć É é Í í Ĺ ĺ Ḿ ḿ Ń ń Ó ó Ŕ ŕ Ś ś Ú ú Ý ý Ź ź </charinsert> &nbsp; <charinsert> À à È è Ì ì M̀ m̀  Ǹ ǹ Ò ò Ù ù </charinsert> &nbsp; <charinsert> Â â Ĉ ĉ Ê ê Ĝ ĝ Ĥ ĥ Î î Ĵ ĵ Ô ô Ŝ ŝ Û û Ŵ ŵ Ŷ ŷ </charinsert> &nbsp; <charinsert> A̤ a̤ E̤ e̤ I̤ i̤ O̤ o̤ Ṳ ṳ </charinsert> &nbsp;\n<charinsert> A̍ a̍ E̍ e̍ I̍ i̍ O̍ o̍ U̍ u̍ </charinsert> &nbsp; <charinsert> À̤ à̤ È̤ è̤ Ì̤ ì̤ Ò̤ ò̤ Ṳ̀ ṳ̀ </charinsert> &nbsp;\n<charinsert> Á̤ á̤ É̤ é̤ Í̤ í̤ Ó̤ ó̤ Ṳ́ ṳ́ </charinsert> &nbsp; <charinsert> A̤̍ a̤̍ E̤̍ e̤̍ I̤̍ i̤̍ O̤̍ o̤̍ Ṳ̍ ṳ̍ </charinsert> &nbsp;\n<charinsert> Â̤ â̤ Ê̤ ê̤ Î̤ î̤ Ô̤ ô̤ Ṳ̂ ṳ̂ </charinsert> &nbsp; <charinsert> Â â Ĉ ĉ Ê ê Ĝ ĝ Ĥ ĥ Î î Ĵ ĵ Ô ô Ŝ ŝ Û û Ŵ ŵ Ŷ ŷ </charinsert> &nbsp; <charinsert> Ä ä Ë ë Ï ï Ö ö Ü ü Ÿ ÿ </charinsert> &nbsp; <charinsert> ß </charinsert> &nbsp; <charinsert> Ã ã Ẽ ẽ Ĩ ĩ Ñ ñ Õ õ Ũ ũ Ỹ ỹ</charinsert> &nbsp; <charinsert> Ç ç Ģ ģ Ķ ķ Ļ ļ Ņ ņ Ŗ ŗ Ş ş Ţ ţ </charinsert> &nbsp; <charinsert> Đ đ </charinsert> &nbsp; <charinsert> Ů ů </charinsert> &nbsp; <charinsert> Ǎ ǎ Č č Ď ď Ě ě Ǐ ǐ Ľ ľ Ň ň Ǒ ǒ Ř ř Š š Ť ť Ǔ ǔ Ž ž </charinsert> &nbsp; <charinsert> Ā ā Ē ē Ī ī Ō ō Ū ū Ȳ ȳ Ǣ ǣ </charinsert> &nbsp; <charinsert> ǖ ǘ ǚ ǜ </charinsert> &nbsp; <charinsert> Ă ă Ĕ ĕ Ğ ğ Ĭ ĭ Ŏ ŏ Ŭ ŭ </charinsert> &nbsp; <charinsert> Ċ ċ Ė ė Ġ ġ İ ı Ż ż </charinsert> &nbsp; <charinsert> Ą ą Ę ę Į į Ǫ ǫ Ų ų </charinsert> &nbsp; <charinsert> Ḍ ḍ Ḥ ḥ Ḷ ḷ Ḹ ḹ Ṃ ṃ Ṇ ṇ Ṛ ṛ Ṝ ṝ Ṣ ṣ Ṭ ṭ </charinsert> &nbsp; <charinsert> Ł ł </charinsert> &nbsp; <charinsert> Ő ő Ű ű </charinsert> &nbsp; <charinsert> Ŀ ŀ </charinsert> &nbsp; <charinsert> Ħ ħ </charinsert> &nbsp; <charinsert> Ð ð Þ þ </charinsert> &nbsp; <charinsert> Œ œ </charinsert> &nbsp; <charinsert> Æ æ Ø ø Å å </charinsert> &nbsp; <charinsert> Ə ə </charinsert></span>&nbsp;<span id=\"edittools_latinx_template\">&nbsp;&bull;&nbsp; <charinsert><nowiki>{{</nowiki><nowiki>Unicode|</nowiki>+<nowiki>}}</nowiki></charinsert></span><br/></span> <span id=\"edittools_greek\">'''Hî-lia̍p-vùn:''' <charinsert> Ά ά Έ έ Ή ή Ί ί Ό ό Ύ ύ Ώ ώ </charinsert> &nbsp; <charinsert> Α α Β β Γ γ Δ δ </charinsert> &nbsp; <charinsert> Ε ε Ζ ζ Η η Θ θ </charinsert> &nbsp; <charinsert> Ι ι Κ κ Λ λ Μ μ </charinsert> &nbsp; <charinsert> Ν ν Ξ ξ Ο ο Π π </charinsert> &nbsp; <charinsert> Ρ ρ Σ σ ς Τ τ Υ υ </charinsert> &nbsp; <charinsert> Φ φ Χ χ Ψ ψ Ω ω </charinsert> &nbsp;<span id=\"edittools_greek_template\">•&nbsp; <charinsert><nowiki>{{</nowiki><nowiki>Polytonic|</nowiki>+<nowiki>}}</nowiki></charinsert></span> &nbsp;<span id=\"edittools_greek_example\">•&nbsp; ([[Greek diacritics#Computer encoding|polytonic list]])</span><br/></span> <span id=\"edittools_cyrillic\">'''Cyrillic:''' <charinsert> А а Б б В в Г г </charinsert> &nbsp; <charinsert> Ґ ґ Ѓ ѓ Д д Ђ ђ </charinsert> &nbsp; <charinsert> Е е Ё ё Є є Ж ж </charinsert> &nbsp; <charinsert> З з Ѕ ѕ И и І і </charinsert> &nbsp; <charinsert> Ї ї Й й Ј ј К к </charinsert> &nbsp; <charinsert> Ќ ќ Л л Љ љ М м </charinsert> &nbsp; <charinsert> Н н Њ њ О о П п </charinsert> &nbsp; <charinsert> Р р С с Т т Ћ ћ </charinsert> &nbsp; <charinsert> У у Ў ў Ф ф Х х </charinsert> &nbsp; <charinsert> Ц ц Ч ч Џ џ Ш ш </charinsert> &nbsp; <charinsert> Щ щ Ъ ъ Ы ы Ь ь </charinsert> &nbsp; <charinsert> Э э Ю ю Я я </charinsert> &nbsp;<br/></span> <span id=\"edittools_ipa\">'''IPA:''' <span title=\"Pronunciation in IPA\" class=\"IPA\"><charinsert>t̪ d̪ ʈ ɖ ɟ ɡ ɢ ʡ ʔ </charinsert> &nbsp; <charinsert> ɸ ʃ ʒ ɕ ʑ ʂ ʐ ʝ ɣ ʁ ʕ ʜ ʢ ɦ </charinsert> &nbsp; <charinsert> ɱ ɳ ɲ ŋ ɴ </charinsert> &nbsp; <charinsert> ʋ ɹ ɻ ɰ </charinsert> &nbsp; <charinsert> ʙ ʀ ɾ ɽ </charinsert> &nbsp; <charinsert> ɫ ɬ ɮ ɺ ɭ ʎ ʟ </charinsert> &nbsp; <charinsert> ɥ ʍ ɧ </charinsert> &nbsp; <charinsert> ɓ ɗ ʄ ɠ ʛ </charinsert> &nbsp; <charinsert> ʘ ǀ ǃ ǂ ǁ </charinsert> &nbsp; <charinsert> ɨ ʉ ɯ </charinsert> &nbsp; <charinsert> ɪ ʏ ʊ </charinsert> &nbsp; <charinsert> ɘ ɵ ɤ </charinsert> &nbsp; <charinsert> ə ɚ </charinsert> &nbsp; <charinsert> ɛ ɜ ɝ ɞ ʌ ɔ </charinsert> &nbsp; <charinsert> ɐ ɶ ɑ ɒ </charinsert> &nbsp; <charinsert> ʰ ʷ ʲ ˠ ˤ ⁿ ˡ </charinsert> &nbsp; <charinsert> ˈ ˌ ː ˑ ̪ </charinsert>&nbsp;</span> &nbsp;&bull;&nbsp; <charinsert><nowiki>{{</nowiki><nowiki>IPA|</nowiki>+<nowiki>}}</charinsert></small>\n</div>",
        "nocreatetext": "Chhṳ́ mióng-chham han-chṳ chhóng-chho sîn hong-mien ke kûng-yung. ngì khó-yî fán-fì pin phiên-cho yí-kîn yû ke hong-mien, fe̍t-chá [[Special:UserLogin|tên-liu̍k fe̍t-he chhóng-kien sîn chong-fu]].",
        "nocreate-loggedin": "汝並無權限去創建新頁面。",
        "permissionserrors": "Khièn-han chhâ-chho",
        "permissionserrorstext": "Kîn-kí yî-ha ke ngièn-yîn, ngì vù-yû khièn-han hi-tso yî-ha ke thung-tsok:",
-       "permissionserrorstext-withaction": "根據下背嘅{{PLURAL:$1|原因|原因}},汝並無權限去做$2:",
+       "permissionserrorstext-withaction": "Yîn-vi hâ-poi ke {{PLURAL:$1|ngièn-yîn}}, ngì mò-fap-thu $2:",
        "recreate-moveddeleted-warn": "'''警告:汝今下重新建立一隻先前曾經刪除過嘅頁面。'''\n\n汝應該愛考慮一下繼續編寫邇一隻頁面係毋係合適。\n為到方便,邇一個頁面嘅刪除日誌已經在下背提供:",
        "moveddeleted-notice": "Liá-chak ya̍p-mien yí-kîn san-chhù. \nLiá-chak ya̍p-mien ke san-chhù lâu yì-thûng ngit-chì yí-kîn chhai hâ-poi thì-kiûng lòi chhâm-kháu.",
        "log-fulllog": "Chhà-khon vàn-cháng ngit-chì",
        "undo-failure": "由於中途嘅編寫毋一致,本編輯毋做得撤銷。",
        "undo-norev": "由於其嘅修訂版本毋存在或已刪除,本編寫毋做得撤銷。",
        "undo-summary": "Chhí-sêu yù [[Special:Contributions/$2|$2]] ([[User talk:$2|tui-fa]]) só chok-chhut ke siû-thin $1",
-       "cantcreateaccounttitle": "Mò-fap kien-li̍p chong-ho",
        "cantcreateaccount-text": "從邇隻IP地址('''$1''')建立帳號已經分[[User:$3|$3]]禁止。\n\n當中分$3封禁嘅原因是''$2''",
        "viewpagelogs": "Chhà-khon liá-chak ya̍p-mien ke ngit-chì",
        "nohistory": "無本頁嘅修訂版本記錄。",
        "previousrevision": "← Sông-chak pán-pún",
        "nextrevision": "Hâ-chak pán-pún →",
        "currentrevisionlink": "Chui-sîn pán-pún",
-       "cur": "tông-chhièn",
-       "next": "下一隻",
-       "last": "sông yit-chak",
+       "cur": "kîm",
+       "next": "Heu",
+       "last": "chhièn",
        "page_first": "chui-chó",
        "page_last": "chui-mî",
-       "histlegend": "差別選擇:標記愛比較版本嘅單選按鈕並點擊底部嘅按鈕進行比較。<br />\n說明:'''({{int:cur}})''' 指撈最新版本比較,'''({{int:last}})''' 指撈上隻版本比較,'''{{int:minoreditletter}}''' = 細微修改。",
+       "histlegend": "Chhâ-phe̍t sién-chet: pêu-ki oi pí-káu pán-pún, tiám hâ-poi ke \"Pí-káu sién-chet ke pán-pún\" yung lòi pí-káu.<br />\nSot-mìn: <strong>({{int:cur}})</strong> chṳ́ lâu chui sîn pán-pún pí-káu, <strong>({{int:last}})</strong> chṳ́ thùng chhièn yit ke pán-pún pí-káu, <strong>{{int:minoreditletter}}</strong> = se-mì siû-kói.",
        "history-fieldset-title": "Liù-lám li̍t-sṳ́",
        "history-show-deleted": "Tân-chhiang he yí san-chhù ke",
        "histfirst": "chui-chó",
        "rev-deleted-event": "(日誌已刪除)",
        "rev-deleted-text-permission": "Ke-vùn-chông siû-thin yí-kîn pûn-chhiùng kûng-khiung vùn-tóng chûng yì-chhù. Chhai [{{fullurl:{{#Special:Log}}/suppress|page={{PAGENAMEE}}}} chhù-thet ngit-ki] chûng khó-nèn kiám-chhà to siòng-se ke sin-sit.",
        "rev-deleted-text-view": "Ke-vùn-chông siû-thin yí-kîn pûn-chhiùng kûng-khiung vùn-tóng chûng yì-chhù. Chok-vi mióng-chham ke kón-lî-yèn, khó-yî kiám-chhà; Chhai[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} chhù-thet ngit-ki] chûng khó-nèn kiám-chhà to siòng-se ke sin-sit.",
-       "rev-delundel": "chán-hien / yún-chhông",
-       "rev-showdeleted": "展現",
+       "rev-delundel": "hien / ám",
+       "rev-showdeleted": "hien",
        "revisiondelete": "刪除/恢復刪除修訂版本",
        "revdelete-nooldid-title": "無效嘅目標修訂版本",
        "revdelete-nooldid-text": "汝還吂指定一隻目標修訂版本去進行邇隻功能、\n所指定嘅修訂版本毋存在,或者汝嘗試去隱藏今下嘅修訂版本。",
        "history-title": "\"$1\" ke siû-thin li̍t-sṳ́",
        "difference-title": "\"$1\" siû-thin kiên ke chhâ-bie",
        "lineno": "Thi $1 hàng:",
-       "compareselectedversions": "比較選定嘅修訂版本",
-       "editundo": "Chha̍t-siau",
+       "compareselectedversions": "Pí-káu sién-chet ke pán-pún",
+       "editundo": "Chhí-sêu",
        "searchresults": "Sêu-chhìm kiet-kó",
-       "searchresults-title": "Sêu -chhìm \"$1\" ke kiet-kó",
+       "searchresults-title": "Sêu-chhìm \"$1\" ke kiet-kó",
        "titlematches": "頁面標題相符",
        "textmatches": "頁面內容配得上",
        "notextmatches": "無頁面內容配上",
        "rcnotefrom": "下背係從'''$2'''起嘅更改(最多展示'''$1'''):",
        "rclistfrom": "Chán-sṳ chhiùng $3 $2 yî-lòi ke sîn kiên-kói",
        "rcshowhideminor": "$1細微編寫",
-       "rcshowhideminor-show": "Chán-sṳ",
-       "rcshowhideminor-hide": "Yún-chhông",
+       "rcshowhideminor-show": "Hien",
+       "rcshowhideminor-hide": "Ám",
        "rcshowhidebots": "$1 kî-hi-ngìn ke phiên-siá",
        "rcshowhidebots-show": "Chán-sṳ",
-       "rcshowhidebots-hide": "Yún-chhông",
+       "rcshowhidebots-hide": "Ám",
        "rcshowhideliu": "$1 yí-kîn tên-ngi̍p ke yung-fu",
-       "rcshowhideliu-hide": "Yún-chhông",
+       "rcshowhideliu-show": "Hien",
+       "rcshowhideliu-hide": "Ám",
        "rcshowhideanons": "$1 nit-miàng yung-fu ke phiên-siá",
-       "rcshowhideanons-show": "Chán-sṳ",
-       "rcshowhideanons-hide": "Yún-chhông",
+       "rcshowhideanons-show": "Hien",
+       "rcshowhideanons-hide": "Ám",
        "rcshowhidepatr": "$1巡查過嘅編寫",
        "rcshowhidemine": "$1 ngài-ke phiên-siá",
-       "rcshowhidemine-show": "Chán-sṳ",
-       "rcshowhidemine-hide": "Yún-chhông",
+       "rcshowhidemine-show": "Hien",
+       "rcshowhidemine-hide": "Ám",
        "rclinks": "Chán-sṳ chui-khiûn $2-ngit nui chui-sîn ke $1 chhṳ kói-thûng. <br />$3",
        "diff": "chhâ-phe̍t",
        "hist": "li̍t-sṳ́",
-       "hide": "Yún-chhông",
+       "hide": "Ám",
        "show": "Chán-sṳ",
        "minoreditletter": "se-mì",
        "newpageletter": "Sîn",
        "deletereasonotherlist": "其它理由",
        "rollback": "編寫倒轉頭",
        "rollbacklink": "tá chón-thèu",
-       "rollbacklinkcount": "chha̍t-siau $1 chhṳ phiên-siá",
+       "rollbacklinkcount": "chhí-sêu $1 chhṳ phiên-siá",
        "rollbackfailed": "無法倒轉頭",
        "cantrollback": "編寫無法打轉頭;最後嘅貢獻者人本文嘅唯一作者。",
        "alreadyrolled": "Mò-fap fî-fu̍k yù [[User:$2|$2]] ([[User talk:$2|thó-lun]]) chin-hàng ke [[$1]] ke chui-heu phiên-si̍p; khì-thâ ngìn yí-kîn phiên-siá fe̍t-he fî-fu̍k liáu ke-hong. Chui-heu phiên-si̍p-chá: [[User:$3|$3]] ([[User talk:$3|Thó-lun]])。",
        "sessionfailure": "汝嘅登入會話好像有問題;\n為到防止會話劫持,邇次操作已經畀取消。\n請轉到先前嘅頁面,重新載入邇頁面,然後重試。",
        "protectlogpage": "Pó-fu ngit-chì",
        "protectlogtext": "Ha-mien he vùn-chông só-thin lâu chhí-sêu só-thin ke lie̍t-péu. Chhiáng chhâm-kháu [[Special:ProtectedPages|Pó-fu vùn-chông chhîn-tân]] yî-khi̍p kiám-sṳ tông-chhièn chin-hàng ke vùn-chông pó-fu.",
-       "protectedarticle": "已保護“[[$1]]”",
+       "protectedarticle": "yí-kîn pó-fu \"[[$1]]\"",
        "modifiedarticleprotection": "已經更改“[[$1]]”嘅保護等級",
        "unprotectedarticle": "yí-kîn kié-chhù pó-fu \"[[$1]]\"",
        "protect-title": "更改“$1”嘅保護等級",
        "ipaddressorusername": "IP thi-chí fe̍t yung-fu-miàng:",
        "ipbexpiry": "Khì-han:",
        "ipbreason": "Ngièn-yîn:",
-       "ipbreason-dropdown": "*Yit-pân ke fûng-kim lî-yù \n** Tô-chhṳ kâ-ngi̍p hî-ká chṳ̂-liau \n** San-chhù ya̍p-mien nui-yùng \n** Ngoi-phu lièn-chiap kóng-ko \n** Chhai ya̍p-mien tú chen-kâ mò yi-ngi vùn-sṳ \n** Mò-lî ke hàng-vì, kûng-kit / sâu-yéu phe̍t-sâ \n** Làm-yung tô-chak chòng-ho \n** Cho-m̀ tet chiap-su ke yung-fu-miàng",
-       "ipbcreateaccount": "Chú-chṳ́ chhóng-kien sîn chòng-ho",
+       "ipbreason-dropdown": "*Yit-pân ke fûng-kim lî-yù \n** Tô-chhṳ kâ-ngi̍p hî-ká chṳ̂-liau \n** San-chhù ya̍p-mien nui-yùng \n** Ngoi-phu lièn-chiap kóng-ko \n** Chhai ya̍p-mien tú chen-kâ mò yi-ngi vùn-sṳ \n** Mò-lî ke hàng-vì, kûng-kit / sâu-yéu phe̍t-sâ \n** Làm-yung tô-chak fu-thèu \n** Cho-m̀ tet chiap-su ke yung-fu-miàng",
+       "ipbcreateaccount": "Chú-chṳ́ kien-li̍p sîn fu-thèu",
        "ipbenableautoblock": "Chhṳ-thûng chhà-fûng liá yung-fu chui-heu só yung ke IP thi-chí, lâu heu-lòi sṳ-thù phiên-siá só yung ke só-yû thi-chí",
        "ipbsubmit": "Chhà-fûng liá yung-fu",
        "ipbother": "其它時間:",
        "tooltip-pt-userpage": "{{GENDER:|Ngì ke sṳ́-yung-chá}} ya̍p-mien",
        "tooltip-pt-anonuserpage": "Ngì-ke phiên-siá pún-chham só yung IP ke tui-yin yung-fu-chông",
        "tooltip-pt-mytalk": "{{GENDER:|Ngì ke}} kâu-liù ya̍p",
-       "tooltip-pt-anontalk": "Tui-yî lòi-chhṳ chhṳ́IP thi-tiám phiên-siá ke tui-fa",
+       "tooltip-pt-anontalk": "Liá ke IP vi-chṳ́ yû-koân phiên-siá ke thó-lun",
        "tooltip-pt-preferences": "{{GENDER:|Ngì ke}} phiên-hó sat-thin",
        "tooltip-pt-watchlist": "Ngì kâm-sṳ chûng ya̍p-mien ke kiên-kói lie̍t-péu",
        "tooltip-pt-mycontris": "{{GENDER:|Ngì ke}} kung-hien lie̍t-péu",
-       "tooltip-pt-login": "Kien-ngi ngì tên-ngi̍p, than-he pin fî pit-sî ke",
+       "tooltip-pt-login": "Kien-ngi ngì tên-ngi̍p, m̀-ko mò-yit-thin oi.",
        "tooltip-pt-logout": "Tên-chhut",
+       "tooltip-pt-createaccount": "Kien-ngi ngì siên khôi yit ke fu-thèu chai tên-ngi̍p; m̀-ko mò-yit-thin oi.",
        "tooltip-ca-talk": "Liá ya̍p ke thó-lun",
        "tooltip-ca-edit": "Phiên-siá pún-ya̍p",
        "tooltip-ca-addsection": "Khôi-sṳ́ yit-chak sîn thon-lo̍k",
        "metadata": "Ngièn sú-kí",
        "metadata-help": "邇文件肚包含有擴展嘅信息。邇兜信息可能係由數碼相機或掃描儀在創建或數字化過程肚所加入嘅。\n\n係講邇文件嘅源文件已經分修改,一兜信息在修改後嘅文件肚將毋做得完全反映出來。",
        "metadata-expand": "Hién-sṳ siòng-se ke chṳ̂-liau",
-       "metadata-collapse": "Yún-chhòng siòng-se ke chṳ̂-liau",
+       "metadata-collapse": "Ám-hí siòng-se ke chṳ̂-liau",
        "metadata-fields": "在本信息肚所列出嘅EXIF元數據域將包含在圖片顯示頁面,當元數據表損壞時單淨顯示下背信息。\n其他嘅元數據默認做隱藏。\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-orientation": "Fông-vi",
        "exif-xresolution": "Súi-phìn kié-sak-thu",
        "confirmemail_success": "Ngì-ke sin-siông yí-kîn pûn khok-ngin. Ngì hien-ha khó-yî tên-liu̍k pin sṳ́-yung chhṳ́ mióng-chham liáu.",
        "confirmemail_loggedin": "Ngì-ke sin-siông thi-tiám hien-ha yí-kîn pûn khok-ngin.",
        "confirmemail_subject": "{{SITENAME}} sin-siông thi-tiám khok-ngin",
-       "confirmemail_body": "Yúng-yû IP thi-tiám $1 ke yung-fu (khó-nèn he ngì) chhai {{SITENAME}} chhóng-chho liáu chong-fu  \"$2\", pin thì-kâu liáu ngì-ke email sin-siông thi-tiám.\n\nChhiáng khok-ngin liá-ke chong-fu  he su̍k-yî ngì-ke, pin thùng-sṳ̀ khí-yung chhai {{SITENAME}} sông ke email sin-siông kûng-nèn. Chhiáng chhai hi-khí chûng tá-khôi ha-mien ke lièn-kiet: $3\n\nKó-yèn ngì *mò-yû* thì-chhut liá-ke chhiáng-khiù,  chhiáng put-yeu tiám-kit Chhṳ́ lièn-kiet. Khok-ngin me̍t-me̍t chiông-voi chhai $4 ko-khì.",
+       "confirmemail_body": "Yúng-yû IP thi-tiám $1 ke yung-fu (khó-nèn he ngì) chhai {{SITENAME}} chhóng-chho liáu fu-thèu  \"$2\", pin thì-kâu liáu ngì-ke email sin-siông thi-tiám.\n\nChhiáng khok-ngin liá-ke fu-thèu  he su̍k-yî ngì-ke, pin thùng-sṳ̀ khí-yung chhai {{SITENAME}} sông ke email sin-siông kûng-nèn. Chhiáng chhai hi-khí chûng tá-khôi ha-mien ke lièn-kiet: $3\n\nKó-yèn ngì *mò-yû* thì-chhut liá-ke chhiáng-khiù,  chhiáng put-yeu tiám-kit Chhṳ́ lièn-kiet. Khok-ngin me̍t-me̍t chiông-voi chhai $4 ko-khì.",
        "scarytranscludedisabled": "[Khiam-wiki chón-von me̍t-me̍t put hí-khó yung]",
        "scarytranscludefailed": "[Tui-put-hí, mù-pán $1 thu̍k-chhí sṳt-phai]",
        "scarytranscludetoolong": "[Tui-put-hí; URL thi-tiám thai-chhòng]",
        "revdelete-restricted": "yí-kîn yin-yung han-tsṳ tsṳ tshâu-tsok-yèn",
        "revdelete-unrestricted": "yí-kîn yì-tshù yû-kûan tshâu-tsok-yè ke han-tsṳ",
        "logentry-move-move": "$1 {{GENDER:$2|yí-kîn yì-thûng}} ya̍p-mien $3 to $4",
-       "logentry-newusers-create": "Yí-kîn {{GENDER:$2|kien-li̍p}} sṳ́-yung-chá chong-ho  $1",
+       "logentry-newusers-create": "Yí-kîn {{GENDER:$2|khôi}} yung-fu fu-thèu $1",
        "logentry-upload-upload": "$1 {{GENDER:$2|yí-kîn sông-chhòn}} $3",
        "rightsnone": "(無)",
        "revdelete-summary": "piên-sip tsak-yêu",
index 2de6b59..5dcfbd5 100644 (file)
        "yourpasswordagain": "E kikokiko hou i ka ʻōlelo hūnā:",
        "createacct-yourpasswordagain": "E hōʻoia i ka ʻōlelo hūnā",
        "createacct-yourpasswordagain-ph": "E kikokiko hou i ka ʻōlelo hūnā",
-       "remembermypassword": "Hoʻomanaʻo iaʻu ma kēia lolo uila (no ka palena nui o $1 {{PLURAL:$1|lā|mau lā}})",
        "userlogin-remembermypassword": "Hoʻomanaʻo iaʻu",
        "login": "ʻEʻe",
        "nav-login-createaccount": "ʻEʻe / Kāinoa",
index bdfcfb5..028f7b9 100644 (file)
@@ -35,7 +35,8 @@
                        "פוילישער",
                        "DatGuy",
                        "IKhitron",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Or"
                ]
        },
        "tog-underline": "סימון קישורים בקו תחתי:",
        "tog-watchdeletion": "הוספת דפים וקבצים שאני {{GENDER:|מוחק|מוחקת}} לרשימת המעקב שלי",
        "tog-watchuploads": "הוספת קבצים חדשים שאני מעלה לרשימת המעקב שלי",
        "tog-watchrollback": "הוספת דפים שאני {{GENDER:|מבצע|מבצעת}} בהם שחזור מהיר לרשימת המעקב שלי",
-       "tog-minordefault": "ס×\99×\9e×\95×\9f ×\9b×\9c ×¢×¨×\99×\9b×\94 ×\9b×\9eשנ×\99ת ×\9bברירת מחדל",
+       "tog-minordefault": "ס×\99×\9e×\95×\9f ×\9b×\9c ×\94ער×\99×\9b×\95ת ×\9b×\9eשנ×\99×\95ת ×\91ת×\95ר ברירת מחדל",
        "tog-previewontop": "הצגת תצוגה מקדימה לפני תיבת העריכה",
        "tog-previewonfirst": "הצגת תצוגה מקדימה בעריכה הראשונה",
        "tog-enotifwatchlistpages": "לשלוח אליי דוא\"ל כאשר משתנה דף או קובץ ברשימת המעקב שלי",
        "tog-enotifusertalkpages": "לשלוח אליי דוא\"ל כאשר נעשה שינוי בדף שיחת המשתמש שלי",
-       "tog-enotifminoredits": "לשלוח אליי דוא\"ל גם על עריכות משניות בדפים וקבצים",
+       "tog-enotifminoredits": "×\9cש×\9c×\95×\97 ×\90×\9c×\99×\99 ×\93×\95×\90\"×\9c ×\92×\9d ×¢×\9c ×¢×¨×\99×\9b×\95ת ×\9eשנ×\99×\95ת ×\91×\93פ×\99×\9d ×\95×\91ק×\91צ×\99×\9d",
        "tog-enotifrevealaddr": "לחשוף את כתובת הדוא\"ל שלי בהתראות דוא\"ל",
        "tog-shownumberswatching": "הצגת מספר המשתמשים העוקבים",
        "tog-oldsig": "החתימה הנוכחית שלך:",
        "qbfind": "חיפוש",
        "qbbrowse": "ניווט",
        "qbedit": "עריכה",
-       "qbpageoptions": "×\90פשר×\95×\99×\95ת ×\93×£",
-       "qbmyoptions": "×\94×\90פשר×\95×\99×\95ת שלי",
+       "qbpageoptions": "×\94×\93×£ ×\94×\96×\94",
+       "qbmyoptions": "×\94×\93פ×\99×\9d שלי",
        "faq": "שאלות ותשובות",
        "faqpage": "Project:שאלות ותשובות",
        "actions": "פעולות",
        "deletethispage": "מחיקת דף זה",
        "undeletethispage": "שחזור דף זה",
        "undelete_short": "שחזור {{PLURAL:$1|עריכה אחת|$1 עריכות}}",
-       "viewdeleted_short": "×\94צ×\92ת {{PLURAL:$1|×\92רס×\94 ×¢×¨×\99×\9b×\94 ×\90×\97ת|$1 ×¢×¨×\99×\9b×\94 מחוקות}}",
+       "viewdeleted_short": "×\94צ×\92ת {{PLURAL:$1|ער×\99×\9b×\94 ×\9e×\97×\95ק×\94 ×\90×\97ת|$1 ×¢×¨×\99×\9b×\95ת מחוקות}}",
        "protect": "הגנה",
        "protect_change": "שינוי",
        "protectthispage": "הפעלת הגנה על דף זה",
        "eauthentsent": "דוא\"ל אימות נשלח לכתובת הדוא\"ל שצוינה.\nלפני שדברי דוא\"ל אחרים יישלחו לחשבון הזה, יהיה עליכם לפעול לפי ההוראות בדוא\"ל, כדי לאשר שהחשבון אכן שייך לכם.",
        "throttled-mailpassword": "כבר נשלח דוא\"ל לאיפוס הסיסמה ב{{PLURAL:$1|שעה האחרונה|שעתיים האחרונות|־$1 השעות האחרונות}}.\nכדי למנוע ניצול לרעה, יכול להישלח רק דוא\"ל אחד כזה בכל {{PLURAL:$1|שעה|שעתיים|$1 שעות}}.",
        "mailerror": "שגיאה בשליחת דואר: $1",
-       "acct_creation_throttle_hit": "מבקרים באתר זה דרך כתובת ה־IP שלך כבר יצרו {{PLURAL:$1|חשבון אחד|$1 חשבונות}} ב־$2. זהו המקסימום המותר בתקופה זו.\nלפיכך, כרגע לא ניתן ליצור חשבונות נוספים מכתובת ה־IP הזו.",
+       "acct_creation_throttle_hit": "מבקרים באתר זה דרך כתובת ה־IP שלך כבר יצרו {{PLURAL:$1|חשבון אחד|$1 חשבונות}} במהלך $2. זהו המקסימום המותר בתקופה זו.\nלפיכך, כרגע לא ניתן ליצור חשבונות נוספים מכתובת ה־IP הזו.",
        "emailauthenticated": "כתובת הדוא\"ל שלך אומתה ב־$2 בשעה $3.",
        "emailnotauthenticated": "כתובת הדוא\"ל שלכם עדיין לא אומתה.\nלא יישלח אליכם דוא\"ל עבור אף אחת מהתכונות הבאות.",
        "noemailprefs": "יש לציין כתובת דוא\"ל בהעדפות שלך כדי שתכונות אלה יעבדו.",
        "botpasswords-label-delete": "מחיקה",
        "botpasswords-label-resetpassword": "איפוס ססמה",
        "botpasswords-label-grants": "זיכיונות מתאימים",
-       "botpasswords-help-grants": "×\9b×\9c ×\96×\99×\9b×\99×\95×\9f × ×\95ת×\9f ×\92×\99ש×\94 ×\9c×\94רש×\90×\95ת ×\9eשת×\9eש ×¨×©×\95×\9e×\95ת ×©×\99ש ×\9c×\97ש×\91×\95×\9f ×\94×\9eשת×\9eש. ×¢×\99×\99× ×\95 ×\91[[Special:ListGrants|×\98×\91×\9cת ×\94×\96×\99×\9b×\99×\95× ×\95ת]] ×\9c×\9e×\99×\93×¢ × ×\95סף.",
+       "botpasswords-help-grants": "×\96×\99×\9b×\99×\95× ×\95ת × ×\95תנ×\99×\9d ×\92×\99ש×\94 ×\9c×\94רש×\90×\95ת ×©×\9b×\91ר ×\9e×\95×\97×\96ק×\95ת ×\91×\99×\93×\99 ×\97ש×\91×\95×\9f ×\94×\9eשת×\9eש ×©×\9c×\9a. ×\94פע×\9cת ×\96×\99×\9b×\99×\95×\9f ×\91×\93×£ ×\96×\94 ×\90×\99× ×\94 × ×\95תנת ×\92×\99ש×\94 ×\9c×\94רש×\90×\95ת ×\90×\97ר×\95ת ×©×\90×\99× ×\9f ×\9e×\95×\97×\96ק×\95ת ×\91×\99×\93×\99 ×\97ש×\91×\95×\9f ×\94×\9eשת×\9eש ×©×\9c×\9a. ×\9e×\99×\93×¢ × ×\95סף ×\9e×\95פ×\99×¢ ×\91[[Special:ListGrants|×\98×\91×\9cת ×\94×\96×\99×\9b×\99×\95× ×\95ת]].",
        "botpasswords-label-grants-column": "ניתן זיכיון",
        "botpasswords-bad-appid": "שם הבוט \"$1\" אינו תקין.",
        "botpasswords-insert-failed": "הוספת שם הבוט \"$1\" נכשלה. האם הוא כבר נוסף?",
        "passwordreset-nocaller": "לא סופק הקורא הנדרש",
        "passwordreset-nosuchcaller": "הקורא אינו קיים: $1",
        "passwordreset-ignored": "איפוס הסיסמה לא בוצע. ייתכן שלא הוגדר ספק.",
-       "passwordreset-invalideamil": "כתובת דוא\"ל לא תקינה",
+       "passwordreset-invalidemail": "כתובת דוא\"ל לא תקינה",
        "passwordreset-nodata": "לא סופק שם משתמש או כתובת דוא\"ל",
        "changeemail": "שינוי או הסרת כתובת דוא\"ל",
        "changeemail-header": "יש למלא את הטופס הזה כדי לשנות את כתובת הדוא\"ל שלך. אם ברצונך להימנע משיוך כתובת דוא\"ל כלשהי לחשבון שלך, יש להשאיר את שדה כתובת הדוא\"ל החדשה ריק בעת שליחת הטופס.",
        "searchprofile-advanced-tooltip": "חיפוש במרחבי שם מותאמים אישית",
        "search-result-size": "$1 ({{PLURAL:$2|מילה אחת|$2 מילים}})",
        "search-result-category-size": "{{PLURAL:$1|פריט אחד|$1 פריטים}} ({{PLURAL:$2|קטגוריית משנה אחת|$2 קטגוריות משנה}}, {{PLURAL:$3|קובץ אחד|$3 קבצים}})",
-       "search-redirect": "(הפניה $1)",
+       "search-redirect": "(הפניה מהדף $1)",
        "search-section": "(פסקה $1)",
        "search-category": "(קטגוריה $1)",
        "search-file-match": "(התאמה בתוכן הקובץ)",
        "grant-basic": "הרשאות בסיסיות",
        "grant-viewdeleted": "צפייה בקבצים ודפים שנמחקו",
        "grant-viewmywatchlist": "צפייה ברשימת המעקב שלך",
+       "grant-viewrestrictedlogs": "צפייה בפריטי היומן המוגבלים",
        "newuserlogpage": "יומן רישום משתמשים",
        "newuserlogpagetext": "זהו יומן המכיל הרשמות של משתמשים.",
        "rightslog": "יומן הרשאות",
        "upload-dialog-disabled": "אין אפשרות להעלות קבצים באמצעות תיבת הדו־שיח הזאת באתר זה.",
        "upload-dialog-title": "העלאת קובץ",
        "upload-dialog-button-cancel": "ביטול",
+       "upload-dialog-button-back": "חזרה",
        "upload-dialog-button-done": "בוצע",
        "upload-dialog-button-save": "שמירה",
        "upload-dialog-button-upload": "העלאה",
        "apisandbox-results-fixtoken-fail": "קבלת האסימון \"$1\" נכשלה.",
        "apisandbox-alert-page": "שדות בדף זה אינם תקינים.",
        "apisandbox-alert-field": "הערך של שדה זה אינו תקין.",
+       "apisandbox-continue": "המשך",
+       "apisandbox-continue-clear": "ניקוי",
+       "apisandbox-continue-help": "\"{{int:apisandbox-continue}}\" [https://www.mediawiki.org/wiki/API:Query#Continuing_queries ימשיך] את הבקשה האחרונה; \"{{int:apisandbox-continue-clear}}\" ינקה את הפרמטרים הקשורים להמשך.",
+       "apisandbox-param-limit": "יש לכתוב <kbd>max</kbd> כדי להשתמש בערך המרבי האפשרי.",
        "booksources": "משאבי ספרות חיצוניים",
        "booksources-search-legend": "חיפוש משאבי ספרות חיצוניים",
        "booksources-isbn": "מסת\"ב (ISBN):",
        "booksources-search": "חיפוש",
        "booksources-text": "להלן רשימת קישורים לאתרים אחרים המוכרים ספרים חדשים ויד־שנייה, ושבהם עשוי להיות מידע נוסף לגבי ספרים שאתם מחפשים:",
        "booksources-invalid-isbn": "המסת\"ב שניתן כנראה אינו תקין; אנא בדקו אם ביצעתם טעויות בהעתקה מהמידע המקורי.",
+       "magiclink-tracking-rfc": "דפים שמשתמשים בקישורי קסם ל־RFC",
+       "magiclink-tracking-rfc-desc": "דף זה משתמש בקישורי קסם ל־RFC. באתר [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] מוסבר כיצד יש לשנותם.",
+       "magiclink-tracking-pmid": "דפים שמשתמשים בקישורי קסם ל־PMID",
+       "magiclink-tracking-pmid-desc": "דף זה משתמש בקישורי קסם ל־PMID. באתר [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] מוסבר כיצד יש לשנותם.",
+       "magiclink-tracking-isbn": "דפים שמשתמשים בקישורי קסם ל־ISBN",
+       "magiclink-tracking-isbn-desc": "דף זה משתמש בקישורי קסם ל־ISBN. באתר [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] מוסבר כיצד יש לשנותם.",
        "specialloguserlabel": "בוצעו על־ידי המשתמש:",
        "speciallogtitlelabel": "יעד (שם הדף, או \"{{ns:user}}:שם\" עבור משתמש):",
        "log": "יומנים",
        "activeusers-intro": "זוהי רשימת המשתמשים שביצעו פעולה כלשהי {{PLURAL:$1|ביום האחרון|ביומיים האחרונים|ב־$1 הימים האחרונים}}.",
        "activeusers-count": "{{PLURAL:$1|פעולה אחת|$1 פעולות}} ב{{PLURAL:$3|יום האחרון|יומיים האחרונים|־$3 הימים האחרונים}}",
        "activeusers-from": "הצגת משתמשים החל מ:",
-       "activeusers-hidebots": "הסתרת בוטים",
-       "activeusers-hidesysops": "הסתרת מפעילי מערכת",
+       "activeusers-groups": "הצגת משתמשים השייכים לקבוצות:",
        "activeusers-noresult": "לא נמצאו משתמשים.",
        "activeusers-submit": "הצגת משתמשים פעילים",
        "listgrouprights": "רשימת הרשאות לקבוצה",
        "delete-edit-reasonlist": "עריכת סיבות המחיקה",
        "delete-toobig": "דף זה כולל מעל {{PLURAL:$1|גרסה אחת|$1 גרסאות}} בהיסטוריית העריכות שלו. מחיקת דפים כאלה הוגבלה כדי למנוע פגיעה בביצועי האתר.",
        "delete-warning-toobig": "דף זה כולל מעל {{PLURAL:$1|גרסה אחת|$1 גרסאות}} בהיסטוריית העריכות שלו. מחיקה שלו עלולה להפריע לפעולות בבסיס הנתונים; אנא שקלו שנית את המחיקה.",
-       "deleteprotected": "אין באפשרותך למחוק את הדף כי הוא מוגן.",
+       "deleteprotected": "אין {{GENDER:|באפשרותך|באפשרותך|באפשרותכם}} למחוק את הדף כי הוא מוגן.",
        "deleting-backlinks-warning": "<strong>אזהרה:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|דפים אחרים]] מקשרים לדף ש{{GENDER:|אתה עומד|את עומדת|אתם עומדים}} למחוק או מכלילים אותו.",
        "rollback": "שחזור עריכות",
        "rollbacklink": "שחזור",
        "protectlogtext": "להלן רשימה של שינויי ההגנה על דפים.\nראו גם את [[Special:ProtectedPages|רשימת הדפים המוגנים]] הנוכחית.",
        "protectedarticle": "הופעלה הגנה על הדף \"[[$1]]\"",
        "modifiedarticleprotection": "רמת ההגנה של הדף \"[[$1]]\" שונתה",
-       "unprotectedarticle": "×\94×\94×\92× ×\94 ×¢×\9c ×\94×\93×£ \"[[$1]]\" ×\94×\95סר×\94",
+       "unprotectedarticle": "×\94×\94×\92× ×\94 ×\94×\95סר×\94 ×\9e×\94×\93×£ \"[[$1]]\"",
        "movedarticleprotection": "הגדרות ההגנה של הדף \"[[$2]]\" הועברו לדף \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|הפעיל|הפעילה}} הגנה על הדף \"[[$1]]\"",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|שינה|שינתה}} את רמת ההגנה של הדף \"[[$1]]\"",
+       "unprotectedarticle-comment": "{{GENDER:$2|הסיר|הסירה}} את ההגנה מהדף \"[[$1]]\"",
        "protect-title": "שינוי רמת ההגנה של הדף \"$1\"",
        "protect-title-notallowed": "הצגת רמת ההגנה של הדף \"$1\"",
        "prot_1movedto2": "[[$1]] הועבר לשם [[$2]]",
        "movelogpagetext": "להלן רשימה של כל הדפים ששמם שוּנה.",
        "movesubpage": "{{PLURAL:$1|דף משנה|דפי משנה}}",
        "movesubpagetext": "לדף זה יש {{PLURAL:$1|דף משנה אחד המוצג להלן|$1 דפי משנה המוצגים להלן}}.",
+       "movesubpagetalktext": "לדף השיחה של דף זה יש {{PLURAL:$1|דף משנה אחד המוצג להלן|$1 דפי משנה המוצגים להלן}}.",
        "movenosubpage": "לדף זה אין דפי משנה.",
        "movereason": "סיבה:",
        "revertmove": "החזרה",
        "pageinfo-category-pages": "מספר הדפים",
        "pageinfo-category-subcats": "מספר קטגוריות המשנה",
        "pageinfo-category-files": "מספר הקבצים",
+       "pageinfo-user-id": "המספר המזהה של המשתמש",
        "markaspatrolleddiff": "סימון השינוי כבדוק",
        "markaspatrolledtext": "סימון דף זה כבדוק",
        "markaspatrolledtext-file": "סימון גרסת קובץ זו כבדוקה",
        "patrol-log-header": "יומן זה מציג גרסאות שנבדקו.",
        "log-show-hide-patrol": "$1 יומן שינויים בדוקים",
        "log-show-hide-tag": "$1 יומן תגיות",
+       "confirm-markpatrolled-button": "אישור",
+       "confirm-markpatrolled-top": "לסמן את גרסה $3 של $2 כבדוקה?",
        "deletedrevision": "מחיקת גרסה ישנה ($1)",
        "filedeleteerror-short": "שגיאה במחיקת הקובץ: $1",
        "filedeleteerror-long": "שגיאות שאירעו בעת מחיקת הקובץ:\n\n$1",
        "newimages-showbots": "הצגת העלאות שבוצעו על־ידי בוטים",
        "newimages-hidepatrolled": "הסתרת העלאות בדוקות",
        "noimages": "אין קבצים.",
+       "gallery-slideshow-toggle": "הצגת/הסתרת תמונות ממוזערות",
        "ilsubmit": "חיפוש",
        "bydate": "לפי תאריך",
        "sp-newimages-showfrom": "הצגת קבצים חדשים החל מ־$2, $1",
        "tags-deactivate": "ביטול הפעלה",
        "tags-hitcount": "{{PLURAL:$1|שינוי אחד|$1 שינויים}}",
        "tags-manage-no-permission": "אין לך הרשאה לנהל תגיות שינויים.",
-       "tags-manage-blocked": "×\9c×\90 × ×\99ת×\9f ×\9c× ×\94×\9c ×ª×\92×\99×\95ת ×©×\99× ×\95×\99×\99×\9d ×\91עת ×\97ס×\99×\9e×\94.",
+       "tags-manage-blocked": "×\90×\99× ×\9a ×\9e×\95רש×\94 ×\9c× ×\94×\9c ×ª×\92×\99×\95ת ×©×\99× ×\95×\99×\99×\9d ×\9b×\90שר ×\97ש×\91×\95×\9f ×\94×\9eשת×\9eש {{GENDER:$1|ש×\9c×\9a}} ×\97ס×\95×\9d.",
        "tags-create-heading": "יצירת תגית חדשה",
        "tags-create-explanation": "כברירת מחדל, תגיות חדשות שנוצרות יהיו זמינות לשימושם של משתמשים ובוטים.",
        "tags-create-tag-name": "שם התגית:",
        "tags-deactivate-not-allowed": "לא ניתן לבטל את הפעלת התגית \"$1\".",
        "tags-deactivate-submit": "ביטול הפעלה",
        "tags-apply-no-permission": "אין לך הרשאה להחיל תגיות שינויים יחד עם השינויים שלך.",
-       "tags-apply-blocked": "×\9c×\90 × ×\99ת×\9f ×\9c×\94×\97×\99×\9c ×ª×\92×\99×\95ת ×©×\99× ×\95×\99×\99×\9d ×\99×\97×\93 ×¢×\9d ×\94ש×\99× ×\95×\99×\99×\9d ×©×\9c×\9a ×\91עת ×\97ס×\99×\9e×\94.",
+       "tags-apply-blocked": "×\90×\99× ×\9a ×\9e×\95רש×\94 ×\9c×\94×\97×\99×\9c ×ª×\92×\99×\95ת ×©×\99× ×\95×\99×\99×\9d ×\99×\97×\93 ×¢×\9d ×\94ש×\99× ×\95×\99×\99×\9d ×©×\9c×\9a ×\9b×\90שר ×\97ש×\91×\95×\9f ×\94×\9eשת×\9eש {{GENDER:$1|ש×\9c×\9a|ש×\9c×\9a}} ×\97ס×\95×\9d.",
        "tags-apply-not-allowed-one": "לא ניתן להחיל את התגית \"$1\" ידנית.",
        "tags-apply-not-allowed-multi": "לא ניתן להחיל את {{PLURAL:$2|התגית הבאה|התגיות הבאות}} ידנית: $1",
        "tags-update-no-permission": "אין לך הרשאה להוסיף או להסיר תגיות שינויים לגרסאות מסוימות או לרשומות יומן.",
-       "tags-update-blocked": "×\9c×\90 × ×\99ת×\9f ×\9c×\94×\95ס×\99×£ ×\90×\95 ×\9c×\94ס×\99ר ×ª×\92×\99×\95ת ×©×\99× ×\95×\99×\99×\9d ×\91עת ×\97ס×\99×\9e×\94.",
+       "tags-update-blocked": "×\90×\99× ×\9a ×\9e×\95רש×\94 ×\9c×\94×\95ס×\99×£ ×\90×\95 ×\9c×\94ס×\99ר ×ª×\92×\99×\95ת ×©×\99× ×\95×\99×\99×\9d ×\9b×\90שר ×\97ש×\91×\95×\9f ×\94×\9eשת×\9eש {{GENDER:$1|ש×\9c×\9a|ש×\9c×\9a}} ×\97ס×\95×\9d.",
        "tags-update-add-not-allowed-one": "לא ניתן להוסיף את התגית \"$1\" ידנית.",
        "tags-update-add-not-allowed-multi": "לא ניתן להוסיף את {{PLURAL:$2|התגית הבאה|התגיות הבאות}} ידנית: $1",
        "tags-update-remove-not-allowed-one": "לא ניתן להסיר את התגית \"$1\".",
        "htmlform-cloner-create": "הוספה",
        "htmlform-cloner-delete": "הסרה",
        "htmlform-cloner-required": "דרוש לפחות ערך אחד.",
+       "htmlform-date-placeholder": "YYYY-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "YYYY-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "הערך שכתבת אינו תאריך מוכר. ניתן להשתמש בפורמט YYYY-MM-DD.",
+       "htmlform-time-invalid": "הערך שכתבת אינו שעה מוכרת. ניתן להשתמש בפורמט HH:MM:SS.",
+       "htmlform-datetime-invalid": "הערך שכתבת אינו תאריך ושעה מוכרים. ניתן להשתמש בפורמט YYYY-MM-DD HH:MM:SS.",
+       "htmlform-date-toolow": "הערך שכתבת הוא לפני התאריך המוקדם ביותר האפשרי, $1.",
+       "htmlform-date-toohigh": "הערך שכתבת הוא אחרי התאריך המאוחר ביותר האפשרי, $1.",
+       "htmlform-time-toolow": "הערך שכתבת הוא לפני השעה המוקדמת ביותר האפשרית, $1.",
+       "htmlform-time-toohigh": "הערך שכתבת הוא אחרי השעה המאוחרת ביותר האפשרית, $1.",
+       "htmlform-datetime-toolow": "הערך שכתבת הוא לפני התאריך והשעה המוקדמים ביותר האפשריים, $1.",
+       "htmlform-datetime-toohigh": "הערך שכתבת הוא אחרי התאריך והשעה המאוחרים ביותר האפשריים, $1.",
        "htmlform-title-badnamespace": "[[:$1]] אינו במרחב השם \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" אינו שם של דף שאפשר ליצור",
        "htmlform-title-not-exists": "$1 אינו קיים.",
        "feedback-external-bug-report-button": "דיווח על משימה טכנית",
        "feedback-dialog-title": "שליחת המשוב",
        "feedback-dialog-intro": "באפשרותך להשתמש בטופס הפשוט שלהלן כדי לשלוח משוב. ההערה שלך תתווסף לדף \"$1\", יחד עם שם המשתמש שלך.",
-       "feedback-error-title": "שגיאה",
        "feedback-error1": "שגיאה: תוצאה לא מזוהה מה־API",
        "feedback-error2": "שגיאה: העריכה נכשלה",
        "feedback-error3": "שגיאה: אין תשובה מה־API",
        "feedback-thanks": "תודה! המשוב שלך פורסם בדף \"[$2 $1]\".",
        "feedback-thanks-title": "תודה!",
        "feedback-useragent": "User agent:",
-       "searchsuggest-search": "חיפוש",
+       "searchsuggest-search": "חיפוש ב{{grammar:תחילית|{{SITENAME}}}}",
        "searchsuggest-containing": "כולל...",
        "api-error-autoblocked": "כתובת ה־IP שלך נחסמה אוטומטית, כי היא הייתה בשימוש על־ידי משתמש חסום.",
        "api-error-badaccess-groups": "אינך מורשה להעלות קבצים לאתר הוויקי הזה.",
        "authmanager-authn-autocreate-failed": "יצירה אוטומטית של חשבון מקומי נכשלה: $1",
        "authmanager-change-not-supported": "לא ניתן לשנות את נתוני ההאמנה שניתנו, כי שום דבר לא ישתמש בהם.",
        "authmanager-create-disabled": "אפשרות יצירת החשבונות מבוטלת.",
-       "authmanager-create-from-login": "×\9b×\93×\99 ×\9c×\99צ×\95ר ×\90ת ×\94×\97ש×\91×\95×\9f, × ×\90 ×\9c×\9e×\9c×\90 ×\90ת ×\94ש×\93×\95ת ×©×\9c×\94×\9c×\9f.",
+       "authmanager-create-from-login": "×\9b×\93×\99 ×\9c×\99צ×\95ר ×\90ת ×\94×\97ש×\91×\95×\9f, ×\99ש ×\9c×\9e×\9c×\90 ×\90ת ×\94ש×\93×\95ת.",
        "authmanager-create-not-in-progress": "יצירת החשבון נכשלה או שנתוני הפעולה נאבדו. נא להתחיל את התהליך מחדש.",
        "authmanager-create-no-primary": "האישורים שסופקו לא יכולים להיות בשימוש ביצירת חשבון.",
        "authmanager-link-no-primary": "האישורים שסופקו לא יכולים להיות בשימוש בקישור חשבונות.",
        "usercssispublic": "שימו לב: משתמשים אחרים יכולים לצפות בדפי ה־CSS שלכם, ולכן אין לכלול בהם מידע סודי.",
        "restrictionsfield-badip": "כתובת או טווח כתובות IP בלתי תקין: $1",
        "restrictionsfield-label": "טווחי כתובות IP מותרים:",
-       "restrictionsfield-help": "כתובת IP אחת או טווח CIDR אחד בשורה. כדי לאפשר את הכול, ניתן להשתמש ב:<br><code>0.0.0.0/0</code><br><code>::/0</code>"
+       "restrictionsfield-help": "כתובת IP אחת או טווח CIDR אחד בשורה. כדי לאפשר את הכול, ניתן להשתמש ב:<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "שגיאה: $1",
+       "edit-error-long": "שגיאות:\n\n$1"
 }
index cb933de..0af3f5b 100644 (file)
@@ -73,7 +73,8 @@
                        "YmKavishwar",
                        "Upendradutt93",
                        "Nemo bis",
-                       "Wassan.anmol"
+                       "Wassan.anmol",
+                       "Ziyaurr"
                ]
        },
        "tog-underline": "कड़ियाँ अधोरेखन:",
        "category-file-count-limited": "इस श्रेणी में निम्नलिखित {{PLURAL:$1|फ़ाइल है।|फ़ाइलें हैं।}}",
        "listingcontinuesabbrev": "जारी",
        "index-category": "सूचीबद्ध पृष्ठ",
-       "noindex-category": "असूचीबद्ध पृष्ठ",
+       "noindex-category": "असूचीबद्ध पृष्ठों",
        "broken-file-category": "टूटी हुई फ़ाइल कड़ियों वाले पृष्ठ",
        "about": "के बारे में",
        "article": "सामग्री लेख",
        "botpasswords-label-resetpassword": "पासवर्ड पुनः तय करें",
        "botpasswords-label-grants": "अनुदान आवेदन:",
        "botpasswords-help-grants": "हर अनुदान जो सदस्य अधिकार में  पहले से आता है, उसे अधिकार तक पहुँच देता है।  देखें : [[Special:ListGrants|अनुदान सारणी]]",
-       "botpasswords-label-restrictions": "उपयोग मनाही:",
        "botpasswords-label-grants-column": "प्रदान किया",
        "botpasswords-bad-appid": "बॉट नाम \"$1\" मान्य नहीं है।",
        "botpasswords-insert-failed": "बॉट नाम \"$1\" को जोड़ने में विफल हुआ। क्या यह पहले से है?",
        "passwordreset-emailsentemail": "यदि आपका यह ईमेल आपके खाते के साथ जोड़ा गया है तो पासवर्ड बदलने का ईमेल इसमें भेज दिया गया है।",
        "passwordreset-emailsentusername": "यदि कोई ईमेल इस खाते से जुड़ी है तो पासवर्ड आपके ईमेल में भेज दिया जाएगा।",
        "passwordreset-emailerror-capture2": "{{GENDER:$2|सदस्य}} को ईमेल भेजना विफल : $1 {{PLURAL:$3|सदस्य नाम और पासवर्ड|सदस्य नाम और पासवर्ड की सूची}} नीचे दिया गया है।",
-       "passwordreset-invalideamil": "अवैध ईमेल पता",
+       "passwordreset-invalidemail": "अवैध ईमेल पता",
        "changeemail": "ई-मेल पता परिवर्तित करें",
        "changeemail-header": "अपना ईमेल पता परिवर्तन हेतु इसे पूरा करें। यदि आप अपना वर्तमान ईमेल पता हटाना चाहते हैं, तो इसे खाली छोड़ दें और इसे भेजें।",
        "changeemail-no-info": "इस पृष्ठ का सीधे प्रयोग करने के लिए आपको लॉग इन करना होगा।",
        "action-siteadmin": "डाटाबेस को ताला लगाने या खोलने",
        "action-sendemail": "ई-मेल भेजने",
        "action-editmywatchlist": "ध्यानसूची सम्पादित करने",
-       "action-viewmywatchlist": "à¤\85पनà¥\80 à¤§à¥\8dयानसà¥\82à¤\9aà¥\80 à¤¦à¥\87à¤\96नà¥\87",
+       "action-viewmywatchlist": "à¤\85पनà¥\80 à¤§à¥\8dयानसà¥\82à¤\9aà¥\80 à¤¦à¥\87à¤\96à¥\87à¤\82",
        "action-viewmyprivateinfo": "अपनी व्यक्तिगत जानकारी देखने",
        "action-editmyprivateinfo": "अपनी व्यक्तिगत जानकारी बदलने",
        "action-editcontentmodel": "एक पेज की सामग्री मॉडल को संपादित।",
        "activeusers-intro": "यह सक्रिय सदस्यों की सूची है जिन्होंने पिछले $1 {{PLURAL:$1|दिन|दिनों}} में कुछ गतिविधि करी है।",
        "activeusers-count": "$1 {{PLURAL:$1|कार्य}} पिछले $3 {{PLURAL:$3|दिन|दिनों}} में",
        "activeusers-from": "इस अक्षर से शुरू होने वाले सदस्य दिखाएँ:",
-       "activeusers-hidebots": "बॉट छुपाएँ",
-       "activeusers-hidesysops": "प्रबंधक छुपाएँ",
        "activeusers-noresult": "कोई सदस्य नहीं मिले।",
        "activeusers-submit": "सक्रिय सदस्यों को दिखायें",
        "listgrouprights": "सदस्य समूह अधिकार",
        "table_pager_limit": "एक पृष्ठपर $1 आइटम दर्शायें",
        "table_pager_limit_label": "आइटम प्रति पृष्ठ:",
        "table_pager_limit_submit": "जायें",
-       "table_pager_empty": "रिà¥\9bलà¥\8dà¤\9f नहीं",
+       "table_pager_empty": "à¤\95à¥\8bहà¥\80 à¤ªà¤°à¤¿à¤£à¤¾à¤® नहीं",
        "autosumm-blank": "पृष्ठ को खाली किया",
        "autosumm-replace": "पृष्ठ को '$1' से बदल रहा है।",
        "autoredircomment": "[[$1]] को अनुप्रेषित",
        "htmlform-title-not-exists": "$1 नहीं बना है।",
        "htmlform-user-not-exists": "<strong>$1</strong> मौजूद नहीं है।",
        "htmlform-user-not-valid": "<strong>$1</strong> मान्य प्रयोक्ता नाम नहीं है।",
-       "sqlite-has-fts": "$1 पूर्ण पाठ खोज समर्थन के साथ",
-       "sqlite-no-fts": "$1पूर्ण-पाठ खोज समर्थन के बिना",
        "logentry-delete-delete": "$1 ने पृष्ठ $3 {{GENDER:$2|हटा}} दिया",
        "logentry-delete-restore": "$1 ने पृष्ठ $3 को {{GENDER:$2|पुनर्स्थापित}} कर दिया",
        "logentry-delete-event": "$1 ने $3 पृष्ठ की लॉग {{PLURAL:$5|प्रविष्टि|प्रविष्टियों}} की दृश्यता {{GENDER:$2|बदली}}: $4",
        "feedback-external-bug-report-button": "तकनीकी कार्य को जोड़ना",
        "feedback-dialog-title": "प्रतिपुष्टि भेजिए",
        "feedback-dialog-intro": "आप नीचे दिए गए सरल फ़ॉर्म का प्रयोग करके अपनी प्रतिपुष्टि भेज सकते हैं। आपकी टिप्पणी पृष्ठ \"$1\" से आपके सदस्यनाम के आगे जोड़ दी जाएगी।",
-       "feedback-error-title": "त्रुटि",
        "feedback-error1": "त्रुटि: न पहचाना गया परिणाम एपीआई से",
        "feedback-error2": "त्रुटि: संपादन विफल रहा है",
        "feedback-error3": "त्रुटि: एपीआई से कोई प्रतिक्रिया नहीं",
index 9197873..f694e21 100644 (file)
        "yourpasswordagain": "Password fir se type karo:",
        "createacct-yourpasswordagain": "Aapan password ke confirm karo",
        "createacct-yourpasswordagain-ph": "Hame lagged in rahan do",
-       "remembermypassword": "Ii computer pe hamaar login yaad rakho (jaada se jaada $1 {{PLURAL:$1|din|din}} talak)",
        "userlogin-remembermypassword": "Secure connection ke kaam me lao",
        "userlogin-signwithsecure": "Secure connection ke kaam me lao",
        "yourdomainname": "Aap ke domain:",
        "passwordreset-emailelement": "Sadasya ke naam: \n$1\n\nKuchh din ke khatir password: \n$2",
        "passwordreset-emailsentemail": "Agar ii email aap ke account se associated hai tab ek password reset email ke bheja jaai.",
        "passwordreset-emailsentusername": "Agar ii email aap ke username se associated hai tab ek password reset email ke bheja jaai.",
-       "passwordreset-emailsent-capture": "Ek password yaad karae waala e-mail, jiske niche dekhawa jaawe hae, ke bhej dewa gais hae.",
-       "passwordreset-emailerror-capture": "Ek password yaad karae waala e-mail ke banawa gais hae, jiske niche dekhawa jaawe hae, lekin jiske {{GENDER:$2|user}} ke lage bheje nai jawa sake hae: $1",
        "changeemail": "E-mail address ke badlo, nai to, hatao",
        "changeemail-header": "Aapan email ke badle ke khatir ii form ke bharo. Agar aap koi email ke aapan account se nai associate kare mangtaa hai tab form ke submit kare ke time email address ke blank chhorr do.",
-       "changeemail-passwordrequired": "Ii badlao ke confirm kare ke khatir aap ke aapan password ke enter kare ke parri.",
        "changeemail-no-info": "Ii panna ke sidha dekhe ke khaatir, aap ke login kare ke parri.",
        "changeemail-oldemail": "Abhi ke E-mail address:",
        "changeemail-newemail": "Nawaa E-mail address:",
        "undo-nochange": "Janae hae ki badlao ke pahile delete kar dewa gais hae.",
        "undo-summary": "$1 badlao [[Special:Contributions/$2|$2]] se, ke pahile jaise karo ([[User talk:$2|Talk]])",
        "undo-summary-username-hidden": "Hidden sadasya ke badalo $1 ke pahile jaise karo",
-       "cantcreateaccounttitle": "Account nai banae sakta hai",
        "cantcreateaccount-text": "Ii IP address ('''$1''') se nawaa account banae ke [[User:$3|$3]] block kar diis hai.\n\nIske kaaran, jon ki $3 diis hai, ''$2'' hai",
        "cantcreateaccount-range-text": "Nawaa account banae ke IP addresses range <strong>$1</strong>, jisme aap ke IP address (<strong>$4</strong>) hae, ke[[User:$3|$3]] block kar diis hae.\n\n$3 ke kaaran hae <em>$2</em>",
        "viewpagelogs": "Ii panna ke suchi dekho",
        "activeusers-intro": "Ii suchi uu sadasya ke hae jon ki pahile {{PLURAL:$1|din|din}} me kuchh karin hae.",
        "activeusers-count": "$1 haali ke {{PLURAL:$1|badlao}} pichhle {{PLURAL:$3|din}} me",
        "activeusers-from": "Sadasya jon ki hian se suruu hoe hai ke dekhao:",
-       "activeusers-hidebots": "Bots ke lukao",
-       "activeusers-hidesysops": "Administrator log ke lukao",
        "activeusers-noresult": "koi sadasya ke pawa nai gais hai.",
        "listgrouprights": "Sadasya  ke group adhikar",
        "listgrouprights-summary": "Niche likha hai ek suchi hai groups ke jon ki ii wiki me defined hai, aapan  associated access rights ke saathe\n[[{{MediaWiki:Listgrouprights-helppage}}|additional information]] individual rights ke baare me sait hoi.",
        "htmlform-cloner-create": "Aur add karo",
        "htmlform-cloner-delete": "Remove karo",
        "htmlform-cloner-required": "Kamti se kamti ek value ke jaruri hae",
-       "sqlite-has-fts": "$1 with full-text search support",
-       "sqlite-no-fts": "$1 without full-text search support",
        "logentry-delete-delete": "$1 {{GENDER:$2|deleted}} panna $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|restored}} panna $3",
        "logentry-delete-event": "$1 {{GENDER:$2|changed}} visibility of {{PLURAL:$5|a log event|$5 log events}} on $3: $4",
index 0869b55..59ff3f2 100644 (file)
        "userlogin-yourname-ph": "Ipasulod ang imo nga ngalan-taggamit",
        "yourpassword": "Kontra-senyas:",
        "yourpasswordagain": "Suliton ang kontra-senyas:",
-       "remembermypassword": "Dumdumon ang akon pagsulod sa sini nga brawser (para sa indi magsobra $1 {{PLURAL:$1|nga adlaw|nga mga adlaw}})",
        "yourdomainname": "Imo dominyo",
        "password-change-forbidden": "Indi ka mahimo nga makailis sang pasword sa sini nga wiki.",
        "externaldberror": "Mahimo nga may ara sang sala sa pagpamatood sang database ukon wala ka sa lugar nga magbag-o sang imo pang-guha nga akawnt.",
        "passwordreset-emailtext-user": "Ang manuggamit nga si $1 sa {{SITENAME}} nagpangabay sang pahanumdom sang mga detalye sang imo akawnt para sa {{SITENAME}} \n($4). Ang masunod nga {{PLURAL:$3|akawnt|mga akawnt}} sang manuggamit may kabahin sa sini nga adres sang e-mail:\n\n$2\n\n{{PLURAL:$3|Ang ini nga temporaryo nga pasword|Ang mga ini nga temporaryo nga pasword}} indi na magamit sa {{PLURAL:$5|isa ka adlaw|$5 ka adlaw}}.\nKinahanglan mo nga magsulod kag magpili sang bag-o nga pasword subong. Kon lain nga tawo ang nagbuhat sini\nnga pagpangabay, ukon nadumduman mo na ang imo pasword, kag indi mo na kinahanglan nga ini\npaga-ilisan, mahimo mo nga pabay-an ang ini nga pahanumdom kag magpadayon sa paggamit sang imo daan nga pasword.",
        "passwordreset-emailelement": "Gamit-pangalan: \n$1\n\nTemporaryo nga pasword: \n$2",
        "passwordreset-emailsentemail": "May pahanumdom nga e-mail nga ginpadala.",
-       "passwordreset-emailsent-capture": "May e-mail nga nagapahanumdum, nga ginapakita sa idalom.",
-       "passwordreset-emailerror-capture": "May e-mail nga nagapahanumdom nga ginbuhat, nga ginapakita sa idalom, apang ang pagpadala sa manuggamit indi madinalag-on: $1",
        "changeemail": "Ilisan ang E-mail adres",
        "changeemail-header": "Ilisan ang e-mail adres sang akawnt",
        "changeemail-no-info": "Kinahanglan nga nakasulod ka agod nga makadtoan ang ini nga panid sing derecho.",
        "undo-failure": "Ang pag-ilis indi na maliwat pa tungod sang nagakonplikto nga mga pang-tunga nga pag-ilis.",
        "undo-norev": "Ang pag-ilis indii na maliwat pa tungod kay ini wala naga-eksister ukon ginpanas na.",
        "undo-summary": "Liwaton ang pagbag-o sang $1 sa [[Special:Contributions/$2|$2]] ([[User talk:$2|$2]])",
-       "cantcreateaccounttitle": "Indi mabuhat ang akawnt",
        "cantcreateaccount-text": "Ang pagbuhat sang akawnt sang sini nga adres sang IP ('''$1''') ginpunggan ni [[User:$3|$3]].\n\nAng rason nga ginhatag ni $3 amo ang ''$2''",
        "viewpagelogs": "Tan-awon ang mga log para sa sini nga pahina",
        "nohistory": "Wala sang kasaysayan sang pag-ilis sang sini nga panid.",
index 34e2f51..e78335b 100644 (file)
        "userlogin-yourname": "Suradničko ime",
        "userlogin-yourname-ph": "Unesite Vaše suradničko ime",
        "createacct-another-username-ph": "Upišite suradničko ime:",
-       "yourpassword": "Lozinka:",
+       "yourpassword": "Zaporka:",
        "userlogin-yourpassword": "Zaporka",
        "userlogin-yourpassword-ph": "Unesite Vašu zaporku",
        "createacct-yourpassword-ph": "Unesite zaporku",
-       "yourpasswordagain": "Ponovno upišite lozinku",
+       "yourpasswordagain": "Ponovno upišite zaporku",
        "createacct-yourpasswordagain": "Potvrdi zaporku",
        "createacct-yourpasswordagain-ph": "Unesite zaporku ponovno",
        "userlogin-remembermypassword": "Zapamti me",
        "createacct-benefit-body1": "{{PLURAL:$1|uređivanje|uređivanja}}",
        "createacct-benefit-body2": "{{PLURAL:$1|stranica|stranice|stranica}}",
        "createacct-benefit-body3": "{{PLURAL:$1|nedavni suradnik|nedavnih suradnika}}",
-       "badretype": "Unesene lozinke nisu istovjetne.",
+       "badretype": "Unesene zaporke nisu istovjetne.",
        "userexists": "Uneseno suradničko ime već je u upotrebi.\nUnesite neko drugo ime.",
        "loginerror": "Pogrješka u prijavi",
        "createacct-error": "Pogrješka u stvaranju računa",
        "nosuchusershort": "Ne postoji suradnik s imenom \"$1\". Provjerite Vaš unos.",
        "nouserspecified": "Molimo navedite suradničko ime.",
        "login-userblocked": "Ovaj je suradnik blokiran. Prijava nije dopuštena.",
-       "wrongpassword": "Lozinka koju ste unijeli nije ispravna. Pokušajte ponovno.",
-       "wrongpasswordempty": "Niste unijeli lozinku. Pokušajte ponovno.",
+       "wrongpassword": "Zaporka koju ste unijeli nije ispravna. Pokušajte ponovno.",
+       "wrongpasswordempty": "Niste unijeli zaporku. Pokušajte ponovno.",
        "passwordtooshort": "Zaporka mora sadržavati najmanje {{PLURAL:$1|1 znak|$1 znaka|$1 znakova}}.",
-       "password-name-match": "Vaša lozinka mora biti različita od Vašeg suradničkog imena.",
+       "password-name-match": "Vaša zaporka mora biti različita od Vašeg suradničkog imena.",
        "password-login-forbidden": "Uporaba ovog suradničkog imena i lozinke nije dozvoljena.",
-       "mailmypassword": "Pošalji mi novu lozinku",
-       "passwordremindertitle": "{{SITENAME}}: nova lozinka.",
-       "passwordremindertext": "Netko je (vjerojatno Vi, s IP adrese $1) zatražio novu lozinku za projekt {{SITENAME}} ($4).\nPrivremena lozinka za suradnika \"$2\" je postavljena na \"$3\".\nUkoliko ste to Vi učinili, molimo Vas da se prijavite i promijenite lozinku.\nPrivremena lozinka vrijedi još {{PLURAL:$5|$5 dan|$5 dana}}.\n\nUkoliko niste zatražili novu lozinku, ili ste se sjetili stare lozinke i\nviše ju ne želite promijeniti, slobodno zanemarite ovu poruku i nastavite\nkoristiti staru lozinku.",
+       "mailmypassword": "Pošalji mi novu zaporku",
+       "passwordremindertitle": "{{SITENAME}}: nova zaporka.",
+       "passwordremindertext": "Netko je (vjerojatno Vi, s IP adrese $1) zatražio novu zaporku za projekt {{SITENAME}} ($4).\nPrivremena zaporka za suradnika \"$2\" je postavljena na \"$3\".\nUkoliko ste to Vi učinili, molimo Vas da se prijavite i promijenite zaporku.\nPrivremena zaporka vrijedi još {{PLURAL:$5|$5 dan|$5 dana}}.\n\nUkoliko niste zatražili novu zaporku, ili ste se sjetili stare zaporke i\nviše ju ne želite promijeniti, slobodno zanemarite ovu poruku i nastavite\nkoristiti staru zaporku.",
        "noemail": "Suradnik \"$1\" nema zapisanu e-mail adresu.",
        "noemailcreate": "Morate navesti važeću e-mail adresu",
        "passwordsent": "Nova je zaporka poslana na adresu elektroničke pošte suradnika \"$1\"",
-       "blocked-mailpassword": "Vašoj IP adresi je blokirano uređivanje stranica, a da bi se spriječila nedopuštena radnja, mogućnost zahtijevanja nove lozinke je također onemogućena.",
+       "blocked-mailpassword": "Vašoj IP adresi je blokirano uređivanje stranica, a da bi se spriječila nedopuštena radnja, mogućnost zahtijevanja nove zaporke je također onemogućena.",
        "eauthentsent": "Na navedenu adresu poslana je e-poruka s potvrdom.\nPrije nego što pošaljemo daljnje poruke, molimo Vas otvorite e-poruku i slijedite u njemu sadržana uputstva kako biste potvrdili da je adresa e-pošte zaista Vaša.",
        "throttled-mailpassword": "Već Vam je poslan e-mail za promjenu zaporke, u {{PLURAL:$1|posljednjih sat vremena|posljednja $1 sata|posljednjih $1 sati}}.\nDa bi spriječili zloupotrebu, moguće je poslati samo jedan e-mail za promjenu zaporke {{PLURAL:$1|svakih sat vremena|svaka $1 sata|svakih $1 sati}}.",
        "mailerror": "Pogrješka pri slanju e-pošte: $1",
        "accountcreated": "Suradnički račun otvoren",
        "accountcreatedtext": "Suradnički je račun [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) stvoren.",
        "createaccount-title": "Otvaranje suradničkog računa za {{SITENAME}}",
-       "createaccount-text": "Netko je stvorio suradnički račun s Vašom adresom elektronske pošte na {{SITENAME}} ($4) nazvan \"$2\", s lozinkom \"$3\". Trebali biste se prijaviti i odmah promijeniti lozinku.\n\nMožete zanemariti ovu poruku ako je suradnički račun stvoren nenamjerno.",
+       "createaccount-text": "Netko je stvorio suradnički račun s Vašom adresom e-pošte na {{SITENAME}} ($4) nazvan \"$2\", sa zaporkom \"$3\". Trebali biste se prijaviti i odmah promijeniti zaporku.\n\nMožete zanemariti ovu poruku ako je suradnički račun stvoren nenamjerno.",
        "login-throttled": "Nedavno ste se previše puta pokušali prijaviti.\nMolimo Vas pričekajte $1 prije nego što pokušate ponovno.",
        "login-abort-generic": "Vaša je prijava bila neuspješna te je stoga prekinuta.",
        "login-migrated-generic": "Vaš se suradnički račun preselio, te Vaše suradničko ime više ne postoji u ovom wikiju.",
        "user-mail-no-addy": "Pokušaj slanja e-maila bez e-mail adrese.",
        "user-mail-no-body": "Pokušali ste poslati e-mail bez sadržaja ili s prekratkim sadržajem.",
        "changepassword": "Promjena zaporke",
-       "resetpass_announce": "Da biste završili proces mijenjanja lozinke, upišite \nnovu lozinku.",
-       "resetpass_header": "Promijeni lozinku računa",
-       "oldpassword": "Stara lozinka",
-       "newpassword": "Nova lozinka",
-       "retypenew": "Ponovno unesite lozinku",
-       "resetpass_submit": "Postavite lozinku i prijavite se",
+       "resetpass_announce": "Da biste završili proces mijenjanja zaporke, upišite \nnovu zaporku.",
+       "resetpass_header": "Promijeni zaporku računa",
+       "oldpassword": "Stara zaporka",
+       "newpassword": "Nova zaporka",
+       "retypenew": "Ponovno unesite zaporku",
+       "resetpass_submit": "Postavite zaporku i prijavite se",
        "changepassword-success": "Zaporka je uspješno postavljena!",
        "changepassword-throttled": "Nedavno ste se previše puta pokušali prijaviti.\nMolimo Vas pričekajte $1 prije nego što pokušate ponovno.",
-       "botpasswords": "Lozinke botova",
-       "botpasswords-disabled": "Lozinke botova su onemogućene.",
-       "botpasswords-no-central-id": "Za uporabu lozinki botova, morate biti prijavljeni na središnji račun.",
-       "botpasswords-existing": "Postojeće lozinke botova",
-       "botpasswords-createnew": "Stvorite novu lozinku bota",
-       "botpasswords-editexisting": "Uredite postojeću lozinku bota",
+       "botpasswords": "Zaporke botova",
+       "botpasswords-disabled": "Zaporke botova su onemogućene.",
+       "botpasswords-no-central-id": "Za uporabu zaporki botova, morate biti prijavljeni na središnji račun.",
+       "botpasswords-existing": "Postojeće zaporke botova",
+       "botpasswords-createnew": "Stvorite novu zaporku bota",
+       "botpasswords-editexisting": "Uredite postojeću zaporku bota",
        "botpasswords-label-appid": "Ime bota:",
        "botpasswords-label-create": "Stvori",
        "botpasswords-label-update": "Ažuriraj",
        "botpasswords-bad-appid": "Ime bota \"$1\" nije valjano.",
        "botpasswords-insert-failed": "Nije moguće dodavanje imena bota \"$1\". Možda je već dodano?",
        "botpasswords-update-failed": "Nije moguće ažurirati bot s imenom \"$1\". Možda je izbrisan?",
-       "resetpass_forbidden": "Lozinka ne može biti promijenjena",
+       "resetpass_forbidden": "Zaporka ne može biti promijenjena",
        "resetpass-no-info": "Morate biti prijavljeni da biste izravno pristupili ovoj stranici.",
-       "resetpass-submit-loggedin": "Promijeni lozinku",
+       "resetpass-submit-loggedin": "Promijeni zaporku",
        "resetpass-submit-cancel": "Odustani",
-       "resetpass-wrong-oldpass": "Pogrešna privremena ili trenutačna lozinka.\nMožda ste već uspješno promijenili Vašu lozinku ili ste zatražili novu privremenu lozinku.",
+       "resetpass-wrong-oldpass": "Pogrešna privremena ili trenutačna zaporka.\nMožda ste već uspješno promijenili Vašu zaporku ili ste zatražili novu privremenu zaporku.",
        "resetpass-recycled": "Molimo Vas, promijenite zaporku u nešto drugačiju od Vaše trenutačne zaporke.",
        "resetpass-temp-emailed": "Prijavljeni ste s privremenom zaporkom prijavljenom putem e-poruke.\nDa biste dovršili prijavu morate postaviti novu zaporku.",
-       "resetpass-temp-password": "Privremena lozinka:",
+       "resetpass-temp-password": "Privremena zaporka:",
        "resetpass-abort-generic": "Poništena je promjena zaporke.",
        "resetpass-expired": "Istekla Vam je valjanost zaporke. Molimo Vas, potvrdite novu zaporku za prijavu.",
        "resetpass-expired-soft": "Istekla vam je valjanost zaporke i trebate ju promijeniti. Molimo odaberite novu zaporku ili pritisnite na \"{{int:authprovider-resetpass-skip-label}}\", za kasniju promjenu.",
        "resetpass-validity-soft": "Zaporka Vam ne vrijedi: $1\n\nMolimo odaberite novu zaporku ili pritisnite na \"{{int:authprovider-resetpass-skip-label}}\", za kasniju promjenu.",
-       "passwordreset": "Ponovno postavi lozinku",
+       "passwordreset": "Ponovno postavi zaporku",
        "passwordreset-text-one": "Ispunite ovaj obrazac ako želite ponovno postaviti Vašu zaporku.",
        "passwordreset-text-many": "{{PLURAL:$1|Ispunite jedno od polja da biste dobili privremenu zaporku e-poštom.}}",
        "passwordreset-disabled": "Poništavanje lozinke je onemogućeno na ovom wikiju.",
        "passwordreset-capture-help": "Ako označite ovu kućicu, e-poruka s privremenom lozinkom će biti prikazana i poslana korisniku.",
        "passwordreset-email": "E-mail adresa:",
        "passwordreset-emailtitle": "Pojedinosti o računu na {{SITENAME}}",
-       "passwordreset-emailtext-ip": "Netko (vjerojatno Vi, s IP adrese $1) zatražio je podsjetnik za Vaše detalje računa\nza {{SITENAME}} ($4). Sljedeći {{PLURAL:$3|račun suradnika je|računi suradnika su}}\npovezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena lozinka|Ove privremene lozinke}} će isteći u {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu lozinku. Ukoliko je netko drugi napravio ovaj\nzahtjev, ili ako ste sjeti Vaše izvorne lozinke, a vi je više ne želite promijeniti, \nmožete zanemariti ovu poruku i nastavite koristiti staru lozinku.",
-       "passwordreset-emailtext-user": "Suradnik $1 na {{SITENAME}} zatražio podsjetnik o pojedinostima vašeg računa za {{SITENAME}}\n($4). Sljedeći {{PLURAL:$3|račun suradnika je|računi suradnika su}} povezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena lozinka|Ove privremene lozinke}} će isteći u {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu lozinku. Ukoliko je netko drugi napravio ovaj\nzahtjev, ili ako ste sjeti Vaše izvorne lozinke, a vi je više ne želite promijeniti, \nmožete zanemariti ovu poruku i nastavite koristiti staru lozinku.",
-       "passwordreset-emailelement": "Suradničko ime: \n$1\n\nPrivremena lozinka: \n$2",
+       "passwordreset-emailtext-ip": "Netko (vjerojatno Vi, s IP adrese $1) zatražio je podsjetnik za Vaše detalje računa\nza {{SITENAME}} ($4). Sljedeći {{PLURAL:$3|račun suradnika je|računi suradnika su}}\npovezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena zaporka|Ove privremene zaporke}} će isteći u {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu zaporku. Ukoliko je netko drugi napravio ovaj\nzahtjev, ili ako ste se sjetili Vaše izvorne zaporke, a više je ne želite promijeniti, \nmožete zanemariti ovu poruku i nastavite koristiti staru zaporku.",
+       "passwordreset-emailtext-user": "Suradnik $1 na {{SITENAME}} zatražio je podsjetnik o pojedinostima vašeg računa za {{SITENAME}}\n($4). Sljedeći {{PLURAL:$3|račun suradnika je|računi suradnika su}} povezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena zaporka|Ove privremene zaporke}} će isteći u {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu zaporku. Ukoliko je netko drugi napravio ovaj\nzahtjev, ili ako ste se sjetili Vaše izvorne zaporke, a više je ne želite promijeniti, \nmožete zanemariti ovu poruku i nastavite koristiti staru zaporku.",
+       "passwordreset-emailelement": "Suradničko ime: \n$1\n\nPrivremena zaporka: \n$2",
        "passwordreset-emailsentemail": "Ako je ova adresa povezana s Vašim suradničkim računom, na nju će biti poslan podsjetnik na zaporku.",
        "changeemail": "Promijeni ili izbriši e-mail adresu",
        "changeemail-header": "Promijeni adresu e-pošte računa",
        "loginreqtitle": "Nužna prijava",
        "loginreqlink": "prijavite se",
        "loginreqpagetext": "Da biste vidjeli ostale stranice, molimo $1.",
-       "accmailtitle": "Lozinka poslana.",
-       "accmailtext": "Nova lozinka za [[User talk:$1|$1]] je poslana na $2.\n\nNakon prijave, lozinka za ovaj novi račun može biti promijenjena na stranici ''[[Special:ChangePassword|promijeni lozinku]]'' nakon prijave.",
+       "accmailtitle": "Zaporka poslana.",
+       "accmailtext": "Nova zaporka za [[User talk:$1|$1]] je poslana na $2.\n\nNakon prijave, zaporka za ovaj novi račun može biti promijenjena na stranici ''[[Special:ChangePassword|promijeni zaporku]]'' nakon prijave.",
        "newarticle": "(Novo)",
        "newarticletext": "Došli ste na stranicu koja još ne postoji.\nAko želite stvoriti tu stranicu, počnite tipkati u prozor ispod ovog teksta (pogledajte [$1 stranicu za pomoć]).\nAko ste ovamo dospjeli slučajno, kliknite gumb '''natrag''' (back) u svom pregledniku.",
        "anontalkpagetext": "----''Ovo je stranica za razgovor s neprijavljenim suradnikom koji još nije otvorio suradnički račun ili se njime ne koristi. Zbog toga se moramo služiti brojčanom IP adresom kako bismo ga identificirali. Takvu adresu često može dijeliti više ljudi. Ako ste neprijavljeni suradnik i smatrate da su Vam upućeni irelevantni komentari, molimo Vas da [[Special:CreateAccount|otvorite suradnički račun]] ili [[Special:UserLogin|se prijavite]] te tako u budućnosti izbjegnete zamjenu s drugim neprijavljenim suradnicima.''",
        "prefs-watchlist-edits-max": "Maksimalni broj: 1000",
        "prefs-watchlist-token": "Token popisa praćenja:",
        "prefs-misc": "Razno",
-       "prefs-resetpass": "Promijeni lozinku",
+       "prefs-resetpass": "Promijeni zaporku",
        "prefs-changeemail": "promijeni adresu e-pošte",
        "prefs-setemail": "Postavite E-mail adresu",
        "prefs-email": "Mogućnosti e-maila",
        "upload-copy-upload-invalid-domain": "Kopije postavljenih datoteka nisu dostupne s ove domene.",
        "upload-dialog-title": "Postavi datoteku",
        "upload-dialog-button-cancel": "Odustani",
+       "upload-dialog-button-back": "Natrag",
        "upload-dialog-button-done": "Gotovo",
        "upload-dialog-button-save": "Spremi",
        "upload-dialog-button-upload": "Postavi",
        "booksources-search": "Traži",
        "booksources-text": "Ovdje je popis vanjskih poveznica na internetskim stranicama koje prodaju nove i rabljene knjige, ali mogu sadržavati i ostale podatke o knjigama koje tražite:",
        "booksources-invalid-isbn": "Čini se da dani ISBN nije valjan; provjerite greške kopirajući iz izvornika.",
+       "magiclink-tracking-isbn": "Stranice s čarobnim ISBN poveznicama",
+       "magiclink-tracking-isbn-desc": "Ova stranica rabi čarobne ISBN poveznice. Za njihovu migraciju vidi [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
        "specialloguserlabel": "Suradnik:",
        "speciallogtitlelabel": "Cilj (naslov ili suradnik):",
        "log": "Evidencije",
        "activeusers-intro": "Ovo je popis suradnika koji su napravili neku aktivnost u {{PLURAL:$1|posljednji $1 dan|posljednja $1 dana|posljednjih $1 dana}}.",
        "activeusers-count": "{{PLURAL:$1|nedavna $1 izmjena|nedavne $1 izmjene|nedavnih $1 izmjena}} u {{PLURAL:$3|posljednji $3 dan|posljednja $3 dana|posljednjih $3 dana}}",
        "activeusers-from": "Prikaži suradnike počevši od:",
-       "activeusers-hidebots": "Sakrij botove",
-       "activeusers-hidesysops": "Sakrij administratore",
        "activeusers-noresult": "Niti jedan suradnik nije nađen.",
        "activeusers-submit": "Prikaz aktivnih suradnika",
        "listgrouprights": "Prava suradničkih skupina",
        "emailuserfooter": "Ovu je e-poruku {{GENDER:$1|poslao suradnik|poslala suradnica}} $1 {{GENDER:$2|suradniku $2|suradnici $2}} uporabom mogućnosti \"{{int:emailuser}}\" s projekta {{SITENAME}}.",
        "usermessage-summary": "Ostavljanje poruke sustava.",
        "usermessage-editor": "Uređivač sistemskih poruka",
-       "watchlist": "Moj popis praćenja",
+       "watchlist": "Popis praćenja",
        "mywatchlist": "Popis praćenja",
        "watchlistfor2": "Za $1 $2",
        "nowatchlist": "Na Vašem popisu praćenja nema nijednog članka.",
        "wlshowhideanons": "neprijavljene suradnike",
        "wlshowhidepatr": "ophođena uređivanja",
        "wlshowhidemine": "moje promjene",
+       "wlshowhidecategorization": "kategorizaciju stranica",
        "watchlist-options": "Izbornik popisa praćenja",
        "watching": "Pratim...",
        "unwatching": "Prestajem pratiti...",
        "export-download": "Ponudi opciju snimanja u datoteku",
        "export-templates": "Uključi predloške",
        "export-pagelinks": "Uključi povezane stranice do dubine od:",
-       "allmessages": "Sve sistemske poruke",
+       "allmessages": "Sve poruke sustava",
        "allmessagesname": "Ime",
        "allmessagesdefault": "Prvotni tekst",
        "allmessagescurrent": "Trenutačni tekst",
        "pageinfo-robot-index": "Stranicu je moguće indeksirati",
        "pageinfo-robot-noindex": "Indeksiranje stranice onemogućeno",
        "pageinfo-watchers": "Broj pratitelja stranice",
+       "pageinfo-visiting-watchers": "Broj suradnika pratitelja ove stranice koji su posjetili nedavne promjene",
        "pageinfo-few-watchers": "Manje od $1 {{PLURAL:$1|suradnika koji prate ovu stranicu|suradnika koji prate ovu stranicu}}",
        "pageinfo-redirects-name": "Broj preusmjeravanja na ovu stranicu",
        "pageinfo-subpages-name": "Podstranice",
        "htmlform-cloner-create": "Dodaj još",
        "htmlform-cloner-delete": "Ukloni",
        "htmlform-cloner-required": "Potrebna je barem jedna vrijednost.",
+       "htmlform-date-placeholder": "GGGG-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "GGGG-MM-DD HH:MM:SS",
+       "htmlform-time-invalid": "Unesena vrijednost nije prepoznati format vremena. Pokušajte koristiti format HH:MM:SS.",
+       "htmlform-datetime-toohigh": "Uneseni datum i vrijeme su veći od $1",
        "logentry-delete-delete": "$1 je {{GENDER:$2|obrisao|obrisala}} stranicu $3",
        "logentry-delete-restore": "$1 je {{GENDER:$2|vratio|vratila}} stranicu $3",
        "logentry-delete-event": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost {{PLURAL:$5|zapisa u evidenciji|$5 zapisa u evidenciji}} na $3: $4",
        "feedback-external-bug-report-button": "Arhiviraj tehnički zadatak",
        "feedback-dialog-title": "Slanje povratnih informacija",
        "feedback-dialog-intro": "Da biste poslali povratnu informaciju, rabite jednostavan obrazac. Vaš će komentar biti dodan na stranici \"$1\" s Vašim suradničkim imenom.",
-       "feedback-error-title": "Pogrješka",
        "feedback-error1": "Pogreška: neprepoznati rezultat API funkcije",
        "feedback-error2": "Pogreška: uređivanje nije uspjelo",
        "feedback-error3": "Pogreška: nema odgovora API funkcije",
        "mw-widgets-titleinput-description-new-page": "stranica još ne postoji",
        "mw-widgets-titleinput-description-redirect": "preusmjeravanje na $1",
        "log-action-filter-block": "Vrsta blokiranja:",
+       "log-action-filter-delete": "Vrsta brisanja:",
+       "log-action-filter-import": "Vrsta uvoza:",
+       "log-action-filter-move": "Vrsta premještanja:",
        "log-action-filter-newusers": "Način stvaranja računa:",
        "log-action-filter-patrol": "Vrsta pregledavanja:",
+       "log-action-filter-protect": "Vrsta zaštićivanja:",
+       "log-action-filter-rights": "Vrsta promjene prava:",
        "log-action-filter-upload": "Vrsta postavljanja:",
        "log-action-filter-all": "sve",
        "log-action-filter-block-block": "blokiranje",
        "log-action-filter-block-reblock": "promjena blokiranja",
        "log-action-filter-block-unblock": "deblokiranje",
+       "log-action-filter-delete-delete": "brisanje stranice",
+       "log-action-filter-delete-restore": "vraćanje izbrisane stranice",
+       "log-action-filter-delete-event": "brisanje evidencije",
+       "log-action-filter-delete-revision": "brisanje izmjene",
+       "log-action-filter-import-interwiki": "uvoz između wikija",
+       "log-action-filter-import-upload": "uvoz s XML postavljanjem",
+       "log-action-filter-move-move": "premještanje bez prepisivanja preko preusmjeravanja",
+       "log-action-filter-move-move_redir": "premještanje s prepisivanjem preko preusmjeravanja",
        "log-action-filter-newusers-create": "stvorio anonimni suradnik",
        "log-action-filter-newusers-create2": "stvorio registrirani suradnik",
        "log-action-filter-newusers-autocreate": "automatski stvoren",
        "log-action-filter-newusers-byemail": "stvoren lozinkom poslanom na e-poštu",
-       "log-action-filter-patrol-patrol": "Ručno pregledavanje",
-       "log-action-filter-patrol-autopatrol": "Automatsko pregledavanje",
+       "log-action-filter-patrol-patrol": "ručno ophođeno",
+       "log-action-filter-patrol-autopatrol": "automatsko pregledavanje",
+       "log-action-filter-protect-protect": "zaštićivanje",
+       "log-action-filter-protect-modify": "promjena zaštićivanja",
+       "log-action-filter-protect-unprotect": "uklanjanje zaštite",
+       "log-action-filter-protect-move_prot": "prenosiva zaštita",
+       "log-action-filter-rights-rights": "ručna promjena",
+       "log-action-filter-rights-autopromote": "automatska promjena",
        "log-action-filter-upload-upload": "novo postavljanje",
        "log-action-filter-upload-overwrite": "ponovno postavljanje",
        "changecredentials": "Promjena vjerodajnica",
index 70d984b..6bc52f5 100644 (file)
        "yourpasswordagain": "Passwort repetiere:",
        "createacct-yourpasswordagain": "Passwort bestätiche",
        "createacct-yourpasswordagain-ph": "Geb das Passwort erneit ren",
-       "remembermypassword": "Mit dem Browser dauerhaft oongemeldet bleiwe (maximal $1 {{PLURAL:$1|Tooch|Tooche}})",
        "userlogin-remembermypassword": "Oongemeldt bleiwe",
        "userlogin-signwithsecure": "Sichre Verbinnung verwenne",
        "yourdomainname": "Dein Domain:",
        "passwordreset-emailtext-user": "Benutzer $1 bei {{SITENAME}} hot en Zurücksetzung von dein Passwort bei {{SITENAME}} oongefordert ($4). {{PLURAL:$3|Das follichend Benutzerkonto ist|Die follichend Benutzerkonte sind}} mit der E-Mail-Adress verknüpft:\n\n$2\n\n{{PLURAL:$3|Das temporär Passwort looft|Die temporäre Passwörter loofe}} innerhalb von {{PLURAL:$5|em Tooch|$5 Tooche}} ab. Du sollst dich oonmelde und en neies Passwort vergewe. Falls jemand annres die Oonfroch getäticht hot orrer du dich wieder an den ursprüngliches Passwort erinnre kannst und das net ännre möchst, kannst du die Nachricht ignoriere und weiterhin dein altes Passwort benutze.",
        "passwordreset-emailelement": "Benutzernoome: \n$1\n\nTemporäres Passwort: \n$2",
        "passwordreset-emailsentemail": "En Passwortzurücksetzung-E-Mail woard versandt.",
-       "passwordreset-emailsent-capture": "En Passwortzurücksetzung-E-Mail woard versandt, die unne oongezeicht weard.",
-       "passwordreset-emailerror-capture": "Die unne oongezeichte Passwortzurücksetzungs-E-Mail woard generiert, awer der Versand an {{GENDER:$2|den Benutzer|die Benutzrin}} ist gescheitert: $1",
        "changeemail": "E-Mail-Adress ännre",
        "changeemail-header": "E-Mail-Adress ännre",
        "changeemail-no-info": "Du musst dich oonmelde, um uff die Seit direkt zuzugreife.",
        "undo-nochange": "Anscheinnd woard die Beoorbeitung schon rückgängich gemacht.",
        "undo-summary": "Ändrung $1 von [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskussion]]) rückgängich gemacht.",
        "undo-summary-username-hidden": "Ännrung $1 von en versteckte Benutzer rückgängich gemacht.",
-       "cantcreateaccounttitle": "Das Benutzerkonto kann net erstellt sin",
        "cantcreateaccount-text": "Die Erstellung von en Benutzerkonto raus von der IP-Adresse '''($1)''' woor doorrich [[User:$3|$3]] gesperrt.\n\nGrund der Sperr: ''$2''",
        "cantcreateaccount-range-text": "Das Erstell von Benutzerkonte von IP-Adressen im Bereich <strong>$1</strong>, wo dein IP-Adress (<strong>$4</strong>) enthält, woor von [[User:$3|$3]] gesperrt.\n\nDer oongebne Grund von $3 laut: <em>$2</em>",
        "viewpagelogs": "Logbücher von der Seit oonzeiche",
        "activeusers-intro": "Das ist en List von Benutzer, wo innerhalleb {{PLURAL:$1|vom letzte Tooch|von der letzte $1 Tooch}} Aktivitäte uffwies.",
        "activeusers-count": "$1 {{PLURAL:$1|Aktion|Aktione}} in den {{PLURAL:$3|letzte 24 Stunne|vergangene $3 Tooche}}",
        "activeusers-from": "Zeich Benutzer ab:",
-       "activeusers-hidebots": "Bots ausblende",
-       "activeusers-hidesysops": "Administratore ausblende (verstecke)",
        "activeusers-noresult": "Kene Benutzer gefund.",
        "listgrouprights": "Benutzergrupperechte",
        "listgrouprights-summary": "Das ist ein List vom in dem Wiki definierte Benutzergruppe und ehre damit verbündne Rechte.\nZusätzliche Informatione üwer einzelne Rechte könne [[{{MediaWiki:Listgrouprights-helppage}}|hier]] gefund sin.",
        "htmlform-cloner-create": "Weitre dozu tun",
        "htmlform-cloner-delete": "Entferne",
        "htmlform-cloner-required": "Es ist minschtens en Weart erforderlich.",
-       "sqlite-has-fts": "Version $1 mit Unnerstützung für die Volltextsuch",
-       "sqlite-no-fts": "Version $1 ohne Unnerstützung für die Volltextsuch",
        "logentry-delete-delete": "$1 {{GENDER:$2|löschte}} Seit $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|stellte}} Seit $3 wieder her",
        "logentry-delete-event": "$1 {{GENDER:$2|ännerte}}  die Sichtbarkeit {{PLURAL:$5|von ein Logbucheintrooch|von $5 Logbucheinträch}} uff $3: $4",
        "feedback-bugornote": "Soweit du ganz detalhiert en technisches Problem beschreiben möchst, meld bittschön [$1 en Fehler].\nAnnerfalls kannst du ooch das do unne stehende ganz enfache Formular benutze. Dein Kommentar weard, zusammer mit deinem Benutzernoome und der Version von der von dir verwenndt Webbrowsers sowie Betriebssystems, uff der Seit \"[$3 $2]\" hinzugefücht.",
        "feedback-cancel": "Abbreche",
        "feedback-close": "Erledicht (fertich)",
-       "feedback-error-title": "Fehler",
        "feedback-error1": "Fehler: Unbekanntes Ergebnis von der API",
        "feedback-error2": "Fehler: Beoorbeitung gescheitert",
        "feedback-error3": "Fehler: Ken Antwort von der API",
index 007eada..558b166 100644 (file)
        "yourpasswordagain": "Hesło znowa zapodać:",
        "createacct-yourpasswordagain": "Hesło wobkrućić",
        "createacct-yourpasswordagain-ph": "Zapodaj hesło hišće raz",
-       "remembermypassword": "Na tutym ličaku přizjewjeny wostać (za maksimalnje $1 {{PLURAL:$1|dźeń|dnjej|dny|dnjow}})",
        "userlogin-remembermypassword": "Přizjewjeny wostać",
        "userlogin-signwithsecure": "Wěsty zwisk wužiwać",
        "yourdomainname": "Twoja domejna:",
        "activeusers-intro": "To je lisćina wužiwarjow, kotřiž běchu aktiwni za {{PLURAL:$1|posledni dźeń|poslednjej $1 dnjej|poslednje $1 dny|poslednich $1 dnjow}}:",
        "activeusers-count": "$1 {{PLURAL:$1|akcija|akciji|akcije|akcijow}} w {{PLURAL:$3|zańdźenej dnju|zańdźenymaj $3 dnjomaj|zańdźenych $3 dnjach}}",
        "activeusers-from": "Wužiwarjow zwobraznić, započinajo z:",
-       "activeusers-hidebots": "Boćiki schować",
-       "activeusers-hidesysops": "Administratorow schować",
        "activeusers-noresult": "Žani wužiwarjo namakani.",
        "listgrouprights": "Prawa wužiwarskeje skupiny",
        "listgrouprights-summary": "Slěduje lisćina wužiwarskich skupinow na tutej wikiju z jich wotpowědnymi přistupnymi prawami. Tu móžeš [[{{MediaWiki:Listgrouprights-helppage}}|dalše informacije]] wo jednotliwych prawach namakać.",
        "htmlform-cloner-create": "Wjace přidać",
        "htmlform-cloner-delete": "Wotstronić",
        "htmlform-cloner-required": "Znjamjeńša jedna hódnota je trěbna.",
-       "sqlite-has-fts": "$1 połnotekstowe pytanje podpěruje.",
-       "sqlite-no-fts": "$1 połnotekstowe pytanje njepodpěruje",
        "logentry-delete-delete": "$1 je stronu $3 {{GENDER:$1|zhašał|zhašała}}",
        "logentry-delete-restore": "$1 je stronu $3 {{GENDER:$1wobnowił|wobnowiła}}",
        "logentry-delete-event": "$1 je widźomnosć {{PLURAL:$5|protokoloweho zapiska|$5 protokoloweju zapiskow|$5 protokolowych zapiskow}} na $3 {{GENDER:$2|změnił|změniła}}: $4",
        "feedback-close": "Dokónčeny",
        "feedback-external-bug-report-button": "Techniski nadawk zapodać",
        "feedback-dialog-title": "Komentar pósłać",
-       "feedback-error-title": "Zmylk",
        "feedback-error1": "Zmylk: Njepřipóznaty wuslědk wot API",
        "feedback-error2": "Zmylk: Wobdźěłanje je so njeporadźiło",
        "feedback-error3": "Zmylk: Žana wotmołwa wot API",
index 17df2d7..edb8a7c 100644 (file)
        "yourpasswordagain": "Mete mopas ou an ankò :",
        "createacct-yourpasswordagain": "Konfime modpas la",
        "createacct-yourpasswordagain-ph": "Rantre modpas la ankò",
-       "remembermypassword": "Sonje mopas mwen an nan òdinatè mwen an (pou yon maximum de $1 {{PLURAL:$1|jou|jou}})",
        "userlogin-remembermypassword": "Pa dekonekte m",
        "userlogin-signwithsecure": "Sèvi ak yon koneksyon sekirize",
        "yourdomainname": "Domèn ou an",
index cdd7d39..ce3aaba 100644 (file)
        "passwordreset-nocaller": "A hívó megadása kötelező",
        "passwordreset-nosuchcaller": "A hívó nem létezik: $1",
        "passwordreset-ignored": "A jelszó-visszaállítás nem lett kezelve. Talán nincs konfigurálva szolgáltató?",
-       "passwordreset-invalideamil": "Érvénytelen e-mail cím",
+       "passwordreset-invalidemail": "Érvénytelen e-mail cím",
        "passwordreset-nodata": "Se felhasználónevet, sem e-mail-címet nem adtál meg",
        "changeemail": "E-mail cím megváltoztatása vagy eltávolítása",
        "changeemail-header": "Töltsd ki ezt az űrlapot az e-mail-címed megváltoztatásához. Ha nem szeretnél semmilyen e-mail-címet kapcsolni a fiókodhoz, hagyd üresen az új e-mail-cím mezőjét az űrlap elküldésekor.",
        "editpage-cannot-use-custom-model": "Ennek a lapnak a tartalommodellje nem változtatható.",
        "longpageerror": "'''HIBA: Az általad beküldött szöveg {{PLURAL:$1|egy kilobájt|$1 kilobájt}} hosszú, ami több az engedélyezett {{PLURAL:$2|egy kilobájtnál|$2 kilobájtnál}}.\nA szerkesztést nem lehet elmenteni.'''",
        "readonlywarning": "<strong>FIGYELMEZTETÉS: A wiki adatbázisát karbantartás miatt zárolták, ezért most nem fogod tudni elmenteni a szerkesztéseidet!</strong>\nA lap szövegét másold egy szövegfájlba, amit később felhasználhatsz!\n\nAz adatbázist lezáró rendszeradminisztrátor az alábbi magyarázatot adta: $1",
-       "protectedpagewarning": "'''Figyelem: Ez a lap le van védve, így csak adminisztrátori jogosultságokkal rendelkező szerkesztők módosíthatják.'''\nA legutolsó ide vonatkozó naplóbejegyzés alább látható:",
+       "protectedpagewarning": "<strong>Figyelem: Ez a lap védett, így csak adminisztrátori jogosultságokkal rendelkező szerkesztők módosíthatják.</strong>\nA legutolsó ide vonatkozó naplóbejegyzés alább látható:",
        "semiprotectedpagewarning": "'''Megjegyzés:''' ez a lap védett, így regisztrálatlan vagy újonnan regisztrált szerkesztők nem módosíthatják.",
        "cascadeprotectedwarning": "<strong>Figyelem:</strong> ez a lap le van zárva, csak adminisztrátorok szerkeszthetik, mert a következő kaszkádvédelemmel ellátott {{PLURAL:$1|lapon|lapokon}} be van illesztve:",
        "titleprotectedwarning": "'''Figyelem: Ez a lap le van védve, így csak a [[Special:ListGroupRights|megfelelő jogosultságokkal]] rendelkező szerkesztők hozhatják létre.'''\nA legutolsó ide vonatkozó naplóbejegyzés alább látható:",
        "action-createpage": "ennek a lapnak a létrehozása",
        "action-createtalk": "vitalap létrehozása",
        "action-createaccount": "felhasználói fiók elkészítése",
+       "action-autocreateaccount": "külső fiók automatikus létrehozása",
        "action-history": "laptörténet megtekintése",
        "action-minoredit": "szerkesztés aprónak jelölése",
        "action-move": "lap átnevezése",
        "newsectionsummary": "/* $1 */ (új szakasz)",
        "rc-enhanced-expand": "Részletek megjelenítése",
        "rc-enhanced-hide": "Részletek elrejtése",
-       "rc-old-title": "eredetileg létrehozott \" $1 \"",
+       "rc-old-title": "eredetileg „$1” címen létrehozva",
        "recentchangeslinked": "Kapcsolódó változtatások",
        "recentchangeslinked-feed": "Kapcsolódó változtatások",
        "recentchangeslinked-toolbox": "Kapcsolódó változtatások",
        "upload-dialog-disabled": "Fájl feltöltés ezzel a párbeszéddel tiltott ezen a wikin.",
        "upload-dialog-title": "Fájl feltöltése",
        "upload-dialog-button-cancel": "Mégse",
+       "upload-dialog-button-back": "Vissza",
        "upload-dialog-button-done": "Kész",
        "upload-dialog-button-save": "Mentés",
        "upload-dialog-button-upload": "Feltöltés",
        "apisandbox-results-fixtoken-fail": "A(z) „$1” token lekérése sikertelen.",
        "apisandbox-alert-page": "Hibás mezők vannak ezen a lapon.",
        "apisandbox-alert-field": "Ennek a mezőnek az értéke érvénytelen.",
+       "apisandbox-continue": "Folytatás",
+       "apisandbox-continue-clear": "Törlés",
+       "apisandbox-continue-help": "A {{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries folytatja] az utolsó kérést; a {{int:apisandbox-continue-clear}} törli a folytatáshoz kapcsolódó paramétereket.",
        "booksources": "Könyvforrások",
        "booksources-search-legend": "Könyvforrások keresése",
        "booksources-search": "Keresés",
        "listusers-blocked": "(blokkolva)",
        "activeusers": "Aktív szerkesztők listája",
        "activeusers-intro": "Ez a lap azon felhasználók listáját tartalmazza, akik végeztek valamilyen tevékenységet az elmúlt {{PLURAL:$1|egy|$1}} napban.",
-       "activeusers-count": "$1 szerkesztés az utolsó $3 napban",
+       "activeusers-count": "$1 művelet az elmúlt $3 napban",
        "activeusers-from": "Szerkesztők listázása a következő névtől kezdve:",
-       "activeusers-hidebots": "Botok elrejtése",
-       "activeusers-hidesysops": "Adminisztrátorok elrejtése",
        "activeusers-noresult": "Nem található ilyen szerkesztő.",
        "activeusers-submit": "Aktív szerkesztők megjelenítése",
        "listgrouprights": "Szerkesztői csoportok jogai",
        "movelogpagetext": "Az alábbiakban az átnevezett lapok listája látható.",
        "movesubpage": "{{PLURAL:$1|Allap|Allapok}}",
        "movesubpagetext": "Ennek a lapnak {{PLURAL:$1|egy|$1}} allapja van.",
+       "movesubpagetalktext": "A kapcsolódó vitalapnak az alább látható {{PLURAL:$1|allapja|$1 allapja}} van.",
        "movenosubpage": "Ez a lap nem rendelkezik allapokkal.",
        "movereason": "Indoklás:",
        "revertmove": "visszaállítás",
        "pageinfo-watchers": "Figyelők száma",
        "pageinfo-visiting-watchers": "A lapot figyelők száma, akik nézték a friss változtatásait",
        "pageinfo-few-watchers": "Kevesebb mint $1 szerkesztő figyeli",
+       "pageinfo-few-visiting-watchers": "Nem biztos, hogy látta bárki a lapot, akinek a figyelőlistáján szerepel",
        "pageinfo-redirects-name": "Átirányítások száma erre a lapra",
        "pageinfo-subpages-name": "A lap allapjai",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|átirányítás}}; $3 {{PLURAL:$3|nem átirányítás}})",
        "pageinfo-category-pages": "Lapok száma",
        "pageinfo-category-subcats": "Alkategóriák száma",
        "pageinfo-category-files": "Fájlok száma",
+       "pageinfo-user-id": "Felhasználóazonosító",
        "markaspatrolleddiff": "Ellenőrzöttnek jelölöd",
        "markaspatrolledtext": "Ellenőriztem",
        "markaspatrolledtext-file": "Ellenőriztem",
        "newimages-showbots": "Botos feltöltések mutatása",
        "newimages-hidepatrolled": "Ellenőrzött szerkesztések elrejtése",
        "noimages": "Nem tekinthető meg semmi.",
+       "gallery-slideshow-toggle": "Miniatűrök ki/bekapcsolása",
        "ilsubmit": "Keresés",
        "bydate": "dátum szerint",
        "sp-newimages-showfrom": "Új fájlok mutatása $1 $2 után",
        "htmlform-cloner-create": "További hozzáadása",
        "htmlform-cloner-delete": "Eltávolítás",
        "htmlform-cloner-required": "Legalább egy érték szükséges.",
+       "htmlform-date-placeholder": "ÉÉÉÉ-HH-NN",
+       "htmlform-time-placeholder": "ÓÓ:PP:MM",
+       "htmlform-datetime-placeholder": "ÉÉÉÉ-HH-NN ÓÓ:PP:MM",
+       "htmlform-date-invalid": "A megadott érték nem felismerhető dátum. Próbáld meg ÉÉÉÉ-HH-NN formátumban.",
+       "htmlform-time-invalid": "A megadott érték nem felismerhető idő. Próbáld meg ÓÓ:PP:MM formátumban.",
+       "htmlform-datetime-invalid": "A megadott érték nem felismerhető dátum/idő. Próbáld meg ÉÉÉÉ-HH-NN ÓÓ:PP:MM formátumban.",
+       "htmlform-date-toolow": "A megadott érték korábbi az engedélyezettnél ($1).",
+       "htmlform-date-toohigh": "A megadott érték későbbi az engedélyezettnél ($1).",
+       "htmlform-time-toolow": "A megadott érték korábbi az engedélyezettnél ($1).",
+       "htmlform-time-toohigh": "A megadott érték későbbi az engedélyezettnél ($1).",
+       "htmlform-datetime-toolow": "A megadott érték korábbi az engedélyezettnél ($1).",
+       "htmlform-datetime-toohigh": "A megadott érték későbbi az engedélyezettnél ($1).",
        "htmlform-title-badnamespace": "[[:$1]] nem a(z) „{{ns:$2}}” névtérben található.",
        "htmlform-title-not-creatable": "„$1” nem egy létrehozható lapcím",
        "htmlform-title-not-exists": "$1 nem létezik.",
        "feedback-external-bug-report-button": "A fájl egy technikai feladat",
        "feedback-dialog-title": "Visszajelzés küldése",
        "feedback-dialog-intro": "A visszajelzésedre az alábbi egyszerű űrlapot használhatod. A hozzászólásod a felhasználó neveddel együtt a „$1” oldalon fog megjelenni.",
-       "feedback-error-title": "Hiba",
        "feedback-error1": "Hiba: az API ismeretlen eredménnyel tért vissza",
        "feedback-error2": "Hiba: a szerkesztés nem sikerült",
        "feedback-error3": "Hiba: nem érkezett válasz az API-tól",
        "feedback-thanks": "Köszönjük. A visszajelzésed elküldve a „[$2 $1]” laphoz.",
        "feedback-thanks-title": "Köszönjük!",
        "feedback-useragent": "User agent:",
-       "searchsuggest-search": "Keresés",
+       "searchsuggest-search": "Keresés a wikin",
        "searchsuggest-containing": "tartalmazza…",
        "api-error-autoblocked": "Az IP-címed automatikusan blokkolva lett, mert korábban egy blokkolt szerkesztő használta.",
        "api-error-badaccess-groups": "Nincs jogod fájlokat feltölteni erre a wikire.",
        "authmanager-authn-not-in-progress": "Hitelesítés nincs folyamatban, vagy a folyamat adatai elvesztek. Kérjük, indítsd újra az elejétől.",
        "authmanager-authn-no-primary": "A megadott hitelesítő adatokkal nem lehet hitelesíteni.",
        "authmanager-authn-no-local-user": "A megadott hitelesítő adatok nincsenek társítva egyetlen felhasználóval sem ezen a wikin.",
+       "authmanager-authn-no-local-user-link": "A megadott hitelesítő adatok érvényesek, de nincsenek társítva felhasználóhoz ezen a wikin. Jelentkezz be más módon vagy regisztrálj, és lesz lehetőséged a hitelesítő adatok összekapcsolására a fiókoddal.",
        "authmanager-authn-autocreate-failed": "A helyi fiók automatikus létrehozása sikertelen: $1",
        "authmanager-change-not-supported": "A megadott hitelesítő adatokat nem változtathatók meg, mivel semmi sem használná őket.",
        "authmanager-create-disabled": "Új fiók létrehozása tiltva.",
        "authmanager-provider-password": "Jelszó alapú hitelesítés",
        "authmanager-provider-password-domain": "Jelszó - domain-alapú hitelesítés",
        "authmanager-provider-temporarypassword": "Ideiglenes jelszó",
+       "authprovider-confirmlink-message": "A legutóbbi bejelentkezési próbálkozásaid alapján a következő fiókok kapcsolhatók össze a wikifiókoddal. Az összekapcsolás lehetővé teszi a bejelentkezést ezekkel a fiókokkal. Válaszd ki, melyeket szeretnéd összekapcsolni.",
        "authprovider-confirmlink-request-label": "Összekapcsolandó fiókok",
        "authprovider-confirmlink-success-line": "$1: Sikeresen összekapcsolva.",
        "authprovider-confirmlink-failed": "A fiókok összekapcsolása nem volt teljesen sikeres: $1",
        "unlinkaccounts-success": "A fiókok szétkapcsolva.",
        "authenticationdatachange-ignored": "A hitelesítő adatok változtatása nincs kezelve. Talán nincs beállítva szolgáltató?",
        "userjsispublic": "Figyelem: JavaScript-allapokon ne tárolj bizalmas adatokat, mivel minden felhasználó számára láthatóak.",
-       "usercssispublic": "Figyelem: CSS-allapokon ne tárolj bizalmas adatokat, mivel minden felhasználó számára láthatóak."
+       "usercssispublic": "Figyelem: CSS-allapokon ne tárolj bizalmas adatokat, mivel minden felhasználó számára láthatóak.",
+       "restrictionsfield-badip": "Érvénytelen IP-cím vagy -tartomány: $1",
+       "restrictionsfield-label": "Engedélyezett IP-tartományok:",
+       "restrictionsfield-help": "Egy IP-cím vagy CIDR-tartomány soronként. Minden engedélyezéséhez használd a következő tartományokat:<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Hiba: $1",
+       "edit-error-long": "Hibák:\n\n$1"
 }
index 5920b06..b5326a8 100644 (file)
@@ -26,7 +26,9 @@
                        "Vahe Gharakhanyan",
                        "Aram1985",
                        "KeepingCalm",
-                       "Macofe"
+                       "Macofe",
+                       "Kareyac",
+                       "Irus"
                ]
        },
        "tog-underline": "ընդգծել հղումները՝",
@@ -54,7 +56,7 @@
        "tog-enotifminoredits": "էլ-փոստով տեղեկացնել նաև էջերի չնչին խմբագրումների մասին",
        "tog-enotifrevealaddr": "Ցույց տալ իմ էլ-փոստի հասցեն ծանուցման նամակներում",
        "tog-shownumberswatching": "Ցույց տալ հսկող մասնակիցների թիվը",
-       "tog-oldsig": "Ընթացիկ ստորագրությունը՝",
+       "tog-oldsig": "Ձեր ընթացիկ ստորագրությունը՝",
        "tog-fancysig": "Ստորագրությունը վիքիտեքստի տեսքով (առանց ավտոմատ հղման)",
        "tog-uselivepreview": "Օգտագործել անմիջական նախադիտում",
        "tog-forceeditsummary": "Նախազգուշացնել խմբագրման ամփոփումը դատարկ թողնելու դեպքում",
@@ -71,7 +73,7 @@
        "tog-showhiddencats": "Ցուցադրել թաքնված կատեգորիաները",
        "tog-norollbackdiff": "Չցուցադրել տարբերությունները հետ գլորելուց հետո",
        "tog-useeditwarning": "Զգուշացնել ինձ, երբ ես լքում եմ խմբագրման էջը առանց կատարած փոփոխությունները հիշելու։",
-       "tog-prefershttps": "Õ\84Õ¸Ö\82Õ¿Ö\84 Õ£Õ¸Ö\80Õ®Õ¥Õ¬Õ¸Ö\82Ö\81 Õ°Õ¥Õ¿Õ¸, Õ´Õ«Õ·Õ¿ Õ£Õ¸Ö\80Õ®Õ¡Õ®Õ¥Õ¬ Õ¡Õ¶Õ¾Õ¶Õ¿Õ¡Õ¶Õ£ Õ´Õ«Õ¡Ö\81Õ¸Ö\82Õ´Õ«Ö\81 (HTTPS)",
+       "tog-prefershttps": "Õ\84Õ«Õ·Õ¿ Ö\85Õ£Õ¿Õ¡Õ£Õ¸Ö\80Õ®Õ¥Ö\84 Õ¡Õ¶Õ¾Õ¿Õ¡Õ¶Õ£ Õ´Õ«Õ¡Ö\81Õ¸Ö\82Õ´ Õ°Õ¡Õ´Õ¡Õ¯Õ¡Ö\80Õ£Õ¸Ö\82Õ´ Õ¶Õ¥Ö\80Õ¯Õ¡ÕµÕ¡Ö\81Õ¶Õ¥Õ¬Õ¸Ö\82Ö\81 Õ°Õ¥Õ¿Õ¸",
        "underline-always": "Միշտ",
        "underline-never": "Երբեք",
        "underline-default": "Դիտարկչի կամ թեմայի լռելյայն ոճով",
        "newwindow": "(բացվում է նոր պատուհանում)",
        "cancel": "Չեղարկել",
        "moredotdotdot": "Ավելին...",
-       "morenotlisted": "Ô±ÕµÕ½ Ö\81Õ¡Õ¶Õ¯Õ¶ Õ¡Õ¾Õ¡Ö\80Õ¿Õ¸Ö\82Õ¶ Õ¹Õ§Ö\89",
+       "morenotlisted": "Ô±ÕµÕ½ Ö\81Õ¸Ö\82Ö\81Õ¡Õ¯Õ¨ Õ¯Õ¡Ö\80Õ¸Õ² Õ§ Õ¬Õ«Õ¶Õ¥Õ¬ Õ©Õ¥Ö\80Õ«",
        "mypage": "Էջ",
        "mytalk": "Քննարկում",
        "anontalk": "Քննարկում",
        "talk": "Քննարկում",
        "views": "Դիտումները",
        "toolbox": "Գործիքներ",
+       "tool-link-userrights": "Փոփոխել {{GENDER:$1|մասնակից}} խմբեր",
+       "tool-link-emailuser": "Ուղարկել էլ այս նամակ {{GENDER:$1|մասնակցին}}",
        "userpage": "Դիտել մասնակցի էջը",
        "projectpage": "Դիտել նախագծի էջը",
        "imagepage": "Դիտել նիշքի էջը",
        "jumptosearch": "որոնում",
        "view-pool-error": "Ներեցեք, սերվերները գերբեռնված են այս պահին։\nՇատ օգտվողներ փորձում են դիտել այս էջը։\nԽնդրում ենք սպասել որոշ ժամանակ էջը կրկին դիտելու համար։\n\n$1",
        "generic-pool-error": "Ներեցեք, սերվերները գերբեռնված են այս պահին։\nՇատ օգտվողներ փորձում են դիտել այս էջը։\nԽնդրում ենք սպասել որոշ ժամանակ էջը կրկին դիտելու համար։",
+       "pool-timeout": "Արգելափակման ժամկետը սպառվաց է",
        "pool-errorunknown": "Անհայտ սխալ",
        "poolcounter-usage-error": "Օգտագործման սխալ՝ $1",
        "aboutsite": "{{grammar:genitive|{{SITENAME}}}} մասին",
        "badarticleerror": "Տվյալ գործողությունը չի կարող կատարվել այս էջում։",
        "cannotdelete": "Չհաջողվեց ջնջել «$1» էջը կամ ֆայլը։\nՀավանաբար այն արդեն ջնջվել է մեկ այլ մասնակցի կողմից։",
        "cannotdelete-title": "Հնարավոր չէ ջնջել $1 էջը",
+       "delete-hook-aborted": "Խմբագրել չեղյալ է.\nԼրացուցիչ պարզաբանումներ չի դրվել.",
+       "no-null-revision": "Չի հաջողվել ստեղծել նոր զրոյական правку համար էջը \"$1\"",
        "badtitle": "Անընդունելի անվանում",
        "badtitletext": "Հարցված էջի անվանումը անընդունելի է, դատարկ է կամ սխալ միջ-լեզվական կամ ինտերվիքի անվանում է։ Հնարավոր է, որ այն պարունակում է անթույլատրելի սիմվոլներ։",
        "title-invalid-empty": "Էջի հայցվող վերնագիրը դատարկ է կամ պարունակում է միայն անվանատարածքի անունը։",
+       "title-invalid-utf8": "Հարցումն ստացած անունը էջը պարունակում է կրում սխալ հաջորդականությունը նիշ UTF-8.",
        "perfcached": "Ստորև տվյալները պահուստավորված են և հնարավոր է չարտացոլեն վերջին փոփոխությունները։ Առավելագույն {{PLURAL:$1|արդյունք|$1 արդյունք}} է հասանելի քեշում։",
        "perfcachedts": "Հետևյալ տվյալները վերցված են քեշից և վերջին անգամ թարմացվել են $1։ A maximum of {{PLURAL:$4|one result is|$4 results are}} available in the cache.",
        "querypage-no-updates": "Այս էջի փոփոխությունները ներկայումս արգելված են։ Այստեղի տվյալները այժմ չեն թարմացվի։",
        "password-change-forbidden": "Այս վիքիում չեք կարող փոխել գաղտնաբառ։",
        "externaldberror": "Տեղի է ունեցել վավերացման արտաքին տվյալների բազայի սխալ, կամ դուք չունեք բավարար իրավունքներ ձեր արտաքին հաշվի փոփոխման համար։",
        "login": "Մտնել համակարգ",
+       "login-security": "Հաստատեք Ձեր ինքնությունը",
        "nav-login-createaccount": "Մտնել / Գրանցվել",
        "userlogin": "Մտնել / Գրանցվել",
        "userloginnocreate": "Մտնել",
        "userlogin-resetlink": "Մոռացե՞լ եք Ձեր հաշվի տվյալները։",
        "userlogin-resetpassword-link": "Մոռացե՞լ եք գաղտնաբառը",
        "userlogin-helplink2": "Մուտք գործելու օգնություն",
+       "userlogin-loggedin": "Դուք արդեն մտել է որպես {{GENDER:$1|$1}}.\nՕգտագործեք ստորև բերված ձևը մուտք գործելու համար այլ հաշից",
+       "userlogin-reauth": "Դուք պետք է կրկին համակարգ մուտք գործեք  հաստատելու որ դուք դուք եք {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Ստեղծել այլ հաշիվ",
        "createacct-emailrequired": "Էլ–փոստի հասցե",
        "createacct-emailoptional": "Էլ–փոստի հասցե (ոչ պարտադիր)",
        "newarticle": "(Նոր)",
        "newarticletext": "Դուք հղվել եք դեռևս գոյություն չունեցող էջի։ \nՆոր էջ ստեղծելու համար ստորև գտնվող խմբագրման դաշտում ավելացրեք տեքստ, այնուհետև սեղմեք '''Հիշել էջը''' (այցելեք [$1 օգնության էջը]՝ մանրամասն տեղեկությունների համար)։ \n\nԵթե դուք սխալմամբ եք այստեղ հայտնվել, ապա սեղմեք ձեր դիտարկչի '''հետ''' (back) կոճակը։",
        "anontalkpagetext": "----\n''Այս քննարկման էջը պատկանում է անանուն մասնակցին, որը դեռ չի ստեղծել մասնակցային հաշիվ կամ չի մտել համակարգ մասնակցի անունով։''\nԱյդ իսկ պատճառով օգտագործվում է թվային IP-հասցեն։\nՆման IP-հասցեից կարող են օգտվել մի քանի մասնակիցներ։\nԵթե դուք անանուն մասնակից եք, բայց կարծում եք, որ ուրիշներին վերաբերող դիտողությունները արվում են ձեր հասցեով, ապա խնդրում ենք պարզապես [[Special:CreateAccount|գրանցվել]] կամ [[Special:UserLogin|մտնել համակարգ]], որպեսզի հետագայում ձեզ չշփոթեն այլ անանուն մասնակիցների հետ։",
-       "noarticletext": "Ներկայումս այս էջում որևէ տեքստ չկա։\nԴուք կարող եք [[Special:Search/{{PAGENAME}}|որոնել այս անվանումը]] այլ էջերում, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} որոնել համապատասխան տեղեկամատյանները] կամ [{{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» անվանմամբ գրանցված մասնակից չկա։",
        "searchprofile-advanced-tooltip": "Որոնել նշված անվանատարածքներում",
        "search-result-size": "$1 ({{PLURAL:$2|1 բառ|$2 բառ}})",
        "search-result-category-size": "{{PLURAL:$1|անդամ}} ({{PLURAL:$2|ենթակատեգորիա}}, {{PLURAL:$3|նիշք}})",
-       "search-redirect": "(վերահղում $1)",
+       "search-redirect": "(վերահղում $1-ից)",
        "search-section": "(բաժին $1)",
        "search-suggest": "Գուցե նկատի ունե՞ք՝ $1",
        "search-interwiki-caption": "Կից նախագծեր",
        "listusers-noresult": "Այդպիսի մասնակիցներ չգտնվեցին։",
        "listusers-blocked": "(արգելափակված)",
        "activeusers": "Ակտիվ մասնակիցների ցանկ",
-       "activeusers-hidebots": "Թաքցնել բոտերին",
        "activeusers-noresult": "Այդպիսի մասնակիցներ չեն գտնվել։",
        "activeusers-submit": "Ցույց տալ ակտիվ մասնակիցներին",
        "listgrouprights-members": "(անդամների ցանկ)",
        "whatlinkshere-prev": "{{PLURAL:$1|նախորդ|նախորդ $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|հաջորդ|հաջորդ $1}}",
        "whatlinkshere-links": "← հղումներ",
-       "whatlinkshere-hideredirs": "$1 վերահղում",
-       "whatlinkshere-hidetrans": "$1 Õ¶Õ¥Ö\80Õ¡Õ¼Õ¸Ö\82Õ´Õ¶Õ¥Ö\80Õ¨",
-       "whatlinkshere-hidelinks": "$1 հղում",
+       "whatlinkshere-hideredirs": "$1 վերահղումներ",
+       "whatlinkshere-hidetrans": "$1 Õ¶Õ¥Ö\80Õ¡Õ¼Õ¥Õ¬Õ¸Ö\82",
+       "whatlinkshere-hidelinks": "$1 հղումներ",
        "whatlinkshere-hideimages": "$1 նիշքային հղումներ",
        "whatlinkshere-filters": "Զտիչներ",
        "whatlinkshere-submit": "Գնալ առաջ",
        "ipbexpiry": "Մարման ժամկետ.",
        "ipbreason": "Պատճառ.",
        "ipbreason-dropdown": "*Արգելափակման սովորական պատճառներ\n** Կեղծ տեղեկությունների ներմուծում\n** Էջերից նյութերի հեռացում\n** Արտաքին կայքերին հղումների սպամ\n** Անիմաստ/անկապ տեքստի ներմուծում էջերում\n** Վարկաբեկող/ահաբեկող պահվածք\n** Բազմաթիվ մասնակցային հաշիվների չարաշահում\n** Անպատշաճ մասնակցի անուն",
+       "ipb-hardblock": "Արգելել գրանցված մասնակիցներին խմբագրել այս IP-հասցեից",
        "ipbcreateaccount": "Կանխարգելել մասնակցային հաշվի ստեղծումը",
        "ipbemailban": "Կանխարգելել մասնակցի կողմից էլ-նամակների ուղարկումը",
-       "ipbenableautoblock": "Ավտոմատիկ արգելափակել այս մասնակցի վերջին IP-հասցեն և բոլոր հետագա IP-հասցեները, որոնցից նա կփորձի խմբագրումներ կատարել",
+       "ipbenableautoblock": "Ավտոմատ արգելափակել այս մասնակցի վերջին IP-հասցեն և բոլոր հետագա IP-հասցեները, որոնցից նա կփորձի խմբագրումներ կատարել",
        "ipbsubmit": "Արգելափակել այս մասնակցին",
        "ipbother": "Այլ ժամկետ.",
        "ipboptions": "2 ժամ:2 hours,1 օր:1 day,3 օր:3 days,1 շաբաթ:1 week,2 շաբաթ:2 weeks,1 ամիս:1 month,3 ամիս:3 months,6 ամիս:6 months,1 տարի:1 year,անժամկետ:infinite",
        "ipbhidename": "Թաքցնել մասնակցի անունը արգելափակման տեղեկամատյանից, գործող արգելափակումների ցանկից և մասնակիցների ցանկից։",
+       "ipbwatchuser": "Ավելացնել հսկացանկում մասնակցի էջն ու քննարկման էջն",
+       "ipb-disableusertalk": "Արգելել մասնակցին խմբագրել իր քննարկման էջն արգելափակման ընթացքում",
        "badipaddress": "Սխալ IP-հասցե",
        "blockipsuccesssub": "Արգելափակումը կատարված է",
        "blockipsuccesstext": "[[Special:Contributions/$1|«$1»]] արգելափակված է։\n<br />Տես [[Special:BlockList|արգելափակված IP-հասցեների ցանկը]]։",
        "blocklist": "Արգելափակված մասնակիցներ։",
        "ipblocklist": "Արգելափակված IP-հասցեները և մասնակիցները",
        "ipblocklist-legend": "Արգելափակված մասնակցի որոնում",
+       "blocklist-expiry": "Լրանում է",
        "ipblocklist-submit": "Որոնել",
        "infiniteblock": "ընդմիշտ",
        "expiringblock": "կմարվի $1 $2",
        "markedaspatrollednotify": "Այս փոփոխությունը $1 էջում նշվել է ստուգված",
        "markedaspatrollederrornotify": "Ստուգված նշել չհաջողվեց։",
        "patrol-log-page": "Պարեկման տեղեկամատյան",
+       "confirm-markpatrolled-button": "Լավ",
        "deletedrevision": "Ջնջված է հին տարբերակը $1",
        "filedeleteerror-short": "Նիշքի ջնջման սխալ. $1",
        "filedeleteerror-long": "Տեղի են ունեցել սխալներ նիշքի ջնջման ընթացքում.\n\n$1",
        "tags-activate-submit": "Ակտիվացնել",
        "tags-deactivate-reason": "Պատճառ՝",
        "tags-deactivate-submit": "Ապաակտիվացնել",
+       "tags-update-blocked": "Դուք չեք կարող ավելացնել կամ հեռացնել թեգեր, քանի դեռ {{GENDER:$1|դուք}} արգելափակված եք",
        "comparepages": "Համեմատել էջեր",
        "compare-page1": "Էջ 1",
        "compare-page2": "Էջ 2",
        "feedback-close": "Արված է",
        "feedback-message": "Հաղորդագրություն․",
        "feedback-subject": "Թեմա.",
-       "searchsuggest-search": "Որոնել",
+       "searchsuggest-search": "Որոնել {{SITENAME}} կայքում",
        "duration-seconds": "$1 {{PLURAL:$1|վայրկյան}}",
        "duration-minutes": "$1 {{PLURAL:$1|րոպե}}",
        "duration-hours": "$1 {{PLURAL:$1|ժամ}}",
        "special-characters-group-khmer": "Կխմեր",
        "special-characters-title-endash": "ո գծիկ (en dash)",
        "special-characters-title-emdash": "ա գծիկ (em dash)",
-       "special-characters-title-minus": "հանածի նշան"
+       "special-characters-title-minus": "հանածի նշան",
+       "authmanager-create-from-login": "Հաշիվ ստեղծելու համար, խնդրում ենք լրացնել ստորև դաշտերը"
 }
index 3fc5dfe..c8826a6 100644 (file)
@@ -43,7 +43,7 @@
        "tog-enotifminoredits": "Notificar me etiam de modificationes minor de paginas e files",
        "tog-enotifrevealaddr": "Revelar mi adresse de e-mail in messages de notification",
        "tog-shownumberswatching": "Monstrar le numero de usatores que observa le pagina",
-       "tog-oldsig": "Signatura existente:",
+       "tog-oldsig": "Tu signatura existente:",
        "tog-fancysig": "Tractar signatura como wikitexto (sin ligamine automatic)",
        "tog-uselivepreview": "Usar previsualisation dynamic",
        "tog-forceeditsummary": "Avisar me si io non entra un summario de modification",
@@ -60,7 +60,7 @@
        "tog-showhiddencats": "Monstrar categorias celate",
        "tog-norollbackdiff": "Non monstrar differentias post exequer un revocation",
        "tog-useeditwarning": "Advertir me quando io quita un pagina de modification sin publicar le cambiamentos",
-       "tog-prefershttps": "Sempre usar un connexion secur in session aperte",
+       "tog-prefershttps": "Sempre usar un connexion secur durante session aperte",
        "underline-always": "Sempre",
        "underline-never": "Nunquam",
        "underline-default": "Como definite per tu navigator o apparentia",
        "category-file-count-limited": "Le sequente {{PLURAL:$1|file es|$1 files es}} in le categoria actual.",
        "listingcontinuesabbrev": "cont.",
        "index-category": "Paginas indexate",
-       "noindex-category": "Paginas non indexate",
+       "noindex-category": "Paginas con \"__NOINDEX__\"",
        "broken-file-category": "Paginas con ligamines rupte a files",
        "about": "A proposito",
        "article": "Pagina de contento",
        "newwindow": "(se aperi in un nove fenestra)",
        "cancel": "Cancellar",
        "moredotdotdot": "Plus...",
-       "morenotlisted": "Iste lista non es complete.",
+       "morenotlisted": "Iste lista pote esser incomplete.",
        "mypage": "Pagina",
        "mytalk": "Discussion",
        "anontalk": "Discussion",
        "talk": "Discussion",
        "views": "Representationes",
        "toolbox": "Instrumentos",
+       "tool-link-userrights": "Modificar le gruppos del {{GENDER:$1|usator|usatrice}}",
+       "tool-link-emailuser": "Inviar e-mail a iste {{GENDER:$1|usator|usatrice}}",
        "userpage": "Vider pagina del usator",
        "projectpage": "Vider pagina de projecto",
        "imagepage": "Vider le pagina del file",
        "eauthentsent": "Un message de confirmation ha essite inviate al adresse de e-mail specificate.\nPro permitter que le systema invia altere messages a iste adresse, tu debe sequer le instructiones in iste message pro confirmar que le adresse es realmente tue.",
        "throttled-mailpassword": "Un message pro le reinitialisation del contrasigno ha jam essite inviate intra le ultime {{PLURAL:$1|hora|$1 horas}}.\nPro prevenir le abuso, solmente un message pro le reinitialisation del contrasigno essera inviate per {{PLURAL:$1|hora|$1 horas}}.",
        "mailerror": "Error de inviar e-mail: $1",
-       "acct_creation_throttle_hit": "Le visitatores de iste wiki usante tu adresse IP ha create {{PLURAL:$1|1 conto|$1 contos}} durante le ultime die, e isto es le maximo permittite in iste periodo de tempore.\nA causa de isto, le visitatores usante iste adresse IP non pote crear nove contos al momento.",
+       "acct_creation_throttle_hit": "Le visitatores de iste wiki usante tu adresse IP ha create {{PLURAL:$1|1 conto|$1 contos}} durante le ultime $2, e isto es le maximo permittite in iste periodo de tempore.\nA causa de isto, le visitatores usante iste adresse IP non pote crear nove contos al momento.",
        "emailauthenticated": "Tu adresse de e-mail ha essite confirmate le $2 a $3.",
        "emailnotauthenticated": "Tu non ha ancora confirmate tu adresse de e-mail.\nNulle e-mail essera inviate pro le sequente functiones.",
        "noemailprefs": "Es necessari specificar un adresse de e-mail in tu preferentias pro poter executar iste functiones.",
        "botpasswords-label-delete": "Deler",
        "botpasswords-label-resetpassword": "Reinitialisar le contrasigno",
        "botpasswords-label-grants": "Concessiones applicabile:",
-       "botpasswords-help-grants": "Cata concession da accesso al derectos de usator listate que un conto de usator jam ha. Vide le [[Special:ListGrants|tabula de concessiones]] pro plus information.",
-       "botpasswords-label-restrictions": "Restrictiones de uso:",
+       "botpasswords-help-grants": "Concessiones permitte accesso a derectos jam detenite per tu conto de usator. Activar un concession hic non forni accesso a alcun derecto que tu conto de usator non haberea alteremente. Vide le [[Special:ListGrants|tabula de concessiones]] pro plus information.",
        "botpasswords-label-grants-column": "Concedite",
        "botpasswords-bad-appid": "Le nomine del robot \"$1\" non es valide.",
        "botpasswords-insert-failed": "Le addition del nomine de robot \"$1\" ha fallite. Esque illo ha jam essite addite?",
        "passwordreset-emailelement": "Nomine de usator: \n$1\n\nContrasigno temporari: \n$2",
        "passwordreset-emailsentemail": "Si iste adresse es associate a tu conto, alora un e-mail pro reinitialisar le contrasigno essera inviate.",
        "passwordreset-emailsentusername": "Si il ha un adresse de e-mail associate a iste conto, alora un e-mail pro reinitialisar le contrasigno essera inviate.",
-       "passwordreset-emailsent-capture2": "Le {{PLURAL:$1|message|messages}} de e-mail pro reinitialisation de contrasigno ha essite inviate. Le {{PLURAL:$1|nomine de usator e contrasigno|lista de nomines de usator e contrasignos}} appare hic infra.",
-       "passwordreset-emailerror-capture2": "Le invio de e-mail al {{GENDER:$2|usator}} ha fallite: $1 Le {{PLURAL:$3|nomine de usator e contrasigno|lista de nomines de usator e contrasignos}} appare hic infra.",
+       "passwordreset-emailsent-capture2": "Le {{PLURAL:$1|message|messages}} de e-mail pro reinitialisation de contrasigno ha essite inviate. Le {{PLURAL:$1|nomine de usator e contrasigno|lista de nomines de usator e contrasignos}} es monstrate hic.",
+       "passwordreset-emailerror-capture2": "Le invio de e-mail al {{GENDER:$2|usator}} ha fallite: $1 Le {{PLURAL:$3|nomine de usator e contrasigno|lista de nomines de usator e contrasignos}} es monstrate hic.",
        "passwordreset-nocaller": "Un appellator debe esser fornite",
        "passwordreset-nosuchcaller": "Appellator non existe: $1",
        "passwordreset-ignored": "Le reinitialisation del contrasigno non ha essite realisate. Es possibile que nulle fornitor ha essite configurate?",
-       "passwordreset-invalideamil": "Adresse de e-mail invalide",
+       "passwordreset-invalidemail": "Adresse de e-mail invalide",
        "passwordreset-nodata": "Ni un nomine de usator ni un adresse de e-mail ha essite fornite",
        "changeemail": "Cambiar o remover adresse de e-mail",
        "changeemail-header": "Completa iste formulario pro cambiar tu adresse de e-mail. Si tu vole remover le association de omne adresse de e-mail ab tu conto, lassa le campo pro le nove adresse de e-mail vacue quando tu submitte le formulario.",
        "grant-basic": "Derectos de base",
        "grant-viewdeleted": "Vider files e paginas delite",
        "grant-viewmywatchlist": "Vider le proprie observatorio",
+       "grant-viewrestrictedlogs": "Vider entratas de registro confidential",
        "newuserlogpage": "Registro de creation de usatores",
        "newuserlogpagetext": "Isto es un registro de creation de usatores.",
        "rightslog": "Registro de derectos de usator",
        "upload-dialog-disabled": "Le incargamento de files con iste dialogo es disactivate in iste wiki.",
        "upload-dialog-title": "Incargar file",
        "upload-dialog-button-cancel": "Cancellar",
+       "upload-dialog-button-back": "Retornar",
        "upload-dialog-button-done": "Facite",
        "upload-dialog-button-save": "Salveguardar",
        "upload-dialog-button-upload": "Incargar",
        "apisandbox-results-fixtoken-fail": "Impossibile recuperar indicio \"$1\".",
        "apisandbox-alert-page": "Certe campos in iste pagina non es valide.",
        "apisandbox-alert-field": "Le valor de iste campo non es valide.",
+       "apisandbox-continue": "Continuar",
+       "apisandbox-continue-clear": "Rader",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries continuara] le ultime requesta; {{int:apisandbox-continue-clear}} radera le parametros relative al continuation.",
+       "apisandbox-param-limit": "Scribe <kbd>max</kbd> pro usar le limite maxime.",
        "booksources": "Fontes de libros",
        "booksources-search-legend": "Cercar fontes de libros",
        "booksources-search": "Cercar",
        "booksources-text": "Infra es un lista de ligamines a altere sitos que vende libros nove e usate, e pote etiam haber altere informationes super libros que tu cerca:",
        "booksources-invalid-isbn": "Le ISBN date non pare esser valide; verifica que tu non ha facite errores copiante lo del fonte original.",
+       "magiclink-tracking-rfc": "Paginas usante ligamines magic RFC",
+       "magiclink-tracking-rfc-desc": "Iste pagina usa ligamines magic RFC. Vide [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] pro saper como migrar.",
+       "magiclink-tracking-pmid": "Paginas usante ligamines magic PMID",
+       "magiclink-tracking-pmid-desc": "Iste pagina usa ligamines magic PMID. Vide [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] pro saper como migrar.",
+       "magiclink-tracking-isbn": "Paginas usante ligamines magic ISBN",
+       "magiclink-tracking-isbn-desc": "Iste pagina usa ligamines magic ISBN. Vide [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] pro saper como migrar.",
        "specialloguserlabel": "Executor:",
        "speciallogtitlelabel": "Objectivo (titulo o {{ns:user}}:nomine de usator):",
        "log": "Registros",
        "activeusers-intro": "Isto es un lista de usatores que habeva alcun typo de activitate intra le ultime $1 {{PLURAL:$1|die|dies}}.",
        "activeusers-count": "$1 {{PLURAL:$1|action|actiones}} in le ultime {{PLURAL:$3|die|$3 dies}}",
        "activeusers-from": "Presentar usatores a partir de:",
-       "activeusers-hidebots": "Celar bots",
-       "activeusers-hidesysops": "Celar administratores",
+       "activeusers-groups": "Monstrar usatores pertinente a gruppos:",
        "activeusers-noresult": "Nulle usator trovate.",
        "activeusers-submit": "Monstrar usatores active",
        "listgrouprights": "Derectos del gruppos de usatores",
        "modifiedarticleprotection": "cambiava nivello de protection de \"[[$1]]\"",
        "unprotectedarticle": "removeva le protection de \"[[$1]]\"",
        "movedarticleprotection": "displaciava le configurationes de protection ab \"[[$2]]\" verso \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|Protegeva}} \"[[$1]]\"",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Cambiar nivello de protection}} pro \"[[$1]]\"",
+       "unprotectedarticle-comment": "{{GENDER:$2|Removeva le protection}} de \"[[$1]]\"",
        "protect-title": "Cambiar nivello de protection de \"$1\"",
        "protect-title-notallowed": "Vider nivello de protection de \"$1\"",
        "prot_1movedto2": "displaciava [[$1]] verso [[$2]]",
        "movelogpagetext": "Infra es un lista de paginas renominate.",
        "movesubpage": "{{PLURAL:$1|Subpagina|Subpaginas}}",
        "movesubpagetext": "Iste pagina ha $1 {{PLURAL:$1|subpagina, le qual|subpaginas, le quales}} se monstra infra.",
+       "movesubpagetalktext": "Le pagina de discussion correspondente ha $1 {{PLURAL:$1|subpagina|subpaginas}} monstrate infra.",
        "movenosubpage": "Iste pagina non ha subpaginas.",
        "movereason": "Motivo:",
        "revertmove": "reverter",
        "pageinfo-category-pages": "Numero de paginas",
        "pageinfo-category-subcats": "Numero de subcategorias",
        "pageinfo-category-files": "Numero de files",
+       "pageinfo-user-id": "ID de usator",
        "markaspatrolleddiff": "Marcar como patruliate",
        "markaspatrolledtext": "Marcar iste pagina como patruliate",
        "markaspatrolledtext-file": "Marcar iste version del file como patruliate",
        "patrol-log-header": "Isto es un registro de versiones patruliate.",
        "log-show-hide-patrol": "$1 le registro de versiones patruliate",
        "log-show-hide-tag": "$1 registro de etiquettas",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Marcar le version $3 de $2 como patruliate?",
        "deletedrevision": "Deleva le ancian version $1",
        "filedeleteerror-short": "Error durante le deletion del file: $1",
        "filedeleteerror-long": "Se incontrava errores durante le deletion del file:\n\n$1",
        "newimages-showbots": "Monstrar files incargate per robots",
        "newimages-hidepatrolled": "Celar le files incargate patruliate",
        "noimages": "Nihil a vider.",
+       "gallery-slideshow-toggle": "Alternar miniaturas",
        "ilsubmit": "Cercar",
        "bydate": "per data",
        "sp-newimages-showfrom": "Monstrar nove files a partir del $1 a $2",
        "htmlform-cloner-create": "Adder plus",
        "htmlform-cloner-delete": "Remover",
        "htmlform-cloner-required": "Al minus un valor es requirite.",
+       "htmlform-date-placeholder": "AAAA-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "AAAA-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "Le valor specificate non es recognoscite como data. Tenta usar le formato AAAA-MM-DD.",
+       "htmlform-time-invalid": "Le valor specificate non es recognoscite como hora. Tenta usar le formato HH:MM:SS.",
+       "htmlform-datetime-invalid": "Le valor specificate non es recognoscite como data e hora. Tenta usar le formato AAAA-MM-DD HH:MM:SS.",
+       "htmlform-date-toolow": "Le valor specificate es anterior al prime data permittite, $1.",
+       "htmlform-date-toohigh": "Le valor specificate es posterior al ultime data permittite, $1.",
+       "htmlform-time-toolow": "Le valor specificate es anterior al prime hora permittite, $1.",
+       "htmlform-time-toohigh": "Le valor specificate es posterior al ultime hora permittite, $1.",
+       "htmlform-datetime-toolow": "Le valor specificate es anterior al prime data e hora permittite, $1.",
+       "htmlform-datetime-toohigh": "Le valor specificate es posterior al ultime data e hora permittite, $1.",
        "htmlform-title-badnamespace": "[[:$1]] non es in le spatio de nomines \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" non es un titulo de pagina creabile",
        "htmlform-title-not-exists": "$1 non existe.",
        "feedback-external-bug-report-button": "Signalar un problema technic",
        "feedback-dialog-title": "Submitter commentario",
        "feedback-dialog-intro": "Usa le formulario sequente pro submitter tu commentario, le qual apparera in le pagina \"$1\" insimul a tu nomine de usator.",
-       "feedback-error-title": "Error",
        "feedback-error1": "Error: Resultato del API non recognoscite",
        "feedback-error2": "Error: Modification fallite",
        "feedback-error3": "Error: Nulle responsa del API",
        "feedback-thanks": "Gratias! Tu evalutation ha essite publicate in le pagina \"[$2 $1]\".",
        "feedback-thanks-title": "Gratias!",
        "feedback-useragent": "Agente usator:",
-       "searchsuggest-search": "Cercar",
+       "searchsuggest-search": "Cercar in {{SITENAME}}",
        "searchsuggest-containing": "continente...",
        "api-error-autoblocked": "Tu adresse IP ha essite blocate automaticamente, perque illo ha essite usate per un usator blocate.",
        "api-error-badaccess-groups": "Tu non ha le permission de incargar files in iste wiki.",
        "authmanager-authn-autocreate-failed": "Le creation automatic de un conto local ha fallite: $1",
        "authmanager-change-not-supported": "Le credentiales fornite non pote esser cambiate perque nihil los usarea.",
        "authmanager-create-disabled": "Le creation de contos es disactivate.",
-       "authmanager-create-from-login": "Pro crear tu conto, completa le campos hic infra.",
+       "authmanager-create-from-login": "Pro crear tu conto, completa le campos.",
        "authmanager-create-not-in-progress": "Nulle creation de conto es in curso, o le datos del session ha essite perdite. Per favor, recomencia ab initio.",
        "authmanager-create-no-primary": "Le credentiales fornite non pote esser usate pro crear un conto.",
        "authmanager-link-no-primary": "Le credentiales fornite non pote esser usate pro ligar un conto.",
        "unlinkaccounts-success": "Le conto ha essite disligate.",
        "authenticationdatachange-ignored": "Le cambiamento del datos de authentication non ha succedite. Pote esser que nulle fornitor ha essite configurate?",
        "userjsispublic": "Nota ben: Subpaginas JavaScript non debe continer datos confidential perque altere usatores pote vider los.",
-       "usercssispublic": "Nota ben: Subpaginas CSS non debe continer datos confidential perque altere usatores pote vider los."
+       "usercssispublic": "Nota ben: Subpaginas CSS non debe continer datos confidential perque altere usatores pote vider los.",
+       "restrictionsfield-badip": "Adresse o intervallo IP non valide: $1",
+       "restrictionsfield-label": "Intervallos IP permittite:",
+       "restrictionsfield-help": "Un adresse IP o intervallo CIDR per linea. Pro activar toto, usa<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Error: $1",
+       "edit-error-long": "Errores:\n\n$1"
 }
index fc9b0a6..1254b40 100644 (file)
@@ -48,7 +48,9 @@
                        "Nemo bis",
                        "Mbrt",
                        "Beeyan",
-                       "Bonaditya"
+                       "Bonaditya",
+                       "Irus",
+                       "Presidenvolksraad"
                ]
        },
        "tog-underline": "Garis bawahi pranala:",
@@ -76,7 +78,7 @@
        "tog-enotifminoredits": "Kirimkan saya surel juga pada perubahan kecil",
        "tog-enotifrevealaddr": "Tampilkan alamat surel saya pada surel notifikasi",
        "tog-shownumberswatching": "Tunjukkan jumlah pemantau",
-       "tog-oldsig": "Tanda tangan sekarang:",
+       "tog-oldsig": "Tanda tangan Anda yang sudah ada:",
        "tog-fancysig": "Perlakukan tanda tangan sebagai teks wiki (tanpa suatu pranala otomatis)",
        "tog-uselivepreview": "Gunakan pratayang langsung",
        "tog-forceeditsummary": "Ingatkan saya bila kotak ringkasan suntingan masih kosong",
        "category-file-count-limited": "Kategori ini memiliki {{PLURAL:$1|$1 berkas}} berikut.",
        "listingcontinuesabbrev": "samb.",
        "index-category": "Halaman yang diindeks",
-       "noindex-category": "Halaman yang tidak diindeks",
+       "noindex-category": "Halaman yang diindeks",
        "broken-file-category": "Halaman dengan gambar rusak",
        "categoryviewer-pagedlinks": "($1) ($2)",
        "about": "Tentang",
        "newwindow": "(buka di jendela baru)",
        "cancel": "Batalkan",
        "moredotdotdot": "Lainnya...",
-       "morenotlisted": "Daftar ini belum lengkap.",
+       "morenotlisted": "Daftar ini mungkin tidak lengkap.",
        "mypage": "Halaman",
        "mytalk": "Pembicaraan",
        "anontalk": "Pembicaraan",
        "talk": "Pembicaraan",
        "views": "Tampilan",
        "toolbox": "Perkakas",
+       "tool-link-userrights": "Simpan kelompok {{GENDER:$1|pengguna}}",
+       "tool-link-emailuser": "Kirim surel ke {{GENDER:$1|pengguna}} ini",
        "userpage": "Lihat halaman pengguna",
        "projectpage": "Lihat halaman proyek",
        "imagepage": "Lihat halaman berkas",
        "createacct-yourpasswordagain-ph": "Masukkan lagi kata sandi",
        "userlogin-remembermypassword": "Biarkan saya tetap masuk",
        "userlogin-signwithsecure": "Gunakan server aman",
+       "cannotlogin-title": "Tidak dapat log masuk",
+       "cannotlogin-text": "Log masuk tidak mungkin.",
        "cannotloginnow-title": "Tidak dapat masuk log saat ini",
        "cannotloginnow-text": "Masuk log tidak memungkinkan ketika menggunakan $1.",
+       "cannotcreateaccount-title": "Akun tak dapat dibuat",
+       "cannotcreateaccount-text": "Menetapkan account langsung tidak diaktifkan pada wiki ini.",
        "yourdomainname": "Domain Anda:",
        "password-change-forbidden": "Anda tidak dapat mengubah kata sandi pada wiki ini.",
        "externaldberror": "Telah terjadi kesalahan otentikasi basis data eksternal atau Anda tidak diizinkan melakukan kemaskini terhadap akun eksternal Anda.",
        "passwordreset-nocaller": "Pemanggil harus diberikan",
        "passwordreset-nosuchcaller": "Pemanggil tidak ada: $1",
        "passwordreset-ignored": "Pemulihan kata sandi tidak tertangani. Mungkin penyedia tidak diatur?",
-       "passwordreset-invalideamil": "Alamat surel tidak sah",
+       "passwordreset-invalidemail": "Alamat surel tidak sah",
        "passwordreset-nodata": "Nama pengguna ataupun alamat surel tidak diberikan",
        "changeemail": "Ubah atau hapus alamat surel",
        "changeemail-header": "Lengkapi formulir ini untuk mengubah alamat surel Anda. Jika Anda ingin menghapus seluruh alamat surel yang berkaitan dengan akun Anda, kosongkan alamat surel ketika mengirim formulir.",
        "searchprofile-advanced-tooltip": "Pencarian di ruang nama tertentu",
        "search-result-size": "$1 ({{PLURAL:$2|$2 kata}})",
        "search-result-category-size": "{{PLURAL:$1|1 anggota|$1 anggota}} ({{PLURAL:$2|1 subkategori|$2 subkategori}}, {{PLURAL:$3|1 berkas|$3 berkas}})",
-       "search-redirect": "(pengalihan $1)",
+       "search-redirect": "(Dialihkan dari $1)",
        "search-section": "(bagian $1)",
        "search-category": "(kategori $1)",
        "search-file-match": "(cocok dengan isi berkas)",
        "rightslogtext": "Di bawah ini adalah log perubahan terhadap hak-hak pengguna.",
        "action-read": "membaca halaman ini",
        "action-edit": "menyunting halaman ini",
-       "action-createpage": "membuat halaman baru",
-       "action-createtalk": "membuat halaman pembicaraan baru",
+       "action-createpage": "Membuat halaman ini",
+       "action-createtalk": "Membuat halaman diskusi ini",
        "action-createaccount": "membuat akun pengguna ini",
        "action-autocreateaccount": "buat otomatis akun pengguna luar",
        "action-history": "lihat riwayat halaman ini",
        "upload-http-error": "Kesalahan HTTP terjadi: $1",
        "upload-copy-upload-invalid-domain": "Unggahan salinan tidak tersedia dari domain ini.",
        "upload-foreign-cant-upload": "Wiki ini tidak diatur untuk mengunggah berkas ke gudang penyimpangan asing.",
+       "upload-dialog-disabled": "Unggah berkas menggunakan dialog ini dinonaktifkan pada wiki ini.",
        "upload-dialog-title": "Unggah berkas",
        "upload-dialog-button-cancel": "Batalkan",
        "upload-dialog-button-done": "Selesai",
        "activeusers-intro": "Berikut adalah daftar pengguna yang memiliki suatu bentuk aktivitas selama paling tidak $1 {{PLURAL:$1|hari|hari}} terakhir.",
        "activeusers-count": "$1 {{PLURAL:$1|aktivitas|aktivitas}} dalam {{PLURAL:$3|1 hari|$3 hari}} terakhir",
        "activeusers-from": "Tampilkan pengguna mulai dari:",
-       "activeusers-hidebots": "Sembunyikan bot",
-       "activeusers-hidesysops": "Sembunyikan pengurus",
        "activeusers-noresult": "Pengguna tidak ditemukan.",
        "activeusers-submit": "Tampilkan pengguna aktif",
        "listgrouprights": "Daftar hak kelompok",
        "feedback-external-bug-report-button": "Kirim tugas teknis",
        "feedback-dialog-title": "Kirimkan saran dan tanggapan",
        "feedback-dialog-intro": "Anda bisa menggunakan formulir sederhana di bawah untuk mengirimkan saran dan masukan. Komentar Anda akan ditambahkan pada laman \"$1\" bersama nama pengguna Anda.",
-       "feedback-error-title": "Kesalahan",
        "feedback-error1": "Galat: Hasil tidak dikenal dari API",
        "feedback-error2": "Galat: Penyuntingan gagal",
        "feedback-error3": "Error: API tidak merespons",
index 53a910d..62abac0 100644 (file)
        "yourname": "Nómine de usator:",
        "yourpassword": "Parol-clave:",
        "yourpasswordagain": "Parol-clave denov:",
-       "remembermypassword": "Memorar mi parol-clave in ti navigator (por un maxim de $1 {{PLURAL:$1|die|dies}})",
        "yourdomainname": "Tui dominia:",
        "login": "Aperter session",
        "nav-login-createaccount": "Crear un conto o intrar",
index f379ef2..81b98c5 100644 (file)
        "yourname": "Áhà ọ'bànifé:",
        "yourpassword": "Okwúngáfè:",
        "yourpasswordagain": "Detuari mkpurụ okwu ejị a gafẹ:",
-       "remembermypassword": "Chetá edemede éjim a banyé na orunótuá (nke ukwu nke rürü {{PLURAL:$1|chi|chi}} $1)",
        "yourdomainname": "Obí gi:",
        "login": "Banyé",
        "nav-login-createaccount": "Banyé / ké buwá",
        "content-model-wikitext": "wikitext",
        "parser-template-loop-warning": "Etemete àtụ dị: [[$1]]",
        "undo-summary": "Emekwàlà orübà $1 shí [[Special:Contributions/$2|$2]] ([[User talk:$2|talk]])",
-       "cantcreateaccounttitle": "Enwéghịkị ke buwá",
        "viewpagelogs": "Zi ndetu ncheta màkà ihü a",
        "nohistory": "Ákíkó mbu màkà orü àdíghị màkà ihüá.",
        "currentrev": "Kuwaria nke ubüwạ",
        "listusers-submit": "Zi",
        "listusers-noresult": "Ọ hügị ọ'bànifé.",
        "listusers-blocked": "(kwàchịrị)",
-       "activeusers-hidebots": "Zonari bot",
-       "activeusers-hidesysops": "Zonari ndi íshí",
        "activeusers-noresult": "Ọ hügị ọ'bànifé.",
        "listgrouprights-group": "Ọtú",
        "listgrouprights-rights": "Nkwènyé",
index 46a2e24..904956e 100644 (file)
        "botpasswords-label-resetpassword": "Isaad manen ti kontrasenias",
        "botpasswords-label-grants": "Dagiti sagut a maipakat:",
        "botpasswords-help-grants": "Ti tunggal maysa a sagut ket mangited iti panagserrek kadagiti nailista a karbengan nga addan iti pakabilangan ti agar-aramat. Kitaen ti [[Special:ListGrants|tabla dagiti sagut]] para iti adu pay a pakaammo.",
-       "botpasswords-label-restrictions": "Dagiti panangigawid iti panagusar:",
        "botpasswords-label-grants-column": "Naisaguten",
        "botpasswords-bad-appid": "Saan nga umisu ti nagan ti bot iti \"$1\".",
        "botpasswords-insert-failed": "Napaay iti pananginayon ti nagan ti bot iti \"$1\". Nainayon kadi idin?",
        "passwordreset-nocaller": "Nasken a maited ti maysa nga agtawtawag",
        "passwordreset-nosuchcaller": "Awan ti agtawtawag: $1",
        "passwordreset-ignored": "Saan a natengngel ti panangisaad manen ti kontrasenias. Mabalin a saan a nakompigura ti mangited?",
-       "passwordreset-invalideamil": "Imbalido nga adres ti esurat",
+       "passwordreset-invalidemail": "Imbalido nga adres ti esurat",
        "passwordreset-nodata": "Saan a naited ti nagan ti agar-aramat wenno maysa nga adres ti esurat",
        "changeemail": "Sukatan wenno ikkaten ti adres ti esurat",
        "changeemail-header": "Kompletuen daytoy a porma tapno masukatan ti adres ti esuratmo. No kayatmo a maikkat ti pannakainaig iti ania man nga adres ti esurat manipud iti pakabilangam, ibati a blanko ti baro nga adres ti esurat no ited ti porma.",
        "activeusers-intro": "Daytoy ti listaan dagiti agar-aramat nga adda inar-aramid iti kaunegan dagiti napalabas a $1 {{PLURAL:$1|nga aldaw|nga al-aldaw}}.",
        "activeusers-count": "$1 a {{PLURAL:$1|tignay|tigtignay}} iti napalabas {{PLURAL:$3|nga aldaw|a $3 nga al-aldaw}}",
        "activeusers-from": "Iparang dagiti agar-aramat a mangrugi iti:",
-       "activeusers-hidebots": "Ilemmeng dagiti bot",
-       "activeusers-hidesysops": "Ilemmeng dagiti administrador",
        "activeusers-noresult": "Awan ti nasarakan nga agar-aramat.",
        "activeusers-submit": "Ipakita dagiti aktibo nga agar-aramat",
        "listgrouprights": "Dagiti karbengan ti grupo ti agar-aramat",
        "feedback-bugornote": "No sisasagakan nga agibaga ti teknikal a pakirut a naisalaysay pangngaasi nga [$1 ireporta ti parikut].\nNupay kasta, mausarmo ti nalaka a porma dita baba. Ti komentario nga itedmo ket mainayon iti panid \"[$3 $2], a mairaman ti naganmo nga agar-aramat ken no ania ti pagbasabasa nga us-sarem.",
        "feedback-cancel": "Ukasen",
        "feedback-close": "Nalpasen",
-       "feedback-error-title": "Biddut",
        "feedback-error1": "Biddut: Saan a malasin dagiti nagbanagan manipud ti API",
        "feedback-error2": "Biddut: Napaay ti panagurnos",
        "feedback-error3": "Biddut: Awan ti sungbat manipud ti API",
index d735991..4184353 100644 (file)
        "yourpasswordagain": "Юхаязде къайладIоагIа:",
        "createacct-yourpasswordagain": "Бакъйе пароль",
        "createacct-yourpasswordagain-ph": "Кхы цхьаькхаза Iочуязъе пароль",
-       "remembermypassword": "ДагайоагIаш хилийта са дагара йоазув укх компьютер тӀа (цхьан $1 {{PLURAL:$1|дийнахь}})",
        "userlogin-remembermypassword": "Система чу виса",
        "yourdomainname": "Хьа нана-цIа:",
        "login": "Чувала/яла",
index fd1d4c4..a6344cc 100644 (file)
@@ -52,7 +52,7 @@
        "tog-enotifminoredits": "Senda mér einnig tölvupóst vegna minniháttar breytinga á síðum og skrám",
        "tog-enotifrevealaddr": "Gefa upp netfang mitt í tilkynningarpóstum",
        "tog-shownumberswatching": "Sýna fjölda vaktandi notenda",
-       "tog-oldsig": "Núverandi undirskrift:",
+       "tog-oldsig": "Núverandi undirskriftin þín:",
        "tog-fancysig": "Meðhöndla undirskrift sem wikitexta (án sjálfvirks tengils)",
        "tog-uselivepreview": "Nota beina forskoðun",
        "tog-forceeditsummary": "Birta áminningu þegar breytingarágripið er tómt",
@@ -69,7 +69,7 @@
        "tog-showhiddencats": "Sýna falda flokka",
        "tog-norollbackdiff": "Ekki sýna breytingu eftir að endurvakning síðu hefur verið gerð.",
        "tog-useeditwarning": "Vara mig við þegar ég fer frá breytingarsíðu með óvistaðar breytingar",
-       "tog-prefershttps": "Alltaf nota örugga tengingu við innskráningu",
+       "tog-prefershttps": "Alltaf nota örugga tengingu þegar þú skráir þig inn",
        "underline-always": "Alltaf",
        "underline-never": "Aldrei",
        "underline-default": "Skinn eða sjálfgefið í vafra",
        "newwindow": "(opnast í nýjum glugga)",
        "cancel": "Hætta við",
        "moredotdotdot": "Meira...",
-       "morenotlisted": "Þessi listi er ekki tæmandi.",
+       "morenotlisted": "Þessi listi gæti verið ófullgerður.",
        "mypage": "Síða",
        "mytalk": "Spjall",
        "anontalk": "Spjall",
        "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",
-       "acct_creation_throttle_hit": "Því miður, hafa verið búnir til {{PLURAL:$1|$1 nýr aðgangur|$1 nýjir aðgangar}} í dag sem er hámarksfjöldi nýskráninga á einum degi.\nÞú getur því miður ekki búið til nýjan aðgang frá þessari IP-tölu að svo stöddu.",
+       "acct_creation_throttle_hit": "Gestir á þessu wiki vefsvæði sem nota þitt vistfang hafa búið til {{PLURAL:$1|$1 nýjan aðgang|$1 nýja aðganga}} síðustu $2 sem er hámarksfjöldi nýskráninga yfir þetta tímabil. Vegna þessa geta gestir frá þessu vistfangi ekki búið til fleiri aðganga í augnablikinu.",
        "emailauthenticated": "Netfang þitt var staðfest þann $2 klukkan $3.",
        "emailnotauthenticated": "Tölvupóstfang þitt hefur ekki enn verið staðfest. Enginn póstur verður sendur af neinum af eftirfarandi eiginleikum.",
        "noemailprefs": "Tilgreindu netfang í kjörstillingum þínum svo þessar aðgerðir virki.",
        "searchprofile-advanced-tooltip": "Leita í ákveðnum nafnrýmum",
        "search-result-size": "$1 ({{PLURAL:$2|1 orð|$2 orð}})",
        "search-result-category-size": "{{PLURAL:$1|1 meðlimur|$1 meðlimir}} ({{PLURAL:$2|1 undirflokks|$2 undirflokka}}, {{PLURAL:$3|1 skrá|$3 skrár}})",
-       "search-redirect": "(endurbeining $1)",
+       "search-redirect": "(endurbeint frá $1)",
        "search-section": "(hluti $1)",
        "search-category": "(flokkur $1)",
        "search-file-match": "(passar við innihald skráa)",
        "activeusers-intro": "Þetta er listi yfir notendur sem hafa verið virkir {{PLURAL:$1|síðasta|síðustu}} $1 {{PLURAL:$1|dag|daga}}.",
        "activeusers-count": "$1 {{PLURAL:$1|aðgerð|aðgerðir}} á {{PLURAL:$3|síðasta $3 degi|síðustu $3 dögum}}",
        "activeusers-from": "Sýna notendur sem byrja á:",
-       "activeusers-hidebots": "Fela vélmenni",
-       "activeusers-hidesysops": "Fela möppudýr",
        "activeusers-noresult": "Enginn notandi fannst.",
        "activeusers-submit": "Sýna virka notendur",
        "listgrouprights": "Notandahópréttindi",
        "listgrouprights-namespaceprotection-restrictedto": "Réttindi sem leyfa notanda að breyta",
        "listgrants-rights": "Réttindi",
        "trackingcategories-name": "Heiti skilaboða",
+       "restricted-displaytitle-ignored": "Síður með hunsaða sýnda titla",
        "trackingcategories-nodesc": "Enginn lýsing tiltæk.",
        "trackingcategories-disabled": "Flokkurinn er óvirkur",
        "mailnologin": "Ekkert netfang til að senda á",
        "thumbnail_image-missing": "Skrána virðist vanta: $1",
        "import": "Flytja inn síður",
        "importinterwiki": "Flytja inn frá öðru wiki",
-       "import-interwiki-text": "Veldu wiki og síðutitil til að flytja inn.\nDagsetningumog notandanöfnum breytinganna verður haldið.\nAllir innflutningar frá öðrum wikium eru skráð í [[Special:Log/import|innflutningsskrána]].",
+       "import-interwiki-text": "Veldu wiki og síðutitil til að flytja inn.\nDagsetningum og notandanöfnum breytinganna verður haldið.\nAllir innflutningar frá öðrum wikium eru skráð í [[Special:Log/import|innflutningsskrána]].",
        "import-interwiki-sourcewiki": "Uppruna-wiki:",
        "import-interwiki-sourcepage": "Upprunaleg síða:",
        "import-interwiki-history": "Afrita allar breytingar þessarar síðu",
        "tags-actions-header": "Aðgerðir",
        "tags-active-yes": "Já",
        "tags-active-no": "Nei",
-       "tags-source-extension": "Skilgreint af viðbótarhugbúnaði",
+       "tags-source-extension": "Skilgreint af hugbúnaðinum",
        "tags-source-manual": "Sett inn handvirkt að notendum og vélmennum",
        "tags-source-none": "Ekki lengur í notkun",
        "tags-edit": "breyta",
        "htmlform-title-not-exists": "$1 er ekki til",
        "htmlform-user-not-exists": "<strong>$1</strong> er ekki til.",
        "htmlform-user-not-valid": "<strong>$1</strong> er ekki gilt notandanafn.",
-       "sqlite-has-fts": "$1 með fullum texta leitar stuðningi",
-       "sqlite-no-fts": "$1 án fullum texta leitar stuðningi",
        "logentry-delete-delete": "$1 {{GENDER:$2|eyddi}} síðunni $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|endurvakti}} $3",
        "logentry-delete-event": "$1 {{GENDER:$2|breytti}} sýnileika {{PLURAL:$5|færslu|$5 færslna}} á $3: $4",
        "feedback-external-bug-report-button": "Senda inn tæknilegar lýsingar/verkefni",
        "feedback-dialog-title": "Senda umsögn",
        "feedback-dialog-intro": "Þú getur þú notað einfalt eyðublað hér fyrir neðan til að senda inn umsögn. Athugasemdinni þinni verður bætt við síðuna \"$1\" ásamt notandanafni þínu.",
-       "feedback-error-title": "Villa",
        "feedback-error1": "Villa: Óþekkt útkoma frá API",
        "feedback-error2": "Villa: Breytingin mistókst",
        "feedback-error3": "Villa: Ekkert svar frá API",
        "feedback-thanks": "Takk! Ábendingu þinni hefur verið bætt við á síðuna \"[$2 $1]\".",
        "feedback-thanks-title": "Takk!",
        "feedback-useragent": "Aðgangsforrit:",
-       "searchsuggest-search": "Leita",
+       "searchsuggest-search": "Leita á {{SITENAME}}",
        "searchsuggest-containing": "sem innihalda ...",
        "api-error-badaccess-groups": "Þú hefur ekki leyfi til að hlaða inn skrám.",
        "api-error-badtoken": "Innri villa: Skemmdur tóki.",
index a5bdb02..f183d6e 100644 (file)
                        "Einreiher",
                        "Anto",
                        "Saracrovetto",
-                       "Tosky"
+                       "Tosky",
+                       "Selven"
                ]
        },
        "tog-underline": "Sottolinea i collegamenti:",
        "talk": "Discussione",
        "views": "Visite",
        "toolbox": "Strumenti",
+       "tool-link-userrights": "Modifica gruppi {{GENDER:$1|utente}}",
        "tool-link-emailuser": "Invia una email a questo {{GENDER:$1|utente}}",
        "userpage": "Visualizza la pagina utente",
        "projectpage": "Visualizza la pagina di servizio",
        "createacct-yourpasswordagain-ph": "Inserisci nuovamente la password",
        "userlogin-remembermypassword": "Mantienimi collegato",
        "userlogin-signwithsecure": "Usa una connessione sicura",
+       "cannotlogin-title": "Non è possibile effettuare l'accesso",
        "cannotlogin-text": "L'accesso non è possibile.",
        "cannotloginnow-title": "Impossibile accedere ora",
        "cannotloginnow-text": "L'accesso non è possibile quando si sta usando $1.",
        "botpasswords-label-delete": "Cancella",
        "botpasswords-label-resetpassword": "Reimposta la password",
        "botpasswords-label-grants": "Assegnazioni applicabili:",
-       "botpasswords-help-grants": "Ogni assegnazione dà accesso ai diritti utente elencati che un'utenza ha già. Vedi la [[Special:ListGrants|tabella delle assegnazioni]] per ulteriori informazioni.",
+       "botpasswords-help-grants": "Le assegnazioni consentono l'accesso a diritti che la tua utenza possiede già. Attivare un'assegnazione qui non fornisce l'accesso ad alcun diritto che la tua utenza altrimenti non avrebbe. Vedi la [[Special:ListGrants|tabella delle assegnazioni]] per ulteriori informazioni.",
        "botpasswords-label-grants-column": "Assegnazioni",
        "botpasswords-bad-appid": "Il nome bot \"$1\" non è valido.",
        "botpasswords-insert-failed": "Impossibile aggiungere il nome bot \"$1\". È stato già aggiunto?",
        "passwordreset-nocaller": "Un chiamante deve essere fornito",
        "passwordreset-nosuchcaller": "Chiamante non esiste: $1",
        "passwordreset-ignored": "La reimpostazione della password non è stata gestita. Forse nessun provider è configurato?",
-       "passwordreset-invalideamil": "Indirizzo di posta elettronica non valido",
+       "passwordreset-invalidemail": "Indirizzo di posta elettronica non valido",
        "passwordreset-nodata": "Non è stato fornito né un nome utente né un indirizzo di posta elettronica",
        "changeemail": "Modifica o rimuovi indirizzo di posta elettronica",
        "changeemail-header": "Completa questo modulo per cambiare il tuo indirizzo email. Se vuoi rimuovere l'associazione di qualsiasi indirizzo email dalla tua utenza, lascia il nuovo indirizzo email vuoto quando invii il modulo.",
        "searchprofile-advanced-tooltip": "Cerca nei namespace personalizzati",
        "search-result-size": "$1 ({{PLURAL:$2|una parola|$2 parole}})",
        "search-result-category-size": "{{PLURAL:$1|1 utente|$1 utenti}} ({{PLURAL:$2|1 sottocategoria|$2 sottocategorie}}, {{PLURAL:$3|1 file|$3 files}})",
-       "search-redirect": "(redirect $1)",
+       "search-redirect": "(reindirizzamento da $1)",
        "search-section": "(sezione $1)",
        "search-category": "(categoria $1)",
        "search-file-match": "(corrispondenza nel contenuto del file)",
        "grant-basic": "Diritti di base",
        "grant-viewdeleted": "Vede i file e le pagine cancellati",
        "grant-viewmywatchlist": "Vede i tuoi osservati speciali",
+       "grant-viewrestrictedlogs": "Vedi valori privati del registro",
        "newuserlogpage": "Nuovi utenti",
        "newuserlogpagetext": "Di seguito sono elencate le utenze di nuova creazione.",
        "rightslog": "Diritti degli utenti",
        "upload-http-error": "Si è verificato un errore HTTP: $1",
        "upload-copy-upload-invalid-domain": "Non è consentito il caricamento di copie da questo dominio.",
        "upload-foreign-cant-upload": "Questo wiki non è configurato per caricare i file nel repository di file esterno richiesto.",
+       "upload-foreign-cant-load-config": "Impossibile caricare il file di configurazione per caricarlo nel repositorio esterno.",
        "upload-dialog-disabled": "Il caricamento di file tramite questa finestra di dialogo è disabilitato in questo wiki.",
        "upload-dialog-title": "Carica file",
        "upload-dialog-button-cancel": "Annulla",
+       "upload-dialog-button-back": "Indietro",
        "upload-dialog-button-done": "Fatto",
        "upload-dialog-button-save": "Salva",
        "upload-dialog-button-upload": "Carica",
        "uploadstash-errclear": "La pulizia dei file non è riuscita.",
        "uploadstash-refresh": "Aggiorna l'elenco dei file",
        "uploadstash-thumbnail": "vedi miniatura",
+       "uploadstash-exception": "Impossibile memorizzare il caricamento in stash ($1): \"$2\".",
        "invalid-chunk-offset": "Offset della parte non valido.",
        "img-auth-accessdenied": "Accesso negato",
        "img-auth-nopathinfo": "PATH_INFO mancante.\nIl server non è impostato per passare questa informazione.\nPotrebbe essere basato su CGI e non può supportare img_auth.\nVedi https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization",
        "listfiles_date": "Data",
        "listfiles_name": "Nome",
        "listfiles_user": "Utente",
-       "listfiles_size": "Dimensione in byte",
+       "listfiles_size": "Dimensione",
        "listfiles_description": "Descrizione",
        "listfiles_count": "Versioni",
        "listfiles-show-all": "Includi le vecchie versioni delle immagini",
        "apisandbox-results-fixtoken-fail": "Impossibile recuperare il token \"$1\".",
        "apisandbox-alert-page": "I campi su questa pagina non sono validi.",
        "apisandbox-alert-field": "Il valore di questo campo non è valido.",
+       "apisandbox-continue": "Continua",
+       "apisandbox-continue-clear": "Pulisci",
+       "apisandbox-param-limit": "Inserisci <kbd>max</kbd> per utilizzare il limite massimo.",
        "booksources": "Fonti librarie",
        "booksources-search-legend": "Ricerca di fonti librarie",
        "booksources-isbn": "Codice ISBN:",
        "booksources-search": "Cerca",
        "booksources-text": "Di seguito sono elencati alcuni collegamenti verso siti esterni che vendono libri nuovi e usati, attraverso i quali è possibile ottenere maggiori informazioni sul testo cercato.",
        "booksources-invalid-isbn": "L'ISBN inserito sembra non essere valido; verificare che non siano stati commessi errori nel copiarlo dalla fonte originale.",
+       "magiclink-tracking-rfc": "Pagine che utilizzano collegamenti magici RFC",
+       "magiclink-tracking-rfc-desc": "Questa pagina utilizza collegamenti magici RFC. Vedi [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] su come eseguire la migrazione.",
+       "magiclink-tracking-pmid": "Pagine che utilizzano collegamenti magici PMID",
+       "magiclink-tracking-pmid-desc": "Questa pagina utilizza collegamenti magici PMID. Vedi [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] su come eseguire la migrazione.",
+       "magiclink-tracking-isbn": "Pagine che utilizzano collegamenti magici ISBN",
+       "magiclink-tracking-isbn-desc": "Questa pagina utilizza collegamenti magici ISBN. Vedi [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] su come eseguire la migrazione.",
        "specialloguserlabel": "Azione effettuata da:",
        "speciallogtitlelabel": "Azione effettuata su (titolo della pagina o {{ns:user}}:Nome utente):",
        "log": "Registri",
        "listusers-noresult": "Nessun utente risponde ai criteri impostati.",
        "listusers-blocked": "(bloccato)",
        "activeusers": "Elenco degli utenti attivi",
-       "activeusers-intro": "Questo è un elenco di utenti che hanno avuto qualche tipo di attività da $1 {{PLURAL:$1|giorno|giorni}} a questa parte.",
+       "activeusers-intro": "Questo è un elenco di utenti che hanno avuto qualche tipo di attività {{PLURAL:$1|nell'ultimo giorno|negli ultimi $1 giorni}}.",
        "activeusers-count": "$1 {{PLURAL:$1|azione|azioni}} {{PLURAL:$3|nell'ultimo giorno|negli ultimi $3 giorni}}",
        "activeusers-from": "Mostra gli utenti a partire da:",
-       "activeusers-hidebots": "Nascondi i bot",
-       "activeusers-hidesysops": "Nascondi gli amministratori",
+       "activeusers-groups": "Visualizza gli utenti appartenenti ai gruppi:",
        "activeusers-noresult": "Nessun utente risponde ai criteri impostati.",
        "activeusers-submit": "Mostra utenti attivi",
        "listgrouprights": "Diritti del gruppo utente",
        "modifiedarticleprotection": "ha modificato il livello di protezione di \"[[$1]]\"",
        "unprotectedarticle": "ha sprotetto \"[[$1]]\"",
        "movedarticleprotection": "ha spostato la protezione da \"[[$2]]\" a \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|Protetto}} \"[[$1]]\"",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Modificato il livello di protezione}} per \"[[$1]]\"",
+       "unprotectedarticle-comment": "{{GENDER:$2|Rimossa la protezione}} da \"[[$1]]\"",
        "protect-title": "Modifica del livello di protezione per \"$1\"",
        "protect-title-notallowed": "Visualizza il livello di protezione di \" $1 \"",
        "prot_1movedto2": "ha spostato [[$1]] a [[$2]]",
        "movelogpagetext": "Di seguito sono elencate le pagine spostate di recente.",
        "movesubpage": "{{PLURAL:$1|Sottopagina|Sottopagine}}",
        "movesubpagetext": "Questa pagina ha $1 {{PLURAL:$1|sottopagina mostrata|sottopagine mostrate}} di seguito.",
+       "movesubpagetalktext": "La corrispondente pagina di discussione ha $1 {{PLURAL:$1|sottopagina mostrata|sottopagine mostrate}} di seguito.",
        "movenosubpage": "Questa pagina non ha sottopagine.",
        "movereason": "Motivo:",
        "revertmove": "ripristina",
        "pageinfo-category-pages": "Numero di pagine",
        "pageinfo-category-subcats": "Numero di sottocategorie",
        "pageinfo-category-files": "Numero di file",
+       "pageinfo-user-id": "ID utente",
        "markaspatrolleddiff": "Segna come verificata",
        "markaspatrolledtext": "Segna questa pagina come verificata",
        "markaspatrolledtext-file": "Segna questo file come verificato",
        "patrol-log-header": "Di seguito sono elencate le verifiche delle modifiche.",
        "log-show-hide-patrol": "$1 registro delle modifiche verificate",
        "log-show-hide-tag": "$1 registro delle etichette",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Segna versione $3 di $2 come verificata?",
        "deletedrevision": "Cancellata la vecchia versione di $1.",
        "filedeleteerror-short": "Errore nella cancellazione del file: $1",
        "filedeleteerror-long": "Si sono verificati degli errori nel tentativo di cancellare il file:\n\n$1",
        "newimages-showbots": "Mostra caricamenti di bot",
        "newimages-hidepatrolled": "Nascondi caricamenti verificati",
        "noimages": "Non c'è nulla da vedere.",
+       "gallery-slideshow-toggle": "Alterna miniature",
        "ilsubmit": "Ricerca",
        "bydate": "per data",
        "sp-newimages-showfrom": "Mostra i file più recenti a partire dalle ore $2 del $1",
        "tags-deactivate": "disattiva",
        "tags-hitcount": "$1 {{PLURAL:$1|modifica|modifiche}}",
        "tags-manage-no-permission": "Non si dispone dei permessi necessari per gestire le etichette di modifica.",
-       "tags-manage-blocked": "Non puoi gestire le etichette alle modifiche mentre sei bloccato.",
+       "tags-manage-blocked": "Non puoi gestire le etichette alle modifiche mentre {{GENDER:$1|sei}} bloccato.",
        "tags-create-heading": "Crea un nuovo tag",
        "tags-create-explanation": "Per impostazione predefinita, i tag appena creati saranno disponibili per l'utilizzo di utenti e bot.",
        "tags-create-tag-name": "Nome del tag:",
        "tags-deactivate-not-allowed": "Non è possibile disattivare il tag \"$1\".",
        "tags-deactivate-submit": "Disattiva",
        "tags-apply-no-permission": "Non disponi dell'autorizzazione per applicare la modifica di tag insieme con le tue modifiche.",
-       "tags-apply-blocked": "Non puoi applicare le etichette alle modifiche mentre sei bloccato.",
+       "tags-apply-blocked": "Non puoi applicare le etichette alle modifiche mentre {{GENDER:$1|sei}} bloccato.",
        "tags-apply-not-allowed-one": "L'etichetta \"$1\" non può essere applicata manualmente.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|La seguente etichetta non può essere applicata|Le seguenti etichette non possono essere applicate}}  manualmente: $1",
        "tags-update-no-permission": "Non si dispone dei permessi necessari per aggiungere o rimuovere le etichette di modifica dalle singole versioni o voci di registro.",
-       "tags-update-blocked": "Non puoi aggiungere o rimuovere le etichette alle modifiche mentre sei bloccato.",
+       "tags-update-blocked": "Non puoi aggiungere o rimuovere le etichette alle modifiche mentre {{GENDER:$1|sei}} bloccato.",
        "tags-update-add-not-allowed-one": "Il tag \"$1\" non può essere aggiunto manualmente.",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|Il seguente tag non può essere aggiunto|I seguenti tag non possono essere aggiunti}} manualmente: $1",
        "tags-update-remove-not-allowed-one": "Il tag \"$1\" non può essere rimosso.",
        "htmlform-cloner-create": "Aggiungi altro",
        "htmlform-cloner-delete": "Rimuovi",
        "htmlform-cloner-required": "È obbligatorio almeno un valore.",
+       "htmlform-date-placeholder": "AAAA-MM-GG",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "AAAA-MM-GG HH:MM:SS",
+       "htmlform-date-invalid": "Il valore specificato non è riconosciuto come data. Prova a utilizzare il formato AAAA-MM-GG.",
+       "htmlform-time-invalid": "Il valore specificato non è riconosciuto come orario. Prova a utilizzare il formato HH:MM:SS.",
+       "htmlform-datetime-invalid": "Il valore specificato non è riconosciuto come data e ora. Prova a utilizzare il formato AAAA-MM-GG HH:MM:SS.",
+       "htmlform-date-toolow": "Il valore specificato è precedente alla prima data consentita del $1.",
+       "htmlform-date-toohigh": "Il valore specificato è successivo all'ultima data consentita del $1.",
+       "htmlform-time-toolow": "Il valore specificato è precedente al primo orario consentito del $1.",
+       "htmlform-time-toohigh": "Il valore specificato è successivo all'ultimo orario consentito di $1.",
+       "htmlform-datetime-toolow": "Il valore specificato è precedente alla prima data e ora consentita del $1.",
+       "htmlform-datetime-toohigh": "Il valore specificato è successivo all'ultima data e ora consentita del $1.",
        "htmlform-title-badnamespace": "[[:$1]] non si trova nel namespace \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" è il titolo di una pagina non creabile",
        "htmlform-title-not-exists": "$1 non esiste.",
        "feedback-external-bug-report-button": "Documenta un problema tecnico",
        "feedback-dialog-title": "Invia un feedback",
        "feedback-dialog-intro": "Usa il modulo sottostante per inviare il tuo feedback. Il tuo commento apparirà nella pagina \"$1\", assieme al tuo nome utente.",
-       "feedback-error-title": "Errore",
        "feedback-error1": "Errore: Dalla API è arrivato un risultato non riconosciuto",
        "feedback-error2": "Errore: Non è stato possibile eseguire la modifica",
        "feedback-error3": "Errore: Nessuna risposta dalla API",
        "feedback-thanks": "Grazie! Il tuo feedback è stato pubblicato alla pagina \"[$2 $1]\".",
        "feedback-thanks-title": "Grazie!",
        "feedback-useragent": "Agente utente:",
-       "searchsuggest-search": "Ricerca",
+       "searchsuggest-search": "Cerca all'interno di {{SITENAME}}",
        "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.",
        "authmanager-authn-autocreate-failed": "Creazione automatica di un'utenza locale fallita: $1",
        "authmanager-change-not-supported": "Le credenziali fornite non possono essere modificate, dato che non verrebbero usate da nulla.",
        "authmanager-create-disabled": "La creazione di utenze è disabilitata.",
-       "authmanager-create-from-login": "Per creare la tua utenza, completa i campi qui sotto.",
+       "authmanager-create-from-login": "Per creare la tua utenza, completa i campi.",
        "authmanager-create-not-in-progress": "La creazione di un'utenza non è in corso o i dati della sessione sono andati persi. Si prega di ricominciare nuovamente dall'inizio.",
        "authmanager-create-no-primary": "Le credenziali fornite non possono essere utilizzate per la creazione dell'utenza.",
        "authmanager-link-no-primary": "Le credenziali fornite non possono essere utilizzate per il collegamento dell'utenza.",
        "linkaccounts-submit": "Collega utenze",
        "unlinkaccounts": "Scollega utenze",
        "unlinkaccounts-success": "L'utenza è stata scollegata.",
+       "authenticationdatachange-ignored": "Il cambiamento dei dati di autenticazione non è stato gestito. Forse non è stato configurato nessun provider?",
+       "userjsispublic": "Ricorda: le sottopagine JavaScript non devono contenere dati riservati poichè sono visualizzabili da altri utenti.",
+       "usercssispublic": "Ricorda: le sottopagine CSS non devono contenere dati riservati poichè sono visualizzabili da altri utenti.",
        "restrictionsfield-badip": "Indirizzo IP o intervallo non valido: $1",
        "restrictionsfield-label": "Intervalli IP consentiti:",
-       "restrictionsfield-help": "Un indirizzo IP o intervallo CIDR per linea. Per consentire tutto, utilizza<br><code>0.0.0.0/0</code><br><code>::/0</code>"
+       "restrictionsfield-help": "Un indirizzo IP o intervallo CIDR per linea. Per consentire tutto, utilizza<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Errore: $1",
+       "edit-error-long": "Errori:\n\n$1"
 }
index 72b6873..7d2a8e1 100644 (file)
@@ -72,7 +72,9 @@
                        "Shield-9",
                        "Waiesu",
                        "Matma Rex",
-                       "組曲師"
+                       "組曲師",
+                       "Foresttttttt",
+                       "ネイ"
                ]
        },
        "tog-underline": "リンクの下線:",
        "newwindow": "(新しいウィンドウで開きます)",
        "cancel": "取り消し",
        "moredotdotdot": "続き...",
-       "morenotlisted": "この一覧は完全ではありません。",
+       "morenotlisted": "この一覧はおそらく完全ではありません。",
        "mypage": "ページ",
        "mytalk": "トーク",
        "anontalk": "トーク",
        "talk": "議論",
        "views": "表示",
        "toolbox": "ツール",
+       "tool-link-userrights": "{{GENDER:$1|利用者}}グループの変更",
        "tool-link-emailuser": "この{{GENDER:$1|利用者}}にメールを送信",
        "userpage": "利用者ページを表示",
        "projectpage": "プロジェクトのページを表示",
        "databaseerror-query": "クエリ: $1",
        "databaseerror-function": "関数: $1",
        "databaseerror-error": "エラー: $1",
+       "transaction-duration-limit-exceeded": "書き込み処理時間 ($1) が $2 秒の制限に達したため、過多なレプリケーションの遅延を避けることを目的に、このトランザクションは中止されました。\n一度に多数の変更を試みた場合、処理を複数に細分化して実行してください。",
        "laggedslavemode": "<strong>警告:</strong> ページに最新の編集が反映されていない可能性があります。",
        "readonly": "データベースがロックされています",
        "enterlockreason": "ロックの理由の入力と、ロック解除の予定を、入力してください",
        "createacct-yourpasswordagain-ph": "パスワードを再入力",
        "userlogin-remembermypassword": "ログイン状態を保持",
        "userlogin-signwithsecure": "安全な接続の使用",
+       "cannotlogin-title": "ログイン不能",
+       "cannotlogin-text": "ログインできません",
        "cannotloginnow-title": "今はログインできません",
        "cannotloginnow-text": "$1 使用中には、ログインは不可能です。",
+       "cannotcreateaccount-title": "アカウント作成不可",
+       "cannotcreateaccount-text": "このウィキではアカウントの直接作成が無効になっています。",
        "yourdomainname": "あなたのドメイン:",
        "password-change-forbidden": "このウィキではパスワードを変更できません。",
        "externaldberror": "認証データベースでエラーが発生したか、または外部アカウントの更新が許可されていません。",
        "eauthentsent": "指定したメールアドレスに、アドレス確認のためのメールをお送りしました。\nメールに記載された手順に従って、このアカウントの所有者であることの確認が取れると、このアカウント宛のメールを受け取れるようになります。",
        "throttled-mailpassword": "パスワード再設定メールを過去 {{PLURAL:$1|$1 時間}}に送信済みです。\n悪用防止のため、パスワードの再設定は {{PLURAL:$1|$1 時間}}に 1 回のみです。",
        "mailerror": "メールを送信する際にエラーが発生しました: $1",
-       "acct_creation_throttle_hit": "あなたと同じ IP アドレスでこのウィキに訪れた人が、最近 24 時間で {{PLURAL:$1|$1 アカウント}}を作成しており、これはこの期間で作成が許可されている最大数です。\nそのため、現在この IP アドレスではアカウントをこれ以上作成できません。",
+       "acct_creation_throttle_hit": "あなたと同じ IP アドレスでこのウィキに訪れた人が、直近 $2 で {{PLURAL:$1|$1 個のアカウント}}を作成しており、この期間で作成が許可されている最大数です。\nそのため、現在この IP アドレスからこれ以上のアカウントを作成できません。",
        "emailauthenticated": "メールアドレスは$2で $3に確認済みです。",
        "emailnotauthenticated": "メールアドレスが確認されていません。\n確認されるまで、以下のいかなる機能でもメールは送信されません。",
        "noemailprefs": "これらの機能を有効にするには、個人設定でメールアドレスを登録してください。",
        "botpasswords-label-delete": "削除",
        "botpasswords-label-resetpassword": "パスワードをリセット",
        "botpasswords-label-grants": "該当する権限群",
-       "botpasswords-help-grants": "各権限群は、一覧にある利用者権限で現在の利用者アカウントが既に有している権限を付与します。詳細については、[[Special:ListGrants|権限群の表]]をご覧ください。",
+       "botpasswords-help-grants": "権限群は、現在の利用者アカウントが既に有している権限を付与します。ここで権限群を付与しても、あなたの利用者アカウントが有していない権限を付与しません。詳しくは[[Special:ListGrants|権限群の表]]をご覧ください。",
        "botpasswords-label-grants-column": "付与",
        "botpasswords-bad-appid": "ボット「$1」は有効ではありません。",
        "botpasswords-insert-failed": "ボット「$1」の追加に失敗しました。既に追加されていないか確認してください。",
        "passwordreset-emailsent-capture2": "パスワードリセットの{{PLURAL:$1|メール}}が送信されました。{{PLURAL:$1|利用者名とパスワード|利用者名とパスワードの一覧}}は以下のとおりです。",
        "passwordreset-emailerror-capture2": "{{GENDER:$2|利用者}}へのメール送信に失敗しました: $1{{PLURAL:$3|利用者名とパスワード|利用者名とパスワードの一覧}}は以下のとおりです。",
        "passwordreset-ignored": "パスワードのリセットが処理されませんでした。プロバイダーが設定されていない可能性があります。",
-       "passwordreset-invalideamil": "無効なメールアドレスです",
+       "passwordreset-invalidemail": "無効なメールアドレスです",
        "changeemail": "メールアドレスの変更または除去",
        "changeemail-header": "あなたのメールアドレスを変更するには、このフォームを完成させます。もし、あなたのアカウントから任意のメールアドレスの関連付けを削除したい場合は、フォームの送信時に、新しいメールアドレスを空白のままにします。",
        "changeemail-no-info": "このページに直接アクセスするためにはログインしている必要があります。",
        "right-deletechangetags": "データベースから[[Special:Tags|タグ]]を削除します",
        "grant-group-email": "メールの送信",
        "grant-group-customization": "カスタマイズと個人設定",
+       "grant-group-private-information": "あなたの個人情報にアクセスする",
        "grant-group-other": "その他の活動",
        "grant-blockusers": "利用者をブロックおよびブロック解除",
        "grant-createaccount": "アカウントを作成",
        "grant-highvolume": "多量の編集",
        "grant-oversight": "利用者名および版を秘匿",
        "grant-patrol": "ページへの変更の巡回",
+       "grant-privateinfo": "個人情報アクセス",
        "grant-protect": "ページを保護および保護解除",
        "grant-rollback": "ページヘの変更の巻き戻し",
        "grant-sendemail": "他の利用者へのメールの送信",
        "upload-dialog-disabled": "このウィキでは、このダイアログを使用するファイルのアップロードが無効にされています。",
        "upload-dialog-title": "ファイルをアップロード",
        "upload-dialog-button-cancel": "中止",
+       "upload-dialog-button-back": "戻る",
        "upload-dialog-button-done": "完了",
        "upload-dialog-button-save": "保存",
        "upload-dialog-button-upload": "アップロード",
        "apisandbox-results-fixtoken-fail": "\"$1\" トークンの取得に失敗しました。",
        "apisandbox-alert-page": "このページの欄が有効ではありません。",
        "apisandbox-alert-field": "この欄の値が有効ではありません。",
+       "apisandbox-continue": "続行",
+       "apisandbox-continue-clear": "消去",
        "booksources": "書籍情報源",
        "booksources-search-legend": "書籍情報源を検索",
        "booksources-isbn": "ISBN:",
        "activeusers-intro": "これは過去 $1 {{PLURAL:$1|日|日間}}に何らかの活動をした利用者の一覧です。",
        "activeusers-count": "過去 {{PLURAL:$3|1 日|$3 日間}}に $1 {{PLURAL:$1|回の操作}}",
        "activeusers-from": "最初に表示する利用者:",
-       "activeusers-hidebots": "ボットを隠す",
-       "activeusers-hidesysops": "管理者を隠す",
        "activeusers-noresult": "利用者が見つかりませんでした。",
        "activeusers-submit": "活動中の利用者を表示",
        "listgrouprights": "利用者グループの権限",
        "confirmdeletetext": "ページをすべての履歴とともに削除しようとしています。\n本当にこの操作を行いたいか、操作の結果を理解しているか、およびこの操作が[[{{MediaWiki:Policy-url}}|方針]]に従っているかどうか、確認してください。",
        "actioncomplete": "操作を完了しました",
        "actionfailed": "操作に失敗しました",
-       "deletedtext": "ã\80\8c$1ã\80\8dã\81¯å\89\8aé\99¤ã\81\95ã\82\8cã\81¾ã\81\97ã\81\9fã\80\82\næ\9c\80è¿\91ã\81®å\89\8aé\99¤ã\81«ã\81¤ã\81\84ã\81¦ã\81¯ã\80\81$2ã\82\92å\8f\82ç\85§ã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84。",
+       "deletedtext": "ã\80\8c$1ã\80\8dã\81¯å\89\8aé\99¤ã\81\95ã\82\8cã\81¾ã\81\97ã\81\9fã\80\82\næ\9c\80è¿\91ã\81®å\89\8aé\99¤ã\81¯$2ã\81§å\8f\82ç\85§ã\81§ã\81\8dã\81¾ã\81\99。",
        "dellogpage": "削除記録",
        "dellogpagetext": "以下は最近の削除と復元の一覧です。",
        "deletionlog": "削除記録",
        "rollbacklinkcount": "$1{{PLURAL:$1|編集}}を巻き戻し",
        "rollbacklinkcount-morethan": "$1{{PLURAL:$1|編集}}以上を巻き戻し",
        "rollbackfailed": "巻き戻しに失敗しました",
+       "rollback-missingparam": "リクエストに必要なパラメーターが見当たりません。",
+       "rollback-missingrevision": "版の情報を読み込めませんでした。",
        "cantrollback": "編集を差し戻せません。\n最後の投稿者が、このページの唯一の作者です。",
        "alreadyrolled": "ページ[[:$1]]の[[User:$2|$2]] ([[User talk:$2|トーク]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) による編集を巻き戻せません。\n他の利用者が既に編集または巻き戻しを行ったためです。\n\nこのページの最後の編集は[[User:$3|$3]] ([[User talk:$3|トーク]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]) によるものです。",
        "editcomment": "編集内容の要約: <em>$1</em>",
        "undeletedrevisions-files": "{{PLURAL:$1|$1版}}と{{PLURAL:$2|$2ファイル}}を復元しました",
        "undeletedfiles": "{{PLURAL:$1|$1ファイル}}を復元しました",
        "cannotundelete": "復元に一部またはすべて失敗しました:\n$1",
-       "undeletedpage": "<strong>$1を復元しました。</strong>\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": "削除されたページの検索",
        "revertmove": "差し戻し",
        "delete_and_move_text": "移動先「[[:$1]]」は既に存在します。\n移動のためにこのページを削除しますか?",
        "delete_and_move_confirm": "はい、ページを削除します",
-       "delete_and_move_reason": "ã\80\8c[[$1]]ã\80\8dã\81\8bã\82\89ã\81®ç§»å\8b\95ã\81®ã\81\9fã\82\81ã\81«削除",
+       "delete_and_move_reason": "ã\80\8c[[$1]]ã\80\8dã\81\8bã\82\89ã\81®ç§»å\8b\95ã\81«ä¼´ã\81\86削除",
        "selfmove": "移動元と移動先のページ名が同じです。\n自分自身には移動できません。",
        "immobile-source-namespace": "「$1」名前空間のページは移動できません",
        "immobile-target-namespace": "「$1」名前空間にはページを移動できません",
        "pageinfo-article-id": "ページ ID",
        "pageinfo-language": "ページ本文の言語",
        "pageinfo-content-model": "ページのコンテンツ モデル",
+       "pageinfo-content-model-change": "設定変更",
        "pageinfo-robot-policy": "ロボットによるインデックス作成",
        "pageinfo-robot-index": "許可",
        "pageinfo-robot-noindex": "不許可",
        "pageinfo-category-pages": "ページ数",
        "pageinfo-category-subcats": "下位カテゴリ数",
        "pageinfo-category-files": "ファイル数",
+       "pageinfo-user-id": "利用者 ID",
        "markaspatrolleddiff": "巡回済みにする",
        "markaspatrolledtext": "このページを巡回済みにする",
        "markaspatrolledtext-file": "このファイルの版を巡回済みにする",
        "exif-compression-6": "JPEG (旧式)",
        "exif-copyrighted-true": "著作権あり",
        "exif-copyrighted-false": "著作権情報未設定",
-       "exif-photometricinterpretation-0": "黒と白 (白が0)",
+       "exif-photometricinterpretation-0": "黒と白(白が0です)",
        "exif-photometricinterpretation-1": "黒と白(黒が0)",
        "exif-photometricinterpretation-9": "CIE L*a*b* (ICC エンコード)",
        "exif-photometricinterpretation-10": "CIE L*a*b* (ITU エンコード)",
        "tags-actions-header": "対処操作",
        "tags-active-yes": "はい",
        "tags-active-no": "いいえ",
-       "tags-source-extension": "拡張機能による定義",
+       "tags-source-extension": "ソフトウェアによる定義",
        "tags-source-manual": "利用者およびボットによる手動適用",
        "tags-source-none": "もう使われていない",
        "tags-edit": "編集",
        "tags-deactivate": "無効化",
        "tags-hitcount": "$1 {{PLURAL:$1|回の変更}}",
        "tags-manage-no-permission": "変更タグを管理する権限がありません。",
-       "tags-manage-blocked": "ブロックされているため、変更タグを管理できません",
+       "tags-manage-blocked": "{{GENDER:$1|あなた}}はブロックされているため、変更タグを管理できません。",
        "tags-create-heading": "新しいタグを作成",
        "tags-create-explanation": "既定では、新しく作られたタグは利用者とボットによる使用が可能となります。",
        "tags-create-tag-name": "タグ名:",
        "tags-deactivate-not-allowed": "タグ「$1」は無効化できません。",
        "tags-deactivate-submit": "無効化",
        "tags-apply-no-permission": "あなたには変更と同時に変更タグを適応する権限がありません。",
-       "tags-apply-blocked": "ブロックされているため、変更タグの変更を適用できません。",
+       "tags-apply-blocked": "{{GENDER:$1|あなた}}はブロックされているため、変更タグを適用できません。",
        "tags-apply-not-allowed-one": "タグ \"$1\" の手動適用は認められていません。",
        "tags-apply-not-allowed-multi": "以下の {{PLURAL:$2|タグ}} は手動適用が認められていません: $1",
        "tags-update-no-permission": "あなたには個々の版または記録項目のタグの追加または除去を行う権限がありません。",
-       "tags-update-blocked": "ブロックされているため、変更タグを追加または除去できません。",
+       "tags-update-blocked": "{{GENDER:$1|あなた}}はブロックされているため、変更タグの追加と除去ができません。",
        "tags-update-add-not-allowed-one": "タグ \"$1\" の手動追加は認められていません。",
        "tags-update-add-not-allowed-multi": "以下の {{PLURAL:$2|タグ}} は手動追加が認められていません: $1",
        "tags-update-remove-not-allowed-one": "タグ \"$1\" の除去は認められていません。",
        "htmlform-cloner-create": "さらに追加",
        "htmlform-cloner-delete": "除去",
        "htmlform-cloner-required": "少なくとも 1 つの値が必要です。",
+       "htmlform-date-placeholder": "YYYY-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "YYYY-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "あなたが入力した日付を識別できませんでした。YYYY-MM-DD形式で試してください。",
        "htmlform-title-badnamespace": "[[:$1]]は、\"{{ns:$2}}\"名前空間にありません。",
        "htmlform-title-not-creatable": "\"$1\" は、作成可能なページ名では、ありません。",
        "htmlform-title-not-exists": "$1 は存在しません。",
        "feedback-external-bug-report-button": "技術的タスクをファイル",
        "feedback-dialog-title": "フィードバックの送信",
        "feedback-dialog-intro": "以下のフォームでフィードバックを簡単に提出できます。あなたのコメントは利用者名と共に、ページ \"$1\" に追加されるでしょう。",
-       "feedback-error-title": "エラー",
        "feedback-error1": "エラー: 認識できない結果を API が返しました",
        "feedback-error2": "エラー: 編集に失敗しました",
        "feedback-error3": "エラー: API からの応答がありません",
        "feedback-thanks": "ありがとうございます。フィードバックを「[$2 $1]」のページに投稿しました。",
        "feedback-thanks-title": "お願いします!",
        "feedback-useragent": "ユーザーエージェント:",
-       "searchsuggest-search": "検索",
+       "searchsuggest-search": "{{SITENAME}}内を検索",
        "searchsuggest-containing": "この語句を全文検索",
        "api-error-autoblocked": "あなたの IP アドレスは、過去にブロックされた利用者によって使用されていたため、自動的にブロックされました。",
        "api-error-badaccess-groups": "このウィキへのファイルのアップロードが許可されていません。",
        "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-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-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": "再アップロード",
        "authmanager-authn-not-in-progress": "認証が行われていない、またはセッションデータが失われました。最初からやり直してください。",
        "authmanager-authn-autocreate-failed": "ローカルアカウントの自動作成が失敗しました: $1",
        "authmanager-change-not-supported": "一切利用されないであろう情報のため、指定された証明情報を変更することはできません。",
        "authmanager-create-disabled": "アカウントの作成は禁止されています。",
-       "authmanager-create-from-login": "アカウントを作成するには、以下の入力欄に記入してください。",
+       "authmanager-create-from-login": "アカウントを作成するには、入力欄に記入してください。",
        "authmanager-create-not-in-progress": "アカウントの作成が行われていない、またはセッションデータが失われました。最初からやり直してください。",
        "authmanager-create-no-primary": "指定された証明情報は、アカウントの作成に使用できませんでした。",
        "authmanager-link-no-primary": "指定された証明情報は、アカウントの関連付けに使用できませんでした。",
        "linkaccounts-submit": "アカウントを関連付ける",
        "unlinkaccounts": "アカウントの関連付け解除",
        "unlinkaccounts-success": "アカウントの関連付けが解除されました。",
-       "authenticationdatachange-ignored": "認証データの変更は処理されませんでした。プロバイダーが設定されていない可能性があります。"
+       "authenticationdatachange-ignored": "認証データの変更は処理されませんでした。プロバイダーが設定されていない可能性があります。",
+       "userjsispublic": "注意: JavaScript のサブページは第三者が閲覧可能なため、機微な情報を含めないでください。",
+       "usercssispublic": "注意: CSS のサブページは第三者が閲覧可能なため、機微な情報を含めないでください。",
+       "restrictionsfield-badip": "無効な IP アドレス、またはその範囲: $1",
+       "restrictionsfield-label": "許可する IP の範囲:",
+       "restrictionsfield-help": "一行につき、単一の IP アドレス、もしくは CIDR による範囲。全帯域からの接続を許可する場合は<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "エラー: $1",
+       "edit-error-long": "エラー:\n\n\n\n$1"
 }
index 38a261f..2b14bfc 100644 (file)
        "yourpasswordagain": "Ritaip paaswod:",
        "createacct-yourpasswordagain": "Kanfoerm paaswod",
        "createacct-yourpasswordagain-ph": "Enta paaswod agen",
-       "remembermypassword": "Memba mi lagiin pan dis brouza (fi a maximom a $1 {{PLURAL:$1|die|die}})",
        "userlogin-remembermypassword": "Kip mi lagiin‎",
        "yourdomainname": "Yu domien:",
        "externaldberror": "Aida aatentikieshan dietabies era okor ar yu no lou fi opdiet yu extoernal akount.",
        "permissionserrorstext-withaction": "Yu no ab no poermishan fi $2, fi di falarin {{PLURAL:$1|riizn|riizndem}}:",
        "moveddeleted-notice": "Dis piej eh diliit.\nDi diliishan ah muuv lag fi di piej provaid biluo fi refrans.‎",
        "edit-conflict": "Hedit kanflik: $1",
-       "cantcreateaccounttitle": "Cyannat mek di hakkount",
        "viewpagelogs": "Vyuu lagdem fi dis piej",
        "currentrev-asof": "Lietis rivijan az av $1",
        "revisionasof": "Rivijan az av $1",
index 57d4099..48cf4aa 100644 (file)
        "yourpasswordagain": "Djentast adgångskode:",
        "createacct-yourpasswordagain": "Bekräft adgångskode",
        "createacct-yourpasswordagain-ph": "Intast adgångskode idjen",
-       "remembermypassword": "Husk min brugenaun i denn browser (hyest $1 {{PLURAL:$1|daw}})",
        "userlogin-remembermypassword": "Husk mej",
        "userlogin-signwithsecure": "Brug siker forbinjels",
        "yourdomainname": "Det domænnaun:",
index 50acfa0..4474661 100644 (file)
        "activeusers-intro": "Iki daptar panganggo sing katon lakuné ing $1 {{PLURAL:$1|dina|dina}} kapungkur.",
        "activeusers-count": "$1 {{PLURAL:$1|suntingan|suntingan}} ing {{PLURAL:$3|dina|$3 dina}} pungkasan",
        "activeusers-from": "Tampilna panganggo wiwit saka:",
-       "activeusers-hidebots": "Delikna bot",
-       "activeusers-hidesysops": "Delikna pangurus",
        "activeusers-noresult": "Naraguna ora ana.",
        "listgrouprights": "Hak-hak grup panganggo",
        "listgrouprights-summary": "Ing ngisor iki kapacak dhaftar grup panganggo sing didéfinisi ing wiki iki, kanthi hak-hak aksès gandhèngané.\nInformasi tambahan perkara hak-hak individual bisa ditemokaké ing [[{{MediaWiki:Listgrouprights-helppage}}|kéné]].",
        "feedback-bugornote": "Yèn Sampéyan siap njelasaké masalah tèhnis kanthi rinci mangga [$1 laporaké bug].\nUtawa, Sampéyan bisa nganggo pormulir gampang ngisor. Tanggepan Sampéyan bakal ditambahaké nèng kaca \"[$3 $2]\", bebarengan karo jeneng panganggo Sampéyan lan pramban sing Sampéyan anggo.",
        "feedback-cancel": "Batal",
        "feedback-close": "Rampung",
-       "feedback-error-title": "Cacad",
        "feedback-error1": "Kasalahan: Asil ora dikenal saka API",
        "feedback-error2": "Cacad: Gagal mbesut",
        "feedback-error3": "Kasalahan: Ora ana tanggepan saka API",
        "feedback-submit": "Kirim",
        "feedback-thanks": "Nuwun! Lebon saran Sampéyan wis dipasang nèng kacané \"[$2 $1]\".",
        "searchsuggest-search": "Golèk",
-       "searchsuggest-containing": "ngisi...",
+       "searchsuggest-containing": "ngemu...",
        "api-error-badaccess-groups": "Sampéyan ora dililakaké ngunggah berkas nèng wiki iki.",
        "api-error-badtoken": "Kasalahan njero: Token èlèk.",
        "api-error-copyuploaddisabled": "Ngunggah saka URL dipatèni nèng sasana iki.",
index a85c60b..a2fd8c9 100644 (file)
        "createacct-benefit-heading": "{{SITENAME}} შექმნილია თქვენნაირი ადამიანების მიერ.",
        "createacct-benefit-body1": "{{PLURAL:$1|რედაქტირება|რედაქტირება}}",
        "createacct-benefit-body2": "{{PLURAL:$1|გვერდი|გვერდი}}",
-       "createacct-benefit-body3": "á\83\91á\83\9dá\83\9aá\83\9d {{PLURAL:$1|á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\94á\83\9aá\83\98\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\94á\83\9aი}}",
+       "createacct-benefit-body3": "á\83\91á\83\9dá\83\9aá\83\9d {{PLURAL:$1|á\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\9dá\83 á\83\98\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\9dá\83 ი}}",
        "badretype": "თქვენს მიერ შეყვანილი პაროლები ერთმანეთს არ ემთხვევა.",
        "usernameinprogress": "ამ მომხმარებლისათვის ანგარიში იქმნება. გთხოვთ, დაიცადეთ.",
        "userexists": "ეს სახელი უკვე გამოყენებულია.\nგთხოვთ, აირჩიეთ სხვა.",
        "passwordreset-nocaller": "გამომძახებელი უნდა იყოს მიწოდებული",
        "passwordreset-nosuchcaller": "გამომძახებელი არ არსებობს: $1",
        "passwordreset-ignored": "პაროლის გაუქმება არ იქნა შესრულებული. შეიძლება კონფიგურაციაში პროვაიდერი არ იყო გათვალისწინებული?",
-       "passwordreset-invalideamil": "ელ-ფოსტის არასწორი მისამართი",
+       "passwordreset-invalidemail": "ელ-ფოსტის არასწორი მისამართი",
        "passwordreset-nodata": "არც მომხმარებლის სახელი და არც ელ-ფოსტის მისამართი არ იყო მოწოდებული",
        "changeemail": "ელ-ფოსტის მისამართის შეცვლა ან წაშლა",
        "changeemail-header": "შეავსეთ ეს ფორმა მეილის შესაცვლელად. თუ გსურთ თქვენი ანგარიში არ იყოს დაკავშირებული არცერთ მეილთან, ახალი მეილის მისამართის ველი დატოვეთ ცარიელი.",
        "activeusers-intro": "ეს არის მომხმარებელთა სია, რომელთაც აქვს წვლილი უკანასკნელი $1 {{PLURAL:$1|დღის|დღის}} განმავლობაში.",
        "activeusers-count": "$1 {{PLURAL:$1|მოქმედება|მოქმედება}} {{PLURAL:$3|დღის|$3 დღის}} განმავლობაში.",
        "activeusers-from": "მომხმარებელთა ჩვენება, დაწყებული:",
-       "activeusers-hidebots": "რობოტების დამალვა",
-       "activeusers-hidesysops": "ადმინისტრატორების დამალვა",
        "activeusers-noresult": "მომხმარებლები არ არიან ნაპოვნი.",
        "activeusers-submit": "აქტიური მომხმარებლების ჩვენება",
        "listgrouprights": "მომხმარებელთა ჯგუფების უფლებები",
        "feedback-external-bug-report-button": "ტექნიკური დავალების გაგზავნა",
        "feedback-dialog-title": "გამოხმაურების გაგზავნა",
        "feedback-dialog-intro": "თქვენ შეგიძლიათ ისარგებლოთ ქვემოთ არსებული მარტივი ფორმით, რათა დატოვოთ თქვენი გამოძახილი. კომენტარები თქვენ მომხმარებლის სახელთან ერთად დამატებული იქნება \"$1\" გვერდზე",
-       "feedback-error-title": "შეცდომა",
        "feedback-error1": "შეცდომა. API-ს მოულოდნელი რეზულტატი.",
        "feedback-error2": "შეცდომა: რედაქტირება ვერ განხორციელდა",
        "feedback-error3": "შეცდომა. არ არის API-ს პასუხი .",
index 0dba198..3397906 100644 (file)
        "yourname": "Paydalanıwshı atı:",
        "yourpassword": "Parol:",
        "yourpasswordagain": "Paroldi qayta kiritin':",
-       "remembermypassword": "Menin' kirgenimdi usı kompyuterde saqlap qal (en' ko'bi menen $1 {{PLURAL:$1|ku'nge|ku'nge}} shekem)",
        "yourdomainname": "Sizin' domen:",
        "login": "Kiriw",
        "nav-login-createaccount": "Kiriw / akkaunt jaratıw",
        "moveddeleted-notice": "Bul bet o'shirilgen.\nTo'mende mag'lıwmat ushın bettin' o'shiriw ha'm ko'shiriw jurnalı ko'rsetilgen.",
        "edit-conflict": "O'zgerislerdegi konflikt.",
        "parser-template-loop-warning": "Shablonlarda qaytalanıw tabıldı: [[$1]]",
-       "cantcreateaccounttitle": "Akkaunt jaratılmadı",
        "cantcreateaccount-text": "[[User:$3|$3]] usı IP adresten ('''$1''') akkaunt jaratıwın blokladı.\n\n$3 keltirilgen sebebi: ''$2''",
        "viewpagelogs": "Usı bettin' jurnalın ko'riw",
        "nohistory": "Bul bettin' o'zgertiw tariyxı joq.",
index cd5ff53..3faa3a8 100644 (file)
        "yourpasswordagain": "Ɛiwed ssekcem awal n tbaḍnit",
        "createacct-yourpasswordagain": "Sergeg awal n uɛeddi",
        "createacct-yourpasswordagain-ph": "Sekcem awal n uɛeddi tikelt nniḍen",
-       "remembermypassword": "Cfu ɣef wawal n tbaḍnit inu di uselkim-agi (i afellay n $1 {{PLURAL:$1|ass|ussan}})",
        "userlogin-remembermypassword": "Eǧǧ taɣimit inu turmidt",
        "userlogin-signwithsecure": "Seqdec tuqqna yettwaḥerzen",
        "yourdomainname": "Taɣult inek",
        "passwordreset-emailtext-user": "Aseqdac $1 ɣef {{SITENAME}} yessutered awennez n awal n uɛaddi i {{SITENAME}} ($4). {{PLURAL:$3|Amiḍan n useqdac agi yeqqen|imiḍanen n iseqdacen agi qqenen}} s tansa e-mail agi :\n\n$2\n\n{{PLURAL:$3|Awal n uɛaddi uɛḍil agi ad i aff tasewti-s|Awalen n uɛaddi uɛḍilen agi ad affen taseweti nsen}} deg {{PLURAL:$5|yiwen ass|$5 ussan}}. Ilaq tura ad qqeneḍ dɣa ad freneḍ awal n uɛaddi amaynut. Lukan mačči d kečč/kem i xedmen asuter agi, naɣ tecfiḍ tura i awal n uɛaddi inek/inem, tzemreḍ ad eǧǧeḍ izen agi.",
        "passwordreset-emailelement": "Isem n useqdac : \n$1\n\nAwal n uɛddi akudan : \n$2",
        "passwordreset-emailsentemail": "Tirawt n uwennez n awal n uɛaddi tetwaceggaɛ.",
-       "passwordreset-emailsent-capture": "Tirawt n uwennez n awal n uɛaddi tetwaceggaɛ, ẓeṛ-itt ddaw agi.",
-       "passwordreset-emailerror-capture": "Tirawt n uwennez n awal n uɛaddi t-arewed, ẓeṛ-itt ddaw agi, lamaɛna aceggaɛ i {{GENDER:$2|umseqdac}} yefkad anezri : $1",
        "changeemail": "Beddel tansa n e-mail",
        "changeemail-header": "Beddel tansa n e-mail n umiḍan",
        "changeemail-no-info": "Ilaq ad qqeneḍ iwakken ad ẓṛeḍ asebter agi.",
        "undo-norev": "Abeddel ur yezmer ara ad yetwekkes acku ulac-itt naɣ tetwekkes yakan",
        "undo-summary": "Ssefsu tasiwelt $1 sɣur [[Special:Contributions/$2|$2]] ([[User talk:$2|Meslay]])",
        "undo-summary-username-hidden": "Semmewet tacaggart $1 sɣur amseqdac yeffren",
-       "cantcreateaccounttitle": "Ur yezmir ara ad yexleq isem n wemseqdac",
        "cantcreateaccount-text": "Asnulfu n umiḍan seg tansa IP (<b>$1</b>) tekyef sɣur [[User:$3|$3]].\n\nTaɣẓint n $3 : ''$2''",
        "cantcreateaccount-range-text": "Asnulfu n umiḍan seg tansiwin IP deg tagrumma <strong>$1</strong>, i sseddan tansa inek/inem IP (<strong>$4</strong>), twawḥelen sɣur [[User:$3|$3]].\n\nTaɣẓint i-d yefka/tefka $3 : <em>$2</em>",
        "viewpagelogs": "Ẓer aɣmis n usebter-agi",
        "activeusers-intro": "Wagi d umuɣ n iseqdacen yexedmen armud deg {{PLURAL:$1|ass agi aneggaru|$1 ussan agi ineggura}}.",
        "activeusers-count": "$1 {{PLURAL:$1|tigawt|tigawin}} deg {{PLURAL:$3|ass aneggaru|$3 ussan ineggura}}",
        "activeusers-from": "Ssken iseqdacen seg :",
-       "activeusers-hidebots": "Ffer iṛubuten",
-       "activeusers-hidesysops": "Ffer inedbalen",
        "activeusers-noresult": "Ur yufi aseqdac.",
        "listgrouprights": "Izerfan n igrawen n iseqdacen",
        "listgrouprights-summary": "Asebter agi yesɛa yiwen umuɣ n igrawen i sengelen deg wiki agi dɣa izerfan n wadduf i qqenen.\nZemrent ad ilint [[{{MediaWiki:Listgrouprights-helppage}}|tilɣa nniḍen]] ɣef izerfan n yiwen.",
        "htmlform-no": "Ala",
        "htmlform-yes": "Ih",
        "htmlform-chosen-placeholder": "Fren taxtiṛit",
-       "sqlite-has-fts": "$1 s anadi deg uḍris ummid yezmer",
-       "sqlite-no-fts": "$1 war anadi deg uḍris ummid yezmer",
        "logentry-delete-delete": "$1 {{GENDER:$2|yemḥa}} asebtar $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|yerred|terred}} asebtar $3",
        "logentry-delete-event": "$1 {{GENDER:$2|yebeddel|tebeddel}} tabanit {{PLURAL:$5|n tadyant n uɣmis|n $5 tidyanin n uɣmis}} ɣef $3: $4",
index ffff096..9dd1e0d 100644 (file)
        "yourname": "Уи цӀэр:",
        "yourpassword": "Пэролыр:",
        "yourpasswordagain": "Иджыри зэ пэролыр:",
-       "remembermypassword": "Сызэрихьэр компьютерым щыIыгъын (махуэу $1 {{PLURAL:$1|щIимыгъуу|щIимыгъуу}})",
        "yourdomainname": "Уи доменыр:",
        "externaldberror": "Щэуэгъуэ хъуа, аутентификациэ щекӀуэкӀым иэ апхуэдиз пӀалъэ уиӀу щыткъым, уи нэкугъуэ аккаунтыр зэпхъуэкӀын.",
        "login": "Системэм зыкъегъэцIыхуын",
        "undo-failure": "Гъэтэрэзыгъуэр хэхыжа хъунукъым, гъэтэрэзыгъуэхэм я зэпхыгъуэр зэремыкӀуэкӀыфым щхьэкӀэ",
        "undo-norev": "Гъэтэрэзыгъуэр хэхыжа хъунукъым зэрщымыӀэм щхьэкӀэ иэ хэхыжагъыху щытщ.",
        "undo-summary": "Гъэтэрэзыгъуэ хэхыжыныр $1 цӀыхухэт [[Special:Contributions/$2|$2]] ([[User talk:$2|тепсэлъыхьыгъуэ]])",
-       "cantcreateaccounttitle": "Аккаунтыр щӀыфынукъым",
        "cantcreateaccount-text": "Аккаунт щӀыныр мы IP-адресыкӀэ (<b>$1</b>) триубыдауэ щытщ [[User:$3|цӀыхухэт $3]].\n\n$3 ар зтеухуауэ къитхыр: ''$2''",
        "viewpagelogs": "Мы напэкӀуэцIым щхьэкӀэ тхылъыр гъэлъэгъуэн",
        "nohistory": "Мы напэкӀуэцӀым и зэхъуэкӀыгъуэхэм я тхыдэ иӀэкъым.",
index b01984c..9275e71 100644 (file)
        "yourpasswordagain": "کلمۂ شناخت(پاسورڈو)دوبارہ نیویشے",
        "createacct-yourpasswordagain": "کلمۂ اجازتو تصدیق کورے",
        "createacct-yourpasswordagain-ph": "پاس ورڈو وا داخل کورے",
-       "remembermypassword": "ھیہ براوزیرا مہ داخلِ نوشتگی معلوماتن یاد لاکھے (زیاتاری زیات $1 {{PLURAL:$1|بس|بسان}} بچے)",
        "userlogin-remembermypassword": "مہ داخل بہچاوے",
        "yourdomainname": "تہ ڈومین",
        "password-change-forbidden": "تتے ھیہ ویکیپیڈیا تان پاس روڈو تبدیل کوریکو اختیار نیکی",
        "listusers-noresult": "ھیہ صارف ملاو نو ہوئے",
        "activeusers": "متحرک صارفینان فہرست",
        "activeusers-from": "مطلوبہ حرفاری شروع باک صفحاتن نمائش:",
-       "activeusers-hidebots": "کھوشت خود کار صارف",
-       "activeusers-hidesysops": "کھوشت منتظمان",
        "activeusers-noresult": "ھیہ صارف ملاو نو ہوئے",
        "listgrouprights-group": "گروہ",
        "listgrouprights-rights": "اختیارات",
index b2a514f..5f62837 100644 (file)
        "yourname": "قاتىسۋشى اتىڭىز:",
        "yourpassword": "قۇپىييا ٴسوزىڭىز:",
        "yourpasswordagain": "قۇپىييا ٴسوزدى قايتالاڭىز:",
-       "remembermypassword": "مەنىڭ كىرگەنىمدى بۇل كومپيۋتەردە ۇمىتپا (for a maximum of $1 {{PLURAL:$1|day|days}})",
        "yourdomainname": "جەلى ۇيشىگىڭىز:",
        "externaldberror": "وسى ارادا نە شەتتىك راستاۋ دەرەكقورىندا قاتە بولدى, نەمەسە شەتتىك تىركەلگىڭىزدى جاڭالاۋ رۇقساتى جوق.",
        "login": "كىرۋ",
        "undo-failure": "بۇل وڭدەمە جوققا شىعارىلمايدى, سەبەبى ارادا قاقتىعىستى وڭدەمەلەر بار.",
        "undo-norev": "بۇل وڭدەمە جوققا شىعارىلمايدى, سەبەبى بۇل جوق نەمەسە جويىلعان.",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User_talk:$2|تالقىلاۋى]]) ىستەگەن ٴنومىر $1 نۇسقاسىن جوققا شىعاردى",
-       "cantcreateaccounttitle": "جاڭا تىركەلگى جاسالمادى",
        "cantcreateaccount-text": "بۇل IP جايدان ('''$1''') جاڭا تىركەلگى جاساۋىن [[User:$3|$3]] بۇعاتتاعان.\n\n$3 كەلتىرىلگەن سەبەبى: ''$2''",
        "viewpagelogs": "بۇل بەت ٴۇشىن جۋرنال وقىيعالارىن قاراۋ",
        "nohistory": "مىندا بۇل بەتتىنىڭ تۇزەتۋ تارىيحى جوق.",
index ef53d84..28e84bc 100644 (file)
@@ -23,7 +23,7 @@
        "tog-hideminor": "Жуықтағы өзгерістерден шағын өңдемелерді жасыру",
        "tog-hidepatrolled": "Тексерілген өңдеулерді жуықтағы өзгерістер тізімінде көрсетпеу",
        "tog-newpageshidepatrolled": "Тексерілген беттерді жаңа беттер тізімінде жасыру",
-       "tog-hidecategorization": "Беттерді санаттауларды жасыру",
+       "tog-hidecategorization": "Беттедің санатталуын жасыру",
        "tog-extendwatchlist": "Бақылау тізімді ұлғайтып барлық өзгерістерді көрсету, ең соңғыларды ғана емес",
        "tog-usenewrc": "Жуықтағы өзгерістер және бақылау тізімінде беті бойынша өзгерістерді топтау",
        "tog-numberheadings": "Мазмұн тақырыптарын автоматты нөмірлеу",
@@ -54,7 +54,7 @@
        "tog-watchlisthideliu": "Бақылау тізіміндегі кірген қатысушылардың өңдеулерін көрсетпеу",
        "tog-watchlisthideanons": "Бақылау тізіміндегі аноним қатысушылардың өңдеулерін көрсетпеу",
        "tog-watchlisthidepatrolled": "Бақылау тізімінде тексерілген өңдеулерді көрсетпеу",
-       "tog-watchlisthidecategorization": "Беттерді санаттауларды жасыру",
+       "tog-watchlisthidecategorization": "Беттедің санатталуын жасыру",
        "tog-ccmeonemails": "Басқа қатысушыға жіберген хатымның есесін өзіме жөнелту",
        "tog-diffonly": "Нұсқалар айырмашылықтарының астында бет мағлұматын көрсетпеу",
        "tog-showhiddencats": "Жасырын санаттарды көрсету",
        "history": "Бет тарихы",
        "history_short": "Тарихы",
        "updatedmarker": "соңғы қаралғаннан кейін жаңартылған",
-       "printableversion": "Басып шығару нұсқасы",
+       "printableversion": "Басып шығару",
        "permalink": "Тұрақты сілтеме",
        "print": "Басып шығару",
        "view": "Қарау",
        "talk": "Талқылау",
        "views": "Көрініс",
        "toolbox": "Құралдар",
-       "tool-link-emailuser": "Мұны электронды поштамен жіберіңіз {{GENDER:$1|user}}",
+       "tool-link-userrights": "{{GENDER:$1|Қатысушы}} топтарын өзгерту",
+       "tool-link-emailuser": "Бұл {{GENDER:$1|қатысушыға}} хат жіберу",
        "userpage": "Қатысушы бетін қарау",
        "projectpage": "Жоба бетін қарау",
        "imagepage": "Файл бетін қарау",
        "gotaccount": "Бұған дейін тіркеліп пе едіңіз? '''$1'''.",
        "gotaccountlink": "Кіріңіз",
        "userlogin-resetlink": "Қатысушы атын не құпия сөзді ұмыттыңыз ба?",
-       "userlogin-resetpassword-link": "Құпия сөздіңізді ұмыттыңыз ба?",
+       "userlogin-resetpassword-link": "Құпия сөзіңізді ұмыттыңыз ба?",
        "userlogin-helplink2": "Кіруге көмек",
        "userlogin-loggedin": "{{GENDER:$1|$1}} ретінде әлдеқашан кіргенсіз.\nТөмендегі пішінді басқа қатысушы кіруі ретінде қолданыңыз.",
        "userlogin-createanother": "Басқа тіркелгі жасау",
        "passwordtoopopular": "Көп жағдайда таңдалатын құпиясөзді қолдана алмайсыз. Басқа бірегей құпиясөз таңдаңыз.",
        "password-name-match": "Құпия сөзіңіз қатысушы атынан өзгеше болуы қажет.",
        "password-login-forbidden": "Бұл қатысушы аты мен құпия сөзін пайдалануға тыйым салынған.",
-       "mailmypassword": "Құпия сөзді қалпына кеттіру",
+       "mailmypassword": "Құпия сөзді қалпына келтіру",
        "passwordremindertitle": "{{SITENAME}} үшін жаңа уақытша құпия сөз",
        "passwordremindertext": "Біреу (IP мекенжайы: $1, бәлкім өзіңіз боларсыз) {{SITENAME}} жобасында жаңа құпия сөз жөнелету сұранымын жасаған ($4).\nҚатысушы «$2» үшін уақытша құпия сөз жасалды: «$3». Егер бұл сіздің сұранымыңыз болса қазір жүйеге кіріп жаңа құпия сөз таңдауыңыз керек. \nСіздің уақытша құпия сөзіңіз {{PLURAL:$5|бір күнге|$5 күнге}} дейін белсенді болады.\n\nЕгер бұл сұранымды басқа біреу жасаса, не құпия сөздіңізді еске түсіріп енді өзгерткіңіз келмесе ескі құпия сөзді қолдануды жалғастырып осы хатты елемеуіңізге да болады.",
        "noemail": "Осы арада жазылып алынған «$1» қатысушының е-пошта мекенжайы жоқ.",
        "botpasswords-label-update": "Жаңарту",
        "botpasswords-label-cancel": "Болдырмау",
        "botpasswords-label-delete": "Жою",
-       "botpasswords-label-resetpassword": "Құпия сөзді қалпына кеттіру",
+       "botpasswords-label-resetpassword": "Құпия сөзді қалпына келтіру",
        "botpasswords-label-grants": "Қолданылатын гранттар:",
        "botpasswords-bad-appid": "\"$1\" бот атауы жарамды емес.",
        "botpasswords-insert-failed": "\"$1\" бот атауын қосу орындалмады. Ол әлдеқашан қосылған ба еді?",
        "right-noratelimit": "Еселік шектелімдері ықпал етпейді",
        "right-import": "Басқа уикилерден беттерді сырттан алу",
        "right-importupload": "Файлдарды жүктеу арқылы беттерді сырттан алу",
-       "right-patrol": "Басқарардың өңдемелерін тексерілді деп белгілеу",
+       "right-patrol": "Басқалардың өңдемелерін тексерілді деп белгілеу",
        "right-autopatrol": "Өз өңдемелерін тексерілді деп өздіктік белгілеу",
        "right-patrolmarks": "Жуықтағы өзгерістердегі зерттеу белгілерін көру",
        "right-unwatchedpages": "Бақыланылмаған бет тізімін көру",
        "booksources-search": "Іздеу",
        "booksources-text": "Төменде жаңа және қолданған кітаптар сататын тораптарының сілтемелері тізімделген және ізделген кітаптар туралы қосымша ақпарат болуы мүмкін:",
        "booksources-invalid-isbn": "Берілген ISBN жарамды болып көрінубеуі мүмкін; бастапқы қайнар көзінен еселеуде пайда болған қателерді тексеріңіз.",
+       "magiclink-tracking-isbn": "ISBN сиқырлы сілтемелері қолданылған беттер",
        "specialloguserlabel": "Орындаушы:",
        "speciallogtitlelabel": "Нысана (атауы немесе қатысушының {{ns:user}}:қатысушы есімі):",
        "log": "Журналдар",
        "activeusers-intro": "Бұл соңғы $1 {{PLURAL:$1|күнде|күнде}} қандай да бір іс-әрекет жасаған қатысушылар тізімі.",
        "activeusers-count": "соңғы {{PLURAL:$3|күнде|$3 күнде}} $1 {{PLURAL:$1|әрекет|әрекет}}",
        "activeusers-from": "Мынадан басталатын қатысушыларды көрсет:",
-       "activeusers-hidebots": "Боттарды жасыру",
-       "activeusers-hidesysops": "Әкімшілерді жасыру",
        "activeusers-noresult": "Қатысушылар табылған жоқ.",
        "activeusers-submit": "Белсенді қатысушыларды көрсету",
        "listgrouprights": "Қатысушы тобы құқықтары",
        "trackingcategories-msg": "Санатты қадағалау",
        "trackingcategories-name": "Хабарлама атауы",
        "trackingcategories-desc": "Санаттарды қосу шарттары",
+       "restricted-displaytitle-ignored": "Еленбеген көретілетін атауларымен беттер",
        "noindex-category-desc": "Бұл бет роботтар арқылы индекстелмеген, себебі онда <code><nowiki>__NOINDEX__</nowiki></code> деген сиқырлы сөзі бар және бұл жалауша рұқсат етілген есім кеңістігінде орналасқан.",
        "index-category-desc": "Бұл бетте <code><nowiki>__INDEX__</nowiki></code> деген код бар (және бұл жалауша рұқсат етілген есім кеңістігінде орналасқан), демек мұнда қалыпты жағдайда роботтар арқылы индекстелмейді.",
        "post-expand-template-inclusion-category-desc": "Беттің мөлшері барлық үлгілерді кеңейткен соң мынадан <code>$wgMaxArticleSize</code> үлкенірек болады, сондықтан біраз үлгілер кеңейтілмейді.",
        "pageinfo-hidden-categories": "Жасырылған {{PLURAL:$1|санат|санаттар}} ($1)",
        "pageinfo-templates": "Кіріктірілген {{PLURAL:$1|үлгі|үлгілер}} ($1)",
        "pageinfo-transclusions": "Kіріктірілген {{PLURAL:$1|бет|беттер}} ($1)",
-       "pageinfo-toolboxlink": "Ð\91ұл Ð±ÐµÑ\82 Ñ\82Ñ\83Ñ\80алÑ\8b Ð¼әлімет",
+       "pageinfo-toolboxlink": "Ð\9cәлімет",
        "pageinfo-redirectsto": "Айдатылғандар",
        "pageinfo-redirectsto-info": "Информация",
        "pageinfo-contentpage": "Контент бетке санала ма?",
        "feedback-external-bug-report-button": "Техникалық тапсырманы жіберу",
        "feedback-dialog-title": "Пікірді жіберу",
        "feedback-dialog-intro": "Сіз пікіріңізді жіберу үшін төмендегі пішінді пайдалана аласыз. Сіздің пікіріңіз «$1» бетіне сіздің қатысушы есіміңізбен қосылады.",
-       "feedback-error-title": "Қате",
        "feedback-error1": "Қате: API-дан танылмаған нәтиже",
        "feedback-error2": "Қате: Өңдеме сәтсіздікке ұшырады",
        "feedback-error3": "Қате: API-дан жауап жоқ",
        "feedback-thanks": "Рахмет! Сіздің кері байланысыңыз \"[$2 $1]\" бетіне қойылды.",
        "feedback-thanks-title": "Рақмет!",
        "feedback-useragent": "Қатысушы агент:",
-       "searchsuggest-search": "Іздеу",
+       "searchsuggest-search": "{{SITENAME}} жобасынан іздеу",
        "searchsuggest-containing": "қамтылуда...",
        "api-error-badaccess-groups": "Сізге бұл уикиге файл жүктеуге рұқсат етілмеген.",
        "api-error-badtoken": "Ішкі қате: Жаман байрақша",
index 39773cc..de12302 100644 (file)
        "yourname": "Qatıswşı atıñız:",
        "yourpassword": "Qupïya söziñiz:",
        "yourpasswordagain": "Qupïya sözdi qaýtalañız:",
-       "remembermypassword": "Meniñ kirgenimdi bul komp′ywterde umıtpa (for a maximum of $1 {{PLURAL:$1|day|days}})",
        "yourdomainname": "Jeli üýşigiñiz:",
        "externaldberror": "Osı arada ne şettik rastaw derekqorında qate boldı, nemese şettik tirkelgiñizdi jañalaw ruqsatı joq.",
        "login": "Kirw",
        "undo-failure": "Bul öñdeme joqqa şığarılmaýdı, sebebi arada qaqtığıstı öñdemeler bar.",
        "undo-norev": "Bul öñdeme joqqa şığarılmaýdı, sebebi bul joq nemese joýılğan.",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User_talk:$2|talqılawı]]) istegen nömir $1 nusqasın joqqa şığardı",
-       "cantcreateaccounttitle": "Jaña tirkelgi jasalmadı",
        "cantcreateaccount-text": "Bul IP jaýdan ('''$1''') jaña tirkelgi jasawın [[User:$3|$3]] buğattağan.\n\n$3 keltirilgen sebebi: ''$2''",
        "viewpagelogs": "Bul bet üşin jwrnal oqïğaların qaraw",
        "nohistory": "Mında bul bettiniñ tüzetw tarïxı joq.",
index 282444d..89564eb 100644 (file)
        "yourpasswordagain": "វាយពាក្យសម្ងាត់ម្តងទៀត៖",
        "createacct-yourpasswordagain": "អះអាង​ពាក្យ​សម្ងាត់",
        "createacct-yourpasswordagain-ph": "បញ្ចូលពាក្យសម្ងាត់ម្ដងទៀត",
-       "remembermypassword": "ចងចាំកំណត់ឈ្មោះចូលរបស់ខ្ញុំក្នុងកុំព្យូទ័រនេះ (សំរាប់រយៈពេលយូរបំផុត $1 {{PLURAL:$1|ថ្ងៃ|ថ្ងៃ}})",
        "userlogin-remembermypassword": "រក្សាស្ថានភាពកត់ឈ្មោះចូលរបស់ខ្ញុំ",
        "userlogin-signwithsecure": "ប្រើការតភ្ជាប់មានសុវត្ថិភាព",
        "yourdomainname": "ដូម៉ែនរបស់អ្នក៖",
        "activeusers-intro": "នេះជាបញ្ជីរាយនាមអ្នកប្រើប្រាស់ដែលមានសកម្មភាពក្នុងរូបភាពណាមួយក្នុងរយៈពេល $1 {{PLURAL:$1|ថ្ងៃ|ថ្ងៃ}}ចុងក្រោយ។",
        "activeusers-count": "{{PLURAL:$1|សកម្មភាព|សកម្មភាព}}ចំនួន$1 ក្នុងរយៈពេល{{PLURAL:$3|១ថ្ងៃ|$3 ថ្ងៃ}}ចុងក្រោយ",
        "activeusers-from": "បង្ហាញអត្តនាមផ្ដើមដោយ៖",
-       "activeusers-hidebots": "លាក់រូបយន្ត",
-       "activeusers-hidesysops": "លាក់អភិបាល",
        "activeusers-noresult": "អ្នកប្រើប្រាស់​រកមិនឃើញ​។​",
        "listgrouprights": "សិទ្ធិនិងក្រុមអ្នកប្រើប្រាស់",
        "listgrouprights-summary": "ខាងក្រោមនេះជាបញ្ជីរាយឈ្មោះក្រុមអ្នកប្រើប្រាស់ដែលបានកំណត់ជាមួយនឹងសិទ្ធិរបស់គេនៅលើវិគីនេះ។ មាន[[{{MediaWiki:Listgrouprights-helppage}}|ព័ត៌មានបន្ថែម]] អំពីសិទ្ធិផ្ទាល់ខ្លួន។",
index f09c38b..c3926de 100644 (file)
@@ -65,6 +65,7 @@
        "tog-watchlisthidebots": "ವೀಕ್ಷಣಾಪಟ್ಟಿಯಲ್ಲಿ ಬಾಟ್ ಸಂಪಾದನೆಗಳನ್ನು ಅಡಗಿಸು",
        "tog-watchlisthideminor": "ಚಿಕ್ಕ ಬದಲಾವಣೆಗಳನ್ನು ವೀಕ್ಷಣಾ ಪಟ್ಟಿಯಿಂದ ಅಡಗಿಸು",
        "tog-watchlisthideliu": "ಲಾಗ್ ಇನ್ ಆಗಿರುವ ಸದಸ್ಯರ ಸಂಪಾದನೆಗಳನ್ನು ವೀಕ್ಷಣಾಪಟ್ಟಿಯಲ್ಲಿ ಅಡಗಿಸು",
+       "tog-watchlistreloadautomatically": "ಯಾವುದೇ ಫಿಲ್ಟರು ಬದಲಾದಾಗ ವೀಕ್ಷಣಾಪಟ್ಟಿ ಮತ್ತೆ ಲೋಡ್ ಆಗಲಿ (ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಇರಬೇಕು)",
        "tog-watchlisthideanons": "ಅನಾಮಧೇಯ ಬಳಕೆದಾರರ ಸಂಪಾದನೆಗಳನ್ನು ವೀಕ್ಷಣಾಪಟ್ಟಿಯಲ್ಲಿ ಅಡಗಿಸು",
        "tog-watchlisthidepatrolled": "ವೀಕ್ಷಣಾ ಪತ್ತಿಯಲ್ಲಿ ಹಸ್ತುಕದರ್ ಬದಲಾವಣೆಗಳನ್ನು ಅದಗಿಸು",
        "tog-watchlisthidecategorization": "ಪುಟಗಳ ವರ್ಗೀಕರಣವನ್ನು ಅಡಗಿಸು",
        "actionthrottled": "ಕ್ರಿಯೆಯನ್ನು ನಿಯಂತ್ರಿಸಲಾಗಿದೆ",
        "actionthrottledtext": "ಸ್ಪ್ಯಾಮ್ ವಿರೋಧಿ ವಿಧಾನದ ಪ್ರಕಾರ, ನಿಮ್ಮನ್ನು ಸ್ವಲ್ಪ ಸಮಯದಲ್ಲಿ ಬಹಳ ಸಲ ಈ ಕ್ರಿಯೆಯನ್ನು ಮಾಡುವುದರಿಂದ ನಿಯಂತ್ರಿಸಲಾಗಿದೆ ಮತ್ತು ನೀವು ಸೀಮೆಯನ್ನು ಮಿರಿದ್ದಿರಿ. ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.",
        "protectedpagetext": "ಈ ಪುಟವನ್ನು ಸಂಪಾದನೆ ಮಾಡಲಾಗದಂತೆ ಸಂರಕ್ಷಿಸಲಾಗಿದೆ.",
-       "viewsourcetext": "ಈ ಪುಟದ ಮೂಲವನ್ನು ನೀವು ವೀಕ್ಷಿಸಬಹುದು ಮತ್ತು ನಕಲು ಮಾಡಬಹುದು:",
-       "viewyourtext": "ನೀವು \"ನಿಮ್ಮ ಸಂಪಾದನೆಗಳ\"ನ್ನು ವಿಕ್ಷಿಸಿ ಮತ್ತು ಅದರ ಮೂಲವನ್ನು ಈ ಹಾಳೆಗೆ ನಕಲಿಸಬಹುದು:",
+       "viewsourcetext": "ಈ ಪುಟದ ಮೂಲವನ್ನು ನೀವು ವೀಕ್ಷಿಸಬಹುದು ಮತ್ತು ನಕಲು ಮಾಡಬಹುದು.",
+       "viewyourtext": "ನೀವು <strong>ನಿಮ್ಮ ಸಂಪಾದನೆಗಳನ್ನು</strong> ವೀಕ್ಷಿಸಿ ಮತ್ತು ಅದರ ಮೂಲವನ್ನು ಈ ಹಾಳೆಗೆ ನಕಲಿಸಬಹುದು.",
        "protectedinterface": "ಈ ಪುಟವು ತಾಂತ್ರಿಕತೆಗೆ ಸಂಪರ್ಕ ಪಠ್ಯವನ್ನು ವಿಕಿಯಲ್ಲಿ ಒದಗಿಸುತ್ತದೆ, ಹಾಗು ದುರುಪಯೋಗ ಆಗದಿರಲೆಂದು ಇದನ್ನು ಸಂರಕ್ಷಿಸಲಾಗಿದೆ. ಎಲ್ಲ ವಿಕಿಗಳಿಗೆ ಭಾಷಾಂತರವನ್ನು ಕೂಡಿಸಲು ಹಾಗು ಬದಲಿಸಲು, [https://translatewiki.net/ translatewiki.net], the MediaWiki localisation ಯೋಜನೆಯನ್ನು ಉಪಯೊಗಿಸಿ",
        "editinginterface": "'''ಎಚ್ಚರಿಕೆ:''' ನೀವು ತಂತ್ರಾಂಶವು ತಾಣವನ್ನು ಪ್ರದರ್ಶಿಸಲು ಉಪಯೋಗಿಸುವ ಪಠ್ಯವನ್ನು ಹೊಂದಿರುವ ಪುಟವೊಂದನ್ನು ಸಂಪಾದಿಸುತ್ತಿರುವಿರಿ.\nಈ ಪುಟದಲ್ಲಾಗುವ ಬದಲಾವಣೆಗಳು ಇತರ ಬಳಕೆದಾರರಿಗೆ ತಾಣವು ಕಾಣುವ ರೀತಿಯನ್ನು ಬದಲಾಯಿಸುತ್ತದೆ.\nಅನುವಾದಗಳನ್ನು ಮಾಡುತ್ತಿದ್ದರೆ, ದಯವಿಟ್ಟು ಮೀಡಿಯವಿಕಿಯ ಪ್ರಾಂತೀಯತೆ ಯೋಜನೆ [https://translatewiki.net/ translatewiki.net], the MediaWiki localisation project ಯೋಜನೆಯನ್ನು ಉಪಯೊಗಿಸಿ",
        "cascadeprotected": "ಈ ಪುಟವು ಸಂಪಾದನೆ ಮಾಡಲಾಗದಂತೆ ಸಂರಕ್ಷಿಸಲಾಗಿದೆ. ಇದಕ್ಕೆ ಕಾರಣ ಈ ಪುಟವನ್ನು ಈ ಕೆಳಗಿನ ತಡಸಲು-ಸಂರಕ್ಷಣೆ ಅಳವಡಿಸಲಾದ {{PLURAL:$1|ಪುಟದಲ್ಲಿ|ಪುಟಗಳಲ್ಲಿ}} ಉಪಯೋಗಿಸಲಾಗಿದೆ:\n$2",
        "mypreferencesprotected": "ನಿಮ್ಮ ಆಯ್ಕೆಗಳನ್ನು  ಸಂಪಾದಿಸಲು ನಿಮಗೆ ಅನುಮತಿ ಇಲ್ಲ",
        "ns-specialprotected": "ವಿಶೇಷ ಪುಟಗಳನ್ನು ಸಂಪಾದಿಸಲು ಆಗುವುದಿಲ್ಲ.",
        "titleprotected": "ಈ ಹೆಸರಿನ ಪುಟವನ್ನು ಸೃಷ್ಟಿಸಲಾಗದಂತೆ [[User:$1|$1]] ಅವರು ಸಂರಕ್ಷಿಸಿದ್ದಾರೆ.\nಸಂರಕ್ಷಣೆಗೆ ನೀಡಿರುವ ಕಾರಣ: <em>$2</em>.",
-       "filereadonlyerror": "\"$1\" ಕಡತವು ಓದಲು ಮಾತ್ರ ಸಾದ್ಯವಿರುವ ರೀತಿಯಲ್ಲಿರುವ\"$2\" ಸಂಪುಟದಲ್ಲಿರುವುದರಿಂದ ಇದನ್ನು  ಮಾರ್ಪಡಿಸಲು ಸಾದ್ಯವಾಗುತ್ತಿಲ್ಲ.\nಇದನ್ನು ಬದ್ದಗೊಳಿಸಿರುವ ನಿರ್ವಾಹಕರು \"$3\" ಈ ವಿವರಣೆಯನ್ನು ನೀಡುತ್ತಿದ್ದಾರೆ.",
+       "filereadonlyerror": "\"$1\" ಕಡತವು ಓದಲು ಮಾತ್ರ ಸಾದ್ಯವಿರುವ ರೀತಿಯಲ್ಲಿರುವ \"$2\" ಸಂಪುಟದಲ್ಲಿ ಇರುವುದರಿಂದ ಇದನ್ನು  ಮಾರ್ಪಡಿಸಲು ಸಾದ್ಯವಾಗುತ್ತಿಲ್ಲ.\nಇದನ್ನು ಬದ್ದಗೊಳಿಸಿರುವ ನಿರ್ವಾಹಕರು ಈ ವಿವರಣೆಯನ್ನು ನೀಡುತ್ತಿದ್ದಾರೆ: \"$3\"",
        "invalidtitle-knownnamespace": "\"$2\"ನೇಮ್ ಸ್ಪೇಸ್ ಮತ್ತು \"$3\"ಪಠ್ಯದೊಂದಿಗೆ ಅಸಮಂಜಸ ತಲೆಬರಹ",
        "invalidtitle-unknownnamespace": "$1ನೇಮ್ ಸ್ಪೇಸ್ ಮತ್ತು \"$2\"ಪಠ್ಯದೊಂದಿಗೆ ಅಸಮಂಜಸ ತಲೆಬರಹ",
        "exception-nologin": "ಲಾಗಿನ್ ಆಗಿಲ್ಲ",
-       "exception-nologin-text": "ಈ ಪುಟ ಅಥವಾ ಚಟುವಟಿಕೆಗೆ ನೀವು ಈ ವಿಕಿಗೆ [[Special:Userlogin|ಲಾಗಿನ್]] ಆಗಿರಬೇಕಾಗಿರುತ್ತದೆ.",
+       "exception-nologin-text": "ಈ ಪುಟವನ್ನು ವೀಕ್ಷಿಸಲು ಅಥವ ಚಟುವಟಿಕೆಯನ್ನು ಮಾಡಲು ಲಾಗಿನ್ ಆಗಬೇಕು.",
        "exception-nologin-text-manual": "ಈ ಪುಟ ಅಥವಾ ಚಟುವಟಿಕೆಗೆ $1 ಮಾಡಿ",
        "virus-badscanner": "ಅಸಮಂಜಸ ವಿನ್ಯಾಸ:ಅಪರಿಚಿತ ವೈರಸ್ ಸ್ಕಾನರ್:''$1''",
        "virus-scanfailed": "ಸ್ಕಾನ್ ವಿಫಲ (code $1)",
        "virus-unknownscanner": "ಅಪರಿಚಿತ ವೈರಾಣುನಾಶಕ:",
        "logouttext": "'''ನೀವು ಈಗ ಲಾಗ್ ಔಟ್ ಆಗಿರುವಿರಿ.'''\n \nಗಮನಿಸಿ: ನಿಮ್ಮ ಬ್ರೌಸರ್‍ನ cache ಅನ್ನು ಅಳಿಸುವವರೆಗೂ ಕೆಲವು ಪುಟಗಳು ನೀವಿನ್ನೂ ಲಾಗ್ ಇನ್ ಆಗಿರುವಂತೆ ಪ್ರದರ್ಶಿತವಾಗಬಹುದು.",
+       "cannotlogoutnow-title": "ಈಗ ಲಾಗ್ ಔಟ್ ಮಾಡಲಾಗುತ್ತಿಲ್ಲ",
+       "cannotlogoutnow-text": "$1 ಬಳಸುವಾಗ ಲಾಗ್ ಔಟ್ ಆಗಲು ಸಾಧ್ಯವಿಲ್ಲ.",
        "welcomeuser": "ಸುಸ್ವಾಗತ,$1!",
        "welcomecreation-msg": "ನಿಮ್ಮ ಖಾತೆ ತೆರೆಯಲಾಗಿದೆ.ನಿಮ್ಮ [[Special:Preferences|{{SITENAME}} preferences]]ಬದಲಾಯಿಸಲು ಮರೆಯಬೇಡಿ.",
        "yourname": "ನಿಮ್ಮ ಬಳಕೆಯ ಹೆಸರು",
        "createacct-yourpasswordagain-ph": "ಪ್ರವೇಶಪದವನ್ನು ಮತ್ತೊಮ್ಮೆ ನಮೂದಿಸಿ",
        "userlogin-remembermypassword": "ನನ್ನನ್ನು ಲಾಗಿನ್ ಆಗಿಯೇ ಇಡಿ",
        "userlogin-signwithsecure": "ಸುರಕ್ಷಿತವಾದ ಕನೆಕ್ಷನ್ ಉಪಯೋಗಿಸಿ.",
+       "cannotlogin-title": "ಲಾಗ್ ಇನ್ ಮಾಡಲಾಗುತ್ತಿಲ್ಲ",
+       "cannotlogin-text": "ಲಾಗ್ ಇನ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ.",
+       "cannotloginnow-title": "ಈಗ ಲಾಗ್ ಇನ್ ಮಾಡಲು ಆಗುತ್ತಿಲ್ಲ",
+       "cannotloginnow-text": "$1 ಬಳಸುವಾಗ ಲಾಗ್ ಇನ್ ಆಗಲು ಸಾಧ್ಯವಿಲ್ಲ.",
+       "cannotcreateaccount-title": "ಖಾತೆಗಳನ್ನು ಸೃಷ್ಟಿಸಲಾಗುತ್ತಿಲ್ಲ",
        "yourdomainname": "ನಿಮ್ಮ ಕ್ಷೇತ್ರ:",
        "password-change-forbidden": "ನೀವು ಈ ವಿಕಿಯಲ್ಲಿ ಪ್ರವೇಶಪದವನ್ನು ಬದಲಾಯಿಸಲು ಸಾದ್ಯವಿಲ್ಲ.",
        "login": "ಲಾಗ್ ಇನ್",
        "userlogin-resetlink": "ನಿಮ್ಮ ಲಾಗಿನ್ ವಿವರಗಳನ್ನು ಮರೆತಿದ್ದೀರಾ?",
        "userlogin-resetpassword-link": "ನಿಮ್ಮ ಪ್ರವೇಶಪದ ಮರೆತಿರೇ?",
        "userlogin-helplink2": "ಲಾಗಿನ್ ಆಗಲು ಸಹಾಯ",
+       "userlogin-reauth": "ನೀವು {{GENDER:$1|$1}} ಎಂದು ಖಾತ್ರಿ ಮಾಡಲು ಮತ್ತೆ ಲಾಗ್ ಇನ್ ಆಗಬೇಕು.",
        "userlogin-createanother": "ಇನ್ನೊಂದು ಖಾತೆಯನ್ನು ಸೃಷ್ಟಿಸಿ",
        "createacct-emailrequired": "ಇ-ಮೇಲ್ ವಿಳಾಸ:",
        "createacct-emailoptional": "ಮಿಂಚಂಚೆ ವಿಳಾಸ (ಐಚ್ಛಿಕ)",
        "createacct-reason": "ಕಾರಣ",
        "createacct-reason-ph": "ನೀವು ಯಾಕೆ ಇನ್ನೊಂದು ಖಾತೆ ತೆರೆಯುತ್ತಿದ್ದೀರಿ",
        "createacct-submit": "ಖಾತೆಯನ್ನು ಸೃಷ್ಟಿಸಿ",
-       "createacct-another-submit": "ಇನ್ನು ಒಂದು ಖಾತ ಮಾಡಿ",
+       "createacct-another-submit": "ಖಾತೆಯನ್ನು ಸೃಷ್ಟಿಸಿ",
+       "createacct-continue-submit": "ಖಾತೆಯ ಸೃಷ್ಟಿಯನ್ನು ಮುಂದುವರೆಸಿ",
+       "createacct-another-continue-submit": "ಖಾತೆಯ ಸೃಷ್ಟಿಯನ್ನು ಮುಂದುವರೆಸಿ",
        "createacct-benefit-heading": "{{SITENAME}} ನಿಮ್ಮಂತಹ ಜನರಿಂದಲೇ ಮಾಡಿದ್ದು.",
        "createacct-benefit-body1": "{{PLURAL:$1|ಸಂಪಾದನೆ|ಸಂಪಾದನೆಗಳು}}",
        "createacct-benefit-body2": "{{PLURAL:$1|ಪುಟ|ಪುಟಗಳು}}",
        "pt-createaccount": "ಹೊಸ ಖಾತೆ ತೆರೆಯಿರಿ",
        "pt-userlogout": "ಲಾಗ್ ಔಟ್",
        "changepassword": "ಪ್ರವೇಶ ಪದ ಬದಲಾಯಿಸಿ",
-       "resetpass_announce": "ನà³\80ವà³\81 à²¤à²¾à²¤à³\8dà²\95ಾಲಿà²\95 à²\87-à²\85à²\82à²\9aà³\86 à²\95à³\8bಡà³\8d à²\85ನà³\8dನà³\81 à²\89ಪಯà³\8bà²\97ಿಸಿ à²²à²¾à²\97à³\8d à²\87ನà³\8d à²\86à²\97ಿರà³\81ವಿರಿ.\nಲಾà²\97à³\8d à²\87ನà³\8d à²ªà³\82ರà³\8dಣà²\97à³\8aಳಿಸಲà³\81 à²¨à³\80ವಿಲà³\8dಲ à²¹à³\8aಸ à²ªà³\8dರವà³\87ಶಪದ à²¨à³\80ಡಬà³\87à²\95à³\81:",
+       "resetpass_announce": "ಲಾà²\97à³\8d à²\87ನà³\8d à²ªà³\82ರà³\8dಣà²\97à³\8aಳಿಸಲà³\81 à²¨à³\80ವà³\81 à²¹à³\8aಸ à²ªà³\8dರವà³\87ಶಪದವನà³\8dನà³\81 à²¨à²®à³\82ದಿಸಬà³\87à²\95à³\81.",
        "resetpass_header": "ಖಾತೆಯ ಪ್ರವೇಶಪದ ಬದಲಾಯಿಸಿ",
        "oldpassword": "ಹಳೆಯ ಪ್ರವೇಶ ಪದ",
        "newpassword": "ಹೊಸ ಪ್ರವೇಶ ಪದ",
        "retypenew": "ಹೊಸ ಪ್ರವೇಶಪದವನ್ನು ಮತ್ತೆ ಟೈಪಿಸು:",
        "resetpass_submit": "ಪ್ರವೇಶ ಪದವನ್ನು ನಿಶ್ಚಯಿಸಿ ಲಾಗ್ ಇನ್ ಆಗಿ",
-       "changepassword-success": "ನಿಮ್ಮ ಪ್ರವೇಶ ಪದವನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಬದಲಾಯಿಸಲಾಗಿದೆ. ಈಗ ನಿಮ್ಮನ್ನು ಲಾಗ್ ಇನ್ ಮಾಡಲಾಗುತ್ತಿದೆ...",
+       "changepassword-success": "ನಿಮ್ಮ ಪ್ರವೇಶಪದವನ್ನು ಬದಲಾಯಿಸಲಾಗಿದೆ!",
+       "changepassword-throttled": "ನೀವು ಬಹಳ ಸಾರಿ ಲಾಗ್ ಇನ್ ಆಗಲು ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. \nಮತ್ತೆ ಪ್ರಯತ್ನಿಸಲು $1 ಕಾಯಬೇಕು.",
+       "botpasswords": "ಬಾಟ್ ಪ್ರವೇಶ ಪದಗಳು",
        "resetpass_forbidden": "ಪ್ರವೇಶಪದಗಳನ್ನು ಬದಲಾಯಿಸುವಂತಿಲ್ಲ.",
        "resetpass-no-info": "ನೀವು ಈ ಪುಟವನ್ನು ನೇರತಲುಪಲು ಲಾಗಿನ್ ಆಗಿರುವುದು ಆವಶ್ಯಕ.",
        "resetpass-submit-loggedin": "ಪ್ರವೇಶಪದ ಬದಲಾಯಿಸು",
        "sig_tip": "ಸಮಯಮುದ್ರೆಯೊಂದಿಗೆ ನಿಮ್ಮ ಸಹಿ",
        "hr_tip": "ಅಡ್ಡ ಗೆರೆ (ಆದಷ್ಟು ಕಡಿಮೆ ಉಪಯೋಗಿಸಿ)",
        "summary": "ಸಾರಾಂಶ:",
-       "subject": "ವಿಷಯ/ತಲೆಬರಹ:",
+       "subject": "ವಿಷಯ:",
        "minoredit": "ಇದು ಚುಟುಕಾದ ಬದಲಾವಣೆ",
        "watchthis": "ಈ ಪುಟವನ್ನು ವೀಕ್ಷಿಸಿ",
        "savearticle": "ಪುಟವನ್ನು ಉಳಿಸಿ",
+       "savechanges": "ಬದಲಾವಣೆಗಳನ್ನು ಉಳಿಸಿ",
        "publishpage": "ಪುಟವನ್ನು ಪ್ರಕಟಿಸು",
        "publishchanges": "ಬದಲಾವಣೆಗಳನ್ನು ಪ್ರಕಟಿಸು",
        "preview": "ಮುನ್ನೋಟ",
        "showpreview": "ಮುನ್ನೋಟ ತೋರಿಸು",
        "showdiff": "ಬದಲಾವಣೆಗಳನ್ನು ತೋರಿಸು",
-       "anoneditwarning": "'''ಎಚ್ಚರ:''' ನೀವು ಲಾಗ್ ಇನ್ ಆಗಿಲ್ಲ. ನಿಮ್ಮ ಐಪಿ ವಿಳಾಸವು ಪುಟದ ಸಂಪಾದನೆಗಳ ಇತಿಹಾಸದಲ್ಲಿ ದಾಖಲಾಗುತ್ತದೆ.",
+       "blankarticle": "<strong>ಎಚ್ಚರಿಕೆ:</strong> ನೀವು ಸೃಷ್ಟಿಸುತ್ತಿರುವ ಪುಟ ಖಾಲಿ ಇದೆ.\n\"{{int:savearticle}}\" ಅನ್ನು ಮತ್ತೆ ಕ್ಲಿಕ್ಕಿಸಿದರೆ, ಏನೂ ಇರದಂತೆಯೆ ಈ ಪುಟವು ಸೃಷ್ಟಿಯಾಗುತ್ತದೆ.",
+       "anoneditwarning": "<strong>ಎಚ್ಚರ:</strong> ನೀವು ಲಾಗ್ ಇನ್ ಆಗಿಲ್ಲ. ನೀವು ಸಂಪಾದನೆ ಮಾಡಿದಲ್ಲಿ ನಿಮ್ಮ ಐಪಿ ವಿಳಾಸವು ಎಲ್ಲರಿಗೂ ಕಾಣಲು ಸಿಗುತ್ತದೆ. ನೀವು <strong>[$1 ಲಾಗ್ ಇನ್ ಆದರೆ]</strong> ಅಥವ <strong>[$2 ಹೊಸ ಖಾತೆಯನ್ನು ಸೃಷ್ಟಿಸಿದರೆ]</strong>, ನಿಮ್ಮ ಸಂಪಾದನೆಗಳನ್ನು ನೀವು ನಿಮ್ಮ ಬಳಕೆದಾರ ಹೆಸರಿನ ಅಡಿಯಲ್ಲಿ ಪ್ರದರ್ಶಿಸಬಹುದು.",
        "anonpreviewwarning": "''ನೀವು ಲಾಗಿನ್ ಆಗಿಲ್ಲ . ಉಳಿಸಲು ಪ್ರಯತ್ನಿಸಿದಾಗ ನಿಮ್ಮ IP ವಿಳಾಸವನ್ನು ಈ ಪುಟದ ಸಂಪಾದನೆ ಇತಿಹಾಸದಲ್ಲಿ ನಮೂದಿಸಲಗುವುದು.''",
        "missingsummary": "'''ಗಮನಿಸಿ:''' ನಿಮ್ಮ ಸಂಪಾದನೆಯ ಸಾರಾಂಶವನ್ನು ನೀವು ನೀಡಿಲ್ಲ. ಮತ್ತೊಮ್ಮೆ \"ಉಳಿಸು\" ಗುಂಡಿಯನ್ನು ಒತ್ತಿದರೆ, ಸಾರಾಂಶವಿಲ್ಲದೆಯೇ ನಿಮ್ಮ ಸಂಪಾದನೆಯನ್ನು ಉಳಿಸಲಾಗುವುದು.",
        "missingcommenttext": "ಕೆಳಗೆ ಒಂದು ಟಿಪ್ಪಣಿ ನಮೂದಿಸಿ",
-       "missingcommentheader": "'''ಗಮನಿಸಿ:''' ಈ ವ್ಯಾಖ್ಯಾನಕ್ಕೆ ವಿಷಯ ಅಥವ ತಲೆಬರಹ ನೀವು ಸೂಚಿಸಿಲ್ಲ. ನೀವು \"{{int:savearticle}}\"\nಮತ್ತೊಮೆ ಒತ್ತಿದರೆ ನಿಮ್ಮ ಸಂಪಾದನೆಯನ್ನು ಹಾಗೆಯೇ ಉಳಿಸಲಾಗುವುದು.",
+       "missingcommentheader": "<strong>ಗಮನಿಸಿ:</strong> ನಿಮ್ಮ ಸಂಪಾದನೆಯ ಸಾರಾಂಶವನ್ನು ನೀವು ನೀಡಿಲ್ಲ. ಮತ್ತೊಮ್ಮೆ \"{{int:savearticle}}\" ಅನ್ನು ಒತ್ತಿದರೆ, ಸಾರಾಂಶವಿಲ್ಲದೆಯೇ ನಿಮ್ಮ ಸಂಪಾದನೆಯನ್ನು ಉಳಿಸಲಾಗುವುದು.",
        "summary-preview": "ತಾತ್ಪರ್ಯ ಮುನ್ನೋಟ:",
        "subject-preview": "ವಿಷಯದ ಮುನ್ನೋಟ:",
        "blockedtitle": "ಈ ಸದಸ್ಯರನ್ನು ತಡೆ ಹಿಡಿಯಲಾಗಿದೆ.",
        "whitelistedittext": "ಪುಟಗಳನ್ನು ಸಂಪಾದಿಸಲು ನೀವು $1 ಆಗಬೇಕು.",
        "confirmedittext": "ಪುಟಗಳನ್ನು ಸಂಪಾದಿಸುವ ಮುನ್ನ ನೀವು ನಿಮ್ಮ ಇ-ಅಂಚೆ ವಿಳಾಸವನ್ನು ಧೃಡೀಕರಿಸಬೇಕು.\nದಯವಿಟ್ಟು [[Special:Preferences|ಬಳಕೆದಾರ ಆಯ್ಕೆಗಳು]] ಪುಟದಲ್ಲಿ ತಮ್ಮ ಇ-ಅಂಚೆ ವಿಳಾಸವನ್ನು ನಮೂದಿಸಿ ಮತ್ತು ಧೃಡೀಕರಿಸಿ.",
        "nosuchsectiontitle": "ಆ ಹೆಸರಿನ ವಿಭಾಗ ಯಾವುದೂ ಇಲ್ಲ",
-       "nosuchsectiontext": "ನೀವು ಅಸ್ಥಿತ್ವದಲ್ಲಿ ಇರದ ಒಂದು ವಿಭಾಗವನ್ನು ಸಂಪಾದಿಸಲು ಪ್ರಯತ್ನಿಸಿದಿರಿ.",
+       "nosuchsectiontext": "ನೀವು ಅಸ್ಥಿತ್ವದಲ್ಲಿ ಇರದ ಒಂದು ವಿಭಾಗವನ್ನು ಸಂಪಾದಿಸಲು ಪ್ರಯತ್ನಿಸಿದಿರಿ.\nನೀವು ಪುಟವನ್ನು ವೀಕ್ಷಿಸುವಾಗ ಆ ವಿಭಾಗವು ಸ್ಥಳಾಂತರಗೊಂಡಿರಬಹುದು ಅಥವ ಅಳಿಸಲ್ಪಟ್ಟಿರಬಹುದು.",
        "loginreqtitle": "ಲಾಗಿನ್ ಆಗಬೇಕು",
        "loginreqlink": "ಲಾಗ್ ಇನ್",
        "loginreqpagetext": "ಇತರ ಪುಟಗಳನ್ನು ನೋಡಲು ನೀವು $1 ಆಗಬೇಕು.",
        "newarticle": "(ಹೊಸತು)",
        "newarticletext": "ಇನ್ನೂ ಅಸ್ಥಿತ್ವದಲ್ಲಿ ಇರದ ಪುಟದ ಲಿಂಕ್ ಅನ್ನು ನೀವು ಒತ್ತಿರುವಿರಿ.\nಈ ಪುಟವನ್ನು ಸೃಷ್ಟಿಸಲು ಕೆಳಗಿನ ಚೌಕದಲ್ಲಿ ಬರೆಯಲು ಆರಂಭಿಸಿರಿ.\n(ಹೆಚ್ಚು ಮಾಹಿತಿಗೆ [$1 ಸಹಾಯ ಪುಟ] ನೋಡಿ).\nಈ ಪುಟಕ್ಕೆ ನೀವು ತಪ್ಪಾಗಿ ಬಂದಿದ್ದಲ್ಲಿ ನಿಮ್ಮ ಬ್ರೌಸರ್‍ನ '''back''' ಬಟನ್ ಅನ್ನು ಒತ್ತಿ.",
        "anontalkpagetext": "----''ಇದು ಖಾತೆಯೊಂದನ್ನು ಹೊಂದಿರದ ಅನಾಮಧೇಯ ಬಳಕೆದಾರರೊಬ್ಬರ ಚರ್ಚೆ ಪುಟ.\nಖಾತೆಯಿಲ್ಲದಿರುವುದರಿಂದ ಅವರನ್ನು ಗುರುತಿಸಲು ಅವರ IP ವಿಳಾಸವನ್ನು ಉಪಯೋಗಿಸುತ್ತಿದ್ದೇವೆ.\nಈ ರೀತಿಯ IP ವಿಳಾಸವು ಅನೇಕ ಬಳಕೆದಾರರಿಂದ ಉಪಯೋಗದಲ್ಲಿರಬಹುದು.\nನೀವು ಅನಾಮಧೇಯ ಬಳಕೆದಾರರಾಗಿದ್ದಲ್ಲಿ, ಹಾಗು ನಿಮಗೆ ಸಂಬಂಧವಿಲ್ಲದಂತ ಸಂದೇಶಗಳು ಬರುತ್ತಿವೆ ಎಂದು ಅನಿಸಿದರೆ, ಮುಂದೆ ಬೇರೆ ಅನಾಮಧೇಯ ಬಳಕೆದಾರರೊಂದಿಗೆ ತಪ್ಪಾಗಿ ಗುರುತಿಸಬಾರದೆಂದಿದ್ದರೆ ದಯವಿಟ್ಟು [[Special:CreateAccount|ಸದಸ್ಯರಾಗಿ]] ಅಥವ [[Special:UserLogin|ಲಾಗ್ ಇನ್ ಆಗಿ]].''",
-       "noarticletext": "à²\88 à²ªà³\81à²\9fದಲà³\8dಲಿ à²¸à²¦à³\8dಯà²\95à³\8dà²\95à³\86 à²\8fನà³\82 à²\87ಲà³\8dಲ.\nನà³\80ವà³\81 à²\87ತರ à²ªà³\81à²\9fà²\97ಳಲà³\8dಲಿ [[Special:Search/{{PAGENAME}}|à²\88 à²¹à³\86ಸರನà³\8dನà³\81 à²¹à³\81ಡà³\81à²\95ಬಹà³\81ದà³\81]],\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} à²¸à²\82ಬà²\82ಧಿತ à²¦à²¾à²\96ಲà³\86à²\97ಳನà³\8dನà³\81 à²¹à³\81ಡà³\81à²\95ಬಹà³\81ದà³\81],\nà²\85ಥವ [{{fullurl:{{FULLPAGENAME}}|action=edit}} à²\88 à²ªà³\81à²\9fವನà³\8dನà³\81 à²¸à²\82ಪಾದಿಸಬಹುದು]</span>.",
-       "noarticletext-nopermission": "ಈ ಪುಟದಲ್ಲಿ ಸದ್ಯಕ್ಕೆ ಯಾವ ಪಠ್ಯವೂ ಇಲ್ಲ.\nನೀವು ಇತರ ಪುಟಗಳಲ್ಲಿ [[ವಿಶೇಷ:Search/{{PAGENAME}}|ಈ ಶೀರ್ಷಿಕೆಗಾಗಿ ಹುಡುಕಬಹುದು]],\nಅಥವಾ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ಸಂಬಂಧಿಸಿದ ದಾಖಲಾತಿ ಹುಡುಕಬಹುದು]</span>, ಆದರೆ ನಿಮಗೆ ಈ ಪುಟವನ್ನು ಸಂಪಾದಿಸಲು ಅನುಮತಿಯಿಲ್ಲ.",
+       "noarticletext": "à²\88 à²ªà³\81à²\9fದಲà³\8dಲಿ à²¸à²¦à³\8dಯà²\95à³\8dà²\95à³\86 à²\8fನà³\82 à²\87ಲà³\8dಲ.\nನà³\80ವà³\81 à²\87ತರ à²ªà³\81à²\9fà²\97ಳಲà³\8dಲಿ [[Special:Search/{{PAGENAME}}|à²\88 à²¹à³\86ಸರನà³\8dನà³\81 à²¹à³\81ಡà³\81à²\95ಬಹà³\81ದà³\81]],\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} à²¸à²\82ಬà²\82ಧಿತ à²¦à²¾à²\96ಲà³\86à²\97ಳನà³\8dನà³\81 à²¹à³\81ಡà³\81à²\95ಬಹà³\81ದà³\81],\nà²\85ಥವ [{{fullurl:{{FULLPAGENAME}}|action=edit}} à²\88 à²ªà³\81à²\9fವನà³\8dನà³\81 à²¸à³\83ಷà³\8dà²\9fಿಸಬಹುದು]</span>.",
+       "noarticletext-nopermission": "ಈ ಪುಟದಲ್ಲಿ ಸದ್ಯಕ್ಕೆ ಯಾವ ಪಠ್ಯವೂ ಇಲ್ಲ.\nನೀವು ಇತರ ಪುಟಗಳಲ್ಲಿ [[Special:Search/{{PAGENAME}}|ಈ ಶೀರ್ಷಿಕೆಗಾಗಿ ಹುಡುಕಬಹುದು]], ಅಥವಾ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ಸಂಬಂಧಿಸಿದ ದಾಖಲೆಗಳನ್ನು ಹುಡುಕಬಹುದು]</span>, ಆದರೆ ನಿಮಗೆ ಈ ಪುಟವನ್ನು ಸೃಷ್ಟಿಸಲು ಅನುಮತಿಯಿಲ್ಲ.",
        "userpage-userdoesnotexist": "ಬಳಕೆದಾರ ಖಾತೆ \"<nowiki>$1</nowiki>\" ದಾಖಲಾಗಿಲ್ಲ. ನೀವು ಇದೇ ಪುಟವನ್ನು ಸೃಷ್ಟಿ/ಸಂಪಾದನೆ ಮಾಡಬೇಕೆಂದಿರುವಿರಿ ಎಂದು ಖಾತ್ರಿ ಮಾಡಿಕೊಳ್ಳಿ.",
        "blocked-notice-logextract": "ಈ ಬಳಕೆದಾರರನ್ನು  ಪ್ರಸ್ತುತವಾಗಿ  ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ. \nಇತ್ತೀಚಿನ  ನಿರ್ಬಂಧನೆಯ ದಾಖಲೆಯನ್ನು ಉಲ್ಲೇಖಕ್ಕಾಗಿ ಕೆಳಗೆ ಕೊಟ್ಟಿದೆ:",
        "usercssyoucanpreview": "'''ಗಮನಿಸಿ:''' ಉಳಿಸುವ ಮುನ್ನ 'ಮುನ್ನೋಟ' ಗುಂಡಿಯನ್ನು ಉಪಯೋಗಿಸಿ ನಿಮ್ಮ ಹೊಸ CSS ಅನ್ನು ಪ್ರಯೋಗ ಮಾಡಿ.",
        "revertmerge": "ಸೇರ್ಪಡೆಯನ್ನು ತೊಡೆದುಹಾಕು",
        "mergelogpagetext": "ಒಂದು ಪುಟದ ಇತಿಹಾಸವನ್ನು ಇನ್ನೊಂದರೊಳಗೆ ಇತ್ತೀಚೆಗೆ ಸೇರ್ಪಡೆ ಮಾಡಲಾಗಿರುವ ಪಟ್ಟಿ ಕೆಳಗಿದೆ.",
        "history-title": "\"$1\" ಪುಟದ ಬದಲಾವಣೆಗಳ ಇತಿಹಾಸ",
+       "difference-title": "\"$1\" ಆವೃತ್ತಿಗಳ ಮಧ್ಯದ ಬದಲಾವಣೆಗಳು",
        "lineno": "$1 ನೇ ಸಾಲು:",
        "compareselectedversions": "ಆಯ್ಕೆ ಮಾಡಿದ ಆವೃತ್ತಿಗಳನ್ನು ಹೊಂದಾಣಿಕೆ ಮಾಡಿ ನೋಡಿ",
        "showhideselectedversions": "ಆಯ್ದ ಆವೃತ್ತಿಗಳನ್ನು ತೋರಿಸು/ಅಡಗಿಸು",
        "editundo": "ಹಿಂದಿನಂತೆ",
        "diff-empty": "( ಯಾವುದೇ ವ್ಯತ್ಯಾಸವಿಲ್ಲ )",
+       "diff-multi-sameuser": "(ಅದೇ ಬಳಕೆದಾರನ {{PLURAL:$1|ಮಧ್ಯದಲ್ಲಿನ ಬದಲಾವಣೆಯನ್ನು|$1 ಮಧ್ಯದ ಬದಲಾವಣೆಗಳನ್ನು}} ತೋರಿಸುತ್ತಿಲ್ಲ)",
        "searchresults": "ಶೋಧನೆಯ ಫಲಿತಾಂಶಗಳು",
        "searchresults-title": "\"$1\" ಅನ್ನು ಹುಡುಕಿದ ಫಲಿತಾಂಶಗಳು",
        "titlematches": "ಹೊಂದಿಕೆಯಿರುವ ಪುಟ ಶೀರ್ಷಿಕೆಗಳು",
        "shown-title": "ಪ್ರತಿ ಪುಟದಲ್ಲಿಯೂ $1 {{PLURAL:$1|result|results}} ತೋರಿಸು",
        "viewprevnext": "ವೀಕ್ಷಿಸು ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "'''\"[[:$1]]\" ಹೆಸರಿನ ಪುಟ ಈ ವಿಕಿಯಲ್ಲಿದೆ.'''",
-       "searchmenu-new": "'''''[[:$1]]'' ಪುಟವನ್ನು ಈ ವಿಕಿಯಲ್ಲಿ ಸೃಷ್ಟಿಸಿ!'''",
+       "searchmenu-new": "<strong>\"[[:$1]]\" ಪುಟವನ್ನು ಈ ವಿಕಿಯಲ್ಲಿ ಸೃಷ್ಟಿಸಿ!!</strong> {{PLURAL:$2|0=|See also the page found with your search.|See also the search results found.}}",
        "searchprofile-articles": "ಲೇಖನ ಪುಟ",
        "searchprofile-images": "ಮಲ್ಟಿಮೀಡಿಯ",
        "searchprofile-everything": "ಪ್ರತಿಯೊಂದು",
        "searchprofile-everything-tooltip": "ಎಲ್ಲಾ ಮಾಹಿತಿಗಳನ್ನು ಹುಡುಕಿ (ಚರ್ಚೆಯನ್ನೂ ಸೇರಿಸಿ)",
        "searchprofile-advanced-tooltip": "ಬಳಕೆಯ ನಾಮವರ್ಗಗಳಲ್ಲಿ ಹುಡುಕಿ",
        "search-result-size": "$1 ({{PLURAL:$2|೧ ಪದ|$2 ಪದಗಳು}})",
-       "search-redirect": "(ಪುನರ್ನಿರ್ದೇಶನ $1)",
+       "search-redirect": "($1 ಇಂದ ಪುನರ್ನಿರ್ದೇಶಿತ)",
        "search-section": "(ವಿಭಾಗ $1)",
        "search-suggest": "ನೀವು ಇದನ್ನು ಹುಡುಕುತ್ತಿರುವಿರೆ: $1",
        "search-interwiki-caption": "ಬಳಗದ ಇತರ ಯೋಜನೆಗಳು",
        "recentchanges-label-unpatrolled": "ಈ ಸಂಪಾದನೆಯನ್ನು ಇನ್ನೂ ಪರೀಕ್ಷೆಗೆ ಒಳಪಡಿಸಿಲ್ಲ",
        "recentchanges-label-plusminus": "ಪುಟದ ಗಾತ್ರವು ಇಷ್ಟು ಸಂಖ್ಯೆಯ ಬೈಟ್‍ಗಳಿಂದ ಬದಲಾಯಿಸಲ್ಪಟ್ಟಿದೆ",
        "recentchanges-legend-heading": "<strong>ಪರಿವಿಡಿ:</strong>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|ಹೊಸ ಪುಟಗಳ ಪಟ್ಟಿ]]ಯನ್ನೂ ನೋಡಿ)",
        "rcnotefrom": "'''$2''' ಇಂದ ಆಗಿರುವ ಬದಲಾವಣೆಗಳು ಕೆಳಗಿವೆ (ಕೊನೆಯ '''$1'''ರವರೆಗೆ ತೋರಿಸಲಾಗಿದೆ).",
        "rclistfrom": "$3 $2 ಇಂದ ಪ್ರಾರಂಭಿಸಿ ಮಾಡಲಾದ ಬದಲಾವಣೆಗಳನ್ನು ನೋಡಿ",
        "rcshowhideminor": "ಚಿಕ್ಕಪುಟ್ಟ ಬದಲಾವಣೆಗಳನ್ನು $1",
        "deletereason-dropdown": "*ಸಾಮಾನ್ಯ ಅಳಿಸುವಿಕೆಯ ಕಾರಣಗಳು\n** ಸಂಪಾದಕರ ಕೋರಿಕೆ\n** ಕೃತಿಸ್ವಾಮ್ಯತೆಯ ಉಲ್ಲಂಘನೆ\n** Vandalism",
        "delete-edit-reasonlist": "ಅಳಿಸುವಿಕೆ ಕಾರಣಗಳನ್ನು ಸಂಪಾದಿಸು",
        "rollbacklink": "ತೊಡೆದುಹಾಕು",
+       "rollbacklinkcount": "$1 {{PLURAL:$1|ಸಂಪಾದನೆಯನ್ನು|ಸಂಪಾದನೆಗಳನ್ನು}} ತೊಡೆದುಹಾಕು",
        "changecontentmodel": "ಪುಟದ ವಿಷಯ ಮಾದರಿಯನ್ನು ಬದಲಾಯಿಸಿ",
        "changecontentmodel-legend": "ವಿಷಯ ಮಾದರಿಯನ್ನು ಬದಲಾಯಿಸಿ",
        "changecontentmodel-title-label": "ಪುಟ ಶೀರ್ಷಿಕೆ",
        "contributions": "{{GENDER:$1|User}} ಕಾಣಿಕೆಗಳು",
        "contributions-title": "$1 ಸದಸ್ಯರ ಕಾಣಿಕೆಗಳು",
        "mycontris": "ಕಾಣಿಕೆಗಳು",
+       "anoncontribs": "ಕಾಣಿಕೆಗಳು",
        "contribsub2": "$1 ($2) ಗೆ",
        "uctop": "(ಪ್ರಸಕ್ತ)",
        "month": "ಈ ತಿಂಗಳಿಂದ (ಮತ್ತು ಮುಂಚಿನ):",
        "whatlinkshere-next": "{{PLURAL:$1|ಮುಂದಿನ|ಮುಂದಿನ $1}}",
        "whatlinkshere-links": "← ಕೊಂಡಿಗಳು",
        "whatlinkshere-hideredirs": "$1 ಪುನರ್ನಿರ್ದೇಶನಗಳು",
-       "whatlinkshere-hidetrans": "$1 à²¸à³\87ರಿಸà³\81ವಿà²\95ೆಗಳು",
+       "whatlinkshere-hidetrans": "$1 à²¸à³\87ರà³\8dಪಡೆಗಳು",
        "whatlinkshere-hidelinks": "$1 ಕೊಂಡಿಗಳು",
        "whatlinkshere-hideimages": "$1 ಚಿತ್ರದ ಕೊಂಡಿಗಳು",
        "whatlinkshere-filters": "ಶೋಧಕಗಳು",
        "tooltip-pt-anonuserpage": "ನೀವು ಸಂಪಾದನೆ ಮಾಡುತ್ತಿರುವ ipಯ ಬಳಕೆದಾರ ಪುಟ",
        "tooltip-pt-mytalk": "ನಿಮ್ಮ ಚರ್ಚೆ ಪುಟ",
        "tooltip-pt-anontalk": "ಈ ip ವಿಳಾಸದಿಂದ ಮಾಡಲಾದ ಸಂಪಾದನೆಗಳ ಬಗ್ಗೆ ಚರ್ಚೆ",
-       "tooltip-pt-preferences": "ನನà³\8dನ ಆಯ್ಕೆಗಳು",
+       "tooltip-pt-preferences": "ನಿಮà³\8dಮ ಆಯ್ಕೆಗಳು",
        "tooltip-pt-watchlist": "ನೀವು ಬದಲಾವಣೆಗಳ ಮೇಲೆ ನಿಗಾ ವಹಿಸುತ್ತಿರುವ ಪುಟಗಳ ಪಟ್ಟಿ",
        "tooltip-pt-mycontris": "ನಿಮ್ಮ ಕಾಣಿಕೆಗಳ ಪಟ್ಟಿ",
        "tooltip-pt-login": "ನೀವು ಲಾಗ್ ಇನ್ ಆಗಬೇಕೆಂದು ಕೋರುತ್ತೇವೆ, ಆದರೆ ಅದು ಖಡ್ಡಾಯ ಎನೂ ಅಲ್ಲ.",
        "tooltip-t-recentchangeslinked": "ಈ ಪುಟದಿಂದ ಸಂಪರ್ಕ ಹೊಂದಿರುವ ಪುಟಗಳಲ್ಲಿನ ಇತ್ತೀಚಿನ ಬದಲಾವಣೆಗಳು",
        "tooltip-feed-rss": "ಈ ಪುಟಕ್ಕೆ RSS ಫೀಡು",
        "tooltip-feed-atom": "ಈ ಪುಟಕ್ಕೆ Atom ಫೀಡು",
-       "tooltip-t-contributions": "ಈ ಸದಸ್ಯರ ಕಾಣಿಕೆಗಳ ಪಟ್ಟಿಯನ್ನು ತೋರಿಸು",
+       "tooltip-t-contributions": "{{GENDER:$1|ಈ ಸದಸ್ಯರ}} ಕಾಣಿಕೆಗಳ ಪಟ್ಟಿ",
        "tooltip-t-emailuser": "ಈ ಸದಸ್ಯರಿಗೆ ಇ-ಅಂಚೆಯನ್ನು ಕಳುಹಿಸು",
        "tooltip-t-upload": "ಫೈಲನ್ನು ಮೇಲಕ್ಕೆರಿಸಿ",
        "tooltip-t-specialpages": "ಎಲ್ಲಾ ವಿಶೇಷ ಪುಟಗಳ ಪಟ್ಟಿ",
        "exif-bitspersample": "ಪ್ರತಿ ಭಾಗಕ್ಕಿರುವ ಬಿಟ್‍ಗಳು",
        "exif-compression": "ಕುಗ್ಗಿಸಲು ಉಪಯೋಗಿಸಿರುವ ಪ್ರಕಾರ",
        "exif-photometricinterpretation": "ಚಿತ್ರಬಿಂದು ರಚನೆ",
+       "exif-orientation": "ದೃಷ್ಟಿಕೋನ",
        "exif-ycbcrpositioning": "Y ಮತ್ತು C ಸ್ಥಾನ",
        "exif-datetime": "ಫೈಲು ಬದಲಾದ ದಿನಾಂಕ ಮತ್ತು ಕಾಲ",
        "exif-imagedescription": "ಚಿತ್ರದ ಶೀರ್ಷಿಕೆ",
        "exif-artist": "ಕರ್ತೃ",
        "exif-copyright": "ಕೃತಿಸ್ವಾಮ್ಯತೆಯನ್ನು ಹೊಂದಿರುವವರು",
        "exif-exifversion": "Exif ಆವೃತ್ತಿ",
+       "exif-colorspace": "ರಂಗ ವಿಸ್ತಾರ",
        "exif-pixelxdimension": "ಭಾವಚಿತ್ರದ ಅಗಲ",
        "exif-pixelydimension": "ಭಾವಚಿತ್ರದ ಎತ್ತರ",
        "exif-usercomment": "ಬಳಕೆದಾರನ ಟಿಪ್ಪಣಿ",
        "revdelete-summary": "ಸಂಪಾದನೆಯ ತಾತ್ಪರ್ಯ",
        "feedback-message": "ಸಂದೇಶ:",
        "feedback-subject": "ವಿಷಯ:",
-       "searchsuggest-search": "ಹುಡುಕು",
+       "searchsuggest-search": "{{SITENAME}} ಅನ್ನು ಹುಡುಕಿ",
        "duration-seconds": "$1 {{PLURAL:$1|ಕ್ಷಣ|ಕ್ಷಣಗಳು}}",
        "duration-minutes": "$1 {{PLURAL:$1|ನಿಮಿಷ|ನಿಮಿಷಗಳು}}",
        "duration-hours": "$1 {{PLURAL:$1|ಘಂಟೆ|ಘಂಟೆಗಳು}}",
index 1689175..61511ec 100644 (file)
@@ -62,7 +62,9 @@
                        "Ellif",
                        "HDNua",
                        "Ykhwong",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Tursetic",
+                       "Jerrykim306"
                ]
        },
        "tog-underline": "링크에 밑줄:",
@@ -90,7 +92,7 @@
        "tog-enotifminoredits": "문서나 파일의 사소한 편집도 이메일로 알림",
        "tog-enotifrevealaddr": "알림 메일에 내 이메일 주소를 밝히기",
        "tog-shownumberswatching": "주시하는 사용자 수 보이기",
-       "tog-oldsig": "현재 서명:",
+       "tog-oldsig": "당신의 기존 서명:",
        "tog-fancysig": "서명을 위키텍스트로 취급 (자동으로 링크를 걸지 않음)",
        "tog-uselivepreview": "실시간 미리 보기 사용하기",
        "tog-forceeditsummary": "편집 요약을 쓰지 않았을 때 내게 물어보기",
        "tog-diffonly": "편집 차이를 비교할 때 문서 내용을 보지 않기",
        "tog-showhiddencats": "숨은 분류 보이기",
        "tog-norollbackdiff": "되돌리기 후 차이를 보지 않기",
-       "tog-useeditwarning": "바꾼 내용을 저장하지 않고 편집 페이지를 벗어날 때 내게 경고하기",
+       "tog-useeditwarning": "바꾼 내용을 저장하지 않고 편집 페이지를 벗어날 때 내게 알리기",
        "tog-prefershttps": "로그인하는 동안 항상 보안 연결 사용",
        "underline-always": "항상",
        "underline-never": "항상 치지 않기",
        "poolcounter-usage-error": "사용법 오류: $1",
        "aboutsite": "{{SITENAME}} 소개",
        "aboutpage": "Project:소개",
-       "copyright": "ë\82´ì\9a©ì\9d\80 ë³\84ë\8f\84ë¡\9c ëª\85ì\8b\9cí\95\98ì§\80 ì\95\8aì\9d\84 ê²½ì\9a° $1에 따라 사용할 수 있습니다.",
+       "copyright": "ë³\84ë\8f\84ë¡\9c ëª\85ì\8b\9cí\95\98ì§\80 ì\95\8aì\9d\80 ê²½ì\9a°, ë\82´ì\9a©ì\9d\80 $1에 따라 사용할 수 있습니다.",
        "copyrightpage": "{{ns:project}}:저작권",
        "currentevents": "요즘 화제",
        "currentevents-url": "Project:요즘 화제",
        "passwordreset-nocaller": "호출자를 지정해야 합니다",
        "passwordreset-nosuchcaller": "호출자가 존재하지 않습니다: $1",
        "passwordreset-ignored": "비밀번호 재설정을 처리하지 못했습니다. 제공자가 구성되지 않았기 때문일 수 있습니다.",
-       "passwordreset-invalideamil": "잘못된 이메일 주소",
+       "passwordreset-invalidemail": "잘못된 이메일 주소",
        "passwordreset-nodata": "사용자 이름이나 이메일 주소가 지정되지 않았습니다",
        "changeemail": "이메일 주소를 바꾸거나 제거하기",
        "changeemail-header": "이메일 주소를 바꾸려면 이 양식을 채우세요. 계정에서 이메일 연동을 취소하고 싶다면 양식을 제출할 때 새 이메일 주소를 공란으로 두세요.",
        "prefs-personal": "사용자 정보",
        "prefs-rc": "최근 바뀜",
        "prefs-watchlist": "주시문서 목록",
-       "prefs-editwatchlist": "주시목록 편집",
+       "prefs-editwatchlist": "주ì\8b\9c문ì\84\9c ëª©ë¡\9d í\8e¸ì§\91",
        "prefs-editwatchlist-label": "주시문서 목록의 항목을 편집합니다:",
        "prefs-editwatchlist-edit": "주시문서의 제목을 보고 지우기",
        "prefs-editwatchlist-raw": "주시문서 목록 직접 편집하기",
        "file-thumbnail-no": "파일 이름이 <strong>$1</strong>으로 시작합니다.\n이 파일은 그림의 크기를 줄인 (섬네일) 파일인 것 같습니다.\n더 해상도가 좋은 파일이 있다면 그 파일을 올리거나 아니면 올리려는 파일 이름을 바꾸세요.",
        "fileexists-forbidden": "같은 이름의 파일이 이미 있고, 덮어쓸 수 없습니다.\n그래도 파일을 올리시려면, 뒤로 돌아가서 다른 이름으로 시도해 주시기 바랍니다.\n[[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "같은 이름의 파일이 이미 위키미디어 공용에 있습니다.\n그래도 파일을 올리려면 뒤로 돌아가서 다른 이름으로 시도해 주시기 바랍니다.\n[[File:$1|thumb|center|$1]]",
+       "fileexists-no-change": "업로드한 항목은 <strong>[[:$1]]</strong>의 현재 판과 완전히 중복입니다.",
+       "fileexists-duplicate-version": "업로드한 항목은 <strong>[[:$1]]</strong>의 {{PLURAL:$2|과거의 판}}과 완전히 중복입니다.",
        "file-exists-duplicate": "현재 올리고 있는 {{PLURAL:$1|파일}}이 아래 파일과 중복됩니다:",
        "file-deleted-duplicate": "이 파일과 같은 파일 ([[:$1]])이 이전에 삭제된 적이 있습니다. 파일을 다시 올리기 전에 문서의 삭제 기록을 확인해 주시기 바랍니다.",
        "file-deleted-duplicate-notitle": "이 파일과 같은 파일이 이전에 삭제된 적이 있으며, 제목은 숨겨져 있습니다.\n다시 올리기 전에 상확은 검토하기 위해 숨겨진 파일 데이터를 볼 수 있는 누군가에게 물어봐야 합니다.",
        "upload-dialog-disabled": "이 대화창을 이용한 파일 올리기는 이 위키에서 비활성화되어 있습니다.",
        "upload-dialog-title": "파일 올리기",
        "upload-dialog-button-cancel": "취소",
+       "upload-dialog-button-back": "뒤로",
        "upload-dialog-button-done": "완료",
        "upload-dialog-button-save": "저장",
        "upload-dialog-button-upload": "올리기",
        "apisandbox-results-fixtoken-fail": "\"$1\" 토크을 가져오는데 실패했습니다.",
        "apisandbox-alert-page": "이 문서에 있는 필드가 유효하지 않습니다.",
        "apisandbox-alert-field": "이 필드의 값이 유효하지 않습니다.",
+       "apisandbox-continue": "계속",
+       "apisandbox-continue-clear": "지우기",
+       "apisandbox-param-limit": "최대 한계치를 사용하려면 <kbd>max</kbd>를 입력하십시오.",
        "booksources": "책 찾기",
        "booksources-search-legend": "책 원본 검색",
        "booksources-isbn": "ISBN:",
        "booksources-search": "검색",
        "booksources-text": "아래의 목록은 새 책이나 중고 책을 판매하는 바깥 사이트로, 원하는 책의 정보를 얻을 수 있습니다.",
        "booksources-invalid-isbn": "입력한 ISBN이 올바르지 않은 것으로 보입니다. 원본과 대조해 문제가 있는지 확인해보세요.",
+       "magiclink-tracking-rfc": "RFC 매직 링크를 사용하는 문서",
+       "magiclink-tracking-rfc-desc": "이 문서는 RFC 매직 링크를 사용합니다. 이관 방법을 보려면 [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org]를 참조하십시오.",
+       "magiclink-tracking-pmid": "PMID 매직 링크를 사용하는 문서",
+       "magiclink-tracking-pmid-desc": "이 문서는 PMID 매직 링크를 사용합니다. 이관 방법을 보려면 [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org]를 참조하십시오.",
+       "magiclink-tracking-isbn": "ISBN 매직 링크를 사용하는 문서",
+       "magiclink-tracking-isbn-desc": "이 문서는 ISBN 매직 링크를 사용합니다. 이관 방법을 보려면 [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org]를 참조하십시오.",
        "specialloguserlabel": "작업 수행자:",
        "speciallogtitlelabel": "대상 (사용자계정에 대한 제목 또는 {{ns:user}}:사용자이름):",
        "log": "기록 목록",
        "activeusers-intro": "다음은 최근 $1{{PLURAL:$1|일}} 동안 활동한 사용자의 목록입니다.",
        "activeusers-count": "마지막 {{PLURAL:$3|$3일}} 사이의 {{PLURAL:$1|활동}} $1회",
        "activeusers-from": "다음으로 시작하는 사용자를 보기:",
-       "activeusers-hidebots": "봇을 숨기기",
-       "activeusers-hidesysops": "관리자를 숨기기",
+       "activeusers-groups": "그룹에 속한 사용자 표시:",
        "activeusers-noresult": "사용자를 찾을 수 없습니다.",
        "activeusers-submit": "활동하고 있는 사용자 보이기",
        "listgrouprights": "사용자 권한 목록",
        "movelogpagetext": "아래는 이동된 모든 문서의 목록입니다.",
        "movesubpage": "{{PLURAL:$1|하위 문서}}",
        "movesubpagetext": "이 문서에는 다음 {{PLURAL:$1|하위 문서}} $1개가 있습니다.",
+       "movesubpagetalktext": "관련 토론 문서에 속한 $1개의 {{PLURAL:$1|하위 문서}}는 아래와 같습니다.",
        "movenosubpage": "이 문서에는 하위 문서가 존재하지 않습니다.",
        "movereason": "이유:",
        "revertmove": "되돌리기",
        "pageinfo-category-pages": "문서 수",
        "pageinfo-category-subcats": "하위 분류 수",
        "pageinfo-category-files": "파일 수",
+       "pageinfo-user-id": "사용자 ID",
        "markaspatrolleddiff": "점검한 문서로 표시",
        "markaspatrolledtext": "이 문서를 점검한 것으로 표시",
        "markaspatrolledtext-file": "이 파일 버전을 점검한 것으로 표시",
        "patrol-log-header": "문서 점검에 대한 기록입니다.",
        "log-show-hide-patrol": "점검 기록을 $1",
        "log-show-hide-tag": "태그 기록을 $1",
+       "confirm-markpatrolled-button": "확인",
        "deletedrevision": "예전 $1 판이 삭제되었습니다.",
        "filedeleteerror-short": "파일 삭제 오류: $1",
        "filedeleteerror-long": "파일을 삭제하는 도중 오류가 발생했습니다:\n\n$1",
        "newimages-showbots": "봇이 올린 것 보기",
        "newimages-hidepatrolled": "점검한 업로드 숨기기",
        "noimages": "그림이 없습니다.",
+       "gallery-slideshow-toggle": "섬네일 토글",
        "ilsubmit": "검색",
        "bydate": "날짜",
        "sp-newimages-showfrom": "$1 $2부터 시작하는 새 파일 보기",
        "tags-deactivate": "비활성화",
        "tags-hitcount": "$1개 {{PLURAL:$1|바뀜}}",
        "tags-manage-no-permission": "태그를 변경할 권한이 없습니다.",
-       "tags-manage-blocked": "차단된 상태에서는 변경 태그를 관리할 수 없습니다.",
+       "tags-manage-blocked": "{{GENDER:$1|당신이}} 차단된 상태에서는 변경 태그를 관리할 수 없습니다.",
        "tags-create-heading": "태그 생성",
        "tags-create-explanation": "기본적으로 새로 생성된 태그는 사용자와 봇이 사용할 수 있습니다.",
        "tags-create-tag-name": "태그 이름:",
        "tags-deactivate-not-allowed": "\"$1\" 태그를 비활성화할 수 없습니다.",
        "tags-deactivate-submit": "비활성화",
        "tags-apply-no-permission": "사용자의 변경 사항과 변경 태그를 적용할 권한이 없습니다.",
-       "tags-apply-blocked": "차단된 상태에서는 사용자의 변경 사항과 변경 태그를 적용할 수 없습니다.",
+       "tags-apply-blocked": "{{GENDER:$1|당신이}} 차단된 상태에서는 사용자의 변경 사항과 변경 태그를 적용할 수 없습니다.",
        "tags-apply-not-allowed-one": "\"$1\" 태그를 수동으로 추가하는 것은 허용되지 않습니다.",
        "tags-apply-not-allowed-multi": "다음 {{PLURAL:$2|태그를}} 수동으로 추가하는 것은 허용되지 않습니다: $1",
        "tags-update-no-permission": "태그를 문서 판이나 로그 기록에서 추가하거나 삭제할 권한이 없습니다.",
-       "tags-update-blocked": "차단된 상태에서는 변경 태그를 추가하거나 제거할 수 없습니다.",
+       "tags-update-blocked": "{{GENDER:$1|당신이}} 차단된 상태에서는 변경 태그를 추가하거나 제거할 수 없습니다.",
        "tags-update-add-not-allowed-one": "\"$1\" 태그를 수동으로 추가하는 것은 허용되지 않습니다.",
        "tags-update-add-not-allowed-multi": "다음 {{PLURAL:$2|태그는}} 수동으로 추가하는 것이 허용되지 않습니다: $1",
        "tags-update-remove-not-allowed-one": "\"$1\" 태그를 제거하는 것은 허용되지 않습니다.",
        "dberr-again": "잠시 기다리고 나서 다시 불러오세요.",
        "dberr-info": "(데이터베이스 서버에 연결할 수 없습니다: $1)",
        "dberr-info-hidden": "(데이터베이스 서버에 연결할 수 없습니다)",
-       "dberr-usegoogle": "그 동안 Google을 통해 검색할 수도 있습니다.",
+       "dberr-usegoogle": "잠시 동안 Google을 통해 검색해볼 수 있습니다.",
        "dberr-outofdate": "수집된 내용은 오래된 것일 수도 있음을 참고하세요.",
        "dberr-cachederror": "다음은 요청한 문서의 캐시된 복사본이며, 최신이 아닐 수도 있습니다.",
        "htmlform-invalid-input": "입력한 값에 문제가 있습니다.",
        "htmlform-cloner-create": "더 추가",
        "htmlform-cloner-delete": "제거",
        "htmlform-cloner-required": "적어도 하나의 값이 필요합니다.",
+       "htmlform-date-placeholder": "YYYY-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "YYYY-MM-DD HH:MM:SS",
        "htmlform-title-badnamespace": "[[:$1]] 문서는 \"{{ns:$2}}\" 이름공간에 없습니다.",
        "htmlform-title-not-creatable": "\"$1\"은 만들 수 없는 문서 제목입니다.",
        "htmlform-title-not-exists": "$1 문서는 존재하지 않습니다.",
        "feedback-external-bug-report-button": "기술적 보고 제기",
        "feedback-dialog-title": "피드백 제출",
        "feedback-dialog-intro": "당신의 피드백을 제출하기 위해 아래 쉬운 양식을 사용할 수 있습니다. 당신의 의견은 당신의 사용자 이름과 함께, \"$1\" 문서에 추가됩니다.",
-       "feedback-error-title": "오류",
        "feedback-error1": "오류: API 실행 결과를 인식할 수 없음",
        "feedback-error2": "오류: 편집 실패",
        "feedback-error3": "오류: API가 응답하지 않음",
        "feedback-thanks": "감사합니다! \"[$2 $1]\" 문서에 의견을 남겼습니다.",
        "feedback-thanks-title": "감사합니다!",
        "feedback-useragent": "사용자 에이전트:",
-       "searchsuggest-search": "검색",
+       "searchsuggest-search": "{{SITENAME}} 검색",
        "searchsuggest-containing": "다음 문자열 포함...",
        "api-error-autoblocked": "사용자의 IP 주소는 차단된 사용자에 의해 사용되었으므로 자동으로 차단된 상태입니다.",
        "api-error-badaccess-groups": "이 위키에 파일을 올릴 권한이 없습니다.",
        "authmanager-authn-autocreate-failed": "로컬 계정 자동 생성 실패: $1",
        "authmanager-change-not-supported": "지정된 자격 증명을 사용하고 있는 곳이 없어서 변경할 수 없습니다.",
        "authmanager-create-disabled": "계정 만들기가 금지되어 있습니다.",
-       "authmanager-create-from-login": "ê³\84ì \95ì\9d\84 ë§\8cë\93\9c려면, ì\95\84ë\9e\98ì\9d\98 ì¹¸ë\93¤을 채워 주십시오.",
+       "authmanager-create-from-login": "ê³\84ì \95ì\9d\84 ë§\8cë\93¤ë ¤ë©´ ë¹\88칸을 채워 주십시오.",
        "authmanager-create-not-in-progress": "계정 만들기가 진행 중이 아니거나 세션 데이터를 분실했습니다. 처음부터 다시 시작해 주십시오.",
        "authmanager-create-no-primary": "제공된 자격 증명은 계정 생성에 쓰일 수 없습니다.",
        "authmanager-link-no-primary": "제공된 자격 증명은 계정을 연결하는 데 쓰일 수 없습니다.",
        "userjsispublic": "주목해 주십시오: 자바스크립트의 하위 문서들은 다른 사용자들이 볼 수 있기 때문에 기밀 데이터를 포함해서는 안 됩니다.",
        "usercssispublic": "주목해 주십시오: CSS의 하위 문서들은 다른 사용자들이 볼 수 있기 때문에 기밀 데이터를 포함해서는 안 됩니다.",
        "restrictionsfield-badip": "유효하지 않은 IP 주소나 대역: $1",
-       "restrictionsfield-label": "허용된 IP 대역:"
+       "restrictionsfield-label": "허용된 IP 대역:",
+       "restrictionsfield-help": "줄 단위의 하나의 IP 주소 또는 CIDR 대역입니다. 모든 곳에 적용하려면, 다음을 사용하세요<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "오류: $1",
+       "edit-error-long": "오류:\n\n$1"
 }
index 18976ba..557bc61 100644 (file)
        "yourpasswordagain": "Паролну джангыдан джаз:",
        "createacct-yourpasswordagain": "Паролну бегит",
        "createacct-yourpasswordagain-ph": "Паролну энтда бир кере джаз",
-       "remembermypassword": "Бу компьютерде мени тергеў джазыўуму сакълаб тур (эм кёб: $1 {{PLURAL:$1|бир кюн|кюн}})",
        "userlogin-remembermypassword": "Системада туруу",
        "userlogin-signwithsecure": "Джакъланнган байлам",
        "yourdomainname": "Сизни доменигиз:",
        "passwordreset-emailtitle": "{{SITENAME}} сайтдагъы тергеу джазыуну юсюнден билгиле",
        "passwordreset-emailelement": "Къошулуучуну аты: \n$1\n\nБолджаллы пароль: \n$2",
        "passwordreset-emailsentemail": "Пароль бла e-mail ийилди.",
-       "passwordreset-emailsent-capture": "Ийилген пароль эсгертиу e-mail тюбюрекде берилибди.",
-       "passwordreset-emailerror-capture": "Пароль эсгертиу e-mail генерация этилди (тюбюрекде берилибди), аны {{GENDER:$2|къошулуучугъа}} ашырыу джетишимсиз болду, чурум: $1",
        "changeemail": "Электрон почтаны адресин ауушдур",
        "changeemail-header": "Электрон почтаны адресин ауушдуруу",
        "changeemail-no-info": "Бу бетни кёрюр ючюн сиз системагъа тергеу джазыуугъуз (аккаунтугъуз) бла кирирге керексиз.",
        "undo-failure": "Бир-бирине келишмегени себебли, тюрлениу ызына алынамады.",
        "undo-norev": "Болмагъаны неда кетерилгени ючюн, тюрлениу ызына алыналлыкъ тюлдю.",
        "undo-summary": "$1 тюрлениу [[Special:Contributions/$2|$2]] ([[User talk:$2|сюзюу]]) ызына алынды.",
-       "cantcreateaccounttitle": "Акууант къурар мадар джокъду",
        "cantcreateaccount-text": "Бу IP-адресден ('''$1''') хайырланыучу къошулуу, [[User:$3|$3]] джанындан тыйылгъанды.\n\n\n$3 джанындан берилген сылтау: ''$2''",
        "viewpagelogs": "Бу бетни журналларына къара",
        "nohistory": "Бу бетни тюрлениулерини тарихи джокъду.",
        "activeusers-intro": "Бу, ахыр $1 {{PLURAL:$1|1=кюнде|кюнде}} къаллайда болсун ишлетме кёргюзген къошлуучуланы тизмесиди.",
        "activeusers-count": "Ахыр {{PLURAL:$3|1=кюнде|$3 кюнде}} $1 {{PLURAL:$1|1=тюрлендириу|тюрлендириу}}",
        "activeusers-from": "Бу бла башланнган къошлуучуланы кёргюз:",
-       "activeusers-hidebots": "Ботланы джашыр",
-       "activeusers-hidesysops": "Администраторланы джашыр",
        "activeusers-noresult": "Къошлуучу табылмады.",
        "listgrouprights": "Къошулуучуланы къауумуну хакълары",
        "listgrouprights-summary": "Тюбюндеги бу викиде танылгъан къошулуучу къауумланы эмда аланы хакъларыны тизмеси.\nЭнчи хакъла бла байламлы [[{{MediaWiki:Listgrouprights-helppage}}|асламыракъ билги]] болургъа болур.",
        "htmlform-chosen-placeholder": "Вариантны сайлагъыз",
        "htmlform-cloner-create": "Энтда къош",
        "htmlform-cloner-delete": "Кетер",
-       "sqlite-has-fts": "$1 толу текст излеуню хайырландыргъан",
-       "sqlite-no-fts": "$1 толу текст излеуню хайырландыра билмеген",
        "logentry-delete-delete": "$3 бетни $1 {{GENDER:$2|кетерди}}",
        "logentry-delete-restore": "$3 бетни $1 {{GENDER:$2|ызына салды}}",
        "revdelete-content-hid": "ичиндегиси джашырылыбды",
index 3586530..7d67c36 100644 (file)
        "yourpasswordagain": "Noch ens dat Passwood",
        "createacct-yourpasswordagain": "Noch ens dat Paßwoot",
        "createacct-yourpasswordagain-ph": "Jivv_et Paßwoot norrens en!",
-       "remembermypassword": "Op Duur aanmelde (hält {{PLURAL:$1|för eine Daach|bes op $1 Dääsch|bloß för hück}})",
        "userlogin-remembermypassword": "Op Duur enlogge",
        "userlogin-signwithsecure": "Verschlößeld enlogge",
        "cannotloginnow-title": "Ennlogge jeiht jrahd nit",
        "botpasswords-label-resetpassword": "Paßwoot neu säze",
        "botpasswords-label-grants": "Aanwändba Rääschte:",
        "botpasswords-help-grants": "Jehde Ennwellejong deihjd e Räsch wigger jävve, wad enem Metmaacher övver singe Zohjang alld zohschteihjt.\nLoor op de Sigg met de [[Special:ListGrants|Tabäll met de Rääschde un Enwellejonge]], wann De mih weße wells.",
-       "botpasswords-label-restrictions": "Beschränkonge:",
        "botpasswords-label-grants-column": "Zohjelohße",
        "botpasswords-bad-appid": "„$1“ es keine jölltejje Nahme för ene Bot.",
        "botpasswords-insert-failed": "Kunnt keine Bot mem Nahme „$1“ derbei donn. Wohr velleijsch ald doh.",
        "passwordreset-emailerror-capture2": "{{GENDER:$2|Däm|Däm|Däm Metmaacher|Dä|Däm}} $1 en <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> ze scheke hät nit jeflupp: {{PLURAL:$3|Dä Nahme vum Metmaacher un dat Paßwood|Di Leß met dä Nahme un Paßwööter|Nix weed}} heh noh aanjezeijsch.",
        "passwordreset-nocaller": "Entärne Fähler: Ene Oprohfer moß aanjejovve sin.",
        "passwordreset-nosuchcaller": "Entärne Fähler: Dä Oprohfer „$1“ känne mer nit.",
-       "passwordreset-invalideamil": "Dat es en onjöltejje Addräß fö de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i>",
+       "passwordreset-invalidemail": "Dat es en onjöltejje Addräß fö de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i>",
        "passwordreset-nodata": "Keine Metmaacher_Nahme un kein Adräß för de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> es aanjejovve woode.",
        "changeemail": "Donn en Adräß för de <i lang=\"en\">e-mail</i> ändere udder fott schmiiße",
        "changeemail-header": "Donn heh dat Fommulaa ußfölle, öm Ding Adräß för de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> ze ändere. Wann De en Adräß loß wähde wells, maach dat Fäld läddesch, ih dat De dat Fommolaa loß scheks.",
        "activeusers-intro": "Dat heh es en Leß met dä Metmaacher, di {{PLURAL:$1|zick jäßtere|en de läzde $1 Dääsch|hück}} ööhnsjät jemaat han.",
        "activeusers-count": "{{PLURAL:$1|ein Änderong|$1 Änderonge|kein Änderonge}} {{PLURAL:$3|aam lezde Daach|en de lezte $3 Dääsch|hück}}",
        "activeusers-from": "Donn de Metmaacher zeije aff:",
-       "activeusers-hidebots": "De Bots fott lohße",
-       "activeusers-hidesysops": "De Wiki_Köbesse fott lohße",
        "activeusers-noresult": "Kein Metmaacher jefonge.",
        "activeusers-submit": "Lohß jonn!",
        "listgrouprights": "Metmaacher_Jroppe-Rääschte",
        "htmlform-title-not-exists": "$1 jidd_et nit.",
        "htmlform-user-not-exists": "<strong>$1</strong> jidd_et nit.",
        "htmlform-user-not-valid": "<strong>$1</strong> es keine jöltejje Nahme för ene Metmaacher.",
-       "sqlite-has-fts": "Version $1 (un kann en janze Täxte söhke)",
-       "sqlite-no-fts": "Version $1 (kann ävver nit en janze Täxte söhke)",
        "logentry-delete-delete": "{{GENDER:$2|Dä|Dat|Dä Metmaacher|De|Dat}} $1 hät di Sigg „$3“ fottjeschmeße.",
        "logentry-delete-restore": "{{GENDER:$2|Dä|Dat|Dä Metmaacher|De|Dat}} $1 hät di vörmohls fottjeschmeße Sigg „$3“ wider zeröck jehollt.",
        "logentry-delete-event": "{{GENDER:$2|Dä|Dat|Dä Metmaacher|De|Dat}} $1 hät för {{PLURAL:$5|eine Logboochendraach|$5 Logboochendrääsh|keine Logboochendraach}} vun dä Sigg „$3“ $4.",
        "feedback-external-bug-report-button": "Donne ene Fähler mällde, ene Wonsch för en Verbäßerong ennreische, udder anndere täschneche Idee opbränge.",
        "feedback-dialog-title": "En Rökmäldong jävve",
        "feedback-dialog-intro": "Dat Fommolaa kam_mer för en Rökmäldong bruche. Di kütt zesamme met Dingem Metmaacher_Nahme op di Sigg „$1“.",
-       "feedback-error-title": "Fähler",
        "feedback-error1": "Fähler: dat <i lang=\"en\">API</i> säät jät, wat mer nit kenne",
        "feedback-error2": "Fähler: de Sigg ze ändere es donävve jejange",
        "feedback-error3": "Fähler: dat <i lang=\"en\">API</i> joov kein Antwoot",
index ebee06b..0a101ec 100644 (file)
@@ -18,7 +18,8 @@
                        "Uygar",
                        "MikaelF",
                        "Macofe",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Stryn"
                ]
        },
        "tog-underline": "Xetekê di bin girêdanê de çêke:",
        "yourpasswordagain": "Şîfreyê dîsa binivîse:",
        "createacct-yourpasswordagain": "Şîfreyê bipejirîne",
        "createacct-yourpasswordagain-ph": "Şîfreyê ji nû ve binivîse",
-       "remembermypassword": "Şifreya min di her têketina min de bîne bîra xwe (herî zêde $1 {{PLURAL:$1|rojekê|rojan}})",
        "userlogin-remembermypassword": "Min têketî bihêle",
        "userlogin-signwithsecure": "Girêdana parastî bikarbîne",
        "yourdomainname": "Domainê te",
        "nocookiesnew": "Hesabê bikarhêner hatibû çêkirin, lê te xwe qeyd nekiriye. {{SITENAME}} ji bo qeydkirina bikarhêneran cookie'yan bikartîne. Te bikaranîna cookie'yan girtiye. Xêra xwe cookie'yan qebûl bike, piştre bi navê bikarhêner û şîfreya xwe têkeve.",
        "nocookieslogin": "Ji bo qeydkirina bikarhêneran {{SITENAME}} \"cookies\" bikartîne. Te fonksîyona \"cookies\" girtîye. Xêra xwe kerema xwe \"cookies\" gengaz bike û careke din biceribîne.",
        "noname": "Navê ku te nivîsand ne derbasdar e.",
-       "loginsuccesstitle": "Têketin serkevtî bû!",
+       "loginsuccesstitle": "Tu têketî",
        "loginsuccess": "Tu niha di {{SITENAME}} de tomarkirî yî wek \"$1\".",
        "nosuchuser": "Bikarhênerê bi navê \"$1\" tune. Navê rast binivîse an bi vê formê <b>hesabekî nû çêke</b>. (Ji bo hevalên nû \"Têkeve\" çênabe!)",
        "nosuchusershort": "Li vê derê ne bikarhênerek bi navî \"$1\" heye. Li nivîsandinê xwe seke.",
        "retypenew": "Şîfreya nû careke din binîvîse",
        "resetpass_submit": "Şîfreyê pêkbîne û têkeve",
        "changepassword-success": "Şîfreya te hate guhertandin!",
+       "botpasswords": "Şîfreyên bot",
        "botpasswords-label-appid": "Navê bot:",
        "botpasswords-label-create": "Çêke",
        "botpasswords-label-update": "Rojane bike",
        "passwordreset-emailtitle": "Hûragahiyên hesab li ser {{SITENAME}}",
        "passwordreset-emailelement": "Navê bikarhêner:\n$1\n\nŞîfreya niha:\n$2",
        "passwordreset-emailsentemail": "E-nameyeke bibîrxistinê hate şandin.",
-       "passwordreset-invalideamil": "Navnîşana enameyê ya nederbasdar",
+       "passwordreset-invalidemail": "Navnîşana enameyê ya nederbasdar",
        "changeemail": "Navnîşana enameya xwe biguherîne an rabike",
        "changeemail-oldemail": "Navnîşana e-nameya niha:",
        "changeemail-newemail": "Navnîşana e-nameya nû:",
        "preview": "Pêşdîtin",
        "showpreview": "Pêşdîtinê nîşan bide",
        "showdiff": "Guherandinan nîşan bide",
-       "anoneditwarning": "<strong>Hişyarî:<strong> Tu netêketî yî! Navnîşana IP'ya te wê di dîroka guherandina vê rûpelê de bê tomarkirin. Heke tu <strong>[$1 têkevî]</strong> an jî  <strong>[$2 hesabekî çêbikî]</strong>, li gel sûdên te yên din guhertinên ku tu bikî jî wê ji nasnavê te re bê atfkirin.",
+       "anoneditwarning": "<strong>Hişyarî:</strong> Tu netêketî yî! Navnîşana IP'ya te wê di dîroka guherandina vê rûpelê de bê tomarkirin. Heke tu <strong>[$1 têkevî]</strong> an jî <strong>[$2 hesabekî çêbikî]</strong>, li gel sûdên te yên din guhertinên ku tu bikî jî wê ji nasnavê te re bê atfkirin.",
        "anonpreviewwarning": "''Tu ne têketî yî. Tomarkirin wê navnîşana IP'ya te di dîroka guhertinan de nîşan bide.''",
        "missingsummary": "<span style=\"color:#990000;\">'''Zanibe:'''</span> Te nivîsekî kurt ji bo guherandinê ra nenivîsand. Eger tu niha carekî din li Tomar xê, guherandinê te vê nivîsekî kurt yê were tomarkirin.",
        "missingcommenttext": "Ji kerema xwe kurteya naverokê li jêr binivisîne.",
        "undo-success": "Ev guherandin dikare were şûndekirin. Ji kerema xwe ferqa piştî tomarkirinê bibîne, bê ka tu dixwazî vê guhertoyê tomar bikî an na. Ger te şaşîtiyek kir, ji kerema xwe derkeve.",
        "undo-failure": "Ev guhertin ji ber guherandinên piştî wê re nikare were şûndekirin.",
        "undo-summary": "Guhertoya $1 ya [[Special:Contributions/$2|$2]] ([[User talk:$2|gotûbêj]]) şûnde kir",
-       "cantcreateaccounttitle": "Hesab nikarîbû were çêkirin",
        "cantcreateaccount-text": "Çêkirinê hesaban ji vê IP'yê ('''$1''') hatiye qedexekirin ji [[User:$3|$3]].\n\nSedema qedexekirina $3 ev e: ''$2''",
        "viewpagelogs": "Guhertinên vê rûpelê bibîne",
        "nohistory": "Dîroka guherandina vê rûpelê nîne.",
        "searchprofile-images-tooltip": "Li pelan bigere",
        "searchprofile-everything-tooltip": "Di hemû naverokada bigere (tevî gotûbêja)",
        "search-result-size": "$1 ({{PLURAL:$2|peyvek|$2 peyv}})",
-       "search-redirect": "(beralîkirin $1)",
+       "search-redirect": "(beralîkirina ji $1)",
        "search-section": "(beş $1)",
        "search-category": "(kategorî $1)",
        "search-file-match": "(bi naveroka dosye re lê te)",
        "statistics-pages": "Rûpel",
        "statistics-pages-desc": "Hemû rûpelên di vê wîkiyê de, bi hemû rûpelên gotûbêj, beralîkirin, hwd.",
        "statistics-files": "Wêneyên barkirî",
+       "statistics-edits": "Hejmara guherandinên rûpelan ji avabûna {{SITENAME}} heta niha",
        "statistics-users": "[[Special:ListUsers|Bikarhênerên tomarkirî]]",
        "statistics-users-active": "Bikarhênerên çalak",
        "pageswithprop-submit": "Biçe",
        "protectedtitles-submit": "Sernavan nîşan bide",
        "listusers": "Lîsteya bikarhêneran",
        "listusers-editsonly": "Tenê bikarhênerên bi guherrandinan nîşan bide",
+       "listusers-creationsort": "Li gorî dema çêkirina hesab parzûn bike",
        "usercreated": "di $1 de, li $2 hate çêkirin",
        "newpages": "Rûpelên nû",
        "newpages-submit": "Nîşan bide",
        "listusers-blocked": "(hate astengkirin)",
        "activeusers": "Lîsteya bikarhênerên çalak",
        "activeusers-from": "Li bikarhênerên bi vê dest pê dikin bigere:",
-       "activeusers-hidebots": "Bot'an veşêre",
-       "activeusers-hidesysops": "Rêveberan veşêre",
        "activeusers-noresult": "Tu bikarhêner nehate dîtin.",
        "activeusers-submit": "Bikarhênerên çalak nîşan bide",
        "listgrouprights": "Mafên koma bikarhêner",
        "wlshowlast": "Guhertinên berî $1 saetan, $2 rojan, ya  nîşan bide",
        "watchlist-hide": "Veşêre",
        "watchlist-submit": "Nîşan bide",
+       "wlshowhideminor": "guherandinên biçûk",
        "wlshowhidebots": "bot",
        "wlshowhideliu": "bikarhênerên tomarkirî",
        "wlshowhideanons": "bikarhênerên bênav",
        "sp-contributions-userrights": "birêvebirina mafên bikarhêneran",
        "sp-contributions-search": "Li beşdariyan bigere",
        "sp-contributions-username": "Navnîşana IP'yê an jî navê bikarhêner:",
+       "sp-contributions-newonly": "Tenê rûpelên hatine çêkirin nîşan bide",
+       "sp-contributions-hideminor": "Guherandinên biçûk veşêre",
        "sp-contributions-submit": "Lêgerîn",
        "whatlinkshere": "Girêdanên li ser vê rûpelê",
        "whatlinkshere-title": "Rûpelan, yê berve $1 tên",
        "pageinfo-header-properties": "Taybetmendiyên rûpelê",
        "pageinfo-display-title": "Sernavê nîşan bide",
        "pageinfo-language": "Zimanê naveroka rûpelê",
-       "pageinfo-watchers": "Hejmara kesên dişopînin",
+       "pageinfo-watchers": "Hejmara şopînerên rûpelê",
        "pageinfo-redirects-name": "Hejmara beralîkirinên ber bi vê rûpelê ve",
        "pageinfo-subpages-name": "Binrûpelên vê rûpelê",
        "pageinfo-firsttime": "Dema çêkirina rûpelê",
        "markedaspatrolled": "Wek sererastkirî tê nîşandan",
        "markedaspatrolledtext": "Guherandina rûpelê wek serrastkirî tê nîşandan.",
        "patrol-log-page": "Têketina kontrolkirinê",
+       "confirm-markpatrolled-button": "Baş e",
        "deletedrevision": "Guhertoya berê $1 hate jêbirin.",
        "filedelete-missing": "Dane \"$1\" nikare were jêbirin, ji ber ku ew tune ye.",
        "filedelete-current-unregistered": "Daneya \"$1\" li sîstemê tune ye.",
        "imagelisttext": "Jêr lîsteyek ji $1 file'an heye, duxrekirin $2.",
        "newimages-summary": "Ev rûpela taybet dosyeyên ku herî dawî hatine barkirin, nîşan dide.",
        "newimages-legend": "Parzûn",
+       "newimages-showbots": "Barkirinên ji aliyê botan nîşan bide",
        "noimages": "Ne tiştek tê dîtin.",
        "ilsubmit": "Lêgerîn",
        "bydate": "li gor dîrokê",
        "feedback-back": "Paşve",
        "feedback-cancel": "Betal bike",
        "feedback-close": "Çêbû",
-       "feedback-error-title": "Çewtî",
        "feedback-message": "Peyam:",
        "feedback-subject": "Mijar:",
        "feedback-submit": "Tomar bike",
index 6b316da..e4f1e44 100644 (file)
        "yourpasswordagain": "Jynnskrifewgh agas ger tremena arta:",
        "createacct-yourpasswordagain": "Afydhyewgh an ger tremena",
        "createacct-yourpasswordagain-ph": "Entrewgh an ger tremena arta",
-       "remembermypassword": "Perthi kov a'm omgelmi war an jynn amontya-ma (rag $1 {{PLURAL:$1|dydh}} dhe'n moyha)",
        "userlogin-remembermypassword": "Perthi kov a'm omgelmi",
        "userlogin-signwithsecure": "Devnydhya junyans diogel",
        "yourdomainname": "Agas tiredh:",
        "passwordreset-email": "Trigva ebost:",
        "passwordreset-emailtitle": "Manylyon agas akont war {{SITENAME}}",
        "passwordreset-emailsentemail": "Ebost dassettya ger tremena re beu danvenys.",
-       "passwordreset-emailsent-capture": "Ebost dassettya ger tremena re beu danvenys, hag y hyllir y weles a-woles.",
        "changeemail": "Chanjya trigva ebost",
        "changeemail-header": "Chanjya trigva ebost an akont",
        "changeemail-oldemail": "Agas trigva ebost a-lemmyn:",
        "editwarning-warning": "Mar kesowgh an folen ma, hwi a allsa kelli chanjyow gwrys genowgh.\nMars owgh hwi omgelmys, hwi a yll diallosegi an gwarnyans ma yn tregh \"{{int:prefs-editing}}\" agas dewisyow.",
        "undo-success": "Y hyllir diswul an chanj-ma.\nCheckyewgh mar pleg an kehevelyans a-woles rag gwirya bos hemma an pyth a vynnowgh, hag ena gwithewgh an chanjyow a-woles rag gorfenna diswul an chanj.",
        "undo-summary": "Amendyans $1 gans [[Special:Contributions/$2|$2]] ([[User talk:$2|keskows]]) diswrys",
-       "cantcreateaccounttitle": "Ny yllir gwruthyl an akont",
        "viewpagelogs": "Gweles kovnotennow an folen ma",
        "currentrev": "Amendyans diwettha",
        "currentrev-asof": "An amendyans diwettha a-dhia $1",
        "activeusers": "Rol a dhevnydhyoryon vyw",
        "activeusers-intro": "Hemm yw rol a dhevnydhyoryon re wrug gwrians war an wiki-ma y'n $1 {{PLURAL:$1|jydh|dydh}} diwettha.",
        "activeusers-count": "$1 {{PLURAL:$1|wrians|gwrians}} y'n {{PLURAL:$3|jydh|$3 dydh}} diwettha",
-       "activeusers-hidebots": "Kudha botow",
-       "activeusers-hidesysops": "Kudha menystroryon",
        "listgrouprights-members": "(rol eseli)",
        "emailuser": "Ebostya an devnydhyer-ma",
        "defemailsubject": "Ebost danvenys dre {{SITENAME}} gans an devnydhyer \"$1\"",
index 0d7d482..8b2d94f 100644 (file)
@@ -15,7 +15,8 @@
                        "아라",
                        "Askar Nazyrov",
                        "Macofe",
-                       "Janatkg"
+                       "Janatkg",
+                       "Irus"
                ]
        },
        "tog-underline": "Шилтемелердин алдын сызуу:",
        "privacypage": "Project:Купуялуулук саясаты",
        "badaccess": "Кирүү катасы",
        "badaccess-group0": "Сиз сураган аракетти аткара албайсыз.",
+       "badaccess-groups": "Аракети сиз запросили поциент нарын {{PLURAL:$2|топ|бир топтор}}: $1.",
        "versionrequired": "MediaWiki'нин $1 версиясы керек",
        "versionrequiredtext": "Бул барак менен иштөө үчүн MediaWiki $1 версиясы талап кылынат. Кара.[[Special:Version|version page]].",
        "ok": "OK",
        "nstab-template": "Калып",
        "nstab-help": "Жардам",
        "nstab-category": "Категория",
+       "mainpage-nstab": "Башбарак",
        "nosuchaction": "Мындай аракет жок",
        "nosuchspecialpage": "Мындай кызматтык барак жок",
        "error": "Ката",
        "yourpasswordagain": "Сырсөздү кайра терүү:",
        "createacct-yourpasswordagain": "Сырсөздү тастыктаңыз",
        "createacct-yourpasswordagain-ph": "Сырсөздү кайрадан териңиз",
-       "remembermypassword": "Бул браузерде колдонуучу атымды ($1 {{PLURAL:$1|күнгө}} чейин сактоо)",
        "userlogin-remembermypassword": "Мени системге кирген боюнча калтыр",
        "userlogin-signwithsecure": "Коопсуз байланышты колдонуу",
        "yourdomainname": "Сиздин домен:",
        "grouppage-suppress": "{{ns:project}}:Ревизорлор",
        "right-read": "барактарды карап чыгуу",
        "right-edit": "Барактарды оңдоо",
+       "right-createpage": "Түзүү барактан (талкуулоо жок талкуулоо)",
+       "right-createtalk": "Түзүү бет талкуулоо",
+       "right-createaccount": "Түзүүгө, жаңы эсепке алуу жазуулары пайдалануучулардын",
        "right-move": "барактардын атын өзгөртүү",
        "right-move-rootuserpages": "катышуучулардын түпкү барактарынын атын өзгөртүү",
        "right-movefile": "файлдардын атын өзгөртүү",
        "right-upload": "Файлдарды жүктөө",
        "right-reupload": "Бар болгон файлдардын үстүнөн жаздыруу",
+       "right-writeapi": "Пайдалануу API үчүн жазуу",
        "right-delete": "Барактарды өчүрүү",
        "right-browsearchive": "Өчүрүлгөн барактарды издөө",
        "right-suppressionlog": "Жеке журналдарды көрүү",
        "action-createtalk": "талкуулоо барагын түзүү",
        "action-createaccount": "бул эсеп жазуусун түзүү",
        "action-upload": "бул файлды жүктөө",
+       "action-writeapi": "пайдалануу API үчүн жазуу",
        "action-delete": "бул баракты өчүрүү",
        "action-suppressionlog": "бул жеке журналды көрүү",
        "action-userrights": "бүткүл колдонуучулардын укуктарын оңдоо",
        "listusers-noresult": "Колдонуучу табылган жок.",
        "listusers-blocked": "(бөгөттөлгөн)",
        "activeusers": "Активдүү колдонуучулардын тизмеси",
-       "activeusers-hidebots": "Ботторду жашыруу",
-       "activeusers-hidesysops": "Администраторлорду жашыруу",
        "activeusers-noresult": "Колдонуучулар табылган жок.",
        "listgrouprights-group": "Топ",
        "listgrouprights-rights": "Укуктар",
index 5c34a58..171a911 100644 (file)
        "listusers-blocked": "(obstructus)",
        "activeusers": "Index usorum activorum",
        "activeusers-count": "{{PLURAL:$1|una recensio {{PLURAL:$3|hodie|his $3 diebus}} facta|$1 recensiones {{PLURAL:$3|hodie|his $3 diebus}} factae}}",
-       "activeusers-hidebots": "Celare automata",
-       "activeusers-hidesysops": "Celare magistratus",
        "activeusers-noresult": "Nullus usor inventus.",
        "listgrouprights": "Gregum usorum potestates",
        "listgrouprights-group": "Grex",
        "tooltip-ca-move": "Movere hanc paginam",
        "tooltip-ca-watch": "Hanc paginam observandam habere",
        "tooltip-ca-unwatch": "Hanc paginam non iam observandam habere",
-       "tooltip-search": "Aliquid in {{grammar:ablative|{{SITENAME}}}} quaerere",
+       "tooltip-search": "Quaerere apud {{grammar:accusative|{{SITENAME}}}}",
        "tooltip-search-go": "Si modo sit, paginam huius ipsius tituli invisere",
        "tooltip-search-fulltext": "Hunc textum in paginis requirere",
        "tooltip-p-logo": "Ire ad paginam primam",
        "feedback-close": "Factum",
        "feedback-error2": "Error: Recensio non additur",
        "feedback-message": "Nuntius:",
-       "searchsuggest-search": "Quaerere",
+       "searchsuggest-search": "Quaerere apud {{grammar:accusative|{{SITENAME}}}}",
        "searchsuggest-containing": "continens...",
        "api-error-empty-file": "Fasciculus inmissus vacuus est.",
        "api-error-emptypage": "Vacuas novas paginas creare non licet.",
index 4f3f53a..db6cd9f 100644 (file)
        "yourpasswordagain": "Entra de muevo el kóddiche:",
        "createacct-yourpasswordagain": "Konfirme contrasenya",
        "createacct-yourpasswordagain-ph": "Eskrive la kontrasenya de muevo",
-       "remembermypassword": "Acódrate de mi entrada de kullaneador en este navigador (por un maksimum de {{PLURAL:$1|día|días}})",
        "yourdomainname": "Tu dominyo:",
        "password-change-forbidden": "No se puede kambiar contrasenyas en este viki.",
        "login": "Entrar",
        "post-expand-template-inclusion-category": "Hojas con sovrecarga de şablones",
        "post-expand-template-argument-warning": "'''Aviso:''' Esta oja tiene kuanto menos un kampo enel xablon muy lungo.\nEste o estos kampos no van ser amostrados",
        "post-expand-template-argument-category": "Ojas ke tienen xablones kon parametros no uzados",
-       "cantcreateaccounttitle": "No se puede krear el kuento",
        "viewpagelogs": "Ver los registros de esta hoja",
        "currentrev": "Enderechamiento d'al cavo",
        "currentrev-asof": "Enderechamiento dalcavo de $2 a las $3 la ora",
        "linksearch-line": "Atamiento para $1 en la hoja $2",
        "listusers-submit": "Amostrar",
        "listusers-noresult": "No se topo usuario",
-       "activeusers-hidebots": "Eskonder bots",
        "activeusers-noresult": "No se toparon usuario.",
        "listgrouprights": "Derechos del grupo de usuario",
        "listgrouprights-group": "Grupo",
index a3edcfc..78ad437 100644 (file)
        "botpasswords-label-delete": "Läschen",
        "botpasswords-label-resetpassword": "D'Passwuert zrécksetzen",
        "botpasswords-label-grants": "Applikabel Rechter:",
-       "botpasswords-help-grants": "All Berechtegung gëtt Zougang op déi Benotzerrechter déi e Benotzerkont schonn huet. Kuckt d'[[Special:ListGrants|Tabell vun de Berechtigunge]] fir méi Informatiounen.",
+       "botpasswords-help-grants": "Berechtegunge ginn Zougang op déi Benotzerrechter déi Äre Benotzerkont schonn huet. D'Aktivéiere vun enger Berechtegung hei gëtt Iech keen Zougang op Rechter déi Äre Benotzerkont net scho souwisou huet. Kuckt d'[[Special:ListGrants|Tabell vun de Berechtigunge]] fir méi Informatiounen.",
        "botpasswords-label-grants-column": "Accordéiert",
        "botpasswords-bad-appid": "Den Numm vum Bot \"$1\" ass net valabel.",
        "botpasswords-insert-failed": "De Botnumm \"$1\" konnt net dobäigesat ginn. Gouf e schonn derbäigesat?",
        "passwordreset-emailelement": "Benotzernumm: \n$1\n\nTemporärt Passwuert: \n$2",
        "passwordreset-emailsentemail": "Wann dës E-Mailadress mat Ärem Benotzerkont assoziéiert ass, da gëtt Eng E-Mail fir d'Passwuert zréckzesetze geschéckt.",
        "passwordreset-emailsentusername": "Wann eng E-Mailadress mat dësem Benotzernumm associéiert ass, da gëtt Eng E-Mail fir d'Passwuert zeréckzesetze geschéckt.",
-       "passwordreset-invalideamil": "Net-valabel E-Mail-Adress",
+       "passwordreset-invalidemail": "Net-valabel E-Mail-Adress",
        "passwordreset-nodata": "Et gouf weder e Benotzernumm nach e Passwuert uginn",
        "changeemail": "E-Mail-Adress änneren oder ewechhuelen",
        "changeemail-header": "Fëllt dëse Formulaire aus fir Är E-Mailadress z'änneren.  Wann Dir d'Verbindung tëscht Ärer E-Mailadress an Ärem Benotzerkont ewechhuele wëllt, da loosst d'Feld e-Mailadress eidel wann Dir de Formulaire späichert.",
        "changeemail-no-info": "Dir musst ageloggt sinn, fir direkt op dës Säit ze kommen.",
        "changeemail-oldemail": "Aktuell Mailadress:",
        "changeemail-newemail": "Nei Mailadress:",
+       "changeemail-newemail-help": "Dëst Feld soll eidel gelooss gi wann Dir Är E-Mailadress ewechhuele wëllt. Dir kënnt d'Passwuert net zrécksetze wann Dir et vergiess hutt an Dir kritt och keng E-Maile vun dëser Wiki esoubal d'E-Mailadress ewechgeholl gouf.",
        "changeemail-none": "(keng)",
        "changeemail-password": "Äert {{SITENAME}}-Passwuert:",
        "changeemail-submit": "Mailadress änneren",
        "permissionserrors": "Net genuch Rechter",
        "permissionserrorstext": "Dir hutt net genuch Rechter fir déi Aktioun auszeféieren. {{PLURAL:$1|Grond|Grënn}}:",
        "permissionserrorstext-withaction": "Dir sidd, aus {{PLURAL:$1|dësem Grond|dëse Grënn}}, net berechtegt $2 :",
+       "contentmodelediterror": "Dir kënnt dës Versioun net ännere well hiren Inhaltsmodell <code>$1</code> ass dee verschidde vum aktuellen Inhaltsmodell vun der Säit <code>$2</code> ass.",
        "recreate-moveddeleted-warn": "'''Opgepasst: Dir sidd am Gaang eng Säit unzeleeën déi schonn eng Kéier geläscht gouf.'''\n\nFrot Iech ob et wierklech sënnvoll ass dës Säit nees nei ze schafen.\nFir Iech z'informéieren fannt Dir hei d'Logbuch vum Läsche mam Grond:",
        "moveddeleted-notice": "Dës Säit gouf geläscht.\nHei ass den Extrait aus dem Logbuch vum Réckelen a Läsche fir déi Säit.",
        "moveddeleted-notice-recent": "Leider gouf dëse Säit rezent (bannent de leschte 24 Stonnen) geläscht. D'Logbuch vum Läschen a Réckele vun dëser Säit fannt Dir fir Ar Informatioun hei drënner.",
        "history-feed-description": "Versiounshistorique fir dës Säit op der Wiki",
        "history-feed-item-nocomment": "$1 ëm $2",
        "history-feed-empty": "Déi ugefrote Säit gëtt et net.\nVläicht gouf se geläscht oder geréckelt.\n[[Special:Search|Sicht]] op {{SITENAME}} no relevanten neie Säiten.",
+       "history-edit-tags": "Markéierungen (tags) vun den erausgesichte Versiounen änneren",
        "rev-deleted-comment": "(Resumé vun der Ännerung ewechgeholl)",
        "rev-deleted-user": "(Benotzernumm ewechgeholl)",
        "rev-deleted-event": "(Detailer aus dem Logbuch erausgeholl)",
        "searchprofile-advanced-tooltip": "Sich an den Nummraim déi an de perséinlichen Astellungen festgeluecht sinn",
        "search-result-size": "$1 ({{PLURAL:$2|1 Wuert|$2 Wierder}})",
        "search-result-category-size": "{{PLURAL:$1|1 Säit|$1 Säiten}} ({{PLURAL:$2|1 Ënnerkategorie|$2 Ënnerkategorien}}, {{PLURAL:$3|1 Fichier|$3 Fichieren}})",
-       "search-redirect": "(Viruleedung $1)",
+       "search-redirect": "(Viruleedung vu(n) $1)",
        "search-section": "(Abschnitt $1)",
        "search-category": "(Kategorie $1)",
        "search-file-match": "(Inhalt vum Fichier passt)",
        "upload-options": "Optioune vum Eroplueden",
        "watchthisupload": "Dëse Fichier iwwerwaachen",
        "filewasdeleted": "E Fichier mat dësem Numm gouf schonn eemol eropgelueden an duerno nees geläscht. Kuckt w.e.g op $1 no, ier Dir dee Fichier nach eng Kéier eropluet.",
+       "filename-thumb-name": "Dësen Numm gesäit aus wéi den Numm vun engem Miniaturbild. Luet w.e.g. keng Miniatur-Biller zréck op déi selwecht Wiki. Sollt et sech ëm een anert Bild handelen da sicht w.e.g. e Fichiersnumm dee méi verständlech ass an den net sou ufänkt wéi e Miniaturbild.",
        "filename-bad-prefix": "Den Numm vum Fichier fänkt mat '''„$1“''' un. Dësen Numm krut en automatesch vun der Kamera a seet näischt iwwer dat aus, wat drop ass. Gitt dem Fichier w.e.g. en Numm, deen den Inhalt besser beschreift, an deen net verwiesselt ka ginn.",
        "upload-proto-error": "Falsche Protokoll",
        "upload-proto-error-text": "D'URL muss mat <code>http://</code> oder <code>ftp://</code> ufänken.",
        "upload-dialog-disabled": "D'Eropluede vu Fichieren mat dësem Dialog ass op dëser Wiki desaktivéiert.",
        "upload-dialog-title": "Fichier eroplueden",
        "upload-dialog-button-cancel": "Ofbriechen",
+       "upload-dialog-button-back": "Zréck",
        "upload-dialog-button-done": "Fäerdeg",
        "upload-dialog-button-save": "Späicheren",
        "upload-dialog-button-upload": "Eroplueden",
        "upload-form-label-own-work": "Dëst ass mäin eegent Wierk",
        "upload-form-label-infoform-categories": "Kategorien",
        "upload-form-label-infoform-date": "Datum",
+       "upload-form-label-own-work-message-generic-local": "Ech confirméieren datt ech dëse Fichier ënner dëse Bedingungen a Lizenz-Richtlinnen op {{SITENAME}} eroplueden.",
+       "upload-form-label-not-own-work-message-generic-local": "Wann Dir dëse Fichier net ënner de Richtlinne vu(n) {{SITENAME}} eropluede kënnt da maacht w.e.g. dësen Dialog zou a probéiert eng aner Method.",
        "upload-form-label-not-own-work-local-generic-local": "Dir kënnt och [[Special:Upload|d'Standardsäit vum Eroplueden]] ausprobéieren.",
        "backend-fail-stream": "De Fichier $1 konnt net iwwerdroe ginn.",
        "backend-fail-backup": "De Fichier $1 konnt net geséchert ginn.",
        "apisandbox-submit": "Ufro maachen",
        "apisandbox-reset": "Eidel maachen",
        "apisandbox-retry": "Nach eng Kéier probéieren",
+       "apisandbox-loading": "Informatioune fir den API-Modul \"$1\" gi gelueden ...",
        "apisandbox-no-parameters": "Dësen API-Modul huet keng Parameteren.",
        "apisandbox-helpurls": "Hëllef-Linken",
        "apisandbox-examples": "Beispiller",
        "apisandbox-dynamic-error-exists": "Et gëtt schonn e Parameter mam Numm \"$1\".",
        "apisandbox-deprecated-parameters": "Vereelst Parameter",
        "apisandbox-submit-invalid-fields-title": "E puer Felder sinn net valabel.",
+       "apisandbox-submit-invalid-fields-message": "Verbessert w.e.g. déi markéiert Felder a probéiert nach eng Kéier.",
        "apisandbox-results": "Resultater",
        "apisandbox-sending-request": "Schécke vun der API-Ufro...",
        "apisandbox-loading-results": "Ofruffe vun den API-Resultater...",
        "apisandbox-request-time": "Dauer vun der Ufro: {{PLURAL:$1|$1 ms}}",
        "apisandbox-alert-page": "Felder op dëser Säit sinn net valabel.",
        "apisandbox-alert-field": "De wäert vun dësem Feld ass net valabel.",
+       "apisandbox-continue": "Virufueren",
+       "apisandbox-continue-clear": "Eidel maachen",
        "booksources": "Bicherreferenzen",
        "booksources-search-legend": "No Bicherreferenze sichen",
        "booksources-search": "Sichen",
        "booksources-text": "Hei ass eng Lëscht mat Linken op Internetsäiten, déi nei a gebraucht Bicher verkafen. Do kann et sinn datt Dir méi Informatiounen iwwer déi Bicher fannt déi Dir sicht.",
        "booksources-invalid-isbn": "D'ISBN-Nummer déi Dir uginn hutt schéngt net gëlteg ze sinn. Kuckt w.e.g. no ob beim Kopéiere kee Feeler geschitt ass.",
+       "magiclink-tracking-rfc": "Säiten, déi magesch RFC-Linke benotzen.",
+       "magiclink-tracking-rfc-desc": "Dës Säit benotzt magesch RFC-Linken. Kuckt [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] fir d'Migratioun.",
+       "magiclink-tracking-pmid": "Säiten, déi magesch PMID-Linke benotzen.",
+       "magiclink-tracking-pmid-desc": "Dës Säit benotzt magesch PMID-Linken. Kuckt [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] fir d'Migratioun.",
+       "magiclink-tracking-isbn": "Säiten, déi magesch ISBN-Linke benotzen.",
+       "magiclink-tracking-isbn-desc": "Dës Säit benotzt magesch ISBN-Linken. Kuckt [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] fir d'Migratioun.",
        "specialloguserlabel": "Aktive Benotzer:",
        "speciallogtitlelabel": "Zil (Titel oder {{ns:user}}:Benotzernumm fir e Benotzer):",
        "log": "Logbicher",
        "activeusers-intro": "Dëst ass eng Lëscht vun de Benotzer déi op iergend eng Manéier an de leschten $1 {{PLURAL:$1|Dag|Deeg}} aktiv waren.",
        "activeusers-count": "$1 {{PLURAL:$1|Aktioun|Aktiounen}} {{PLURAL:$3|gëschter|an de leschten $3 Deeg}}",
        "activeusers-from": "Benotzer weisen, ugefaange bei:",
-       "activeusers-hidebots": "Botte verstoppen",
-       "activeusers-hidesysops": "Administrateure verstoppen",
+       "activeusers-groups": "Benotzer weisen déi zu de Gruppe gehéieren:",
        "activeusers-noresult": "Keng Benotzer fonnt.",
        "activeusers-submit": "Aktiv Benotzer weisen",
        "listgrouprights": "Rechter vun de Benotzergruppen",
        "addedwatchtext-short": "D'Säit \"$1\" gouf op Är Iwwerwaachungslëscht derbäigesat.",
        "removewatch": "Vun der Iwwerwaachungslëscht erofhuelen",
        "removedwatchtext": "\"[[:$1]]\" a seng Diskussiounssäit goufe vun Ärer [[Special:Watchlist|Iwwerwaachungslëscht]] erofgeholl.",
+       "removedwatchtext-talk": "\"[[:$1]]\" a seng associéiert Säit goufe vun Ärer [[Special:Watchlist|Iwwerwaachungslëscht]] erofgeholl.",
        "removedwatchtext-short": "D'Säit \"$1\" gouf vun Ärer Iwwerwaachungslëscht erofgeholl.",
        "watch": "Iwwerwaachen",
        "watchthispage": "Dës Säit iwwerwaachen",
        "changecontentmodel-cannot-convert": "Den Inhalt vu(n) [[:$1]] kann net op den Typ $2 ëmgewandelt ginn.",
        "changecontentmodel-nodirectediting": "Den Inhaltsmodell $1 ënnerstëtzt keng direkt Ännerungen",
        "changecontentmodel-emptymodels-title": "Keng Modeller fir Inhalter disponibel",
+       "changecontentmodel-emptymodels-text": "Den Inhalt vu(n) [[:$1]] kann net op een aneren Typ ëmgewandelt ginn.",
+       "log-description-contentmodel": "Evenementer a Relatioun mat den Inhaltsmodeller vun enger Säit",
        "logentry-contentmodel-change-revertlink": "zrécksetzen",
        "logentry-contentmodel-change-revert": "zrécksetzen",
        "protectlogpage": "Protektiounslogbuch",
        "modifiedarticleprotection": "huet d'Protektioun vun \"[[$1]]\" geännert",
        "unprotectedarticle": "huet d'Spär vu(n) \"[[$1]]\" opgehuewen",
        "movedarticleprotection": "huet de Säiteschutz vun \"[[$2]]\" op \"[[$1]]\" geännert",
+       "protectedarticle-comment": "huet \"[[$1]]\" {{GENDER:$2|gespaart}}",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Huet}} den Niveau vun der Spär vu(n) \"[[$1]]\" geännert",
+       "unprotectedarticle-comment": "{{GENDER:$2|huet}} d'Spär vu(n) \"[[$1]]\" ewechgeholl",
        "protect-title": "Ännerung vun der Protektioun vu(n) „$1“",
        "protect-title-notallowed": "Den Niveau vun der Protektioun vu(n) \"$1\" weisen",
        "prot_1movedto2": "[[$1]] gouf op [[$2]] geréckelt",
        "undeletehistorynoadmin": "Dës Säit gouf geläscht. De Grond fir d'Läsche gesitt der ënnen, zesumme mat der Iwwersiicht vun den eenzele Versioune vun der Säit an hiren Auteuren. Déi verschidden Textversioune kënnen awer just vun Administrateure gekuckt a restauréiert ginn.",
        "undelete-revision": "Geläscht Versioun vu(n) $1 (Versioun vum $4 um $5 Auer) vum $3:",
        "undeleterevision-missing": "Ongëlteg oder Versioun déi feelt. Entweder ass de Link falsch oder d'Versioun gouf aus dem Archiv restauréiert oder geläscht.",
+       "undeleterevision-duplicate-revid": "{{PLURAL:$1|Eng Versioun konnt|$1 Versioune konnten}} net restauréiert ginn, well hir <code>rev_id</code> scho benotzt {{PLURAL:$1|gëtt|ginn}}.",
        "undelete-nodiff": "Et si keng méi al Versiounen do.",
        "undeletebtn": "Restauréieren",
        "undeletelink": "weisen/restauréieren",
        "block-log-flags-hiddenname": "Benotzernumm verstoppt",
        "range_block_disabled": "Dem Administrateur seng Fähegkeet fir ganz Adressberäicher ze spären ass ausser Kraaft.",
        "ipb_expiry_invalid": "D'Dauer déi Dir uginn hutt ass ongülteg.",
+       "ipb_expiry_old": "Oflafzäit ass an der Vergaangenheet.",
        "ipb_expiry_temp": "Verstoppt Späre vu Benotzernimm solle permanent sinn.",
        "ipb_hide_invalid": "Dëse Benotzerkont kann net geläscht ginn; de Benotzer huet méi wéi {{PLURAL:$1|eng Ännerung|$1 Ännerunge}} gemaach.",
        "ipb_already_blocked": "\"$1\" ass scho gespaart.",
        "movelogpagetext": "Dëst ass eng Lëscht vun alle geréckelte Säiten.",
        "movesubpage": "{{PLURAL:$1|Ënnersäit|Ënnersäiten}}",
        "movesubpagetext": "Dës Säit huet $1 {{PLURAL:$1|Ënnersäit|Ënnersäiten}} déi hei ënnendrënner stinn.",
+       "movesubpagetalktext": "D'Diskussiounssäit déi dozou gehéiert huet $1 {{PLURAL:$1|Ënnersäit|Ënnersäiten}} déi hei ënnendrënner stinn.",
        "movenosubpage": "Dës Säit huet keng Ënnersäiten.",
        "movereason": "Grond:",
        "revertmove": "zréck réckelen",
        "pageinfo-robot-index": "Erlaabt",
        "pageinfo-robot-noindex": "Net erlaabt",
        "pageinfo-watchers": "Zuel vun de Benotzer déi d'Säit iwwerwaachen",
+       "pageinfo-visiting-watchers": "Zuel vun de Benotzer déi iwwerwaachen déi déi rezent Ännerunge besicht hunn",
        "pageinfo-few-watchers": "Manner wéi $1 {{PLURAL:$1|Benotzer deen iwwerwaacht|Benotzer déi iwwerwaachen}}",
        "pageinfo-redirects-name": "Zuel vun de Viruleedungen op dës Säit",
        "pageinfo-subpages-name": "Ënnersäite vun dëser Säit",
        "pageinfo-category-pages": "Zuel vun de Säiten",
        "pageinfo-category-subcats": "Zuel vun den Ënnerkategorien",
        "pageinfo-category-files": "Zuel vun de Fichieren",
+       "pageinfo-user-id": "Benotzernummer",
        "markaspatrolleddiff": "Als nogekuckt markéieren",
        "markaspatrolledtext": "Dës Säit als nogekuckt markéieren",
        "markaspatrolledtext-file": "Dës Versioun vum Fichier als nogekuckt markéieren",
        "patrol-log-page": "Logbuch vun den iwwerkuckte Versiounen",
        "patrol-log-header": "Dëst ass d'Logbuch vun den nogekuckte Versiounen.",
        "log-show-hide-patrol": "Kontroll-Logbuch $1",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Versioun $3 vu(n) $2 als kontrolléiert markéieren?",
        "deletedrevision": "Al, geläscht Versioun vu(n) $1",
        "filedeleteerror-short": "Feeler beim Läsche vum Fichier: $1",
        "filedeleteerror-long": "Bäim Läsche vum Fichier si Feeler festgestallt ginn:\n\n$1",
        "invalidateemail": "Annulléier d'E-Mailconfirmation",
        "notificationemail_subject_changed": "D'E-Mail-Adress déi op {{SITENAME}} enregistréiert war gouf geännert",
        "notificationemail_subject_removed": "D'E-Mail-Adress déi op {{SITENAME}} enregistréiert war gouf ewechgeholl",
+       "notificationemail_body_changed": "Een, wahrscheinlech Dir, vun der IP-Adress $1, huet d'E-Mailadress vum Benotzerkont \"$2\" opm\"$3\" op {{SITENAME}} geännert.",
        "scarytranscludedisabled": "[Interwiki-Abannung ass ausgeschalt]",
        "scarytranscludefailed": "[D'Siche no der Schabloun fir $1 huet net funktionéiert]",
        "scarytranscludefailed-httpstatus": "[D'Opruffe vun der Schabloun $1: HTTP $2 huet net funktionéiert]",
        "tags-delete-explanation-initial": "Dir sidd am Gaang d'Markéierung (tag) \"$1\" aus der Datebank ze läschen.",
        "tags-delete-explanation-warning": "Dës Aktioun ass <strong>irreversibel</strong> a <strong>kann net réckgängeg gemaach ginn</strong>, net emol vun den Administrateure vun der Datebank. Sidd Iech sécher datt et dës Markéierung ass déi Dir läsche wëllt.",
        "tags-delete-reason": "Grond:",
+       "tags-delete-submit": "Dës Markéierung definitiv läschen",
        "tags-delete-not-found": "D'Markéierung (tag) ''$1'' gëtt et net.",
        "tags-activate-title": "Markéierung (tag) aktivéieren",
        "tags-activate-question": "Dir sidd am Gaang d'Markéierung \"$1\" z'aktivéieren.",
        "htmlform-cloner-create": "Méi derbäisetzen",
        "htmlform-cloner-delete": "Ewechhuelen",
        "htmlform-cloner-required": "Mindestens ee Wäert ass obligatoresch.",
+       "htmlform-date-placeholder": "JJJJ-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "JJJJ-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "De Wäert deen Dir aginn hutt gouf net als Datum erkannt. Probéiert de Format JJJJ-MM-DD ze benotzen.",
+       "htmlform-time-invalid": "De Wäert deen Dir aginn hutt gouf net als Zäit erkannt. Probéiert de Format HH:MM:SS ze benotzen.",
+       "htmlform-datetime-invalid": "De Wäert deen Dir aginn hutt gouf net als Datum an Zäit erkannt. Probéiert de Format JJJJ-MM-DD HH:MM:SS ze benotzen.",
+       "htmlform-date-toolow": "De Wäert deen Dir aginn hutt ass virun deem éischten erlaabten Datum vum $1.",
+       "htmlform-date-toohigh": "De wäert deen Dir aginn hutt ass nom leschten erlaabten Datum vum $1.",
+       "htmlform-time-toolow": "De Wäert deen Dir aginn hutt ass virun der éischter erlaabter Zäit vu(n) $1.",
+       "htmlform-time-toohigh": "De Wäert deen Dir aginn hutt ass no der leschter erlaabter Zäit vu(n) $1.",
+       "htmlform-datetime-toolow": "De Wäert deen Dir uginn hutt ass virum éischten erlaabten Datum an der Zäit vu(n) $1.",
+       "htmlform-datetime-toohigh": "De Wäert deen Dir uginn hutt ass nom leschten erlaabten Datum an der Zäit vu(n) $1.",
        "htmlform-title-badnamespace": "[[:$1]] ass net am Nummraum \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" ass kee Säitentitel deen ugeluecht ka ginn",
        "htmlform-title-not-exists": "$1 gëtt et net.",
        "logentry-block-unblock": "$1 {{GENDER:$2|huet}} d'Spär vum {{GENDER:$4|$3}} opgehuewen",
        "logentry-import-upload": "$1 {{GENDER:$2|huet}} $3 duerch Eropluede vun engem Fichier importéiert",
        "logentry-import-interwiki": "$1 huet $3 vun enger anerer Wiki {{GENDER:$2|importéiert}}",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|huet}} $3 vu(n) $5 importéiert ({{PLURAL:$4|Eng Versioun|$4 Versiounen}})",
        "logentry-move-move": "$1 huet d'Säit $3 op $4 {{GENDER:$2|geréckelt}}",
        "logentry-move-move-noredirect": "$1 huet d'Säit $3 op $4 {{GENDER:$2|geréckelt}} ouni eng Viruleedung unzeleeën",
        "logentry-move-move_redir": "$1 huet d'Säit $3 op $4 {{GENDER:$2|geréckelt}} an derbäi gouf eng Viruleedung iwwerschriwwen",
        "feedback-close": "Fäerdeg",
        "feedback-external-bug-report-button": "Eng technesch Aufgab notifizéieren",
        "feedback-dialog-title": "Feedback schécken",
-       "feedback-error-title": "Feeler",
        "feedback-error1": "Feeler: Resultat vum API gouf net erkannt",
        "feedback-error2": "Feeler: D'Ännerung gouf net gespäichert",
        "feedback-error3": "Feeler: Keng Äntwert vum API",
        "feedback-thanks": "Merci! Äre Feedback gouf op der Säit \"[$2 $1]\" gespäichert.",
        "feedback-thanks-title": "Merci!",
        "feedback-useragent": "User Agent:",
-       "searchsuggest-search": "Sichen",
+       "searchsuggest-search": "Op {{SITENAME}} 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.",
        "mediastatistics-summary": "Statistike vun den Type vun den eropgeluedene Fichieren. Dobäi gëtt nëmmen déi lescht Versioun vun engem Fichier gezielt, al oder geläscht Versioune vu Fichiere sinn ausgeschloss.",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 Byte|$1 Byten}} ($2; $3%)",
        "mediastatistics-bytespertype": "Gesamtgréisst vun de Fichiere vun dësem Abschnitt:  {{PLURAL:$1|$1 Byte|$1 Bytes}} ($2; $3%).",
+       "mediastatistics-allbytes": "Gesamtgréisst vun alle Fichieren: {{PLURAL:$1|$1 Byte|$1 Bytes}} ($2; $3%).",
        "mediastatistics-table-mimetype": "MIME-Typ",
        "mediastatistics-table-extensions": "Méiglech Erweiderungen",
        "mediastatistics-table-count": "Zuel vun de Fichieren",
        "log-action-filter-import": "Importtyp:",
        "log-action-filter-move": "Réckeltyp:",
        "log-action-filter-protect": "Typ vu Spär",
+       "log-action-filter-rights": "Typ vun Ännerung vu Rechter:",
        "log-action-filter-upload": "Eropluedtyp:",
        "log-action-filter-all": "All",
        "log-action-filter-block-block": "Spären",
        "log-action-filter-upload-upload": "Neien Upload",
        "log-action-filter-upload-overwrite": "Nees eroplueden",
        "authmanager-create-disabled": "D'Opmaache vu Benotzerkonten ass gespaart.",
-       "authmanager-create-from-login": "Fir Äre Benotzerkont unzeleeën fëllt w.e.g. d'Felder hei drënner aus.",
+       "authmanager-create-from-login": "Fir Äre Benotzerkont unzeleeën fëllt w.e.g. d'Felder aus.",
        "authmanager-authplugin-setpass-failed-title": "Änner vum Passwuert huet net funktionéiert",
        "authmanager-authplugin-setpass-bad-domain": "Net valabelen Domain.",
        "authmanager-autocreate-noperm": "Automatescht Uleeë vu Benotzerkonten ass net erlaabt.",
        "authprovider-confirmlink-failed": "Verbanne vum Benotzerkont huet net richteg geklappt: $1",
        "authprovider-resetpass-skip-label": "Iwwersprangen",
        "authprovider-resetpass-skip-help": "D'Zrécksetze vum Passwuert iwwersprangen",
+       "authform-nosession-signup": "De Benotzerkont gouf ugeluecht, awer Äre Browser kann net \"verhalen\" datt dir ageloggt sidd.\n\n$1",
        "authform-notoken": "Toke feelt",
        "authform-wrongtoken": "Falschen Token",
        "specialpage-securitylevel-not-allowed-title": "Net erlaabt",
        "specialpage-securitylevel-not-allowed": "Leider däerft Dir dës Säit net benotze well Är Identitéit net konnt iwwerpréift ginn.",
-       "cannotauth-not-allowed-title": "Erlaabnes refuséiert",
+       "cannotauth-not-allowed-title": "Autorisatioun refuséiert",
        "cannotauth-not-allowed": "Dir däerft dës Säit net benotzen",
        "changecredentials-submit": "Idendifikatiounsinformatiounen änneren",
        "changecredentials-success": "Är Idendifikatiounsinformatioune goufe geännert.",
        "removecredentials-submit": "Idendifikatiounsinformatiounen ewechhuelen",
+       "removecredentials-success": "Är Idendifikatiounsinformatioune goufen ewechgeholl.",
        "credentialsform-account": "Numm vum Kont:",
        "cannotlink-no-provider-title": "Et gëtt keng Benotzerkonte fir ze verlinken",
+       "cannotlink-no-provider": "Et gëtt keng Benotzerkonte fir ze verlinken.",
        "linkaccounts": "Benotzerkonte verbannen",
+       "linkaccounts-success-text": "De Benotzerkont gouf verlinkt.",
        "linkaccounts-submit": "Benotzerkonte verbannen",
        "userjsispublic": "DEnkt drun: Op JavaScript-Ënnersäite solle keng vertraulech Informatioune stoe well se vun anere Benotzer kënne gesi ginn.",
        "restrictionsfield-badip": "Net valabel IP-Adress oder Beräich: $1",
-       "restrictionsfield-label": "Zougeloossen IP-Beräicher:"
+       "restrictionsfield-label": "Zougeloossen IP-Beräicher:",
+       "edit-error-short": "Feeler: $1",
+       "edit-error-long": "Feeler:\n\n$1"
 }
index f1d9a18..a497488 100644 (file)
        "yourname": "Уртахдин тӀвар",
        "yourpassword": "Парол",
        "yourpasswordagain": "Парол кхьин хъувун:",
-       "remembermypassword": "И браузерда зи логин рикӀел хуьхь (лап гзаф $1 {{PLURAL:$1|1=югъ|йикъар}})",
        "yourdomainname": "Куь домен",
        "login": "Гьахьун",
        "nav-login-createaccount": "Гьахьун/аккаунт туькӀуьрун",
        "youremail": "Электрон почта:",
        "username": "Уртахдин тӀвар",
        "yourrealname": "Xалис тIвар:",
-       "yourlanguage": "ЧIалар",
+       "yourlanguage": "ЧӀалар",
        "yournick": "ЦӀийи къул:",
        "yourgender": "Жинс:",
        "gender-male": "итимдин",
        "file-anchor-link": "Файл",
        "filehist": "Файлдин тарих",
        "filehist-help": "Файлдин виликан жуьре килигун патал, гьа а жуьредин тарих/вахт илиса,",
-       "filehist-deleteall": "виÑ\80и ÐºÑ\8aакÑ\8aудун",
-       "filehist-deleteone": "кÑ\8aакÑ\8aудун",
+       "filehist-deleteall": "виÑ\80и Ð°Ð»удун",
+       "filehist-deleteone": "алудун",
        "filehist-revert": "элкъуьрна хкун",
        "filehist-current": "алай",
        "filehist-datetime": "Тарих/вахт",
        "filedelete": "$1 алудун",
        "filedelete-legend": "Файл алудун",
        "filedelete-comment": "Кар",
-       "filedelete-submit": "Ð\9aÑ\8aакÑ\8aудун",
+       "filedelete-submit": "Ð\90лудун",
        "filedelete-reason-otherlist": "Муькуь себеб",
        "mimesearch": "MIME ахтармишун",
        "download": "АцIун",
        "unwatching": "Амма клигнай",
        "created": "туькIуьрнава",
        "changed": "дегишнава",
-       "deletepage": "Ð\9aÑ\8aакÑ\8aудун хъувун",
+       "deletepage": "Ð\90лудун хъувун",
        "confirm": "Тестикьун",
        "delete-confirm": "«$1» алудун",
-       "delete-legend": "Ð\9aÑ\8aакÑ\8aудун",
+       "delete-legend": "Ð\90лудун",
        "confirmdeletetext": "Квез чlуриз кlанзани чарар гьадан вири тарихар галаз.                                                                                                                         Буюр, сидикъара,куьне чlурзатlа, куьн агъавурда автlа вуч ийизатlа ва куьне ийизатlа жуьреда [[{{MediaWiki:Policy-url}}| политика]].",
        "actioncomplete": "Кар авунва",
        "actionfailed": "Кар йиз алакьнавач",
index dd1e9d4..3a8e61b 100644 (file)
        "yourname": "Nom de usor:",
        "yourpassword": "Sinia de entra:",
        "yourpasswordagain": "Retape la sinia:",
-       "remembermypassword": "Memora me sinia de entra a esta computador (for a maximum of $1 {{PLURAL:$1|day|days}})",
        "yourdomainname": "Tu domina:",
        "login": "Identifia",
        "nav-login-createaccount": "Sinia per entra",
index af7f9be..7afd6f8 100644 (file)
        "yourname": "Ery'obwa memba",
        "yourpassword": "Ekigambo ekikuumi",
        "yourpasswordagain": "Ddamu ekigambo ekikuumi",
-       "remembermypassword": "Tereka ekigambo kyange ekikuumi ku kompyuta eno (okumala {{PLURAL:$1|olunaku|ennaku ezitasukka mu}} $1)",
        "yourdomainname": "Linnya lya twale lya kayungirizi lyo:",
        "externaldberror": "Waliwo kiremya mu ggwanika lya data ekozesebwa okukakasa bamemba oba tokkirizibwa okukyusa ku akawunti yo ey'awalala.",
        "login": "Yingira",
index 779c36c..a82bd16 100644 (file)
@@ -45,7 +45,7 @@
        "tog-enotifminoredits": "Versjik  mich 'ne e-mail bie klein bewirkinge op pagina's en bestenj op mien volglies",
        "tog-enotifrevealaddr": "Mien e-mailadres tuine in e-mailberichte",
        "tog-shownumberswatching": "'t Aantal gebroekers tuine die dees pagina volg",
-       "tog-oldsig": "Bestaonde ongerteikening:",
+       "tog-oldsig": "Dien bestaonde ongerteikening:",
        "tog-fancysig": "Es wikiteks behanjele (zonder autematische verwiezing)",
        "tog-uselivepreview": "\"live veurbesjouwing\" gebroeke",
        "tog-forceeditsummary": "'n Melding gaeve bie 'n laeg samevatting",
        "category-file-count-limited": "Dees categorie bevat {{PLURAL:$1|'t volgende bestandj|de volgende $1 bestenj}}.",
        "listingcontinuesabbrev": "wiejer",
        "index-category": "Geïndexeerde paazjes",
-       "noindex-category": "Óngeïndexeerde paazjes",
+       "noindex-category": "Neet-geïndexeerde pazjena's",
        "broken-file-category": "Pazjena's mit ónjuuste bestandjsverwiezinge",
        "about": "Informatie",
        "article": "Pagina",
        "newwindow": "(in nuuj venster)",
        "cancel": "Aafbraeke",
        "moredotdotdot": "Miè...",
-       "morenotlisted": "Deze lies is neet compleet.",
+       "morenotlisted": "Deze lies is mäögelik neet compleet.",
        "mypage": "Mien gebroekerspagina",
        "mytalk": "Euverlèk",
        "anontalk": "Euverlèk veur dit IP adres",
        "yourpassword": "Die wachwaord",
        "userlogin-yourpassword": "Wachwaord",
        "yourpasswordagain": "Wachwaord opnuuj intype",
-       "remembermypassword": "Mien wachwaord onthouwe veur later sessies (hoegstens $1 {{PLURAL:$1|daag|daag}})",
        "yourdomainname": "Die domein",
        "externaldberror": "d'r Is 'n fout opgetraoje biej 't aanmelje biej de database of doe höbs gén toesjtömming diene externe gebroeker biej te wèrke.",
        "login": "Aanmèlde",
        "activeusers-intro": "Dit is 'n lies mit gebroekers die aktief zeen gewaes in de aafgeloupe {{PLURAL:$1|daag|$1 daag}}.",
        "activeusers-count": "$1 {{PLURAL:$1|bewèrking|bewèrkinger}} inne {{PLURAL:$3|lèsten daag|lès $3 daag}}",
        "activeusers-from": "Tuin gebroekers vanaaf:",
-       "activeusers-hidebots": "Verberg bots",
-       "activeusers-hidesysops": "Verberg admins",
        "activeusers-noresult": "Gein gebroekers gevónje.",
        "listgrouprights": "Rechte van gebroekersgróppe",
        "listgrouprights-summary": "Op dees pazjena sjtaon de gebroekersgróppe in deze wiki besjreve, mit zien biebehurende rechte.\nInfermasie daoreuver èn de individueel rechter vinjs te [[{{MediaWiki:Listgrouprights-helppage}}|hie]].",
        "htmlform-submit": "Slaon óp",
        "htmlform-reset": "Maak verangeringe óngedaon",
        "htmlform-selectorother-other": "Anges",
-       "sqlite-has-fts": "Zeuk versie $1 mit óngersteuning veur \"full-text\"",
-       "sqlite-no-fts": "Zeuk versie $1 zónger óngersteuning veur \"fulltext\"",
        "logentry-delete-delete": "$1 {{GENDER:$1|haet}} de pagina $3 gewösj",
        "logentry-delete-restore": "$1 haet de pagina $3 trögkgezat",
        "logentry-delete-event": "$1 haet de zichbaarheid van {{PLURAL:$5|'ne logbookregel|$5 logbookregels}} van $3 gewiezig: $4",
index 8c5b16c..992caf7 100644 (file)
@@ -16,7 +16,7 @@
                ]
        },
        "tog-underline": "Sottolineâ i collegamenti",
-       "tog-hideminor": "asconde e modifiche minori inte ùrtime modifiche",
+       "tog-hideminor": "Ascondi e modiffiche minoî inti urtime modiffiche",
        "tog-hidepatrolled": "Ascondi e modifiche verificæ inte ùrtime modifiche",
        "tog-newpageshidepatrolled": "Ascondi e paggine verificæ da  l'elenco de paggine ciù reçenti",
        "tog-hidecategorization": "Ascondi a categorizzassion de paggine",
        "tog-watchuploads": "Azonzi i noeuvi file che metto in osservaçion",
        "tog-watchrollback": "Azonzi a-i sotta osservassion e paggine dovve ho fæto un rollback",
        "tog-minordefault": "Indica de longo comme menô e modiffiche",
-       "tog-previewontop": "Veddi l'anteprimma de d'äto a-o spaçio pe cangiâ",
-       "tog-previewonfirst": "Veddi l'anteprimma a-o primmo cangiamento",
+       "tog-previewontop": "Mostra l'anteprimma de d'ato a-a casella de modiffica",
+       "tog-previewonfirst": "Mostra l'anteprimma in sciâ primma modiffica",
        "tog-enotifwatchlistpages": "Famme savéi via e-mail quande 'na paggina o in file inti mæ osservæ a ven cangiâ.",
        "tog-enotifusertalkpages": "Màndime un'e-mail se gh'é de modìffiche inta mæ pagina de discuscion.",
        "tog-enotifminoredits": "Mandime una email ascì pe e modifiche menoî de pagine e di file",
        "tog-enotifrevealaddr": "Mostra o mæ addresso inte e-mail de notiffica",
        "tog-shownumberswatching": "Mostra o numero di utenti che tegnan d'oeuggio sta pagina",
-       "tog-oldsig": "Firma attuale:",
+       "tog-oldsig": "Firma attoale:",
        "tog-fancysig": "Tratta a firma comme wikitesto (sensa un collegamento aotomatico)",
        "tog-uselivepreview": "Abillita a fonsion de l'anteprimma in diretta",
        "tog-forceeditsummary": "Domanda conferma se o campo ogetto o l'è veuo",
-       "tog-watchlisthideown": "Ascondi e mæ modiffiche da-a lista che tegno d'oeuggio",
-       "tog-watchlisthidebots": "Ascondi e modiffiche di bot da-a lista che tegno d'oeuggio",
-       "tog-watchlisthideminor": "Ascondi e modiffiche menoî da-a lista che tegno d'oeuggio",
-       "tog-watchlisthideliu": "Ascondi e modiffiche di utenti intræ da-a lista che tegno d'oeuggio",
+       "tog-watchlisthideown": "Ascondi e mæ modiffiche da-a lista sotta-oservaçion",
+       "tog-watchlisthidebots": "Ascondi e modiffiche di bot da-a lista sotta oservaçion",
+       "tog-watchlisthideminor": "Ascondi e modiffiche minoî da-a lista sotta oservaçion",
+       "tog-watchlisthideliu": "Ascondi e modiffiche di utenti intræ da-a lista sotta-oservaçion",
        "tog-watchlistreloadautomatically": "Recarrega aotomaticamente a lista di oservæ quande vegne cangiòu un filtro (ghe veu o JavaScript)",
-       "tog-watchlisthideanons": "Ascondi e modiffiche di utenti anonnimi da-a lista che tegno d'oeuggio",
-       "tog-watchlisthidepatrolled": "Ascondi e modiffiche za controllæ da-a lista che tegno d'oeuggio",
+       "tog-watchlisthideanons": "Ascondi e modiffiche di utenti anonnimi da-a lista sotta-oservaçion",
+       "tog-watchlisthidepatrolled": "Ascondi e modiffiche za controllæ da-a lista sotta-oservaçion",
        "tog-watchlisthidecategorization": "Ascondi a categorizzassion de paggine",
        "tog-ccmeonemails": "Mandime 'na coppia de e-mail che mando a-i atri utenti",
        "tog-diffonly": "No mostrâ o contegnuo da paggina sotta o confronto tra verscioin",
-       "tog-showhiddencats": "Fa vedde e categorîe ascose",
+       "tog-showhiddencats": "Fanni vedde e categorîe ascose",
        "tog-norollbackdiff": "Ometti o confronto tra verscioin doppo ch'ho fæto o ripristino",
        "tog-useeditwarning": "Avertime se lascio 'na paggina de modiffica sens'avei sarvou i cangi",
-       "tog-prefershttps": "Deuvia sempre una connescion segua quande se intra",
+       "tog-prefershttps": "Adœuvia delongo una connescion segua quande se intra",
        "underline-always": "Sempre",
        "underline-never": "Mâi",
        "underline-default": "Impostassioin predefinie do navegatô o da skin",
        "category-file-count-limited": "Questa categoria a contegne {{PLURAL:$1|o file indicao|i $1 file indicæ}} chi de sotta.",
        "listingcontinuesabbrev": "cont.",
        "index-category": "Paggine indiçizzæ",
-       "noindex-category": "Pàgine sénsa indiçe",
+       "noindex-category": "Paggine sença endexo",
        "broken-file-category": "Paggine con di colegamenti a di file che no ghe son",
        "about": "Informaçioìn",
-       "article": "Pagina di contegnùi",
+       "article": "Voxe",
        "newwindow": "(O s'arve inte 'n âtro barcon)",
        "cancel": "Scancella",
        "moredotdotdot": "De ciû...",
-       "morenotlisted": "Questa lista a no l'è completa.",
+       "morenotlisted": "Questa lista a poriæ ese incompleta.",
        "mypage": "Paggina",
        "mytalk": "Discuscioin",
        "anontalk": "Discuscion pe questo addresso IP",
        "talk": "Discuscion",
        "views": "Vìxite",
        "toolbox": "Arneixi",
+       "tool-link-userrights": "Modiffica groppi {{GENDER:$1|utente}}",
+       "tool-link-emailuser": "Manda un'e-mail a questo {{GENDER:$1|utente}}",
        "userpage": "Veddi a paggina utente",
-       "projectpage": "Veddi a paggina de servissio",
+       "projectpage": "Amia a paggina de serviççio",
        "imagepage": "Vizualizza a paggina do file",
        "mediawikipage": "Vizualizza o messaggio",
        "templatepage": "Vizualizza o modello",
        "userlogin-remembermypassword": "Mantegnime collegou",
        "userlogin-signwithsecure": "Adoeuvia una conescion segua",
        "cannotlogin-title": "Imposcibbile intrâ",
+       "cannotlogin-text": "L'accesso o no l'è poscibbile.",
        "cannotloginnow-title": "Aoa no se poeu intrâ",
        "cannotloginnow-text": "Quande s'adoeuvia $1 no se poeu intrâ.",
        "cannotcreateaccount-title": "Imposcibbile creâ di utençe",
+       "cannotcreateaccount-text": "A creaçion diretta de l'utença a no l'è attivâ insce questo wiki.",
        "yourdomainname": "Indirisso do scito:",
        "password-change-forbidden": "No ti peu cangiâ poula segretta in questa wiki.",
        "externaldberror": "Gh'è stæto un aro co-o server de aotenticaçion esterno, oppû no ti g'hæ i aotorizzaçioin pe aggiornâ o to accesso esterno.",
        "eauthentsent": "Un messaggio e-mail de conferma o l'è stæto inviòu a l'addresso indicòu.\nPe abilitâ l'invîo de messaggi e-mail pe quest'utensa, se deve seguî e instrussioin indicæ, pe confermâ che ti t'ê o legittimo propietâio de l'utensa.",
        "throttled-mailpassword": "Un'e-mail de reimpostassione da poula segretta a l'è zà stæta inviâ da meno de {{PLURAL:$1|1 oa|$1 oe}}.\nPe prevegnî di abuxi, a fonsion de reimpostassion da poula segretta a peu vese deuviâ solo che 'na votta ogni {{PLURAL:$1|oa|$1 oe}}.",
        "mailerror": "Errô inte l'invio do messaggio: $1",
-       "acct_creation_throttle_hit": "{{PLURAL:$1|1 registraçion a l'è zà stæta effettuâ|$1 registraçioin son zà stæte effettuæ}} da quarcun co-o to mæximo addresso IP inte l'urtimo giorno: o l'è o mascimo consentio inte questo periodo de tempo.\nPerçò, i utenti ch'adeuvian sto addresso IP pe-o momento no peuan registrase.",
+       "acct_creation_throttle_hit": "{{PLURAL:$1|1 registraçion a l'è zà stæta effettoâ|$1 registraçioin son zà stæte effettoæ}} da quarcun co-o to mæximo adresso IP inti urtimi $2, ch'o l'è o mascimo consentio inte questo periodo de tempo.\nPerçò, i utenti ch'adoeuvian st'adresso IP pe-o momento no poeuan ciu registrâse.",
        "emailauthenticated": "O teu adresso e-mail o l'è stæto aotenticòu o $2 a $3.",
        "emailnotauthenticated": "L'adresso de posta elettronica o no l'è stæto ancon confermòu.\nNo saian inviæ messaggi e-mail pe-e funçioin elencæ chì de sotta.",
        "noemailprefs": "Pe attivâ ste fonçioin ti g'hæ da mette n'adresso e-mail inte preferençe.",
        "botpasswords-label-resetpassword": "Reimposta a poula segretta",
        "botpasswords-label-grants": "Assegnaçioin applicabile:",
        "botpasswords-help-grants": "Ogni assegnaçion a dà accesso a-i driti utente elencæ che un'utença a g'ha zà. Amia a [[Special:ListGrants|tabella d'e assegnaçioin]] pe de ulteioî informaçioin.",
-       "botpasswords-label-restrictions": "Restriçioin d'utilizzo:",
        "botpasswords-label-grants-column": "Assegnaçioin",
        "botpasswords-bad-appid": "O nomme bot \"$1\" o no l'è vallido.",
        "botpasswords-insert-failed": "Imposcibile azonze o nomme bot \"$1\". O l'è za stæto azonto?",
        "passwordreset-emailelement": "Nomme utente: \n$1\n\nPoula segretta temporannia: \n$2",
        "passwordreset-emailsentemail": "Se questo addresso de posta elettronnica o l'è associou a-a teu utença, alloa saiâ inviou un'e-mail pe rempostâ a poula segretta.",
        "passwordreset-emailsentusername": "Se gh'è un adreçço de posta elettronica associou con questo nomme utente, alloa saiâ inviou una email pe rempostâ a password.",
-       "passwordreset-emailsent-capture2": "L'email de rempostaçion da password {{PLURAL:$1|a l'è stæta inviâ|son stæte inviæ}}. {{PLURAL:$1|O nomme|L'elenco di nommi}} utente e password o l'è mostrou chì de sotta.",
-       "passwordreset-emailerror-capture2": "Invio de email {{GENDER:$2|a l'utente}} non ariescio: $1. {{PLURAL:$3|O nomme|L'elenco di nommi}} utente e password o l'è mostrou chì de sotta.",
+       "passwordreset-emailsent-capture2": "{{PLURAL:$1|L'|E }}e-mail de rempostaçion da password {{PLURAL:$1|a l'è stæta inviâ|son stæte inviæ}}. {{PLURAL:$1|O nomme|L'elenco di nommi}} utente e password o l'è mostrou chì.",
+       "passwordreset-emailerror-capture2": "Invio d'e-mail {{GENDER:$2|a l'utente}} non ariescio: $1. {{PLURAL:$3|O nomme|L'elenco di nommi}} utente e password o l'è mostrou chì de sotta.",
        "passwordreset-nocaller": "Un chi ciamma ti g'hæ da dâlo",
        "passwordreset-nosuchcaller": "O ciamante o no l'existe: $1",
        "passwordreset-ignored": "A reimpostaçion da password a no l'è stæta gestia. Foscia n'è stæto configuou nisciun provider ?",
-       "passwordreset-invalideamil": "Addresso e-mail non vallido",
+       "passwordreset-invalidemail": "Addresso e-mail non vallido",
        "passwordreset-nodata": "No è stæto fornio ni un nomme utente ni un adreçço de posta elettronica",
        "changeemail": "Cangia o elimmina l'adresso e-mail",
        "changeemail-header": "Completa sto formulaio pe cangiâ o to adresso e-mail. Se ti veu rimeuve l'associaçion de quasesegge addresso e-mail da-a teu utensa, lascia io neuvo addresso e-mail veuo quande ti invii o formulaio.",
        "bold_tip": "Grascetto",
        "italic_sample": "Testo in corscivo",
        "italic_tip": "Corscivo",
-       "link_sample": "Nomme de l'ingancio",
+       "link_sample": "Tittolo de l'ingancio",
        "link_tip": "Ingancio interno",
-       "extlink_sample": "http://www.example.com Nomme de l'ingancio",
+       "extlink_sample": "http://www.example.com tittolo de l'ingancio",
        "extlink_tip": "Colegaménto esterno (inclûdde o prefisso http:// )",
        "headline_sample": "Tìtolo",
        "headline_tip": "Tìtolo de 2° livello",
        "searchprofile-advanced-tooltip": "Çerca inti namespace personalizæ",
        "search-result-size": "$1 ({{PLURAL:$2|1 paròlla|$2 paròlle}})",
        "search-result-category-size": "{{PLURAL:$1|1 utente|$1 utenti}} ({{PLURAL:$2|1 sottocategoria|$2 sottocategorie}}, {{PLURAL:$3|1 file|$3 file}})",
-       "search-redirect": "(redirect $1)",
+       "search-redirect": "(Rendriçço da $1)",
        "search-section": "(seçión $1)",
        "search-category": "(categoria $1)",
        "search-file-match": "(corrispondença into contegnuo do file)",
        "gender-unknown": "Into mençunâte, o software o l'adoeuviâ de paole de genere noeütro ogni votta che saiâ poscibile",
        "gender-male": "O l'è registrou insce {{SITENAME}}",
        "gender-female": "A l'è registrâ insce {{SITENAME}}",
-       "prefs-help-gender": "L'impostassion de sta preferensa a l'è opsionâ.\nO software o deuvia sto valô pe addressâse a ti e mensunate a-i atri deuviando o gennere grammaticale apropiou.\nQuesta informassion a saiâ pubblica.",
+       "prefs-help-gender": "L'impostaçion de sta preferença a l'è opçionâ.\nO software o doeuvia sto valô pe indriçâse a ti e mençunâte a-i atri doeuviando o gennere grammaticale apropiou.\nQuest'informaçion a saiâ pubbrica.",
        "email": "Posta elettronega",
        "prefs-help-realname": "O veo nomme o l'è facortativo.\nSe fornio, o poeu ese deuviou pe attribuite a paternitæ do to travaggio.",
        "prefs-help-email": "L'email a no l'é obligatöia, ma a te permette de reçéive a paròlla segrétta se ti l'ascòrdi.",
        "largefileserver": "O file o suppera e dimenscioin consentie da-a configuaçion do server.",
        "emptyfile": "O file apen-a caregou pâ esee voeuo. Questo poriæ ese dovuo a un aro into nomme do file. Controlla se ti voeu davei caregâ sto file.",
        "windows-nonascii-filename": "Questo wiki o no supporta di nommi de file con di caratteri speciali.",
-       "fileexists": "Un papê con sto nomme o l'existe za, pe piaxei danni 'n'euggiâ a <strong>[[:$1]]</strong> se no ti t'ê seguo de voeilo cangiâ.\n[[$1|thumb]]",
+       "fileexists": "Un file con sto nomme o l'existe za, pe piaxei danni 'n'oeuggiâ a <strong>[[:$1]]</strong> se no ti t'ê seguo de voeilo cangiâ.\n[[$1|thumb]]",
        "filepageexists": "A pagina de descriçion de questo file a l'è za stæta creâ a l'adreçço <strong>[[:$1]]</strong>, sciben che no ghe segge ancon un file con questo nomme. A descriçion de l'oggetto inseia in fase de caregamento a no l'appariâ in scia pagina de descriçion. Pe fâ scì che l'oggetto o comparisce in sciâ pagina de descriçion, saiâ necessaio modificala manualmente.\n[[$1|thumb]]",
        "fileexists-extension": "Un file co-in nomme scimile a questo o l'esiste za: [[$2|thumb]]\n* Nomme do file caregou: <strong>[[:$1]]</strong>\n* Nomme do file existente: <strong>[[:$2]]</strong>\nTi voeu miga çerne un nomme ciu caratteristego?",
-       "fileexists-thumbnail-yes": "O file caregou o pâ ese una miniatua ''(thumbnail)''. [[$1|thumb]]\nVerifica, pe confronto, il file <strong>[[:$1]]</strong>.\nSe se tratta da mæxima inmaggine, inte dimenscioin originale, no l'è necessaio caregâne un'atra in miniatua.",
+       "fileexists-thumbnail-yes": "O file caregou o pâ ese 'na miniatua ''(thumbnail)''. [[$1|thumb]]\nControlla o file <strong>[[:$1]]</strong>.\nSe se tratta da mæxima inmaggine, inte dimenscioin originale, no l'è necessaio caregâne un'atra in miniatua.",
        "file-thumbnail-no": "O nomme do file comença con <strong>$1</strong>; pâ ch'o segge un'inmaggine de dimenscioin redute ''(miniatua)''.\nSe ti dispon-i del'immaggine inta risoluçion originale, carreghila. Sedunque, pe piaxei, cangighe o nomme.",
        "fileexists-forbidden": "Un file con questo nomme o l'existe za e o no poeu ese soviascrito. Se ti voeu caregâ o to file, torna inderê e dagghe un atro nomme. [[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Un file con questo nomme o l'esiste za inte l'archivio de risorse multimediæ condivise. Se ti dexiddei ancon caregâ o file, torna inderê e modifica o nomme co-o quæ caregâ o file. [[File:$1|thumb|center|$1]]",
        "upload-source": "File de origine",
        "sourcefilename": "Nomme do file d'origgine:",
        "sourceurl": "URL de origine:",
-       "destfilename": "Nomme do file de destinassion:",
+       "destfilename": "Nomme do file de destinaçion:",
        "upload-maxfilesize": "Dimenscion mascima do file: $1",
        "upload-description": "Descriçion do file",
        "upload-options": "Opçioin de caregamento",
        "upload-dialog-disabled": "O caregamento di file tramite questo barcon de dialogo o l'è disabilitou inte questo wiki.",
        "upload-dialog-title": "Carrega file",
        "upload-dialog-button-cancel": "Anulla",
+       "upload-dialog-button-back": "Inderê",
        "upload-dialog-button-done": "Fæto",
        "upload-dialog-button-save": "Sarva",
        "upload-dialog-button-upload": "Carrega",
        "uploadstash-errclear": "O nettezzo di file o no l'è ariescio.",
        "uploadstash-refresh": "Aggiorna l'elenco di file",
        "uploadstash-thumbnail": "veddi miniatua",
+       "uploadstash-exception": "Imposcibile memoizâ o caregamento in stash ($1): \"$2\".",
        "invalid-chunk-offset": "Offset d'a parte non vallido.",
        "img-auth-accessdenied": "Accesso negou",
        "img-auth-nopathinfo": "PATH_INFO mancante.\nO server o no l'è impostou pe passâ quest'informaçion.\nO poriæ ese basou insce CGI e o no poeu supportâ img_auth.\nAmia https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "upload-curl-error6-text": "Imposcibile razonze a URL specificâ. Verifica che a URL a sæ scrita correttamente e che o scito in question o sæ attivo.",
        "upload-curl-error28": "Tempo descheito pe l'upload",
        "upload-curl-error28-text": "O scito remoto o l'ha impiegou troppo tempo a risponde. Verifica che o sito o sæ attivo, attendi quarche menuto e proeuva torna, se mai inte 'n momento con meno traffego.",
-       "license": "Licensa:",
+       "license": "Liçençia:",
        "license-header": "Licensa",
        "nolicense": "Nisciûnn-a liçensa indicâa",
        "licenses-edit": "Modiffica opçioin de liçença",
        "apisandbox-results-fixtoken-fail": "Imposcibile recuperâ o token \"$1\".",
        "apisandbox-alert-page": "I campi insce questa pagina no son vallidi.",
        "apisandbox-alert-field": "O valô de questo campo o no l'è vallido.",
+       "apisandbox-continue": "Continnoa",
+       "apisandbox-continue-clear": "Nettezza",
        "booksources": "Fonte libraie",
        "booksources-search-legend": "Çerca e fonti",
        "booksources-isbn": "Codice ISBN:",
        "activeusers-intro": "Questo o l'è un elenco di utenti ch'han avuo quarche tipo d'attivitæ da $1 {{PLURAL:$1|giorno|giorni}} a questa parte.",
        "activeusers-count": "$1 {{PLURAL:$1|açione|açioin}} {{PLURAL:$3|inte l'urtimo giorno|inti urtimi $3 giorni}}",
        "activeusers-from": "Mostra i utenti a partî da:",
-       "activeusers-hidebots": "Ascondi i bot",
-       "activeusers-hidesysops": "Ascondi i amministratoî",
        "activeusers-noresult": "Nisciun utente o risponde a-i critei impostæ.",
        "activeusers-submit": "Mostra utenti attivi",
        "listgrouprights": "Driti do groppo utente",
        "trackingcategories-disabled": "A categoria a l'è disabilitâ",
        "mailnologin": "Nisciun adreçço a chi mandâ o messaggio",
        "mailnologintext": "Pe inviâ di messaggi e-mail a di atri utenti l'è necessaio [[Special:UserLogin|accede a-o scito]] e avei registrou un adreçço vallido inte proppie [[Special:Preferences|preferençe]].",
-       "emailuser": "Invia 'na email a st'utente chi",
+       "emailuser": "Invia 'n'e-mail a questo utente",
        "emailuser-title-target": "Invia un'email a questo {{GENDER:$1|utente}}",
        "emailuser-title-notarget": "Invia una email a un utente",
        "emailpagetext": "Doeuvia o moddulo sottostante pe inviâ un messaggio e-mail a l'{{GENDER:$1|utente}} indicou. L'adreçço speçificou inte [[Special:Preferences|preferençe]] do mittente o l'appariâ into campo \"Da:\" do messaggio pe consentî a-o destinataio de risponde direttamente.",
        "undeletepage": "Veddi e recuppera e pagine scançellæ",
        "undeletepagetitle": "'''Quanto segue o l'è composto da de revixoin scassæ de [[:$1|$1]]'''.",
        "viewdeletedpage": "Veddi e paggine scassæ",
-       "undeletepagetext": "{{PLURAL:$1|A seguente pagina a l'è stæta scassâ, ma a l'è ancon in archivio e pertanto a poeu ese recuperâ|Le seguente pagine son stæte scassæ, ma son ancon in archivio e pertanto poeuan ese recuperæ}}. L'archivio o poeu ese vuou periodicamente.",
+       "undeletepagetext": "{{PLURAL:$1|A seguente pagina a l'è stæta scassâ, ma a l'è ancon in archivio e pertanto a poeu ese recuperâ|E seguente pagine son stæte scassæ, ma son ancon in archivio e pertanto poeuan ese recuperæ}}. L'archivio o poeu ese vuou periodicamente.",
        "undelete-fieldset-title": "Ripristina revixoin",
        "undeleteextrahelp": "Pe recuperâ l'intrega cronologia da pagina, lascia tutte e caselle deseleçionæ e fanni clic insce '''''{{int:undeletebtn}}'''''.\nPe effettuâ un ripristino selettivo, seleçion-a e caselle corrispondente a-e verscioin da ripristinâ e fanni clic insce '''''{{int:undeletebtn}}'''''.",
        "undeleterevisions": "{{PLURAL:$1|Una revixon scassâ|$1 revixoin scassæ}}",
        "movepagetalktext": "Se ti seleçion-i questa casella, a corispondente paggina de discuscion a saiâ mesciâ aotomaticamente a-o neuvo tittolo, a meno che existe zà una paggina de discuscion ch'a no segge veua.\n\nInte sti caxi, ti doviæ mesciâ o unî manoalmente a paggina, se proppio ti veu.",
        "moveuserpage-warning": "'''Attençione:''' Ti stæ pe mesciâ una pagina utente. Notta che solo a pagina a saiâ mesciâ. L'utente o ''no'' saiâ rinominou.",
        "movecategorypage-warning": "<strong>Attençione:</strong> ti stæ pe mesciâ una categoria. Notta che solo sta paggina a saiâ mesciâ e tutte e pagine inta vegia categoria <em>no</em> saian inseie inta noeuva.",
-       "movenologintext": "O stramuo dee paggine o l'è consentio solo che a-i utenti registræ ch'han eseguio l'[[Special:UserLogin|accesso]] a-o scito.",
+       "movenologintext": "O stramuo de paggine o l'è consentio solo che a-i utenti registræ ch'han eseguio l'[[Special:UserLogin|accesso]] a-o scito.",
        "movenotallowed": "No ti g'hæ o permisso pe mesciâ de paggine.",
        "movenotallowedfile": "No ti g'hæ o permisso pe mesciâ di file.",
        "cant-move-user-page": "No ti g'hæ o permisso pe mesciâ de pagine utente (escluse e sottopagine).",
        "allmessagesdefault": "Testo predefinio",
        "allmessagescurrent": "Testo corrente",
        "allmessagestext": "Sta chie a l'è a lista de tutti i messaggi de scistema disponibili into namespace MediaWiki.\nVixita [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki Localisation] e [https://translatewiki.net translatewiki.net] se ti voeu contribuî a-a localizzaçion generrica de MediaWiki.",
-       "allmessagesnotsupportedDB": "'''{{ns:special}}:Allmessages''' o non ti te peu vedde, perchè '''$wgUseDatabaseMessages''' o non l'è attivo.",
+       "allmessagesnotsupportedDB": "No l'è poscibbile doeuviâ sta paggina perchè o flag '''$wgUseDatabaseMessages''' o no l'è attivo.",
        "allmessages-filter-legend": "Filtro",
        "allmessages-filter": "Filtra pe stato de modiffica:",
        "allmessages-filter-unmodified": "Non modificæ",
        "tooltip-undo": "\"Anùlla\" o permette de anulâ sto cangiaménto e o l'arve o modulo de cangiaménto inta modalitæ anteprìmma. Ti peu ascì métte a raxón inte l'ogetto do cangiaménto.",
        "tooltip-preferences-save": "Sarva e preferençe",
        "tooltip-summary": "Scrîvi 'na scintexi",
-       "common.css": "/** i stili css scriti chie se applicana tutte e skin */",
+       "common.css": "/** i stili css scriti chì se apprican a tutte e skin */",
        "anonymous": "{{PLURAL:$1|Utente anonnimo|Utenti anonnimi}} de {{SITENAME}}",
        "siteuser": "$1, utente de {{SITENAME}}",
        "anonuser": "$1, utente anonnimo de {{SITENAME}}",
        "previousdiff": "← Diferensa precedénte",
        "nextdiff": "Pròscima diferensa →",
        "mediawarning": "'''Attençione''': Questo file o poriæ contegnî un codiçe maligno. A so esecuçion a poriæ dannezzâ o to scistema.",
-       "imagemaxsize": "Dimenscion mascima de ibmaggine:<br />''(pe-e paggine de descriçion do file)''",
+       "imagemaxsize": "Dimenscion mascima d'e inmaggine:<br />''(pe-e paggine de descriçion do file)''",
        "thumbsize": "Dimescion de l'imaginetta:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|paggina|paggine}}",
        "file-info": "dimenscion do file: $1, tipo MIME: $2",
        "saturday-at": "Sabbo a $1",
        "sunday-at": "Domenega a $1",
        "yesterday-at": "Vei a $1",
-       "bad_image_list": "O formato o l'è coscì:\nVan conscideræ sôlo e righe che comensan co-o càratere *.\nO primmo ingancio in sce ògni riga o dev'ese 'n ingancio ch'o no fonçionn-a\nI inganci sucescivi, in scia mæxima riga, van conscideræ comme eceçioìn (pagine donde o file o pêu ese reciamòu normalmente).",
+       "bad_image_list": "O formato o l'è coscì:\nVan conscideræ sôlo e righe che comensan co-o càratere *.\nO primmo ingancio in sce ògni riga o dev'ese 'n ingancio ch'o no fonçionn-a\nI inganci sucescivi, in scia mæxima riga, van conscideræ comme eceçioìn (pagine donde o file o poeu ese reciamòu normalmente).",
        "metadata": "Metadati",
        "metadata-help": "Sto file o contegne de informaçioìn in ciù, fòscia misse da-a fotocamera ò dò-u scansô dêuviòu pe creâla ò digitalizâla. Se o file o l'è stæto cangiòu, çerti detàggi porieivan no corisponde a-i cangi aportæ.",
        "metadata-expand": "Fâ vedde dettaggi",
        "tag-filter-submit": "Filtro",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Etichetta|Etichette}}]]: $2)",
        "tag-mw-contentmodelchange": "cangio a-o modello di contegnui",
+       "tag-mw-contentmodelchange-description": "Modiffiche che [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel cangian o modello di contegnui] de 'na paggina",
        "tags-title": "Etichette",
        "tags-intro": "Questa pagina a l'elenca i etichette che o software o poriæ associâ a 'na modiffica e o so scignificou.",
        "tags-tag": "Nomme de l'etichetta",
        "htmlform-cloner-create": "Azonzi de l'atro",
        "htmlform-cloner-delete": "Leva",
        "htmlform-cloner-required": "Ghe voeu a-o manco un valô.",
+       "htmlform-date-placeholder": "AAAA-MM-GG",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "AAAA-MM-GG HH:MM:SS",
+       "htmlform-date-invalid": "O valô specificou o no l'è riconoscito comme dæta. Prœuva a dœuviâ o formato AAAA-MM-GG.",
+       "htmlform-time-invalid": "O valô specificou o no l'è riconosciuo comme oraio. Prœuva a dœuviâ o formato HH:MM:SS.",
+       "htmlform-datetime-invalid": "O valô specificou o no l'è riconosciuo comme dæta e oa. Prœuva a dœuviâ o formato AAAA-MM-GG HH:MM:SS.",
+       "htmlform-date-toolow": "O valô specificou o l'è precedente a-a primma dæta consentia do $1.",
+       "htmlform-date-toohigh": "O valô specificou o l'è succescivo a l'urtima dæta consentia do $1.",
+       "htmlform-time-toolow": "O valô specificou o l'è precedente a-o primmo oraio consentio do $1.",
+       "htmlform-time-toohigh": "O valô specificou o l'è succescivo a l'urtimo oraio consentio do $1.",
+       "htmlform-datetime-toolow": "O valô specificou o l'è precedente a-a primma dæta e oa consentia do $1.",
+       "htmlform-datetime-toohigh": "O valô specificou o l'è succescivo a l'urtima dæta e oa consentia do $1.",
        "htmlform-title-badnamespace": "[[:$1]] a no se troeuva into namespace \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" o l'è o tittolo de una paggina non creabile",
        "htmlform-title-not-exists": "$1 a no l'existe.",
        "feedback-external-bug-report-button": "Documenta un problema tecnico",
        "feedback-dialog-title": "Invia un feedback",
        "feedback-dialog-intro": "Doeuvia o moddulo sottostante pe inviâ o to feedback. O to commento o l'appariâ inta paggina \"$1\", assemme a-o to nomme utente.",
-       "feedback-error-title": "Errô",
        "feedback-error1": "Errô: Da-a API l'è arrivou un risultou non riconosciuo",
        "feedback-error2": "Errô: No l'è stæto poscibbile eseguî a modiffica",
        "feedback-error3": "Errô: Nisciun-a risposta da-a API",
        "feedback-thanks": "Graççie! O to feedback o l'è stæto pubricou a-a paggina \"[$2 $1]\".",
        "feedback-thanks-title": "Graççie!",
        "feedback-useragent": "Agente utente:",
-       "searchsuggest-search": "Çerca",
+       "searchsuggest-search": "Çerca in {{SITENAME}}",
        "searchsuggest-containing": "ch'o conten...",
        "api-error-autoblocked": "O to adreçço IP o l'è stæto bloccou aotomaticamente, perché o l'è stæto doeuviou da un utente bloccou.",
        "api-error-badaccess-groups": "No t'ê aotorizzou a caregâ di file insce questa wiki.",
        "limitreport-expansiondepth": "Mascima profonditæ d'espanscion",
        "limitreport-expensivefunctioncount": "Nummero de fonçioin do parser dispendiose",
        "expandtemplates": "Espanscion di template",
-       "expand_templates_intro": "Questa pagina speciale a l'elabboa un testo espandendo tutti i template presenti.\nA carcoa ascì o risultou de fonçioon supportæ da-o parser comme\n<code><nowiki>{{</nowiki>#language:…}}</code> e de variabbile de scistema quæ\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>,\nsaiv'a dî inta prattica tutto 'lo che s'attroeuva tra parentexi graffe dogge.",
+       "expand_templates_intro": "Questa pagina speciale a l'elabboa un scrito espandendo tutti i template presenti.\nA calcola ascì o risultato de fonçioin supportæ da-o parser comme\n<code><nowiki>{{</nowiki>#language:…}}</code> e de variabbile de scistema quæ\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>,\nsaiv'a dî inta prattica tutto 'lo che s'attroeuva tra parentexi graffe dogge.",
        "expand_templates_title": "Contesto (pe {{FULLPAGENAME}} eçç.):",
        "expand_templates_input": "Testo da espande:",
        "expand_templates_output": "Risultou",
        "linkaccounts-submit": "Collega utençe",
        "unlinkaccounts": "Scollega utençe",
        "unlinkaccounts-success": "L'utença a l'è stæta scollegâ.",
-       "authenticationdatachange-ignored": "O cangiamento da dæta d'aotenticaçion o no l'è passou. Foscia che no gh'ea un provider configuou?"
+       "authenticationdatachange-ignored": "O cangiamento da dæta d'aotenticaçion o no l'è passou. Foscia che no gh'ea un provider configuou?",
+       "userjsispublic": "Regorda: e sottopaggine JavaScript no devan contegnî dæti riservæ percose son vixoalizabbile da-i atri utenti.",
+       "usercssispublic": "Regorda: e sottopagine CSS no devan contegnî dæti riservæ percose son vixoalizabbile da i atri utenti.",
+       "restrictionsfield-badip": "Intervallo d'adreççi IP non vallido:$1",
+       "restrictionsfield-label": "Intervalli IP consentii:",
+       "restrictionsfield-help": "Un adresso IP ò intervallo CIDR pe linnia. Pe consentî tutto, adœuvia<br><code>0.0.0.0/0</code><br><code>::/0</code>"
 }
index 0eec9c6..c906996 100644 (file)
        "yourname": "Kȭlbatijiznim:",
        "yourpassword": "Sallisõnä:",
        "yourpasswordagain": "Kēratigid sallisõnā ūtstõ:",
-       "remembermypassword": " Mǟdlõgid sallisõnā (kuņtš $1 {{PLURAL:$1|päuvõ|päuvõ}})",
        "login": "Log sīezõ",
        "nav-login-createaccount": "Log sīezõ agā registrīer kȭlbatijizõks",
        "userlogin": "Sīezõ loggimi agā kȭlbatijiz-konto lūomi",
index 74b2357..8c5fa41 100644 (file)
        "yourpasswordagain": "تکرار گذرواژه:",
        "createacct-yourpasswordagain": "گذرواژه را دوباره وارد کنید",
        "createacct-yourpasswordagain-ph": "گذرواژه را وارد کنید برای بار دوم",
-       "remembermypassword": "رمزعبورت وة ئئ رایانة ئةویرت/یادت بو(تابیشترإژ$1{{PLURAL:$1|رووژةل|رووژ}})",
        "userlogin-remembermypassword": "مإ وارد  بی بیل",
        "userlogin-signwithsecure": "إژ ورود امن استفاده کةن",
        "cannotloginnow-title": "ایسه نمه‌تونین باینه نوم",
        "activeusers-intro": "در زیر فهرستی از کاربرانی را می‌بینید که در $1 {{PLURAL:$1|روز|روزها}} گذشته فعالیتی داشته‌اند.",
        "activeusers-count": "$1 {{PLURAL:$1|فعالیت|فعالیت ها}} در {{PLURAL:$3|روز|$3 روز}} اخیر",
        "activeusers-from": "نمایش کاربران با آغاز از:",
-       "activeusers-hidebots": "نهفتن ربات‌ها",
-       "activeusers-hidesysops": "نهفتن مدیران",
        "activeusers-noresult": "کاربری پیدا نشد.",
        "activeusers-submit": "نمایش کاربةرةل فعال/کارکةر",
        "listgrouprights": "اختیارات گروه‌های کاربری",
        "htmlform-title-not-exists": "$1 وجود ندارد.",
        "htmlform-user-not-exists": "<strong>$1</strong> وجود ندارد.",
        "htmlform-user-not-valid": "حساوو کاربةری <strong>$1</strong> معتبر نیة.",
-       "sqlite-has-fts": "$1 با پشتیبانی از جستجو در متن کامل",
-       "sqlite-no-fts": "$1 بدون پشتیبانی از جستجو در متن کامل",
        "logentry-delete-delete": "$1 VALGA $3{{GENDER:$2|HAZF Kerdi}}",
        "logentry-delete-restore": "$1 وةڵگة $3 را {{GENDER:$2|احیا کرد}}",
        "logentry-delete-event": "$1 پیدایی {{PLURAL:$5|یک مورد سیاهه|$5 مورد سیاهه}} را در $3 {{GENDER:$2|تغییر داد}}: $4",
        "feedback-external-bug-report-button": "پرونده‌سازی یک عمل فنی",
        "feedback-dialog-title": "ارسال یک بازخورد",
        "feedback-dialog-intro": "شما می توانید از فرم زیر برای بازخورد استفاده کنید. متن شما همراه با نام کاربریتان به وةڵگة \"$1\" افزوده خواهد شد.",
-       "feedback-error-title": "خطا",
        "feedback-error1": "خطا: پاسخ‌های ناشناخته از رابط برنامه‌نویسی نرم‌افزار",
        "feedback-error2": "خطا: شکست در ویرایش",
        "feedback-error3": "خطا: عدم پاسخ از رابط برنامه‌نویسی نرم‌افزار",
index 822718f..0555632 100644 (file)
        "yourpasswordagain": "Tùrna a scrìer la password",
        "createacct-yourpasswordagain": "Conférma la password",
        "createacct-yourpasswordagain-ph": "Tùrna a mèter dét la password",
-       "remembermypassword": "Regordass la mé password (per mìa de piö de {{PLURAL:$1|dé|dé}})",
        "userlogin-remembermypassword": "Tègnem colegàt",
        "userlogin-signwithsecure": "Dòpra 'na conesiù sigüra",
        "yourdomainname": "Specificà 'l domini",
        "passwordreset-emailtitle": "Detài de l'ütènsa sö {{SITENAME}}",
        "passwordreset-emailelement": "Nòm ütènt: \n$1\n\nPassword temporànea: \n$2",
        "passwordreset-emailsentemail": "Gh'è stat mandàt vià 'na e-mail de redefinisiù de la password.",
-       "passwordreset-emailsent-capture": "Gh'è stat mandàt vià chèsta e-mail de redefinisiù de la password:",
        "changeemail": "Càmbia l'indirìs e-mail",
        "changeemail-header": "Càmbia l'indirìs e-mail de l'ütènsa",
        "changeemail-none": "(nisü)",
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
        "undo-summary": "Scancelada la mudifega $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|Ciciarada]])",
-       "cantcreateaccounttitle": "Impusìbol creà 'n ütènt",
        "cantcreateaccount-text": "La creasiù de ütènse de part de chèsto indirìs IP (<strong>$1</strong>) l'è stàda blocàda de l'ütènt [[User:$3|$3]]. El mutìf specificàt de $3 l'è <em>$2</em>",
        "cantcreateaccount-range-text": "La creasiù de ütènse de part de indirìs IP endèl interval <strong>$1</strong>, del qual el fà part apò a 'l tò (<strong>$4</strong>), l'è stàda blocàda de [[User:$3|$3]].\n\nEl mutìf specificàt de $3 l'è <em>$2</em>.",
        "viewpagelogs": "Varda i register de quela pagina chì",
        "listusers-submit": "Fà ved",
        "activeusers": "Lìsta dei ütèncc atìf",
        "activeusers-from": "Fàm vedè i dupradur a partì da:",
-       "activeusers-hidebots": "Scond i bot",
-       "activeusers-hidesysops": "Scond i aministradur",
        "activeusers-noresult": "Nisü ütènt troàt",
        "listgrouprights": "Diricc del grüp dei ütèncc",
        "listgrouprights-group": "Grüp",
index 690b149..0cebddf 100644 (file)
@@ -4,7 +4,8 @@
                        "Passawuth",
                        "Tuinui",
                        "아라",
-                       "Iberia2011"
+                       "Iberia2011",
+                       "Aefgh39622"
                ]
        },
        "tog-underline": "ຂີດເສັ້ນກ້ອງລິງກ໌:",
        "yourname": "ຊື່ຜູ້ໃຊ້",
        "yourpassword": "ລະຫັດຜ່ານ",
        "yourpasswordagain": "ພິມລະຫັດຜ່ານອີກ",
-       "remembermypassword": "ຈົດຈໍາການເຊັນເຂົ້າຂອງຂ້ອຍ ຢູ່ ຄອມພິວເຕີໜ່ວຍນີ້ (for a maximum of $1 {{PLURAL:$1|day|days}})",
        "yourdomainname": "ໂດເມນ ຂອງ ທ່ານ",
        "login": "ເຊັນເຂົ້າ",
        "nav-login-createaccount": "ເຊັນເຂົ້າ / ສ້າງບັນຊີ",
        "retypenew": "ພິມລະຫັດຜ່ານໃໝ່ອີກ:",
        "resetpass_submit": "ຕັ້ງລະຫັດຜ່ານ ແລະ ເຊັນເຂົ້າ",
        "changepassword-success": "ສຳເລັດການປ່ຽນແປງ ລະຫັດຜ່ານຂອງທ່ານແລ້ວ! ດຽວນີ້ ທ່ານ ເຊັ່ນເຂົ້າ ໃນ ...",
+       "passwordreset-invalidemail": "ທີ່ຢູ່ອີເມລບໍ່ຖືກຕ້ອງ",
        "bold_sample": "ໂຕໜັງສືເຂັ້ມ",
        "bold_tip": "ໂຕໜັງສືເຂັ້ມ",
        "italic_sample": "ໂຕເນີ້ງ",
        "template-protected": "(ປົກປ້ອງ)",
        "template-semiprotected": "(ເຄິ່ງປົກປ້ອງ)",
        "nocreatetext": "{{SITENAME}} ໄດ້ຈຳກັດການສ້າງໜ້າໃໝ່.\nທ່ານສາມາດກັບໄປ ດັດແກ້ ໜ້າທີ່ມີແລ້ວ ຫຼື [[Special:UserLogin|ເຊັນເຂົ້າ ຫຼື ສ້າງບັນຊີ]].",
-       "cantcreateaccounttitle": "ບໍ່ສາມາດສ້າງ ບັນຊີ ໄດ້",
        "cantcreateaccount-text": "ການສ້າງບັນຊີ ຈາກ IP ນີ້ (<b>$1</b>) ໄດ້ຖືກຫ້າມ ໂດຍ [[User:$3|$3]].\n\nເຫດຜົນ ໃຫ້ໄວ້ ໂດຍ $3 ແມ່ນ ''$2''",
        "viewpagelogs": "ເບິ່ງບັນທຶກ ຂອງ ໜ້ານີ້",
        "nohistory": "ຍັງບໍ່ມີ ປະຫວັດການດັດແກ້ໜ້ານີ້ເທື່ອ.",
        "tooltip-compareselectedversions": "ເບິ່ງສ່ວນຕ່າງລະຫວ່າງ ສອງ ສະບັບເລືອກ.",
        "tooltip-watch": "ເພີ່ມໜ້ານີ້ໃສ່ລາຍການຕິດຕາມຂອງທ່ານ",
        "anonymous": "ຜູ້ໃຊ້ ບໍ່ສະແດງຊື່ ຈາກ {{SITENAME}}",
+       "confirm-markpatrolled-button": "ຕົກລົງ",
        "previousdiff": "ສ່ວນຕ່າງກ່ອນ",
        "nextdiff": "ສ່ວນຕ່າງຕໍ່ໄປ →",
        "imagemaxsize": "ກຳນົດຄວາມໃຫຍ່ຂອງ ຮູບ ຫຼື ໜ້າອະທິບາຍຮູບ ບໍ່ໃຫ້ກາຍ:",
index 4a0cbcc..3b90e11 100644 (file)
        "yourname": "Sebelu:",
        "yourpassword": "Sebu dafi:",
        "yourpasswordagain": "Ritapi sebu dafi:",
-       "remembermypassword": "Askevusize zwa menuhile kwa bye kompyuta (for a maximum of $1 {{PLURAL:$1|day|days}})",
        "yourdomainname": "Zwa domeni:",
        "login": "Menuhile",
        "nav-login-createaccount": "Menuhile / ipupezi sebelu",
        "template-semiprotected": "(bukelezi di pagafi)",
        "nocreatetext": "{{SITENAME}} sa simplekile petulo.\nA afi e kenki/[[Special:UserLogin|menuhile]].",
        "recreate-moveddeleted-warn": "'''!: A sa hloli petulo dy sa afi kulobala.'''\n\nA sa luku a kenki dyangitubilinisize petulo.\nDesu dafi kulobala di petulo sa gi di informasi:",
-       "cantcreateaccounttitle": "Ni sa hloli di sebelu",
        "viewpagelogs": "Kamukile desu di petulo",
        "currentrev": "Selt nca",
        "revisionasof": "Selt di $1",
index 7aed884..996551b 100644 (file)
        "yourpasswordagain": "یئ گئل هأنی رازینە گوڤاردئن نە بأزە",
        "createacct-yourpasswordagain": "رازینە گوڤاردئن نە پوشت راس کو",
        "createacct-yourpasswordagain-ph": "یئ گئل هأنی رازینە گوڤاردئن نە بأزە",
-       "remembermypassword": "ئوٙمائن ڤامین مئنە د ئی دوڤارتە نیأر د ڤیر داشتوٙ (سی بیشتئروٙنە $1{{PLURAL:$1|روٙز|روٙزیا}})",
        "userlogin-remembermypassword": "مئنە د ساموٙنە ڤادار",
        "userlogin-signwithsecure": "ڤأصل بییئن أمن نە ڤئ کار بئیر",
        "yourdomainname": "پوشگئر شوما:",
        "passwordreset-emailtext-user": "کاریار $1 د {{SITENAME}} د نۊ زئنە کئردئن رازینە گوڤاردئن شومانە د{{SITENAME}} ($4) حاستە. {{PLURAL:$3|حئساڤ|حئساڤیا}} کاریاری کئ هان د هار و ڤا ئی تیرنئشوٙن أنجومانامە هان د ئرتئڤاط:\n\n$2\n\n رازینە گوڤاردئن {{PLURAL:$3|ئی رازینە یا گوڤاردئن موڤأقأتی|ئی رازینە یا گوڤاردئن موڤأقأتی}} شوما د گات {{PLURAL:$5|یئ روٙ|$5 روٙ}} باطئل بوٙە.\nأر کأسی هأنی چئن حاستی داشتە یا یە کئ رازینە گوڤاردئن دئمایی شوما د ڤیرئتوٙ ئوٙما و دە نئمیهایت ڤئنە آلئشت کاری بأکیت، می توٙنیت د ئی پئیغوم تیە پوٙشی بأکیت و هأموٙ رازینە گوڤاردئن دئمایی نە بونیت د کار.",
        "passwordreset-emailelement": "نوم کاریاری: \n$1\n\nرازینە گوڤاردئن موڤأقتی: \n$2",
        "passwordreset-emailsentemail": "یئ گئل رازینە گوڤاردئن هأنی سی أنجومانامە کئل بییە.",
-       "passwordreset-emailsent-capture": "رازینە گوڤاردئن تازە توٙ سی أنجومانامە توٙ کئ ها د هار کئل بییە.",
-       "passwordreset-emailerror-capture": "رازینە گوڤاردئن د أنجومانامە د نۊ زئنە کون کئل بییە،و ڤئ د هار دیاری میکە، ڤألی کئل بییئن ڤئ سی {{GENDER:$2|کاریار}} ناخوش سأرنجوم بییە:$1",
        "changeemail": "أنجومانامە توٙنە آلئشت کاری بأکیت",
        "changeemail-header": "ئی فورمئ نە سی آلئشتکاری أنجومانامە توٙ پور بأکیت. أر میھایت ھأر جوٙر أنجومانامە یی نە د مینجا حئساڤئتوٙ پاکسا بأکیت، جاگە دأئن أنجومانامە نئ د چئنی فورمی حالی بأنیت.",
-       "changeemail-passwordrequired": "شوما سی پوشت راستکاری ئی آلئشت بایأد یئ گئل رازینە گوڤاردئن بأزئنیت.",
        "changeemail-no-info": "شوما سی یە کئ د ئی بألگە دأسرئسی داشتوٙییت باس بیاییت ڤامین.",
        "changeemail-oldemail": "تیرنئشوٙن أنجومانامە ئیسئنی:",
        "changeemail-newemail": "تیرنئشوٙن أنجومانامە تازە:",
        "undo-nochange": "وه نظر میا که ای ویرایشت د ایسنیا خومثی بیه.",
        "undo-summary": "خومثی بیئن وانئری وا $1 [[Special:Contributions/$2|$2]] ([[User talk:$2|چک چنه]])",
        "undo-summary-username-hidden": "خومثی بیئن وانئری $1 وا یه گل کاریار قام بیه",
-       "cantcreateaccounttitle": "نأبوٙە حئساڤ راس بأکیت",
        "cantcreateaccount-text": "حساو دروس بیه و ا ای تیرنشون آی پی(<strong>$1</strong>) وه دس ای [[کاریار:$3|$3]] قلف بیه.\n\n\nدلیل دئه بیه وا $3 ها د<em>$2</em>",
        "cantcreateaccount-range-text": "حساو دروس بیه وا تیرنشون آی پی که د پوشینه <strong>$1</strong> ، که وه ئم مینونه دار تیرنشون آی پی شما ئم هئ(<strong>$4</strong>)، وه دس [[کاریار:$3|$3]]قلف بیه.\n\nدلیل دئه بیه وا $3، \"$2\" ئه.",
        "viewpagelogs": "سئیل پئرئستنوٙمە یا ئی بألگە بأکیت",
        "activeusers-intro": "شما د هار یه گل نومگه د کاریاریایی نه مینیت که د $1 {{PLURAL:$1|رو|رو}} دماتر کنشتگر بینه.",
        "activeusers-count": "$1 {{PLURAL:$1|کنشت|کنشت}} در {{PLURAL:$3|رو|$3 رو}} دماتر",
        "activeusers-from": "کاریاریایی که د شرو بینه نشو بیه:",
-       "activeusers-hidebots": "بوتیا قام کو",
-       "activeusers-hidesysops": "دیوون داریا نه قام کو",
        "activeusers-noresult": "هیچ کاروری پیدا نبی",
        "listgrouprights": "حقوق گرو کاریاری",
        "listgrouprights-summary": "نومگه های گرته د ور گرویا کاریاری تعریف بیه د ای ویکی و اختیارات دئه بیه د ونونه.\nدونسمنیا بیشتر دباره هرکوم د اختیارات نه د   [[{{MediaWiki:Listgrouprights-helppage}}]] پیدا بکیت.",
        "htmlform-cloner-create": "هنی اضاف بکیت",
        "htmlform-cloner-delete": "ؤرداشتن",
        "htmlform-cloner-required": "سی کمترونه یه گل ارزایشت لازمه",
-       "sqlite-has-fts": "$1 وا حامینداری پی جوری تمام نیسسه یی",
-       "sqlite-no-fts": "$1 وا بی حامینداری پی جوری تمام نیسسه یی",
        "logentry-delete-delete": "$1 بلگه {{GENDER:$2|پاکسا بیه}} $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|}} بلگه $3 د نو زنه کرده",
        "logentry-delete-event": "$1 دیاری {{PLURAL:$5|یه گل رخ ون د پهرستنومه|$5 رخ ونیا د پهرستنومه}} نه $3 {{GENDER:$2|آلشتکاری کرد}}: $4",
        "feedback-external-bug-report-button": "جانیا سازی یه گل کنشتیاری کسمدار",
        "feedback-dialog-title": "دیار بیین نهاحردیاری",
        "feedback-dialog-intro": "شما می تونیت نوم بلگه هاری نه سی دماداری هوال حونتو وه کار بئریت.نیسسه شما واگرد نوم کاریاریتو د بلگه \"$1\" اضاف موئه.",
-       "feedback-error-title": "خطا",
        "feedback-error1": "خطا: جواویا نادیار د پیوندکار برنامه نیسی نرم افزار",
        "feedback-error2": "خطا:ویرایشت خو نبی",
        "feedback-error3": "خطا: جواو ندئن د پیوندکار برنامه نیسی نرم افزار",
index 90f5c98..5b6dee4 100644 (file)
        "tog-hidepatrolled": "Slėpti patikrintus keitimus paskutinių keitimų sąraše",
        "tog-newpageshidepatrolled": "Slėpti patikrintus puslapius iš naujausių straipsnių sąrašo",
        "tog-hidecategorization": "Slėpti puslapių kategorizavimą",
-       "tog-extendwatchlist": "Išplėsti stebimųjų sąrašą, kad rodytų visus tinkamus keitimus, ne tik pačius naujausius.",
+       "tog-extendwatchlist": "Išplėsti stebimųjų sąrašą, kad rodytų visus tinkamus keitimus, ne tik pačius naujausius",
        "tog-usenewrc": "Grupuoti pakeitimas pagal puslapį paskutinių keitimų ir stebėjimo sąrašuose",
        "tog-numberheadings": "Automatiškai numeruoti skyrelius",
        "tog-showtoolbar": "Rodyti redagavimo įrankių juosta",
        "tog-editondblclick": "Puslapių redagavimas dvigubu spustelėjimu (JavaScript)",
        "tog-editsectiononrightclick": "Įjungti skyrelių redagavimą paspaudus skyrelio pavadinimą dešiniuoju pelės klavišu (JavaScript)",
-       "tog-watchcreations": "Pridėti puslapius, kuriuos aš sukuriu, į stebimų sąrašą",
-       "tog-watchdefault": "Pridėti puslapius, kuriuos aš redaguoju, į stebimų sąrašą",
-       "tog-watchmoves": "Pridėti puslapius, kuriuos aš perkeliu, į stebimų sąrašą",
-       "tog-watchdeletion": "Pridėti puslapius, kuriuos aš ištrinu, į stebimų sąrašą",
+       "tog-watchcreations": "Pridėti mano sukuriamus puslapius į stebimųjų sąrašą",
+       "tog-watchdefault": "Pridėti puslapius, kuriuos aš redaguoju, į stebimų sąrašą",
+       "tog-watchmoves": "Pridėti puslapius ir failus, kuriuos aš perkeliu, į stebimųjų sąrašą",
+       "tog-watchdeletion": "Pridėti puslapius, kuriuos aš ištrinu, į stebimų sąrašą",
        "tog-watchuploads": "Pridėti naujus failus, kurios aš įkeliu, į mano stebimųjų sąrašą",
-       "tog-watchrollback": "Pridėti puslapius, kuriuose aš atlikau atmetimus į mano stebėjimo sąrašą",
+       "tog-watchrollback": "Pridėti puslapius, kuriuose aš atlikau atmetimus, į stebimųjų sąrašą",
        "tog-minordefault": "Pagal nutylėjimą pažymėti redagavimus kaip smulkius",
        "tog-previewontop": "Rodyti peržiūrą virš redagavimo lauko",
        "tog-previewonfirst": "Rodyti peržiūrą pirmą kartą pakeitus",
        "tog-enotifminoredits": "Siųsti man laišką, kai puslapio keitimas yra smulkus",
        "tog-enotifrevealaddr": "Rodyti mano el. pašto adresą priminimo laiškuose",
        "tog-shownumberswatching": "Rodyti stebinčių naudotojų skaičių",
-       "tog-oldsig": "Jūsų egzistuojantis parašas:",
+       "tog-oldsig": "Jūsų dabartinis parašas:",
        "tog-fancysig": "Laikyti parašą vikitekstu (be automatinių nuorodų)",
        "tog-uselivepreview": "Naudoti tiesioginę peržiūrą",
        "tog-forceeditsummary": "Klausti, kai palieku tuščią keitimo komentarą",
-       "tog-watchlisthideown": "Slėpti mano keitimus stebimų sąraše",
-       "tog-watchlisthidebots": "Slėpti robotų keitimus stebimų sąraše",
-       "tog-watchlisthideminor": "Slėpti smulkius keitimus stebimų sąraše",
+       "tog-watchlisthideown": "Slėpti mano keitimus stebimų sąraše",
+       "tog-watchlisthidebots": "Slėpti botų keitimus stebimųjų sąraše",
+       "tog-watchlisthideminor": "Slėpti smulkius keitimus stebimų sąraše",
        "tog-watchlisthideliu": "Slėpti prisijungusių naudotojų keitimus stebimųjų sąraše",
        "tog-watchlistreloadautomatically": "Atnaujinti stebėjimų sąrašą automatiškai, kai tik filtras yra pakeičiamas (reikalingas JavaScript)",
        "tog-watchlisthideanons": "Slėpti anoniminių naudotojų keitimus stebimųjų sąraše",
        "talk": "Aptarimas",
        "views": "Peržiūros",
        "toolbox": "Įrankiai",
-       "tool-link-userrights": "Keisti {{GENDER:$1|vartotojo|vartotojos}} grupes",
-       "tool-link-emailuser": "Siusti el. laišką {{GENDER:$1|šiam vartotojui|šiai vartotojai}}",
+       "tool-link-userrights": "Keisti {{GENDER:$1|naudotojo|naudotojos}} grupes",
+       "tool-link-emailuser": "Siųsti {{GENDER:$1|šiam naudotojui|šiai naudotojai}} el. laišką",
        "userpage": "Rodyti naudotojo puslapį",
        "projectpage": "Rodyti projekto puslapį",
        "imagepage": "Žiūrėti failo puslapį",
        "ok": "Gerai",
        "retrievedfrom": "Gauta iš „$1“",
        "youhavenewmessages": "Jūs turite $1 ($2).",
-       "youhavenewmessagesfromusers": "Jūs gavote $1 nuo {{PLURAL:$3|kito vartotojo|$3 vartotojų}} ($2).",
+       "youhavenewmessagesfromusers": "Jūs gavote $1 nuo {{PLURAL:$3|kito naudotojo|$3 naudotojų}} ($2).",
        "youhavenewmessagesmanyusers": "Jūs turite $1 iš daugelio vartotojų ( $2 ) .",
        "newmessageslinkplural": "{{PLURAL:$1|nauja žinutė|999=naujos žinutės}}",
        "newmessagesdifflinkplural": "paskutinis {{PLURAL:$1|pakeitimas|999=pakeitimai}}",
        "laggedslavemode": "Dėmesio: Puslapyje gali nesimatyti naujausių pakeitimų.",
        "readonly": "Duomenų bazė užrakinta",
        "enterlockreason": "Įveskite užrakinimo priežastį, taip pat datą, kada bus atrakinta",
-       "readonlytext": "Duomenų bazė šiuo metu yra užrakinta naujiems įrašams ar kitiems keitimams,\nturbūt duomenų bazės techninei profilaktikai,\npo to viskas vėl veiks kaip įprasta.\n\nUžrakinusiojo administratoriaus pateiktas rakinimo paaiškinimas: $1",
+       "readonlytext": "Duomenų bazė šiuo metu yra užrakinta naujiems įrašams ar kitiems keitimams,greičiausiai duomenų bazės techninei profilaktikai,\npo kurios viskas vėl veiks kaip įprasta.\n\nUžrakinusiojo sistemos administratoriaus pateiktas paaiškinimas: $1",
        "missing-article": "Duomenų bazė nerado puslapio teksto, kurį ji turėtų rasti, pavadinto „$1“ $2.\n\nPaprastai tai būna dėl pasenusios skirtumo ar istorijos nuorodos į puslapį, kuris buvo ištrintas.\n\nJei tai ne tas atvejis, jūs galbūt radote klaidą programinėje įrangoje.\nPrašome apie tai pranešti [[Special:ListUsers/sysop|administratoriui]], nepamiršdami nurodyti nuorodą.",
        "missingarticle-rev": "(versija#: $1)",
        "missingarticle-diff": "(Skirt.: $1, $2)",
        "title-invalid-magic-tilde": "Prašomo puslapio pavadinimas turi negalima magiška tildės seką (<nowiki>~~~</nowiki>).",
        "title-invalid-too-long": "Prašomo puslapio pavadinimas yra per ilgas. Jis turi būti ne ilgesnis nei {{PLURAL:$1|baitas|baitai}} UTF-8 koduotėje.",
        "title-invalid-leading-colon": "Prašomo puslapio pavadinimas turi neleistiną dvitaškį pradžioje.",
-       "perfcached": "Rodoma išsaugota duomenų kopija, todėl duomenys gali būti ne patys naujausi. Maksimaliai $1 {{PLURAL:$1|rezultatas|rezultatai|rezultatų}} yra saugoma.",
-       "perfcachedts": "Rodoma išsaugota duomenų kopija, kuri buvo atnaujinta $2 $3. Maksimaliai $4 {{PLURAL:$4|rezultatas|rezultatai|rezultatų}} yra saugoma.",
+       "perfcached": "Rodoma išsaugota duomenų kopija, todėl duomenys gali būti ne patys naujausi. Saugoma iki $1 {{PLURAL:$1|rezultatas|rezultatai|rezultatų}}.",
+       "perfcachedts": "Rodoma išsaugota duomenų kopija, kuri buvo atnaujinta $2 $3. Saugoma iki $4 {{PLURAL:$4|rezultatas|rezultatai|rezultatų}}.",
        "querypage-no-updates": "Atnaujinimai šiam puslapiui dabar yra išjungti. Duomenys čia dabar nebus atnaujinti.",
        "viewsource": "Žiūrėti kodą",
        "viewsource-title": "Peržiūrėti šaltinį $1",
        "actionthrottled": "Veiksmas apribotas",
-       "actionthrottledtext": "Kad būtų apsisaugota nuo reklamų, jums neleidžiama daug kartų atlikti šį veiksmą per trumpą laiko tarpą, bet jūs pasiekėte šį limitą. Prašome vėl pamėginti po kelių minučių.",
+       "actionthrottledtext": "Kad būtų apsisaugota nuo pažeidimų, jums neleidžiama pernelyg daug kartų atlikti šį veiksmą per trumpą laiko tarpą. Jūs viršijote šį limitą. Prašome vėl pamėginti po kelių minučių.",
        "protectedpagetext": "Šis puslapis yra užrakintas, saugant jį nuo redagavimo.",
        "viewsourcetext": "Jūs galite peržiūrėti ir kopijuoti puslapio kodą:",
        "viewyourtext": "Jūs galite peržiūrėti ir kopijuoti <strong>savo pakeitimų</strong> kodą į šį puslapį:",
        "password-login-forbidden": "Šito naudotojo vardo ir slaptažodžio naudojimas yra uždraustas.",
        "mailmypassword": "Atkurti slaptažodį",
        "passwordremindertitle": "Laikinasis {{SITENAME}} slaptažodis",
-       "passwordremindertext": "Kažkas (tikriausiai jūs, IP adresu $1)\npaprašė, kad atsiųstumėte naują slaptažodį projektui {{SITENAME}} ($4).\nLaikinasis naudotojo „$2“ slaptažodis buvo sukurtas ir nustatytas į „$3“.\nJei tai buvo jūs, jūs turėtumėte prisijungti ir pasirinkti naują slaptažodį.\nJūsų laikinasis slaptažodis baigs galioti po {{PLURAL:$5|$5 dienos|$5 dienų|$5 dienų}}.\n\nJei kažkas kitas atliko šį prašymą arba jūs prisiminėte savo slaptažodį ir\nnebenorite jo pakeisti, galite tiesiog nekreipti dėmesio į šį laišką ir toliau\nnaudotis savo senuoju slaptažodžiu.",
+       "passwordremindertext": "Kažkas (tikriausiai jūs, iš IP adreso $1) paprašė atsiųsti naują slaptažodį paskyrai projekte {{SITENAME}} ($4).\nBuvo sukurtas laikinasis naudotojo „$2“ slaptažodis, kuris yra „$3“.\nJei to prašėte jūs, turėtumėte prisijungti ir pasirinkti naują slaptažodį.\nJūsų laikinasis slaptažodis baigs galioti po {{PLURAL:$5|$5 dienos|$5 dienų}}.\n\nJei priminti slaptažodį paprašė kažkas kitas arba jūs prisiminėte savo slaptažodį ir\nnebenorite jo pakeisti, galite tiesiog nekreipti dėmesio į šį laišką ir toliau\nnaudotis savo senuoju slaptažodžiu.",
        "noemail": "Nėra jokio el. pašto adreso įvesto naudotojui „$1“.",
        "noemailcreate": "Jūs turite nurodyti veikiantį el. pašto adresą",
        "passwordsent": "Naujas slaptažodis buvo nusiųstas į el. pašto adresą,\nužregistruotą naudotojo „$1“.\nPrašome prisijungti vėl, kai jūs jį gausite.",
        "eauthentsent": "Patvirtinimo laiškas buvo nusiųstas į paskirtąjį el. pašto adresą.\nPrieš išsiunčiant kitą laišką į jūsų dėžutę, jūs turite vykdyti nurodymus laiške, kad patvirtintumėte, kad dėžutė tikrai yra jūsų.",
        "throttled-mailpassword": "Slaptažodžio priminimas jau buvo išsiųstas, per {{PLURAL:$1|$1 paskutinę valandą|$1 paskutines valandas|$1 paskutinių valandų}}.\n\nNorint apsisaugoti nuo piktnaudžiavimo, slaptažodžio priminimas gali būti išsiųstas tik kas {{PLURAL:$1|$1 valandą|$1 valandas|$1 valandų}}.",
        "mailerror": "Klaida siunčiant laišką: $1",
-       "acct_creation_throttle_hit": "Šio projekto lankytojai, naudojantys jūsų IP adresą, sukūrė {{PLURAL:$1|$1 paskyrą|$1 paskyras|$1 paskyrų}} per paskutiniąją dieną, o tai yra didžiausias leidžiamas kiekis per šį laiko tarpą.\nTodėl šiuo metu lankytojai, naudojantys šį IP adresą, daugiau negali kurti paskyrų.",
+       "acct_creation_throttle_hit": "Šio projekto lankytojai, naudojantys jūsų IP adresą, sukūrė {{PLURAL:$1|$1 paskyrą|$1 paskyras|$1 paskyrų}} per $2, o tai yra didžiausias leidžiamas kiekis per šį laiko tarpą.\nTodėl šiuo metu lankytojai, naudojantys šį IP adresą, daugiau negali kurti paskyrų.",
        "emailauthenticated": "Jūsų el. pašto adresas buvo patvirtintas $2 d. $3.",
        "emailnotauthenticated": "Jūsų el. pašto adresas dar nėra patvirtintas. Jokie laiškai\nnebus siunčiami nei vienai žemiau išvardintai paslaugai.",
        "noemailprefs": "Nurodykite el. pašto adresą, kad šios funkcijos veiktų.",
        "pt-userlogout": "Atsijungti",
        "php-mail-error-unknown": "Nežinoma klaida PHP mail() funkcijoje",
        "user-mail-no-addy": "Bandyta išsiųsti elektroninį laišką be el. pašto adreso.",
-       "user-mail-no-body": "Mėginta siųsti tuščia ar pernelyg trumpą E-pašto žinutė.",
+       "user-mail-no-body": "Bandyta siųsti tuščią ar pernelyg trumpą el. pašto žinutę.",
        "changepassword": "Pakeisti slaptažodį",
        "resetpass_announce": "Norint užbaigti prisijungimą jums reikia nustatyti naująjį slaptažodį.",
        "resetpass_text": "<!-- Įterpkite čia tekstą -->",
        "resetpass-expired": "Jūsų slaptažodžio galiojimas baigėsi. Prašome nustatyti naują prisijungimo slaptažodį.",
        "resetpass-expired-soft": "Jūsų slaptažodžio galiojimas baigėsi ir jį reikia atkurti iš naujo. Pasirinkite naują slaptažodį dabar arba spauskite \"{{int:authprovider-resetpass-skip-label}}\", kad būtų atstatytas vėliau.",
        "resetpass-validity-soft": "Jūsų slaptažodis netinkamas: $1\n\nPasirinkite naują slaptažodį dabar arba spauskite \"{{int:authprovider-resetpass-skip-label}}\", kad būtų atkurtas vėliau.",
-       "passwordreset": "Atstatyti slaptažodį",
+       "passwordreset": "Atkurti slaptažodį",
        "passwordreset-text-one": "Užpildykite šią formą, norėdami atkurti savo slaptažodį.",
-       "passwordreset-text-many": "{{PLURAL:$1|Užpildykite vieną iš laukų slaptažodžio atkūrimui.}}",
+       "passwordreset-text-many": "{{PLURAL:$1|Užpildykite vieną iš laukelių, kad el. paštu gautumėte laikinąjį slaptažodį.}}",
        "passwordreset-disabled": "Slaptažodžių atstatymai šiame wikyje išjungti.",
        "passwordreset-emaildisabled": "El. pašto funkcijos uždraustos šiame wiki.",
        "passwordreset-username": "Naudotojo vardas:",
        "passwordreset-capture-help": "Jei jūs čia pažymėsite, tai e-mail laiškas (su laikinuoju slaptažodžiu) bus parodytas jums prieš išsiunčiant jį naudotojui.",
        "passwordreset-email": "E-pašto adresas:",
        "passwordreset-emailtitle": "Paskyros informacija apie {{sitename}}",
-       "passwordreset-emailtext-ip": "Kažkas (tikriausiai jūs, IP adresu $1) paprašė priminti jūsų slaptažodį svetainėje {{SITENAME}} ($4). Šio naudotojo {PLURAL:$3|paskyra|paskyros}} yra susietos su šiuo elektroninio pašto adresu:\n\n$2\n\n{{PLURAL:$3|Šis laikinas slaptažodis |Šie laikini slaptažodžiai}} baigs galiot po {{PLURAL:$5|vienos dienos|$5 dienų}}. \n\nJūs turėtumėte prisijungti ir pasirinkti naują slaptažodį. Jei kažkas kitas padarė šį prašymą arba jūs prisiminėte savo pirminį slaptažodį, ir jums nebereikia jo pakeisti, galite ignoruoti šį pranešimą ir toliau naudotis savo senuoju slaptažodžiu.",
+       "passwordreset-emailtext-ip": "Kažkas (tikriausiai jūs, iš IP adreso $1) paprašė priminti jūsų slaptažodį svetainėje {{SITENAME}} ($4). Šio naudotojo {{PLURAL:$3|paskyra|paskyros}} yra susietos su šiuo elektroninio pašto adresu:\n\n$2\n\n{{PLURAL:$3|Šis laikinas slaptažodis|Šie laikini slaptažodžiai}} baigs galiot po {{PLURAL:$5|vienos dienos|$5 dienų}}. \n\nJūs turėtumėte prisijungti ir pasirinkti naują slaptažodį. Jei priminti slaptažodį paprašė kažkas kitas arba jūs prisiminėte savo pirminį slaptažodį ir jums nebereikia jo pakeisti, galite ignoruoti šį pranešimą ir toliau naudotis savo senuoju slaptažodžiu.",
        "passwordreset-emailtext-user": "Naudotojas $1 svetainėje {{SITENAME}} sukūrė užklausą slaptažodžio priminimui svetainėje {{SITENAME}}\n($4). Šio naudotojo {{PLURAL:$3|paskyra|paskyros}} susieto su šiuo elektroniniu paštu $2. \n\n{{PLURAL:$3|Šis laikinas slaptažodis|Šie laikini slaptažodžiai}} baigs galioti po {{PLURAL:$5|vienos dienos|$5 dienų}}. Jūs turėtumėte prisijungti ir pasirinkti naują slaptažodį. Jei kažkas padarė tai be jūsų žinios arba jūs prisiminėte savo pirminį slaptažodį, ir jūs nebenorite jo pakeisti, galite ignoruoti šį pranešimą ir toliau naudotis savo senuoju slaptažodžiu.",
        "passwordreset-emailelement": "Naudotojo vardas: \n$1\n\nLaikinas slaptažodis: \n$2",
        "passwordreset-emailsentemail": "Jeigu šis el. pašto adresas yra susietas su jūsų paskyra, tada slaptažodžio atkūrimo laiškas bus išsiųstas.",
        "passwordreset-emailsentusername": "Jeigu buvo el. paštas susietas su šiuo naudotojo vardu, tai slaptažodžio atkūrimo el. laiškas bus išsiųstas.",
        "passwordreset-emailsent-capture2": "Slaptažodžio keitimo {{PLURAL:$1|el. laiškas buvo išsiųstas|el. laiškai buvo išsiųsti}}. {{PLURAL:$1|vartotojo vardas ir slaptažodis rodomi|vartotojų vardų ir slaptažodžių sąrašas rodomas}} čia.",
-       "passwordreset-emailerror-capture2": "El. laiško siuntimas {{GENDER:$2|vartotojui}} nepavyko: $1 {{PLURAL:$3|vartotojo vardas ir slaptažodis rodomi|vartotojų vardų ir slaptažodžių sąrašas rodomas}} čia.",
+       "passwordreset-emailerror-capture2": "El. laiško siuntimas {{GENDER:$2|naudotojui}} nepavyko: $1 {{PLURAL:$3|naudotojo vardas ir slaptažodis rodomi|naudotojų vardų ir slaptažodžių sąrašas rodomas}} čia.",
        "passwordreset-nocaller": "Skambinantysis turi būti nurodytas",
        "passwordreset-nosuchcaller": "Skambinantysis neegzistuoja: $1",
-       "passwordreset-invalideamil": "Neteisingas el. pašto adresas",
+       "passwordreset-invalidemail": "Neteisingas el. pašto adresas",
        "passwordreset-nodata": "Vartotojo vardas ir el. paštas buvo nepateikti",
        "changeemail": "Pakeisti ar pašalinti el. pašto adresą",
        "changeemail-header": "Užpildykite šią formą, kad pakeistumėte savo el. pašto adresą. Jeigu norite pašalinti bet kurio el. pašto adreso susiejimą su savo paskyra, palikite naujojo el. pašto adreso lauką tuščią, kai pateiksite formą.",
        "subject-preview": "Temos peržiūra:",
        "previewerrortext": "Įvyko klaida bandant peržiūrėti jūsų pakeitimus.",
        "blockedtitle": "Naudotojas yra užblokuotas",
-       "blockedtext": "'''Jūsų naudotojo vardas arba IP adresas yra užblokuotas.'''\n\nUžblokavo $1. Nurodyta priežastis yra ''$2''.\n\n* Blokavimo pradžia: $8\n* Blokavimo pabaiga: $6\n* Numatytas blokuojamasis: $7\n\nJūs galite susisiekti su $1 arba kuriuo nors kitu [[{{MediaWiki:Grouppage-sysop}}|administratoriumi]] ir aptarti neaiškumus dėl blokavimo.\nAtkreipkite dėmesį, kad negalėsite naudotis funkcija „Rašyti laišką šiam naudotojui“, jei nesate užsiregistravę ir pateikę realaus savo el. pašto adreso naudotojo [[Special:Preferences|nustatymuose]], arba, jei jums užblokuotas šios funkcijos naudojimas.\nJūsų IP adresas yra $3, o blokavimo ID yra #$5.\nPrašome nurodyti vieną iš jų ar abu, kai kreipiatės dėl blokavimo.",
+       "blockedtext": "'''Jūsų naudotojo vardas arba IP adresas yra užblokuotas.'''\n\nUžblokavo $1. Nurodyta priežastis yra ''$2''.\n\n* Blokavimo pradžia: $8\n* Blokavimo pabaiga: $6\n* Užblokuotasis: $7\n\nJūs galite susisiekti su $1 arba kuriuo nors kitu [[{{MediaWiki:Grouppage-sysop}}|administratoriumi]] ir aptarti neaiškumus dėl blokavimo.\nAtkreipkite dėmesį, kad negalėsite naudotis funkcija „Rašyti laišką šiam naudotojui“, jei nesate užsiregistravę ir pateikę galiojančio el. pašto adreso naudotojo paskyros [[Special:Preferences|nustatymuose]], arba, jei jums užblokuotas šios funkcijos naudojimas.\nJūsų IP adresas yra $3, o blokavimo ID yra #$5.\nPrašome nurodyti vieną iš jų ar abu, kai kreipiatės dėl blokavimo.",
        "autoblockedtext": "Jūsų IP adresas buvo automatiškai užblokuotas, nes jį naudojo kitas naudotojas, kurį užblokavo $1.\nNurodyta priežastis yra ši:\n\n:''$2''\n\n* Blokavimo pradžia: $8\n* Blokavimo pabaiga: $6\n* Numatomas blokavimo laikas: $7\n\nJūs galite susisiekti su $1 arba kitu [[{{MediaWiki:Grouppage-sysop}}|administratoriumi]], kad aptartumėte neaiškumus dėl blokavimo.\n\nJūs negalite naudotis funkcija „Rašyti laišką šiam naudotojui“, jei nesate nurodę tikro el. pašto adreso savo [[Special:Preferences|naudotojo nustatymuose]]. Taip pat Jūs negalite naudotis šia funkcija, jei Jums užblokuotas jos naudojimas.\n\nJūsų IP adresas yra $3, blokavimo ID yra $5.\nPrašome nurodyti šiuos duomenis visais atvejais, kai kreipiatės dėl blokavimo.",
        "blockednoreason": "priežastis nenurodyta",
        "whitelistedittext": "Jūs turite $1, kad redaguotumėte puslapius.",
        "newarticletext": "Jūs patekote į dar neegzistuojantį puslapį.\nNorėdami sukurti puslapį, pradėkite rašyti žemiau esančiame įvedimo lauke\n(plačiau [$1 pagalbos puslapyje]).\nJei patekote čia per klaidą, paprasčiausiai spustelkite  naršyklės mygtuką '''atgal'''.",
        "anontalkpagetext": "----''Tai yra anoniminio naudotojo, nesusikūrusio arba nenaudojančio paskyros, aptarimų puslapis.\nDėl to naudojamas IP adresas jo identifikavimui.\nŠis IP adresas gali būti dalinamas keliems naudotojams.\nJeigu Jūs esate anoniminis naudotojas ir atrodo, kad komentarai nėra skirti Jums, [[Special:CreateAccount|sukurkite paskyrą]] arba [[Special:UserLogin|prisijunkite]], ir nebūsite tapatinamas su kitais anoniminiais naudotojais.''",
        "noarticletext": "Šiuo metu šiame puslapyje nėra jokio teksto.\nJūs galite [[Special:Search/{{PAGENAME}}|ieškoti šio puslapio pavadinimo]] kituose puslapiuose,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ieškoti susijusių įrašų] arba [{{fullurl:{{FULLPAGENAME}}|action=edit}} sukurti šį puslapį]</span>.",
-       "noarticletext-nopermission": "Šiuo metu šiame puslapyje nėra jokio teksto.\nJūs galite [[Special:Search/{{PAGENAME}}|ieškoti šio puslapio pavadinimo]] kituose puslapiuose,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ieškoti susijusių įrašų]</span>, bet jūs neturite teisės sukurti šį puslapį.",
+       "noarticletext-nopermission": "Šiuo metu šiame puslapyje nėra jokio teksto.\nJūs galite [[Special:Search/{{PAGENAME}}|ieškoti šio puslapio pavadinimo]] kituose puslapiuose,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ieškoti susijusių įrašų]</span>, tačiau jūs neturite teisės sukurti šio puslapio.",
        "missing-revision": "Puslapio peržiūra #$1 pavadinto „{{FULLPAGENAME}}“ neegzistuoja.\n\nTai paprastai atsitinka kai pasenusi nuoroda veda į puslapį, kuris buvo ištrintas.\nInformaciją galima rasti [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log].",
        "userpage-userdoesnotexist": "Naudotojo paskyra „<nowiki>$1</nowiki>“ yra neužregistruota. Prašom patikrinti, ar jūs norite kurti/redaguoti šį puslapį.",
        "userpage-userdoesnotexist-view": "Naudotojo paskyra „$1“ neužregistruota.",
        "suppressionlog": "Trynimo sąrašas",
        "suppressionlogtext": "Žemiau yra trynimų ir blokavimų sąrašas, įtraukiant turinį, paslėptą nuo administratorių.\nŽiūrėkite [[Special:BlockList|blokavimų sąrašą]], kad rastumėte dabar veikiančius draudimus ir blokavimus.",
        "mergehistory": "Sujungti puslapių istorijas",
-       "mergehistory-header": "Šis puslapis leidžia jus prijungti vieno pirminio puslapio istorijos versijas į naujesnį puslapį. Įsitikinkite, kad šis pakeitimas palaikys istorinį puslapio tęstinumą.\n\n'''Turi likti bent dabartinė pirminio puslapio versija.'''",
+       "mergehistory-header": "Šis puslapis leidžia jums prijungti vieno pirminio puslapio istorijos versijas į naujesnį puslapį. Įsitikinkite, kad šis pakeitimas palaikys istorinį puslapio tęstinumą.\n\n'''Turi likti bent dabartinė pirminio puslapio versija.'''",
        "mergehistory-box": "Sujungti dviejų puslapių versijas:",
        "mergehistory-from": "Pirminis puslapis:",
        "mergehistory-into": "Paskirties puslapis:",
        "searchprofile-advanced-tooltip": "Ieškoti skirtingose vardų srityse",
        "search-result-size": "$1 ({{PLURAL:$2|1 žodis|$2 žodžiai|$2 žodžių}})",
        "search-result-category-size": "{{PLURAL:$1|1 narys|$1 narių}} ({{PLURAL:$2|1 subkategorijoje|$2 subkategorijų}}, {{PLURAL:$3|1 failas|$3 failų}})",
-       "search-redirect": "(peradresavimas $1)",
+       "search-redirect": "(peradresavimas iš $1)",
        "search-section": "(skyrius $1)",
        "search-category": "(kategorija $1)",
        "search-file-match": "(atitinka rinkmenos turinį)",
        "prefs-user-pages": "Naudotojo puslapiai",
        "prefs-personal": "Naudotojo profilis",
        "prefs-rc": "Naujausi keitimai",
-       "prefs-watchlist": "Stebimų sąrašas",
+       "prefs-watchlist": "Stebimų sąrašas",
        "prefs-editwatchlist": "Redaguoti stebimųjų sąrašą",
-       "prefs-editwatchlist-label": "Redaguoti įrašus savo stebėjimo sąraše:",
-       "prefs-editwatchlist-edit": "Peržiūrėti ir pašalinti pavadinmus savo stebėjimo sąraše",
+       "prefs-editwatchlist-label": "Redaguoti įrašus stebėjimųjų sąraše:",
+       "prefs-editwatchlist-edit": "Peržiūrėti ir pašalinti puslapius iš stebimųjų sąrašo",
        "prefs-editwatchlist-raw": "Redaguoti grynąjį stebimųjų sąrašą",
        "prefs-editwatchlist-clear": "Išvalyti stebimųjų sąrašą",
        "prefs-watchlist-days": "Dienos rodomos stebimųjų sąraše:",
        "timezoneregion-europe": "Europa",
        "timezoneregion-indian": "Indijos vandenynas",
        "timezoneregion-pacific": "Ramusis vandenynas",
-       "allowemail": "Leisti siųsti el. laiškus iš kitų naudotojų",
+       "allowemail": "Leisti kitiems naudotojams siųsti man el. laiškus",
        "prefs-searchoptions": "Paieška",
        "prefs-namespaces": "Vardų sritys",
        "default": "pagal nutylėjimą",
        "email": "El. paštas",
        "prefs-help-realname": "Tikrasis vardas yra neprivalomas.\nJei jūs jį įvesite, jis bus naudojamas pažymėti jūsų darbą.",
        "prefs-help-email": "E-pašto adresas yra neprivalomas, tačiau reikalingas slaptažodį naujo, turi tu pamiršai savo slaptažodį.",
-       "prefs-help-email-others": "Taip pat galite pasirinkti, kad žmonės galėtų susisiekti su jumis per jūsų naudotojo ar naudotojo aptarimo puslapį neatskleidžiant jūsų tapatybės.",
+       "prefs-help-email-others": "Taip pat galite pasirinkti, kad žmonės galėtų susisiekti su jumis el. paštu per jūsų naudotojo ar naudotojo aptarimo puslapyje esančią nuorodą. Jūsų el. pašto adresas, kitam naudotojui su jumis susisiekus, nėra atskleidžiamas.",
        "prefs-help-email-required": "El. pašto adresas yra būtinas.",
        "prefs-info": "Pagrindinė informacija",
        "prefs-i18n": "Kalbos nustatymai",
        "right-edituserjs": "Redaguoti kitų naudotojų JS failus",
        "right-editmyusercss": "Redaguoti savo vartotojo CSS failus",
        "right-editmyuserjs": "Redaguokite savo naudotojo vartotojo JavaScript failus",
-       "right-viewmywatchlist": "Peržiūrėti savo stebimų sąrašą",
+       "right-viewmywatchlist": "Peržiūrėti savo stebimų sąrašą",
        "right-editmywatchlist": "Keiskite savo stebimųjų sąrašą. Atminkite, kad kai kurie veiksmai vis vien pridės puslapius netgi be tokios teisės.",
        "right-viewmyprivateinfo": "Peržiūrėti asmeninius duomenis (pvz., elektroninis paštas, tikras vardas)",
        "right-editmyprivateinfo": "Keisti asmeninius duomenis (pvz., elektroninis paštas, tikras vardas)",
        "grant-generic": "\"$1\" teisių rinkinys",
        "grant-group-page-interaction": "Sąveikauti su puslapiais",
        "grant-group-file-interaction": "Sąveikauti su medija",
-       "grant-group-watchlist-interaction": "Sąveikauti su savo stebimu sąrašu",
+       "grant-group-watchlist-interaction": "Sąveikauti su savo stebimųjų sąrašu",
        "grant-group-email": "Siųsti el. laišką",
        "grant-group-high-volume": "Atlikti didelės apimties veiklą",
        "grant-group-customization": "Pritaikymas ir parinktys",
        "grant-group-administration": "Atlikti administravimo veiksmų",
+       "grant-group-private-information": "Prieiti prie privačių duomenų apie jus",
        "grant-group-other": "Įvairios veiklos",
        "grant-blockusers": "Užblokuoti ir atblokuoti naudotojus",
        "grant-createaccount": "Kurti paskyras",
        "grant-highvolume": "Didelės apimties redagavimas",
        "grant-oversight": "Paslėpti naudotojus ir numalšinti versijas",
        "grant-patrol": "Patrulių pakeitimai puslapiuose",
+       "grant-privateinfo": "Prieiti prie privačių duomenų",
        "grant-protect": "Apsaugoti ir neapsaugoti puslapiai",
        "grant-rollback": "Atšaukti pakeitimus puslapiuose",
        "grant-sendemail": "Siųsti el. laišką kitiems naudotojams",
        "grant-basic": "Pagrindinės teisės",
        "grant-viewdeleted": "Peržiūrėti ištrintus failus ir puslapius",
        "grant-viewmywatchlist": "Peržiūrėti savo stebėjimų sąrašą",
+       "grant-viewrestrictedlogs": "Žiūrėti apribotus žurnalo įrašus",
        "newuserlogpage": "Prisiregistravę naudotojai",
        "newuserlogpagetext": "Tai naudotojų kūrimo sąrašas.",
        "rightslog": "Naudotojų teisių pakeitimai",
        "enhancedrc-history": "istorija",
        "recentchanges": "Naujausi keitimai",
        "recentchanges-legend": "Naujausių keitimų parinktys",
-       "recentchanges-summary": "Å iame puslapyje yra patys naujausi pakeitimai Å¡iame projekte.",
+       "recentchanges-summary": "Žemiau pateikiamas naujausių Å¡io projekto pakeitimų sÄ\85raÅ¡as.",
        "recentchanges-noresult": "Per nurodytą laiką atliktų keitimų, atitinkančių nurodytas sąlygas, nėra.",
        "recentchanges-feed-description": "Sekite pačius naujausius projekto keitimus šiame šaltinyje.",
        "recentchanges-label-newpage": "Šiuo keitimu sukurtas naujas puslapis",
        "upload-foreign-cant-upload": "Šis vikis nėra sukonfigūruotas failų įkėlimui į nurodytą išorinę failų talpyklą.",
        "upload-dialog-title": "Įkelti failą",
        "upload-dialog-button-cancel": "Atšaukti",
+       "upload-dialog-button-back": "Atgal",
        "upload-dialog-button-done": "Atlikta",
        "upload-dialog-button-save": "Išsaugoti",
        "upload-dialog-button-upload": "Įkelti",
        "listfiles-delete": "trinti",
        "listfiles-summary": "Šiame specialiame puslapyje rodomos visos įkeltos rinkmenos.",
        "listfiles_search_for": "Ieškoti failo pavadinimo:",
-       "listfiles-userdoesnotexist": "Vartotojo paskyrą „$1“ nėra registruota.",
+       "listfiles-userdoesnotexist": "Naudotojo paskyra „$1“ nėra užregistruota.",
        "imgfile": "rinkmena",
        "listfiles": "Failų sąrašas",
        "listfiles_thumb": "Miniatiūra",
        "statistics-users-active-desc": "Naudotojai, kurie per {{PLURAL:$1|paskutinę dieną|paskutines $1 dienų}} padarė keitimų",
        "pageswithprop": "Puslapiai su puslapio atributais",
        "pageswithprop-legend": "Puslapiai su puslapio atributais",
-       "pageswithprop-text": "Šiame puslapyje pateikiami puslapiai, kurie ypač naudoja puslapio atributus.",
-       "pageswithprop-prop": "Ypatybės pavadinimas:",
+       "pageswithprop-text": "Šiame puslapyje pateikiami puslapiai, turintys atitinkamą puslapio atributą.",
+       "pageswithprop-prop": "Atributo pavadinimas:",
        "pageswithprop-submit": "Eiti",
        "pageswithprop-prophidden-long": "ilgo teksto turto vertė paslėpta ($1)",
        "pageswithprop-prophidden-binary": "dvejetainė turto vertė paslėpta ($1)",
        "uncategorizedtemplates": "Šablonai, nepriskirti jokiai kategorijai",
        "unusedcategories": "Nenaudojamos kategorijos",
        "unusedimages": "Nenaudojami failai",
-       "wantedcategories": "Geidžiamiausios kategorijos",
-       "wantedpages": "Geidžiamiausi puslapiai",
+       "wantedcategories": "Reikiamiausios kategorijos",
+       "wantedpages": "Reikiamiausi puslapiai",
        "wantedpages-summary": "Sąrašas neegzistuojančių puslapių su daugiausią nuorodų į juos, išskyrus puslapius, kurie turi tik nukreipimus į juos. Jei norite pamatyti sąrašą neegzistuojančių puslapių, su nukreipimais į juos, žiūrėkite [[{{#special:BrokenRedirects}}|neveikiančių nuorodų sąrašą]].",
        "wantedpages-badtitle": "Neleistinas pavadinimas rezultatų rinkinyje: $1",
-       "wantedfiles": "Trokštami failai",
-       "wantedfiletext-cat": "Sekantys failai yra naudojami, bet neegzistuoja. Čia failai iš išorinių saugyklų gali būti išvardinti, nors jie jose ir egzistuoja. Failai netenkinantys šių sąlygų gali būti <del>perbraukti</del>. Papildomai peržiūrėkite [[:$1|puslapius]], kuriuose yra naudojami čia išvardinti neegzistuojantys failai.",
+       "wantedfiles": "Reikiamiausi failai",
+       "wantedfiletext-cat": "Šiame puslapyje pateikiami failai, kurie yra naudojami, bet neegzistuoja. Čia gali būti išvardinti failai iš išorinių saugyklų, nors jie jose ir egzistuoja. Tokiu atveju failų pavadinimai yra <del>perbraukti</del>. Be to, puslapiai, kuriuose esama neegzistuojančių failų, yra išvardinti [[:$1|čia]].",
        "wantedfiletext-cat-noforeign": "Šie failai yra naudojami, bet neegzistuoja. Be to, puslapiai su šiais failais, kurie neegzistuoja yra išvardinti [[:$1]].",
-       "wantedfiletext-nocat": "Sekantys failai yra naudojami, bet neegzistuoja. Čia failai iš išorinių saugyklų gali būti išvardinti, nors jie jose ir egzistuoja. Failai netenkinantys šių sąlygų gali būti <del>perbraukti</del>.",
+       "wantedfiletext-nocat": "Šiame puslapyje pateikiami failai, kurie yra naudojami, bet neegzistuoja. Čia gali būti išvardinti failai iš išorinių saugyklų, nors jie jose ir egzistuoja. Tokiu atveju failų pavadinimai yra <del>perbraukti</del>.",
        "wantedfiletext-nocat-noforeign": "Šios rinkmenos yra naudojamos, tačiau nesti.",
-       "wantedtemplates": "Trokštami šablonai",
+       "wantedtemplates": "Reikiamiausi šablonai",
        "mostlinked": "Daugiausiai nurodomi puslapiai",
        "mostlinkedcategories": "Daugiausiai nurodomos kategorijos",
        "mostlinkedtemplates": "Daugiausiai nurodomi šablonai",
        "apisandbox-submit": "Pateikti prašymą",
        "apisandbox-reset": "Išvalyti",
        "apisandbox-retry": "Bandykite dar kartą",
+       "apisandbox-loading": "API modulio „$1“ informacija įkeliama...",
+       "apisandbox-load-error": "Įvyko klaida įkeliant API modulio „$1“ informaciją: $2",
        "apisandbox-no-parameters": "Šis API modulis neturi parametrų.",
        "apisandbox-helpurls": "Pagalbinės nuorodos",
        "apisandbox-examples": "Pavyzdžiai",
        "apisandbox-results-fixtoken-fail": "Nepavyko gauti „$1“ žetono.",
        "apisandbox-alert-page": "Laukai šiame puslapyje yra negalimi.",
        "apisandbox-alert-field": "Šio lauko reikšmė yra neteisinga.",
+       "apisandbox-continue": "Tęsti",
+       "apisandbox-continue-clear": "Išvalyti",
        "booksources": "Knygų šaltiniai",
        "booksources-search-legend": "Knygų šaltinių paieška",
        "booksources-search": "Ieškoti",
        "booksources-text": "Žemiau yra nuorodų sąrašas į kitas svetaines, kurios parduoda naujas ar naudotas knygas, bei galbūt turinčias daugiau informacijos apie knygas, kurių ieškote:",
        "booksources-invalid-isbn": "Duotas ISBN atrodo neteisingas; patikrinkite, ar nepadarėte kopijavimo klaidų.",
+       "magiclink-tracking-rfc": "Puslapiai, naudojantys RFC magiškas nuorodas",
+       "magiclink-tracking-rfc-desc": "Šis puslapis naudoja RFC magiškas nuorodas. Informacija apie perkėlimą [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
+       "magiclink-tracking-pmid": "Puslapiai, naudojantys PMID magiškas nuorodas",
+       "magiclink-tracking-pmid-desc": "Šis puslapis naudoja PMID magiškas nuorodas. Informacija apie perkėlimą [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
+       "magiclink-tracking-isbn": "Puslapiai, naudojantys ISBN magiškas nuorodas",
+       "magiclink-tracking-isbn-desc": "Šis puslapis naudoja ISBN magiškas nuorodas. Informacija apie perkėlimą [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
        "specialloguserlabel": "Naudotojas:",
        "speciallogtitlelabel": "Tikslas (pavadinimas arba {{ns:user}}:naudotojo vardas naudotojui):",
        "log": "Specialiųjų veiksmų sąrašas",
        "activeusers-intro": "Tai naudotojų sąrašas, kurie ką nors padarė per $1 {{PLURAL:$1|paskutinę dieną|paskutines dienas|paskutinių dienų}}.",
        "activeusers-count": "$1 {{PLURAL:$1|keitimas|keitimai|keitimų}} per {{PLURAL:$3|paskutinę dieną|$3 paskutines dienas|$3 paskutinių dienų}}",
        "activeusers-from": "Rodyti naudotojus, pradedant:",
-       "activeusers-hidebots": "Slėpti robotus",
-       "activeusers-hidesysops": "Slėpti administratorius",
+       "activeusers-groups": "Rodyti vartotojus, priklausančius grupėms:",
        "activeusers-noresult": "Nerasta jokių naudotojų.",
        "activeusers-submit": "Rodyti aktyvius vartotojus",
        "listgrouprights": "Naudotojų grupių teisės",
        "mailnologin": "Nėra adreso",
        "mailnologintext": "Jums reikia būti [[Special:UserLogin|prisijungusiam]] ir turi būti įvestas teisingas el. pašto adresas jūsų [[Special:Preferences|nustatymuose]], kad siųstumėte el. laiškus kitiems nautotojams.",
        "emailuser": "Rašyti laišką šiam naudotojui",
-       "emailuser-title-target": "Siųsti E-pašto žinutę {{GENDER:$1|user}}",
+       "emailuser-title-target": "Siųsti el. pašto žinutę {{GENDER:$1|naudotojui|naudotojai}}",
        "emailuser-title-notarget": "El. pašto vartotojas",
-       "emailpagetext": "Jūs galite pasinaudoti šiuo pavyzdžiu, norėdami nusiųsti elektroninį laišką šiam naudotojui.\nElektroninio pašto adresas, kurį įvedėte [[Special:Preferences|savo naudotojo nustatymuose]], bus rodomas kaip el. pašto siuntėjo adresas, tam, kad gavėjas galėtų jums iškart atsakyti.",
+       "emailpagetext": "Jūs galite pasinaudoti šiuo pavyzdžiu, norėdami nusiųsti elektroninį laišką {{GENDER:$1|šiam naudotojui|šiai naudotojai}}.\nElektroninio pašto adresas, kurį įvedėte [[Special:Preferences|savo naudotojo nustatymuose]], bus rodomas kaip el. pašto siuntėjo adresas tam, kad gavėjas galėtų tiesiogiai jums atsakyti.",
        "defemailsubject": "{{SITENAME}} el. pašto iš vartotojo \" $1 \"",
        "usermaildisabled": "Naudotojo elektroninis paštas išjungtas",
        "usermaildisabledtext": "Jūs negalite siūlsti el. laiško kitiems šio wiki projekto naudotojams.",
        "emailuserfooter": "Šis el. laiškas buvo išsiųstas naudotojo $1 naudotojui $2 naudojant „{{int:emailuser}}“ funkciją {{SITENAME}}.",
        "usermessage-summary": "Paliekamas sistemos pranešimas.",
        "usermessage-editor": "Sistemos pranešėjas",
-       "watchlist": "Stebimų sąrašas",
-       "mywatchlist": "Stebimų sąrašas",
-       "watchlistfor2": "Naudotojo $1 $2",
+       "watchlist": "Stebimų sąrašas",
+       "mywatchlist": "Stebimų sąrašas",
+       "watchlistfor2": "Naudotojas: $1 $2",
        "nowatchlist": "Neturite nei vieno stebimo puslapio.",
        "watchlistanontext": "Prašome prisijungti, kad peržiūrėtumėte ar pakeistumėte elementus savo stebimųjų sąraše.",
        "watchnologin": "Neprisijungęs",
        "addwatch": "Pridėti į stebimųjų sąrašą",
        "addedwatchtext": "\"[[:$1]]\" ir jo aptarimo puslapis buvo įtraukti į Jūsų [[Special:Watchlist|stebėjimo sąrašą]].",
+       "addedwatchtext-talk": "\"[[:$1]]\" ir su juo susijęs puslapis buvo įtraukti į Jūsų [[Special:Watchlist|stebimųjų sąrašą]].",
        "addedwatchtext-short": "Puslapis „$1“ pridėtas į jūsų stebimųjų sąrašą.",
        "removewatch": "Pašalinti iš stebimųjų sąrašo",
        "removedwatchtext": "\"[[:$1]]\" ir jo aptarimo puslapis buvo pašalinti iš Jūsų [[Special:Watchlist|stebėjimo sąrašo]].",
+       "removedwatchtext-talk": "\"[[:$1]]\" ir su juo susijęs puslapis buvo pašalinti iš Jūsų [[Special:Watchlist|stebimųjų sąrašo]].",
        "removedwatchtext-short": "Puslapis „$1“ pašalintas iš jūsų stebimųjų sąrašo.",
        "watch": "Stebėti",
        "watchthispage": "Stebėti šį puslapį",
        "unwatchthispage": "Nustoti stebėti",
        "notanarticle": "Ne turinio puslapis",
        "notvisiblerev": "Versija buvo ištrinta",
-       "watchlist-details": "Stebima {{PLURAL:$1|$1 puslapis|$1 puslapiai|$1 puslapių}} neskaičiuojant aptarimų puslapių.",
+       "watchlist-details": "Stebima {{PLURAL:$1|$1 puslapis|$1 puslapiai|$1 puslapių}}, neskaičiuojant aptarimų puslapių.",
        "wlheader-enotif": "El. pašto pranešimai yra įjungti.",
        "wlheader-showupdated": "Puslapiai pakeisti nuo tada, kai paskutinį kartą apsilankėte juose, yra pažymėti '''pastorintai'''",
        "wlnote": "{{PLURAL:$1|Rodomas '''$1''' paskutinis pakeitimas, atliktas|Rodomi '''$1''' paskutiniai pakeitimai, atlikti|Rodoma '''$1''' paskutinių pakeitimų, atliktų}} per '''$2''' {{PLURAL:$2|paskutinę valandą|paskutines valandas|paskutinių valandų}}, nuo $3 $4.",
        "enotif_lastvisited": "Užeikite į $1, jei norite matyti pakeitimus nuo paskutiniojo apsilankymo.",
        "enotif_lastdiff": "Užeikite į $1, jei norite pamatyti šį pakeitimą.",
        "enotif_anon_editor": "anoniminis naudotojas $1",
-       "enotif_body": "$WATCHINGUSERNAME,\n\n\n$PAGEEDITDATE {{SITENAME}} projekte $PAGEEDITOR $CHANGEDORCREATED puslapį „$PAGETITLE“, dabartinę versiją rasite adresu $PAGETITLE_URL.\n\n$NEWPAGE\n\nRedaguotojo komentaras: $PAGESUMMARY $PAGEMINOREDIT\n\nSusisiekti su redaguotoju:\nel. paštu: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nDaugiau pranešimų apie vėlesnius pakeitimus nebus siunčiama, jei neapsilankysite puslapyje.\nJūs taip pat galite išjungti pranešimo žymę visiems jūsų stebimiems puslapiams savo stebimųjų sąraše.\n\n Jūsų draugiškoji projekto {{SITENAME}} pranešimų sistema\n\n--\nNorėdami pakeisti e-paštu siunčiamų pranešimų nustatymus, užeikite į\n{{canonicalurl:{{#special:Preferences}}}}\n\nNorėdami pakeisti stebimų puslapių nustatymus, užeikite į\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nNorėdami puslapį iš stebimų puslapių sąrašo, užeikite į\n$UNWATCHURL\n\nAtsiliepimai ir pagalba:\n$HELPPAGE",
+       "enotif_body": "$WATCHINGUSERNAME,\n\n\n$PAGEEDITDATE {{SITENAME}} projekte $PAGEEDITOR $CHANGEDORCREATED puslapį „$PAGETITLE“, dabartinę versiją rasite adresu $PAGETITLE_URL.\n\n$NEWPAGE\n\nRedaguotojo komentaras: $PAGESUMMARY $PAGEMINOREDIT\n\nSusisiekti su redaguotoju:\nel. paštu: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nDaugiau pranešimų apie vėlesnius pakeitimus nebus siunčiama, jei neapsilankysite puslapyje.\nJūs taip pat galite išjungti pranešimo žymę visiems jūsų stebimiems puslapiams savo stebimųjų sąraše.\n\n Jūsų draugiškoji projekto {{SITENAME}} pranešimų sistema\n\n--\nNorėdami pakeisti e-paštu siunčiamų pranešimų nustatymus, užeikite į\n{{canonicalurl:{{#special:Preferences}}}}\n\nNorėdami pakeisti stebimųjų puslapių nustatymus, užeikite į\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nNorėdami puslapį iš stebimųjų puslapių sąrašo, užeikite į\n$UNWATCHURL\n\nAtsiliepimai ir pagalba:\n$HELPPAGE",
        "created": "sukurė",
        "changed": "pakeitė",
        "deletepage": "Trinti puslapį",
        "delete-toobig": "Šis puslapis turi ilgą keitimų istoriją, daugiau nei $1 {{PLURAL:$1|revizija|revizijos|revizijų}}. Tokių puslapių trynimas yra apribotas, kad būtų išvengta atsitiktinio {{SITENAME}} žlugdymo.",
        "delete-warning-toobig": "Šis puslapis turi ilgą keitimų istoriją, daugiau nei $1 {{PLURAL:$1|revizija|revizijos|revizijų}}. Trinant jis gali sutrikdyti {{SITENAME}} duomenų bazės operacijas; būkite atsargūs.",
        "deleteprotected": "Jūs šio puslapio ištrinti negalite, nes jis apsaugotas.",
-       "deleting-backlinks-warning": "'''Dėmesio:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Kiti puslapiai]] nurodo ar įtraukia puslapį, kurį ruošiatės trinti.",
+       "deleting-backlinks-warning": "<strong>Dėmesio:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Kiti puslapiai]] nurodo ar įtraukia puslapį, kurį ruošiatės trinti.",
        "rollback": "Atmesti keitimus",
        "rollbacklink": "atmesti",
        "rollbacklinkcount": "atmesti $1 {{PLURAL:$1|keitimą|keitimus}}",
        "rollbacklinkcount-morethan": "atmesti daugiau nei $1 {{PLURAL:$1|keitimą|keitimų}}",
        "rollbackfailed": "Atmetimas nepavyko",
+       "rollback-missingrevision": "Nepavyko įkelti versijos duomenų.",
        "cantrollback": "Negalima atmesti redagavimo; paskutinis keitęs naudotojas yra šio puslapio autorius.",
        "alreadyrolled": "Nepavyko atmesti paskutinio [[User:$2|$2]] ([[User talk:$2|Aptarimas]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) daryto puslapio [[:$1]] keitimo;\nkažkas jau pakeitė puslapį arba suspėjo pirmas atmesti keitimą.\n\nPaskutimas keitimas darytas naudotojo [[User:$3|$3]] ([[User talk:$3|Aptarimas]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Pateiktas toks keitimo paaiškinimas: <em>$1</em>.",
        "revertpage": "Atmestas [[Special:Contributions/$2|$2]] ([[User talk:$2|Aptarimas]]) pakeitimas; sugrąžinta [[User:$1|$1]] versija",
        "revertpage-nouser": "Atversti pakeitimai paslėpto vartotojo, grąžino prieš tai buvusią versiją {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Atmesti $1 pakeitimai;\ngrąžinta prieš tai buvusi $2 versija.",
+       "rollback-success-notify": "Atmesti $1 pakeitimai;\ngrąžinta prieš tai buvusi $2 versija. [$3 Rodyti skirtumus]",
        "sessionfailure-title": "Sesijos klaida",
        "sessionfailure": "Atrodo yra problemų su jūsų prisijungimo sesija; šis veiksmas buvo atšauktas kaip atsargumo priemonė prieš sesijos vogimą.\nPrašome paspausti „atgal“ ir perkraukite puslapį iš kurio atėjote, ir pamėginkite vėl.",
        "changecontentmodel": "Keisti puslapio turinio modelį",
        "changecontentmodel-cannot-convert": "Turinys [[:$1]] negali būti konvertuotas į $2 tipą.",
        "changecontentmodel-nodirectediting": "$1 turinio modelis nepalaiko tiesioginio redagavimo",
        "changecontentmodel-emptymodels-title": "Nėra prieinamų turinio modelių",
+       "changecontentmodel-emptymodels-text": "[[:$1]] turinys negali būti konvertuotas į jokį tipą.",
        "log-name-contentmodel": "Turinio modelio kaitos istorija",
        "log-description-contentmodel": "Įvykiai susiję su puslapio turinio modeliu",
+       "logentry-contentmodel-new": "$1 {{GENDER:$2|sukūrė}} puslapį $3, naudodamas nestandartinį turinio modelį \"$5\"",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|atnaujino}} puslapio $3 turinio modelį iš $4 į $5",
        "logentry-contentmodel-change-revertlink": "atšaukti",
        "logentry-contentmodel-change-revert": "atšaukti",
        "protectlogtext": "Žemiau yra puslapių užrakinimų bei atrakinimų sąrašas.\nDabar veikiančių puslapių apsaugų sąrašą rasite [[Special:ProtectedPages|apsaugotų puslapių sąraše]].",
        "protectedarticle": "užrakino „[[$1]]“",
        "modifiedarticleprotection": "pakeistas „[[$1]]“ apsaugos lygis",
-       "unprotectedarticle": "pašalino apsaugą nuo „[[$1]]“",
+       "unprotectedarticle": "atrakino „[[$1]]“",
        "movedarticleprotection": "perkelti apsaugos nustatymai iš „[[$2]]“ į „[[$1]]“",
+       "protectedarticle-comment": "{{GENDER:$2|Apsaugojo}} „[[$1]]“",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Pakeitė „[[$1]]“ apsaugos lygį}}",
+       "unprotectedarticle-comment": "{{GENDER:$2|Pašalino apsaugą}} iš „[[$1]]“",
        "protect-title": "Nustatomas apsaugos lygis puslapiui „$1“",
        "protect-title-notallowed": "Peržiūrėti \"$1\" apsaugos lygį",
        "prot_1movedto2": "[[$1]] pervadintas į [[$2]]",
        "undeletehistorynoadmin": "Šis puslapis buvo ištrintas. Žemiau rodoma trynimo priežastis bei kas redagavo puslapį iki ištrynimo. Ištrintų puslapių tekstas yra galimas tik administratoriams.",
        "undelete-revision": "Ištrinta $1 versija, kurią $4 d. $5 sukūrė $3:",
        "undeleterevision-missing": "Neteisinga arba dingusi versija. Jūs turbūt turite blogą nuorodą, arba versija buvo atkurta arba pašalinta iš archyvo.",
+       "undeleterevision-duplicate-revid": "{{PLURAL:$1|Viena versija|$1 versijos}} negalėjo būti atkurtos, nes {{PLURAL:$1|jos|jų}} <code>rev_id</code> jau buvo naudojamas.",
        "undelete-nodiff": "Nerasta jokių ankstesnių versijų.",
        "undeletebtn": "Atkurti",
        "undeletelink": "žiūrėti/atkurti",
        "contributions-title": "{{GENDER:$1|Naudotojo|Naudotojos}} $1 indėlis",
        "mycontris": "Indėlis",
        "anoncontribs": "Indėlis",
-       "contribsub2": "Dėl {{GENDER:$3|$1}} ($2)",
+       "contribsub2": "Naudotojas: {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Naudotojo paskyra „$1“ neužregistruota.",
        "nocontribs": "Jokie keitimai neatitiko šių kriterijų.",
        "uctop": "(dabartinis)",
        "sp-contributions-newbies": "Rodyti tik naujų paskyrų keitimus",
        "sp-contributions-newbies-sub": "Neseniai prisiregistravusieji",
        "sp-contributions-newbies-title": "Naujai užsiregistravusių naudotojų indėlis",
-       "sp-contributions-blocklog": "Blokavimų sąrašas",
-       "sp-contributions-suppresslog": "ištrintas naudotojo indėlis",
-       "sp-contributions-deleted": "ištrintas naudotojo indėlis",
+       "sp-contributions-blocklog": "blokavimų sąrašas",
+       "sp-contributions-suppresslog": "ištrintas {{GENDER:$1|naudotojo|naudotojos}} indėlis",
+       "sp-contributions-deleted": "ištrintas {{GENDER:$1|naudotojo|naudotojos}} indėlis",
        "sp-contributions-uploads": "įkėlimai",
-       "sp-contributions-logs": "Specialiųjų veiksmų sąrašas",
+       "sp-contributions-logs": "specialiųjų veiksmų sąrašas",
        "sp-contributions-talk": "Aptarimas",
        "sp-contributions-userrights": "naudotojų teisių valdymas",
        "sp-contributions-blocked-notice": "Šis naudotojas šiuo metu užblokuotas.\nPateikiamas paskutinis blokavimo istorijos įrašas.",
        "sp-contributions-blocked-notice-anon": "Šis IP adresas yra užblokuotas.\nPaskutinis blokavimo įrašas pateikiamas žemiau:",
-       "sp-contributions-search": "Ieškoti įnašo",
+       "sp-contributions-search": "Ieškoti indėlio",
        "sp-contributions-username": "IP adresas arba naudotojo vardas:",
        "sp-contributions-toponly": "Rodyti tik paskutinius keitimus",
        "sp-contributions-newonly": "Rodyti tik tuos keitimus, kuriais sukurti nauji straipsniai",
-       "sp-contributions-hideminor": "Slėpti nedidelius pakeitimus",
+       "sp-contributions-hideminor": "Slėpti smulkius pakeitimus",
        "sp-contributions-submit": "Ieškoti",
        "whatlinkshere": "Susiję puslapiai",
        "whatlinkshere-title": "Puslapiai, kurie nurodo į „$1“",
        "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",
+       "ipb-blocklist-duration-left": "liko $1",
        "unblockip": "Atblokuoti naudotoją",
        "unblockiptext": "Naudokite šią formą, kad atkurtumėte redagavimo galimybę\nankščiau užblokuotam IP adresui ar naudotojui.",
        "ipusubmit": "Atblokuoti šį adresą",
        "movenosubpage": "Šis puslapis neturi subpuslapių.",
        "movereason": "Priežastis:",
        "revertmove": "atmesti",
-       "delete_and_move_text": "==Reikia ištrinti==\n\nPaskirties puslapis „[[:$1]]“ jau yra. Ar norite jį ištrinti, kad galėtumėte pervardinti?",
+       "delete_and_move_text": "Paskirties puslapis „[[:$1]]“ jau yra. Ar norite jį ištrinti, kad galėtumėte pervardinti?",
        "delete_and_move_confirm": "Taip, trinti puslapį",
        "delete_and_move_reason": "Ištrinta dėl perkėlimo iš \"[[$1]]\"",
        "selfmove": "Šaltinio ir paskirties pavadinimai yra tokie patys; negalima pervardinti puslapio į save.",
        "move-leave-redirect": "Pervadinant palikti nukreipimą",
        "protectedpagemovewarning": "'''Dėmesio:''' Šis puslapis buvo užrakintas, kad tik naudotojai su administratoriaus teisėmis galėtų jį pervadinti.\nNaujausias įrašas žurnale yra pateiktas žemiau:",
        "semiprotectedpagemovewarning": "'''Pastaba''': Šis puslapis buvo užrakintas, kad tik registruoti naudotojai galėtų jį redaguoti.\nNaujausias įrašas žurnale yra pateiktas žemiau:",
-       "move-over-sharedrepo": "== Rinkmena jau yra ==\n[[:$1]] esti bendrojoje saugykloje. Įkėlus rinkmeną šiuo pavadinimu, ji pakeis bendrąją rinkmeną.",
+       "move-over-sharedrepo": "[[:$1]] esti bendrojoje saugykloje. Įkėlus rinkmeną šiuo pavadinimu, ji pakeis bendrąją rinkmeną.",
        "file-exists-sharedrepo": "Pasirinktas failo pavadinimas jau yra naudojamas bendrojoje saugykloje.\nPrašome pasirinkti kitą pavadinimą.",
        "export": "Eksportuoti puslapius",
        "exporttext": "Galite eksportuoti vieno puslapio tekstą ir istoriją ar kelių puslapių vienu metu tame pačiame XML atsakyme.\nŠie puslapiai galės būti importuojami į kitą projektą, veikiantį MediaWiki pagrindu, per [[Special:Import|importo puslapį]].\n\nNorėdami eksportuoti puslapius, įveskite pavadinimus žemiau esančiame tekstiniame lauke po vieną pavadinimą eilutėje, taip pat pasirinkite ar norite eksportuoti ir istoriją ar tik dabartinę versiją su paskutinio redagavimo informacija.\n\nPastaruoju atveju, jūs taip pat galite naudoti nuorodą, pvz. [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] puslapiui „[[{{MediaWiki:Mainpage}}]]“.",
        "import-nonewrevisions": "Nebuvo importuotos jokios versijos (visos jau buvo įkeltos arba praleistos dėl klaidų).",
        "xml-error-string": "$1 $2 eilutėje, $3 stulpelyje ($4 baitas): $5",
        "import-upload": "Įkelti XML duomenis",
-       "import-token-mismatch": "Sesijos duomenys prarasti. Bandykite iš naujo.",
+       "import-token-mismatch": "Sesijos duomenys prarasti.\n\nGali būti, kad esate atsijungęs. <strong>Prašome patikrinti, ar vis dar esate prisijungęs, ir pabandyti iš naujo</strong>.\nJei ir toliau nepavyksta, pamėginkite [[Special:UserLogout|atsijungti]] ir vėl prisijungti, taip pat patikrinkite, ar jūsų naršyklė priima šios svetainės slapukus.",
        "import-invalid-interwiki": "Nepavyko importuoti iš nurodyto wiki projekto.",
        "import-error-edit": "Puslapis \"$1\" nebuvo įkeltas, nes jūs neturite teisės jį redaguoti.",
        "import-error-create": "Puslapis „$1“ nebuvo importuotas, nes jūs neturite teisės jį sukurti.",
        "pageinfo-category-pages": "Puslapių skaičius",
        "pageinfo-category-subcats": "Dukterinių kategorijų skaičius",
        "pageinfo-category-files": "Failų skaičius",
+       "pageinfo-user-id": "Vartotojo ID",
        "markaspatrolleddiff": "Žymėti, kad patikrinta",
        "markaspatrolledtext": "Pažymėti, kad puslapis patikrintas",
        "markaspatrolledtext-file": "Pažymėti šią failo versiją kaip patruliuojamą",
        "patrol-log-header": "Tai patvirtintų versijų sąrašas.",
        "log-show-hide-patrol": "$1 patvirtinimų sąrašą",
        "log-show-hide-tag": "$1 žymės žurnalas",
+       "confirm-markpatrolled-button": "GERAI",
        "deletedrevision": "Ištrinta sena versija $1",
        "filedeleteerror-short": "Klaida trinant rinkmeną: $1",
        "filedeleteerror-long": "Įvyko klaidų trinant failą:\n\n$1",
        "confirmemail_success": "Jūsų el. pašto adresas patvirtintas. Dabar galite prisijungti ir mėgautis projektu.",
        "confirmemail_loggedin": "Jūsų el. pašto adresas patvirtintas.",
        "confirmemail_subject": "{{SITENAME}} el. pašto adreso patvirtinimas",
-       "confirmemail_body": "Kažkas, tikriausiai jūs IP adresu $1, užregistravo\npaskyrą „$2“ susietą su šiuo el. pašto adresu projekte {{SITENAME}}.\n\nKad patvirtintumėte, kad ši dėžutė tikrai priklauso jums, ir aktyvuotumėte\nel. pašto paslaugas projekte {{SITENAME}}, atverkite šią nuorodą savo naršyklėje:\n\n$3\n\nJei paskyrą registravote *ne* jūs, eikite šia nuoroda,\nkad atšauktumėte el. pašto adreso patvirtinimą:\n\n$5\n\nPatvirtinimo kodas baigs galioti $4.",
-       "confirmemail_body_changed": "Kažkas, tikriausiai jūs IP adresu $1, projekte {{SITENAME}}\npakeitė paskyros „$2“ el. pašto adresą.\n\nKad patvirtintumėte, kad ši dėžutė tikrai priklauso jums, ir vėl aktyvuotumėte\nel. pašto paslaugas projekte {{SITENAME}}, atverkite šią nuorodą savo naršyklėje:\n\n$3\n\nJei paskyra jums *nepriklauso*, eikite šia nuoroda,\nkad atšauktumėte el. pašto adreso patvirtinimą:\n\n$5\n\nPatvirtinimo kodas baigs galioti $4.",
+       "confirmemail_body": "Kažkas, tikriausiai jūs iš IP adreso $1, užregistravo\npaskyrą „$2“, susietą su šiuo el. pašto adresu projekte {{SITENAME}}.\n\nKad patvirtintumėte, kad ši paskyra tikrai priklauso jums, ir aktyvuotumėte\nel. pašto paslaugas projekte {{SITENAME}}, atverkite šią nuorodą savo naršyklėje:\n\n$3\n\nJei paskyrą registravote *ne* jūs, spustelkite šią nuoroda,\nkad atšauktumėte el. pašto adreso patvirtinimą:\n\n$5\n\nPatvirtinimo kodas baigs galioti $4.",
+       "confirmemail_body_changed": "Kažkas, tikriausiai jūs iš IP adreso $1, projekte {{SITENAME}}\npakeitė paskyros „$2“ el. pašto adresą.\n\nKad patvirtintumėte, kad ši paskyra tikrai priklauso jums, ir vėl aktyvuotumėte\nel. pašto paslaugas projekte {{SITENAME}}, atverkite šią nuorodą savo naršyklėje:\n\n$3\n\nJei paskyra jums *nepriklauso*, spustelkite šią nuorodą,\nkad atšauktumėte el. pašto adreso patvirtinimą:\n\n$5\n\nPatvirtinimo kodas baigs galioti $4.",
        "confirmemail_body_set": "Kažkas (tikriausiai jūs) iš IP adreso $1,\nnustatė svetainės {{SITENAME}} paskyros „$2“ elektroninio pašto adresą į jūsiškį.\n\nKad patvirtintumėte, kad ši paskyra tikrai priklauso jums ir tokiu būdu aktyvuotumėte\nelektroninio pašto galimybes svetainėje {{SITENAME}}, atverkite šią nuorodą savo naršyklėje:\n\n$3\n\nJei paskyra jums *nepriklauso*, spauskite šią nuorodą,\nkad atšauktumėte elektroninio pašto adreso patvirtinimą:\n\n$5\n\nŠis patvirtinimo kodas baigs galioti $4.",
        "confirmemail_invalidated": "El. pašto adreso patvirtinimas atšauktas",
        "invalidateemail": "El. pašto patvirtinimo atšaukimas",
        "confirm-unwatch-button": "Gerai",
        "confirm-unwatch-top": "Pašalinti šį puslapį iš jūsų stebimųjų sąrašo?",
        "confirm-rollback-button": "Gerai",
+       "confirm-rollback-top": "Atmesti šio puslapio pakeitimus?",
        "quotation-marks": "„$1“",
        "imgmultipageprev": "← ankstesnis puslapis",
        "imgmultipagenext": "kitas puslapis →",
        "lag-warn-high": "Dėl didelio duomenų bazės atsilikimo pakeitimai, naujesni nei $1 {{PLURAL:$1|sekundė|sekundės|sekundžių}}, šiame sąraše gali būti nerodomi.",
        "watchlistedit-normal-title": "Redaguoti stebimųjų sąrašą",
        "watchlistedit-normal-legend": "Šalinti puslapius iš stebimųjų sąrašo",
-       "watchlistedit-normal-explain": "Žemiau yra rodomi puslapiai jūsų stebimųjų sąraše.\nNorėdami pašalinti puslapį, prie jo uždėkite varnelė ir paspauskite „{{int:Watchlistedit-normal-submit}}“.\nJūs taip pat galite [[Special:EditWatchlist/raw|redaguoti grynąjį stebimųjų sąrašą]].",
+       "watchlistedit-normal-explain": "Žemiau yra rodomi puslapiai jūsų stebimųjų sąraše.\nNorėdami pašalinti puslapį, pažymėkite greta esančią varnelę ir paspauskite „{{int:Watchlistedit-normal-submit}}“.\nJūs taip pat galite [[Special:EditWatchlist/raw|redaguoti grynąjį stebimųjų sąrašą]].",
        "watchlistedit-normal-submit": "Šalinti puslapius",
        "watchlistedit-normal-done": "$1 {{PLURAL:$1|puslapis buvo pašalintas|puslapiai buvo pašalinti|puslapių buvo pašalinta}} iš jūsų stebimųjų sąrašo:",
        "watchlistedit-raw-title": "Redaguoti grynąjį stebimųjų sąrašą",
        "redirect-file": "Failo vardas",
        "redirect-logid": "Žurnalo įrašo ID",
        "redirect-not-exists": "Vertė nėra nustatyta",
-       "fileduplicatesearch": "Ieškoti dublikuotų failų",
+       "fileduplicatesearch": "Ieškoti pasikartojančių failų",
        "fileduplicatesearch-summary": "Pasikartojančių failų paieška pagal jų kontrolinę sumą.",
        "fileduplicatesearch-filename": "Failo vardas:",
        "fileduplicatesearch-submit": "Ieškoti",
        "tags-edit-reason": "Priežastis:",
        "tags-edit-revision-submit": "Taikyti pakeitimus {{PLURAL:$1|šiai versijai|$1 versijoms}}",
        "tags-edit-logentry-submit": "Taikyti pakeitimus {{PLURAL:$1|šiam žurnalo įrašui|$1 žurnalo įrašams}}",
-       "tags-edit-success": "Pakeitimai sėkmingai pritaikyti.",
+       "tags-edit-success": "Pakeitimai buvo pritaikyti.",
        "tags-edit-failure": "Pokyčiai negali būti taikomi:\n$1",
        "tags-edit-nooldid-title": "Negalima pasirinkta versija",
        "tags-edit-nooldid-text": "Jūs nenurodėte jokio peržiūros, kuriai vykdyti šią funkciją, arba nurodytos peržiūros nėra.",
        "htmlform-cloner-create": "Pridėti dar",
        "htmlform-cloner-delete": "Pašalinti",
        "htmlform-cloner-required": "Bent viena reikšmė būtina.",
+       "htmlform-date-placeholder": "MMMM-MM-DD",
+       "htmlform-time-placeholder": "VV:MM:SS",
+       "htmlform-datetime-placeholder": "MMMM-MM-DD VV:MM:SS",
        "htmlform-title-badnamespace": "[[:$1]] nėra \"{{ns:$2}}\" vardų srityje.",
        "htmlform-title-not-creatable": "\"$1\" nėra tinkamas sukūrimui puslapio pavadinimas",
        "htmlform-title-not-exists": "$1 neegzistuoja.",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|perkėlė}} puslapį $3 į $4 be nukreipimo",
        "logentry-move-move_redir": "$1 {{GENDER:$2|perkėlė}} puslapį $3 į $4 (anksčiau buvo nukreipiamasis)",
        "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|pervadino}} puslapį $3 į $4, nesukurdamas nukreipimo",
-       "logentry-patrol-patrol": "$1 {{GENDER:$2|payžėmjo}} versiją $4 puslapio $3 kaip patruliuojama",
-       "logentry-patrol-patrol-auto": "$1 automatiškai {{GENDER:$2|pažymėjo}} versiją $4 puslapio $3 kaip patruliuojama",
-       "logentry-newusers-newusers": "Vartotojo paskyra $1 buvo {{GENDER:$2|sukurta}}",
+       "logentry-patrol-patrol": "$1 {{GENDER:$2|pažymėjo}} kaip patikrintą puslapio $3 versiją $4",
+       "logentry-patrol-patrol-auto": "$1 automatiškai {{GENDER:$2|pažymėjo}} kaip patikrintą puslapio $3 versiją $4",
+       "logentry-newusers-newusers": "Naudotojo paskyrą $1 {{GENDER:$2|sukūrė}}",
        "logentry-newusers-create": "$1 sukūrė naudotojo paskyrą",
-       "logentry-newusers-create2": "Vartotojo paskyra $3 buvo {{GENDER:$2|sukurta}} $1",
-       "logentry-newusers-byemail": "Vartotojo paskyra $3 buvo {{GENDER:$2|sukurta}} $1 ir slaptažodis išsiųstas el. paštu",
-       "logentry-newusers-autocreate": "Vartotojo paskyra $1 buvo {{GENDER:$2|sukurta}} automatiškai",
+       "logentry-newusers-create2": "$1 sukūrė naudotojo paskyrą $3",
+       "logentry-newusers-byemail": "Naudotojo paskyrą $3 {{GENDER:$2|sukūrė}} $1, slaptažodis išsiųstas el. paštu",
+       "logentry-newusers-autocreate": "Naudotojo paskyra $1 buvo {{GENDER:$2|sukurta}} automatiškai",
        "logentry-protect-move_prot": "$1 {{GENDER:$2|perkėlė}} apsaugos nustatymus iš $4 į $3",
-       "logentry-protect-unprotect": "$1 {{GENDER:$2|pašalino}} apsaugą nuo $3",
-       "logentry-protect-protect": "$1 {{GENDER:$2|apsaugojo}} $3 $4",
-       "logentry-protect-protect-cascade": "$1 {{GENDER:$2|apsaugojo}} $3 $4 [pakopinė]",
+       "logentry-protect-unprotect": "$1 {{GENDER:$2|atrakino}} $3",
+       "logentry-protect-protect": "$1 {{GENDER:$2|užrakino}} $3 $4",
+       "logentry-protect-protect-cascade": "$1 {{GENDER:$2|užrakino}} $3 $4 [pakopinė]",
        "logentry-protect-modify": "$1 {{GENDER:$2|pakeitė}} apsaugos lygį $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|pakeitė}} apsaugos lygį $3 $4 [pakopinė]",
-       "logentry-rights-rights": "$1 {{GENDER:$2|pakeitė}} grupės narystę $3 iš $4 į $5",
+       "logentry-rights-rights": "$1 {{GENDER:$2|pakeitė}} naudotojo $3 grupės narystę iš $4 į $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|pakeista}} narystė grupėje $3",
        "logentry-rights-autopromote": "$1 buvo automatiškai {{GENDER:$2|pervestas}} iš $4 į $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|įkėlė}} $3",
        "feedback-external-bug-report-button": "Užpildyti techninę užduotį",
        "feedback-dialog-title": "Pateikti atsiliepimą",
        "feedback-dialog-intro": "Galite naudoti lengvą formą esančia žemiau, kad pateiktumėte savo atsiliepimus. Jūsų komentaras bus pridėtas prie puslapio \"$1\", kartu su jūsų vartotojo vardu.",
-       "feedback-error-title": "Klaida",
        "feedback-error1": "Klaida: Neatpažįstamas rezultatas iš API",
        "feedback-error2": "Klaida: Redagavimas nepavyko",
        "feedback-error3": "Klaida: Jokio atsakymo iš API",
        "feedback-useragent": "Vartotojo veiksnys:",
        "searchsuggest-search": "Ieškoti",
        "searchsuggest-containing": "turintys",
+       "api-error-autoblocked": "Jūsų IP adresas buvo automatiškai užblokuotas, nes jį naudojo užblokuotas naudotojas.",
        "api-error-badaccess-groups": "Jums neleidžiama įkelti failus į šią wiki.",
        "api-error-badtoken": "Vidinė klaida: blogai atpažinimo ženklas.",
+       "api-error-blocked": "Jus buvote užblokuotas, kad negalėtumėte redaguoti.",
        "api-error-copyuploaddisabled": "Siuntimas pagal URL yra išjungtas šiame serveryje.",
        "api-error-duplicate": "Jau {{PLURAL:$1|yra kitas failas|yra kiti failai}} puslapyje su tuo pačiu turiniu.",
        "api-error-duplicate-archive": "Jau {{PLURAL:$1|buvo kitas failas|buvo kitų failų}} puslapyje su tuo pačiu turiniu, bet {{PLURAL:$1|buvo ištrintas|buvo ištrinti}}.",
        "api-error-nomodule": "Vidinė klaida: nėra nustatytas įkėlimų modulis.",
        "api-error-ok-but-empty": "Vidinė klaida: nėra atsakymo iš serverio.",
        "api-error-overwrite": "Perrašymas esamą failą neleidžiamas.",
+       "api-error-ratelimited": "Jūs per trumpą laiko tarpą bandote įkelti daugiau failų, nei leidžiama šiame projekte.\nPabandykite dar kartą po keleto minučių.",
        "api-error-stashfailed": "Vidinė klaida: serveriui nepavyko išsaugoti laikinąjį failą.",
        "api-error-publishfailed": "Vidinė klaida: serveriui nepavyko paskelbti laikino failo.",
        "api-error-stasherror": "Įvyko klaida keliant failą į laikyklą.",
        "api-error-unknownerror": "Nežinoma klaida: \"$1\"",
        "api-error-uploaddisabled": "Įkėlimas išjungtas šioje wiki.",
        "api-error-verification-error": "Šis failas gali būti sugadintas arba turi neteisingą papildinį.",
+       "api-error-was-deleted": "Failas tokiu pavadinimu anksčiau jau yra buvęs įkeltas, o paskui ištrintas.",
        "duration-seconds": "$1 {{PLURAL:$1|sekundė|sekundės|sekundžių}}",
        "duration-minutes": "$1 {{PLURAL:$1|minutė|minutės|minučių}}",
        "duration-hours": "$1 {{PLURAL:$1|valanda|valandos|valandų}}",
        "expand_templates_generate_xml": "Rodyti XML nagrinėjimo medį",
        "expand_templates_generate_rawhtml": "Rodyti gryną HTML",
        "expand_templates_preview": "Peržiūra",
-       "expand_templates_preview_fail_html": "<em>Nes {{SITENAME}} turi įgalinta gryną HTML ir įvyko sesijos duomenų praradimas, peržiūra yra paslėpta kaip atsargos priemonė prieš JavaScript atakas.</em>\n\n<strong>Jei tai teisėtas peržiūros bandymas, prašome bandyti dar kartą.</strong>\nJei tai vistiek neveikia, pabandykite [[Special:UserLogout|atsijungti]] ir vėl prisijungti.",
+       "expand_templates_preview_fail_html": "<em>Kadangi {{SITENAME}} turi įgalinta gryną HTML ir įvyko sesijos duomenų praradimas, peržiūra yra paslėpta kaip atsargos priemonė prieš JavaScript atakas.</em>\n\n<strong>Jei tai teisėtas peržiūros bandymas, prašome bandyti dar kartą.</strong>\nJei ir toliau neveikia, pabandykite [[Special:UserLogout|atsijungti]] ir vėl prisijungti, taip pat patikrinkite, ar jūsų naršyklė priima šios svetainės slapukus.",
        "expand_templates_preview_fail_html_anon": "<em>Nes {{SITENAME}} turi įgalinta gryną HTML ir jūs esate neprisijungęs, peržiūra paslėpta kaip atsargumo priemonė prieš JavaScript atakas.</em>\n\n<strong>Jei tai teisėtas peržiūros bandymas prašome [[Special:UserLogin|prisijungti]] ir bandyti vėl.</strong>",
        "expand_templates_input_missing": "Turite pateikti bent truputį įvesties teksto.",
        "pagelanguage": "Keisti puslapio kalbą",
        "log-action-filter-delete": "Trynimo tipas:",
        "log-action-filter-import": "Importo tipas:",
        "log-action-filter-managetags": "Žymės tvarkymo veiksmo tipas:",
-       "log-action-filter-move": "Kėlimo tipas:",
+       "log-action-filter-move": "Perkėlimo tipas:",
        "log-action-filter-newusers": "Paskyros kūrimo tipas:",
+       "log-action-filter-patrol": "Patikrinimo tipas:",
        "log-action-filter-protect": "Apsaugos tipas:",
        "log-action-filter-rights": "Teisių tipo keitimas:",
        "log-action-filter-upload": "Įkėlimo tipas:",
        "log-action-filter-managetags-delete": "Žymės trynimas",
        "log-action-filter-managetags-activate": "Žymės aktyvavimas",
        "log-action-filter-managetags-deactivate": "Žymės deaktyvavimas",
+       "log-action-filter-move-move": "Perkėlimai, nepakeičiant nukreipimų",
+       "log-action-filter-move-move_redir": "Perkėlimai, pakeičiant buvusius nukreipimus",
        "log-action-filter-newusers-autocreate": "Automatinis kūrimas",
+       "log-action-filter-patrol-patrol": "„Rankinis“ patikrinimas",
+       "log-action-filter-patrol-autopatrol": "Automatinis patikrinimas",
        "log-action-filter-protect-protect": "Apsauga",
        "log-action-filter-protect-modify": "Apsaugos keitimas",
        "log-action-filter-protect-move_prot": "Apsauga perkelta",
        "log-action-filter-rights-autopromote": "Automatinis keitimas",
        "log-action-filter-upload-upload": "Naujas įkėlimas",
        "log-action-filter-upload-overwrite": "Kelti iš naujo",
+       "authmanager-authn-not-in-progress": "Autentifikavimas nevyksta arba buvo prarasti sesijos duomenys. Prašome pradėti iš naujo.",
        "authmanager-create-disabled": "Paskyros kūrimas yra išjungtas.",
-       "authmanager-create-from-login": "Norėdami sukurti paskyrą užpildykite laukelius žemiau.",
+       "authmanager-create-from-login": "Norėdami sukurti savo paskyrą užpildykite laukelius žemiau.",
+       "authmanager-create-not-in-progress": "Paskyros kūrimas nevyksta arba buvo prarasti sesijos duomenys. Prašome pradėti iš naujo.",
+       "authmanager-link-not-in-progress": "Paskyrų susiejimas nevyksta arba buvo prarasti sesijos duomenys. Prašome pradėti iš naujo.",
        "authmanager-authplugin-setpass-failed-title": "Slaptažodžio keitimas nepavyko",
        "authmanager-authplugin-setpass-bad-domain": "Negalimas domenas.",
        "authmanager-autocreate-noperm": "Automatinis paskyros kūrimas neleidžiamas.",
        "authmanager-provider-password": "Autentifikacija slaptažodžiu",
        "authmanager-provider-password-domain": "Autentifikavimas slaptažodžiu ir domenu",
        "authmanager-provider-temporarypassword": "Laikinas slaptažodis",
+       "authprovider-confirmlink-message": "Remiantis naujausiais jūsų prisijungimo bandymais, šios paskyros gali būti susietos su jūsų wiki paskyra. Jas susieję, galėsite prisijungti per šias paskyras. Prašome pasirinkti, kurios iš jų turėtų būti susietos.",
        "authprovider-confirmlink-request-label": "Paskyros, kurios turėtų būti susietos",
        "authprovider-confirmlink-success-line": "$1: Susieta sėkmingai.",
        "authprovider-confirmlink-failed": "Paskyros susiejimas nebuvo visiškai sėkmingas: $1",
        "authprovider-resetpass-skip-label": "Praleisti",
        "authprovider-resetpass-skip-help": "Praleisti slaptažodžio perstatymą.",
        "specialpage-securitylevel-not-allowed-title": "Neleidžiama",
+       "specialpage-securitylevel-not-allowed": "Apgailestaujame, tačiau jūs negalite naudotis šiuo puslapiu, nes nepavyko patvirtinti jūsų tapatybės.",
        "cannotauth-not-allowed-title": "Teisė nesuteikta",
        "cannotauth-not-allowed": "Jūs negalite naudotis šiuo puslapiu",
        "credentialsform-account": "Paskyros vardas:",
        "linkaccounts-success-text": "Paskyra buvo susieta.",
        "linkaccounts-submit": "Susieti paskyras",
        "unlinkaccounts": "Atsieti paskyras",
-       "unlinkaccounts-success": "Paskyra buvo atsieta."
+       "unlinkaccounts-success": "Paskyra buvo atsieta.",
+       "edit-error-short": "Klaida: $1",
+       "edit-error-long": "Klaidos:\n\n$1"
 }
index 7f67c7c..78695da 100644 (file)
        "viewsource": "Apsavērt kodu",
        "yourname": "Slāgvuords:",
        "yourpassword": "Paroļs:",
-       "remembermypassword": "Atguoduot muni  iz ituo datora (na vaira kai $1 {{PLURAL:$1|dīnu|dīnom|dīnom}})",
        "login": "Dasaslāgt",
        "nav-login-createaccount": "Dasaslāgt / sataiseit jaunu lītuotuoju",
        "userlogin": "Dasaslāgt / sataiseit jaunu lītuotuoju",
index 2b001c6..d0fc2b3 100644 (file)
        "yourname": "Hmangtuhming:",
        "yourpassword": "Thurûk:",
        "yourpasswordagain": "Thurûk ziak nawn leh rawh le:",
-       "remembermypassword": "He ka rangpuifanna hman mék (browser)-ah hian ka luhna (a rei berah ni {{PLURAL:$1||}}$1) min vawnsak rawh, thurûk ziah nawn ngai lo tùrin.",
        "yourdomainname": "I ram:",
        "password-change-forbidden": "Hë wiki-ah hian thurûk i thlâk thei lo.",
        "externaldberror": "Insawifiahna felfai lo a awm lo a nih loh vëk pawhin i pawnlam siangchan tihdanglam phalsak i ni lo a ni ang.",
        "passwordreset-emailtitle": "{{SITENAME}}-a siangchan chanchin kim",
        "passwordreset-emailelement": "Hmangtuhming: \n$1\n\nThurûk lailâwk: \n$2",
        "passwordreset-emailsentemail": "Hriat nawntirna e-lehkha thawn fel a ni.",
-       "passwordreset-emailsent-capture": "Hriat nawntirna e-lehkha thawn a ni, a hnuaia tarlan ang khuan.",
-       "passwordreset-emailerror-capture": "Hriat nawntirna e-lehkha siam chhuah a ni a, a hnuaia tarlan ang khuan; mahsé thawn hlawhchham a ni: $1",
        "changeemail": "E-chenhmun thlâk rawh",
        "changeemail-header": "Siangchan e-chenhmun thlâk rawh",
        "changeemail-no-info": "He phêk lut mai tùr chuan i inziahluh a ngai.",
        "node-count-exceeded-warning": "Suihbawl theih chin pèl phêkte",
        "expansion-depth-exceeded-category": "Tihchiam theih chin pèl phêkte",
        "expansion-depth-exceeded-warning": "Tihchiam theih chin phêkin a pèl",
-       "cantcreateaccounttitle": "Siangchan siam theih loh",
        "viewpagelogs": "He phêk chanchin hi en rawh",
        "nohistory": "Hë phêk siamṭhatna chanchin ziak a awm lo tlat.",
        "currentrev": "Ennawnna hnuhnung ber",
        "listusers-noresult": "Hmangtu an awm lo.",
        "listusers-blocked": "(danbeh)",
        "activeusers": "Hmangtu hlun tlarna",
-       "activeusers-hidebots": "Khawlmi thupna",
-       "activeusers-hidesysops": "Roreltu thupna",
        "activeusers-noresult": "Hmangtu awm lo.",
        "listgrouprights": "Hmangtu pawl dikna-chanvote",
        "listgrouprights-key": "* <span class=\"listgrouprights-granted\">Dikna-chanvo phalsak</span>\n* <span class=\"listgrouprights-revoked\">Dikna-chanvo hnuhkirsak</span>",
        "special-characters-group-lao": "Lao",
        "special-characters-group-khmer": "Khmer",
        "mw-widgets-dateinput-placeholder-day": "KKKK-TT-NN",
-       "mw-widgets-dateinput-placeholder-month": "KKKK-TT",
-       "api-error-blacklisted": "Hming dang, chiang zâwk deuh thlang hräm rawh le."
+       "mw-widgets-dateinput-placeholder-month": "KKKK-TT"
 }
index 82bd5ab..0b8c8c4 100644 (file)
        "talk": "Diskusija",
        "views": "Apskates",
        "toolbox": "Rīki",
+       "tool-link-userrights": "Mainīt {{GENDER:$1|dalībnieka|dalībnieces}} grupas",
+       "tool-link-emailuser": "Nosūtīt e-pastu {{GENDER:$1|šim dalībniekam|šai dalībniecei}}",
        "userpage": "Skatīt dalībnieka lapu",
        "projectpage": "Skatīt projekta lapu",
        "imagepage": "Skatīt faila lapu",
        "view-pool-error": "Atvainojiet, šobrīd serveri ir pārslogoti.\nPārāk daudz dalībnieku mēģina apskatīt šo lapu.\nLūdzu, brīdi uzgaidiet un mēģiniet šo lapu apskatīt vēlreiz.\n\n$1",
        "generic-pool-error": "Atvainojiet, šobrīd serveri ir pārslogoti.\nPārāk daudz lietotāju mēģina apskatīt šo lapu.\nLūdzu, brīdi uzgaidiet un mēģiniet šo lapu apskatīt vēlreiz.",
        "pool-timeout": "Noildze, gaidot bloķēšanu",
+       "pool-queuefull": "Kopas rinda ir pilna",
        "pool-errorunknown": "Nezināma kļūda",
+       "pool-servererror": "Kopas skaitītāja pakalpojums nav pieejams ($1).",
        "poolcounter-usage-error": "Izmantošanas kļūda: $1",
        "aboutsite": "Par {{grammar:akuzatīvs|{{SITENAME}}}}",
        "aboutpage": "Project:Par",
        "createacct-yourpasswordagain-ph": "Vēlreiz ievadiet paroli",
        "userlogin-remembermypassword": "Atcerēties mani",
        "userlogin-signwithsecure": "Izmantot drošu savienojumu",
+       "cannotcreateaccount-title": "Nevar izveidot kontus",
        "yourdomainname": "Tavs domēns",
        "password-change-forbidden": "Šajā wiki paroles nevar mainīt.",
        "externaldberror": "Notikusi vai nu ārējās autentifikācijas datubāzes kļūda, vai arī tev nav atļauts izmainīt savu ārējo kontu.",
        "loginlanguagelabel": "Valoda: $1",
        "pt-login": "Pieslēgties",
        "pt-login-button": "Pieslēgties",
+       "pt-login-continue-button": "Turpināt pieslēgšanos",
        "pt-createaccount": "Reģistrēties",
        "pt-userlogout": "Iziet",
        "php-mail-error-unknown": "Nezināma kļūda PHP mail() funkcijā",
        "passwordreset-emailelement": "Lietotājvārds: \n$1\n\nPagaidu parole: \n$2",
        "passwordreset-emailsentemail": "Paroles atiestatīšanas e-pasts ir nosūtīts.",
        "passwordreset-nosuchcaller": "Izsaucējs nepastāv: $1",
-       "passwordreset-invalideamil": "Nederīga e-pasta adrese",
+       "passwordreset-invalidemail": "Nederīga e-pasta adrese",
        "changeemail": "Mainīt vai noņemt e-pasta adresi",
        "changeemail-header": "Mainīt konta e-pasta adresi",
        "changeemail-oldemail": "Pašreizējā e-pasta adrese:",
        "userrights-no-interwiki": "Tev nav atļaujas izmainīt dalībnieku tiesības citos wiki.",
        "userrights-nodatabase": "Datubāze $1 neeksistē vai nav lokāla.",
        "userrights-nologin": "Tev ir [[Special:UserLogin|jāieiet iekšā]] kā adminam, lai varētu izmainīt dalībnieku grupas.",
-       "userrights-notallowed": "Jūsu lietotāja kontam nav atļaujas pievienot vai noņemt lietotāju tiesības.",
+       "userrights-notallowed": "Tev nav atļaujas pievienot vai noņemt dalībnieku tiesības.",
        "userrights-changeable-col": "Grupas, kuras tu vari izmainīt",
        "userrights-unchangeable-col": "Grupas, kuras tu nevari izmainīt",
        "group": "Grupa:",
        "upload-http-error": "HTTP kļūda: $1",
        "upload-dialog-title": "Augšupielādēt failu",
        "upload-dialog-button-cancel": "Atcelt",
+       "upload-dialog-button-back": "Atpakaļ",
        "upload-dialog-button-done": "Gatavs",
        "upload-dialog-button-save": "Saglabāt",
        "upload-dialog-button-upload": "Augšupielādēt",
        "nolicense": "Neviena licence nav izvēlēta",
        "license-nopreview": "(Priekšskatījums nav pieejams)",
        "upload_source_url": "(derīgs, publiski pieejams URL)",
-       "upload_source_file": "(fails datorā)",
+       "upload_source_file": "(tavs izvēlētais fails tavā datorā)",
        "listfiles-delete": "dzēst",
        "listfiles-summary": "Šajā īpašajā lapā ir redzami visi augšupielādētie faili.",
        "listfiles_search_for": "Meklēt failu pēc vārda:",
        "apisandbox-results": "Rezultāti",
        "apisandbox-request-url-label": "Pieprasījuma URL:",
        "apisandbox-request-time": "Pieprasījuma izpildes laiks: {{PLURAL:$1|$1 ms}}",
+       "apisandbox-continue-clear": "Notīrīt",
        "booksources": "Grāmatu avoti",
        "booksources-search-legend": "Meklēt grāmatu avotus",
        "booksources-search": "Meklēt",
        "activeusers-intro": "Šis ir to dalībnieku saraksts, kuri veikuši kādu darbību {{PLURAL:daudzskaitlī:$1|pēdējā|pēdējās}} $1 {{PLURAL:daudzskaitlī:$1|dienā|dienās}}.",
        "activeusers-count": "$1 {{PLURAL:$1|darbību|darbība|darbības}} {{PLURAL:$3|pēdējās $3 dienās|pēdējā $3 dienā|pēdējās $3 dienās}}",
        "activeusers-from": "Parādīt dalībniekus, sākot ar:",
-       "activeusers-hidebots": "Paslēpt botus",
-       "activeusers-hidesysops": "Paslēpt administratorus",
        "activeusers-noresult": "Neviens dalībnieks nav atrasts.",
        "activeusers-submit": "Parādīt aktīvos dalībniekus",
-       "listgrouprights": "Lietotāju grupu tiesības",
+       "listgrouprights": "Dalībnieku grupu tiesības",
        "listgrouprights-summary": "Šis ir šajā viki definēto dalībnieku grupu uzskaitījums, kopā ar tām atbilstošajām piekļuves tiesībām.\nPapildu informāciju par katru individuālu piekļuves tiesību veidu, iespējams, var atrast [[{{MediaWiki:Listgrouprights-helppage}}|šeit]].",
        "listgrouprights-group": "Grupa",
        "listgrouprights-rights": "Tiesības",
        "year": "No gada (un senāki):",
        "sp-contributions-newbies": "Rādīt jauno lietotāju devumu",
        "sp-contributions-newbies-sub": "Jaunie lietotāji",
-       "sp-contributions-blocklog": "Bloķēšanas reģistrs",
+       "sp-contributions-blocklog": "bloķēšanas reģistrs",
        "sp-contributions-deleted": "dzēstais {{GENDER:$1|dalībnieka|dalībnieces}} devums",
        "sp-contributions-uploads": "augšupielādes",
        "sp-contributions-logs": "reģistri",
        "sp-contributions-talk": "diskusija",
-       "sp-contributions-userrights": "Lietotāju tiesību pārvaldība",
+       "sp-contributions-userrights": "dalībnieka tiesību pārvaldība",
        "sp-contributions-blocked-notice": "Šis lietotājs pašlaik ir nobloķēts.\nPēdējais bloķēšanas reģistra ieraksts ir apskatāms zemāk:",
        "sp-contributions-blocked-notice-anon": "Šī IP adrese pašlaik ir nobloķēta.\nPēdējais bloķēšanas reģistra ieraksts ir apskatāms zemāk:",
        "sp-contributions-search": "Meklēt lietotāju veiktās izmaiņas",
        "ipb-unblock-addr": "Atbloķēt $1",
        "ipb-unblock": "Atbloķēt lietotāju vai IP adresi",
        "ipb-blocklist": "Apskatīt esošos blokus",
-       "ipb-blocklist-contribs": "$1 devums",
+       "ipb-blocklist-contribs": "{{GENDER:$1|$1}} devums",
        "unblockip": "Atbloķēt lietotāju",
        "unblockiptext": "Šeit var atbloķēt iepriekš nobloķētu IP adresi vai lietotāja vārdu (atjaunot viņiem rakstīšanas piekļuvi).",
        "ipusubmit": "Noņemt šo bloku",
        "newimages-legend": "Filtrs",
        "newimages-label": "Faila nosaukums (vai tā daļa):",
        "newimages-showbots": "Parādīt botu augšupielādētos failus",
+       "newimages-hidepatrolled": "Paslēpt pārbaudītās augšupielādes",
        "noimages": "Nav nekā ko redzēt.",
+       "gallery-slideshow-toggle": "Pārslēgt sīktēlus",
        "ilsubmit": "Meklēt",
        "bydate": "<b>pēc datuma</b>",
        "sp-newimages-showfrom": "Rādīt jaunos attēlus sākot no $1, $2",
        "tags-actions-header": "Darbības",
        "tags-active-yes": "Jā",
        "tags-active-no": "Nē",
-       "tags-source-extension": "Nosaka paplašinājums",
+       "tags-source-extension": "Nosaka programmatūra",
        "tags-source-none": "Vairs netiek izmantots",
        "tags-edit": "labot",
        "tags-delete": "dzēst",
        "feedback-cancel": "Atcelt",
        "feedback-close": "Gatavs",
        "feedback-dialog-title": "Iesniegt atsauksmes",
-       "feedback-error-title": "Kļūda",
        "feedback-error1": "Kļūda: API neatpazīts rezultāts",
        "feedback-error2": "Kļūda: Labojums neizdevās",
        "feedback-error3": "Kļūda: Nav atbildes no API",
        "feedback-submit": "Iesniegt",
        "feedback-thanks": "Paldies! Jūsu atsauksmes ir ievietotas lapā \"[$2  $1]\".",
        "feedback-thanks-title": "Paldies!",
-       "searchsuggest-search": "Meklēt",
+       "searchsuggest-search": "Meklēt {{SITENAME}}",
        "searchsuggest-containing": "Meklējamā frāze:",
        "api-error-badaccess-groups": "Jums nav atļauts augšupielādēt failus šajā wiki.",
        "api-error-copyuploaddisabled": "Augšupielāde no URL šajā serverī ir atspējota.",
        "authmanager-realname-label": "Tavs īstais vārds",
        "authmanager-realname-help": "Dalībnieka īstais vārds",
        "authprovider-resetpass-skip-label": "Izlaist",
-       "specialpage-securitylevel-not-allowed-title": "Nav atļauts"
+       "specialpage-securitylevel-not-allowed-title": "Nav atļauts",
+       "edit-error-short": "Kļūda: $1",
+       "edit-error-long": "Kļūdas:\n\n$1"
 }
index 153ab06..81906f6 100644 (file)
        "yourpasswordagain": "復核節",
        "createacct-yourpasswordagain": "訂子符節",
        "createacct-yourpasswordagain-ph": "復告符節",
-       "remembermypassword": "吾之簿通越(達至$1日)",
        "userlogin-remembermypassword": "保我簿登",
        "userlogin-signwithsecure": "以安全伺服登簿",
        "yourdomainname": "汝之網域",
        "undo-failure": "中審之異,此審無返也。",
        "undo-norev": "其審無存或刪,此審無返也。",
        "undo-summary": "返[[Special:Contributions/$2|$2]]([[User talk:$2|書]])之審$1",
-       "cantcreateaccounttitle": "新簿謝焉",
        "cantcreateaccount-text": "[[User:$3|S3]]因''$2''故,封子IP <b>$1</b>。",
        "viewpagelogs": "覽誌",
        "nohistory": "此題無誌",
        "activeusers-intro": "此乃為近$1天內之躍簿也。",
        "activeusers-count": "$3天內之$1易",
        "activeusers-from": "示簿始於:",
-       "activeusers-hidebots": "藏僕",
-       "activeusers-hidesysops": "藏有秩",
        "activeusers-noresult": "無簿矣。",
        "listgrouprights": "權任一覽",
        "listgrouprights-summary": "此所列述,諸職所司也,各有異同。欲知其詳,請閱[[{{MediaWiki:Listgrouprights-helppage}}|此文]]。",
        "htmlform-submit": "呈",
        "htmlform-reset": "復",
        "htmlform-selectorother-other": "他",
-       "sqlite-has-fts": "$1 含全文之尋",
-       "sqlite-no-fts": "$1 不含全文之尋",
        "revdelete-restricted": "應限至有秩",
        "revdelete-unrestricted": "除限自有秩",
        "logentry-newusers-create": "簿$1已{{GENDER:$2|增}}。",
index cd0a50d..7834379 100644 (file)
@@ -9,7 +9,8 @@
                        "Ibero-kolxi",
                        "Reedy",
                        "The Evil IP address",
-                       "아라"
+                       "아라",
+                       "Velg"
                ]
        },
        "tog-underline": "Link'iş tude kogu3’uxaçki:",
        "nstab-template": "Şabloni",
        "nstab-help": "Meşvelaşi but’k’a",
        "nstab-category": "Kʼatʼegori",
+       "mainpage-nstab": "Dudi But'k'a",
        "error": "Çilata",
        "missing-article": "Datʼabeizik, na igoren \"$1\" $2 coxoni butʼkʼaşi tekstʼi var az*iru.\n\nMuşeni? Çunki am butʼkʼa, jileri na ren a butʼkʼaşi golaxteri versiyoni ren.\n\nEger sebebi aya na va renna, pʼrogramis ar çilata z*irit.\nMu iqʼven! Aya, a [[Special:ListUsers/sysop|adminis]], URL-ti çʼareli şekʼilite rapʼortʼi doçʼarit.",
        "missingarticle-rev": "(revizyoni#: $1)",
        "userlogin-yourname": "Skani maxmare-coxo",
        "yourpassword": "Pʼarola-skani:",
        "userlogin-yourpassword": "Pʼarola-skani",
-       "remembermypassword": "Parola-skani goişini (for a maximum of $1 {{PLURAL:$1|day|days}})",
        "yourdomainname": "Skani domaini:",
        "login": "Sitʼeşa amaxti",
        "nav-login-createaccount": "Sitʼeşa amaxti / hesabi dokʼidi",
        "createacct-reason": "Muşen",
        "mailmypassword": "Ağne pʼarola-çkimi moncğoni",
        "loginlanguagelabel": "Nena: $1",
+       "pt-login": "Sitʼeşa amaxti",
+       "pt-createaccount": "Hesabi dokʼidi",
        "oldpassword": "Mcveşi p'arola:",
        "newpassword": "Ağani P'arola:",
        "passwordreset-username": "Skani maxmare-coxo:",
        "rc-enhanced-expand": "Detayepe ko3ʼiri (JavaScript-i unon)",
        "rc-enhanced-hide": "Detayepe doşinaxi",
        "recentchangeslinked": "Alakʼali na renan oktirobape",
+       "recentchangeslinked-toolbox": "Alakʼali na renan oktirobape",
        "recentchangeslinked-title": "\"$1\" kʼala alakʼali na renan oktirobape",
        "recentchangeslinked-summary": "Tude na çʼars listʼe, kʼiti na noğiru butʼkʼaşa (varna kʼiti na noğiru kʼatʼegorişi makʼaturepeşa) kʼontʼaktʼi na ikips butʼkʼapes na ixvenu çodinaşi oktirobapeşi listʼe ren.\n[[Special:Watchlist|Gotxozu na ginon butʼkʼapeşi listʼes]] na renan butʼkʼape '''mçxu''' nçʼaraten niçʼaru.",
        "recentchangeslinked-page": "Butʼkʼaşi coxo:",
        "tooltip-pt-login": "Ginon na sitʼeşa amaxti, mecburi va re",
        "tooltip-pt-logout": "Siteşen Kogamaxti",
        "tooltip-ca-talk": "Butʼkʼaş doloxe na içʼaren çʼarape şeni mutxanepe mi3ʼvit",
-       "tooltip-ca-edit": "Am butʼkʼa kodogaktiren. Mu iqʼven! ipti \"Evvelişen i3ʼkʼedi\" tʼuşi ixmari do na çʼari çʼara ikʼontʼroli, ukʼule ikʼayitʼi.",
+       "tooltip-ca-edit": "Butʼkʼa doktiri",
        "tooltip-ca-addsection": "Ağani burme dokʼidi.",
        "tooltip-ca-viewsource": "Am butʼkʼa içven. Xvala odudeş kʼodi gaz*iren. Doloxe muşi va gaktirinen.",
        "tooltip-ca-history": "Am butʼkʼaşi golaxteri versiyonepe",
        "watchlisttools-raw": "Kʼobo gotxozu listʼe doktiri",
        "specialpages": "Doxmeli butʼkʼape",
        "rightsnone": "(Va ren)",
+       "searchsuggest-search": "Mgori",
        "special-characters-group-latin": "Lat'ini",
        "special-characters-group-greek": "Xorumi",
        "special-characters-group-arabic": "Arabuli"
index 0d7f4fb..c997386 100644 (file)
        "passwordreset-emailtext-user": "प्रयोक्ता $1 {{अन्तर्जाल}} पर अहाँक खाता विवरणक {{SITENAME}} लेल फेरसँ ($4) आग्रह केने छथि। ई प्रयोक्ता {{PLURAL:$3|खाता अछि|खाता सभ अछि}} ऐ ई-पत्र संकेतसँ जुड़ल: $2\n{{PLURAL:$3| ई अस्थायी कूटशब्द|ई सभ अस्थायी कूटशब्द}} खतम भऽ जाएत {{PLURAL:$5|एक दिन|$5 दिन}} मे।\nअहाँ सम्प्रवेश करू आ एकटा नव कूटशब्द आब चुनू। जँ कियो दोसर ई आग्रह केने छथि, वा जँ अहाँकेँ अपन मूल कूटशब्द मोन पड़ि गेल अछि, आ अहाँ आब ओइ कूटशब्दकेँ नै बदलऽ चाहै छी, अहाँ ऐ संदेशकेँ बिसरि सकै छी आ अपन पुरान कूटशब्दक प्रयोग जारी राखि सकै छी।",
        "passwordreset-emailelement": "प्रयोक्ता: \n$1\n\nअस्थायी कूटशब्द: \n$2",
        "passwordreset-emailsentemail": "एकटा ई-पत्र मोन पाड़बा लेल पठाओल गेल अछि।",
-       "passwordreset-invalideamil": "अवैध इमेल ठेगान",
+       "passwordreset-invalidemail": "अवैध इमेल ठेगान",
        "passwordreset-nodata": "प्रयोगकर्ता नाम वा इमेल ठेगान नै देल गेल छल",
        "changeemail": "ई-मेल पता परिवर्तित करी",
        "changeemail-header": "अपन ईमेल पता परिवर्तन हेतु एकरा पुरा करी। यदि अहाँ अपन वर्तमान ईमेल पता हटाबैलेल चाहैत छी, तँ एकरा खाली छोडि दी आ एकरा भेजी।",
        "permissionserrorstext-withaction": "अहाँक अनुमति नै अछि $2 लेल, एकर लेल {{PLURAL:$1|कारण|कारणसभ}}सँ:",
        "recreate-moveddeleted-warn": "'''चेतौनी''': अहाँ फेरसँ ओ पन्ना बना रहल छी जे पहिने मेटा देल गेल छै।'''\n\nअहाँ विचारू जे की ई सम्पादन केनाइ उचित अछि।\nऐ पन्नाक मेटाएल बला आ हटाएल वृत्तलेख एतए सुविधा लेल देल जा रहल अछि:",
        "moveddeleted-notice": "ई पन्ना मेटाएल गेल अछि।\nई पन्ना लेल मेटाएल आ स्थानान्तरणक लग सन्दर्भ लेल नीचाँ देल गेल अछि।",
-       "log-fulllog": "सभà¤\9fा à¤µà¥\83तà¥\8dतलà¥\87à¤\96 देखी",
+       "log-fulllog": "समà¥\8dपà¥\82रà¥\8dण à¤²à¥\8cà¤\97 देखी",
        "edit-hook-aborted": "सम्पादन नोकसीसँ खतम भेल।\nई कोनो कारण नै देलक।",
        "edit-gone-missing": "पन्ना अद्यतन नै भऽ सकल।\nलगैए जे ई मेटा देल गेल अछि।",
        "edit-conflict": "सम्पादन अन्तर्विरोध",
        "expansion-depth-exceeded-warning": "पन्ना विस्तार गहिराई पार केनए अछि",
        "parser-unstrip-loop-warning": "Unstrip लूप पाओल गेल",
        "parser-unstrip-recursion-limit": "Unstrip पुनरावर्तन सीमा पार कइर गेल($1)",
-       "converter-manual-rule-error": "म्यानुअल भाषा परिवर्तन नियम में त्रुटि",
+       "converter-manual-rule-error": "म्यानुअल भाषा परिवर्तन नियममे त्रुटि",
        "undo-success": "ई सम्पादन पूर्ववत बदलल जा सकैए।\nकृपा क' नीचाँक तुलनाक जाँच करू ई देखैले जे ई वएह भेल अछि जे अहाँ चाहै छलहुँ, आ तखन सम्पादन ख़तम करबा लेल नीचाँक परिवर्तन सुरक्षित करू ।",
        "undo-failure": "मध्यवर्ती विरोधी सम्पादनक कारण ऐ सम्पादनकेँ खतम नै कएल जा सकैए।",
        "undo-norev": "ई सम्पादन खतम नै कएला जा सकैए कारण ई अछि नै वा मेटा देल गेल अछि।",
        "revdelete-show-file-submit": "हँ",
        "revdelete-selected-text": "[[:$2]] {{PLURAL:$1|क|के}} चयनित अवतरण:",
        "revdelete-selected-file": "[[:$2]] {{PLURAL:$1|क|के}} चयनित फाइल अवतरण:",
-       "logdelete-selected": "{{PLURAL:$1|à¤\9aà¥\81नल à¤µà¥\83तà¥\8dतलà¥\87à¤\96 à¤\98à¤\9fना|à¤\9aà¥\81नल à¤µà¥\83तà¥\8dतलà¥\87à¤\96 घटनासभ}}:",
+       "logdelete-selected": "{{PLURAL:$1|à¤\9aà¥\81नल à¤²à¥\8cà¤\97 à¤\98à¤\9fना|à¤\9aà¥\81नल à¤²à¥\8cà¤\97 घटनासभ}}:",
        "revdelete-text-text": "हटाएल गेल अवतरण पृष्ठ इतिहासमें देखाएल जाएत मुदा वोकर सामग्री सार्वजनिक रूपसँ नै देखाएल जा सकएत अछि।",
        "revdelete-text-file": "हटाएल गेल अवतरण पृष्ठ इतिहासमें देखाएल जाएत मुदा वोकर सामग्री सार्वजनिक रूपसँ नै देखाएल जा सकएत अछि।",
        "logdelete-text": "हटाए गेल प्रवेश घटनासभ अखैनो भी लॉग में दिखाबल ज्यात, लेकिन ओकर सामग्री के कुछ भाग के सार्वजनीक करबाक के लेल दुर्गम भ्या जेत।",
        "revdelete-reasonotherlist": "दोसर कारण",
        "revdelete-edit-reasonlist": "मेटेबाक कारण बदली",
        "revdelete-offender": "संशोधन केनिहार:",
-       "suppressionlog": "दबाà¤\8fलà¤\97à¥\87ल à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "suppressionlog": "नà¥\81à¤\95ाà¤\8fल à¤²à¥\8cà¤\97",
        "suppressionlogtext": "नीचाँ मेटाएल आ प्रतिबन्धक उल्लेख अछि जे संचालकसँ नुकाएल सामिग्री अछि।\nअखन स्थित प्रभावी प्रतिबन्ध आ अवरोध लेल देखू [[Special:BlockList|IP block list]] ।",
-       "mergehistory": "मिà¤\9cà¥\8dà¤\9dर à¤­à¥\87ल à¤ªà¤¨à¥\8dना à¤¸à¤­à¤\95 à¤\87तिहास",
+       "mergehistory": "पà¥\83षà¥\8dठà¤\95 à¤\87तिहास à¤\8fà¤\95तà¥\8dरित à¤\95रà¥\80",
        "mergehistory-header": "ई पन्ना अहाँकेँ एकटा स्रोत पन्नाक एकटा नव पन्नामे संशोधन इतिहासकेँ मिज्झर करबाक अनुमति दैत अछि।\nसुनिश्चित होउ जे ई परिवर्तन ऐतिहासिक पन्ना सांतत्य स्थापित करत।",
-       "mergehistory-box": "दà¥\82 à¤ªà¤¨à¥\8dनाà¤\95 à¤¸à¤\82शà¥\8bधन à¤®à¤¿à¤\9cà¥\8dà¤\9dर à¤\95रà¥\80।",
+       "mergehistory-box": "दà¥\81à¤\88 à¤ªà¥\83षà¥\8dठसभà¤\95 à¤\87तिहास à¤\8fà¤\95तà¥\8dरित à¤\95रà¥\80:",
        "mergehistory-from": "मूल पन्ना:",
        "mergehistory-into": "लक्ष्य पन्ना:",
-       "mergehistory-list": "मिà¤\9cà¥\8dà¤\9dर à¤¯à¥\8bà¤\97à¥\8dय सम्पादन इतिहास",
+       "mergehistory-list": "à¤\8fà¤\95तà¥\8dरितà¥\80à¤\95रण सम्पादन इतिहास",
        "mergehistory-merge": "[[:$1]] एकर संशोधन सभकेँ [[:$2]] मे मिलाएल जा सकैए।\nरेडियो बटन स्तम्भक प्रयोग मात्र संशोधनकेँ निर्धारित समए वा ओइसँ पहिने मिज्झर करबामे प्रयोग करू।\nमोन राखू जे उपर नीचाँक लागिक प्रयोग ऐ स्तम्भकेँ पुनर्स्थापित कऽ देत।",
-       "mergehistory-go": "मिà¤\9cà¥\8dà¤\9dर à¤¹à¥\8bà¤\87 à¤¯à¥\8bà¤\97à¥\8dय à¤¸à¤®à¥\8dपादन à¤¸à¤­à¤\95à¥\87à¤\81 à¤¦à¥\87à¤\96ाà¤\89",
-       "mergehistory-submit": "सà¤\82शà¥\8bधन à¤¸à¤­à¤\95à¥\87 à¤®à¤¿à¤\9cà¥\8dà¤\9dर करी",
-       "mergehistory-empty": "à¤\95à¥\8bनà¥\8b à¤¸à¤\82शà¥\8bधन à¤®à¤¿à¤\9cà¥\8dà¤\9dर à¤¨à¥\88 à¤\95à¤\8fल à¤\9cा à¤¸à¤\95à¥\88à¤\8f।",
+       "mergehistory-go": "à¤\8fà¤\95तà¥\8dरित à¤\95रà¥\88लà¥\87ल à¤²à¤¾à¤¯à¤\95 à¤¸à¤®à¥\8dपादन à¤¦à¥\87à¤\96ाबà¥\80",
+       "mergehistory-submit": "सà¤\82शà¥\8bधन à¤\8fà¤\95तà¥\8dरित करी",
+       "mergehistory-empty": "à¤\95à¥\8bनà¥\8b à¤­à¥\80 à¤\85वतरण à¤\8fà¤\95तà¥\8dरित à¤¨à¥\88 à¤\95à¤\8fल à¤\9cा à¤¸à¤\95ल।",
        "mergehistory-done": "$3 {{PLURAL:$3|संशोधन|संशोधन सभ}} एकर $1 सफलता पूर्वक मिज्झर कएल गेल [[:$2]] मे।",
        "mergehistory-fail": "इतिहासक मिश्रणकेँ नै कऽ सकल, कृपा कऽ पन्ना आ समए परिमितिकेँ फेरसँ जाँचू।",
        "mergehistory-fail-bad-timestamp": "समय सङ्ख्या अमान्य।",
        "mergehistory-comment": "[[:$1]] केँ [[:$2]] मे मिलाएल गेल: $3",
        "mergehistory-same-destination": "स्रोत आ लक्ष्य पन्ना सभ एक्के नै भऽ सकैए",
        "mergehistory-reason": "कारण:",
-       "mergelog": "मिà¤\9cà¥\8dà¤\9dरबला à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "mergelog": "à¤\8fà¤\95तà¥\8dरà¥\80à¤\95रण à¤²à¥\8cà¤\97",
        "revertmerge": "नै मिज्झर",
        "mergelogpagetext": "नीचाँ एक पन्ना इतिहासक दोसरमे अद्यतन मिश्रणक सूची अछि।",
        "history-title": "\"$1\" क संशोधन इतिहास",
        "right-move-rootuserpages": "मूल प्रयोक्ता पन्ना स्थानान्तरित करी",
        "right-move-categorypages": "श्रेणी पृष्ठ स्थानान्तरित करी",
        "right-movefile": "सञ्चिकासभ स्थानान्तरित करी",
-       "right-suppressredirect": "पà¥\83षà¥\8dठ à¤\98सà¤\95à¥\87बाकाल पुनर्निर्देश नै छोडी",
+       "right-suppressredirect": "पà¥\83षà¥\8dठ à¤¸à¥\8dथानानà¥\8dतरित à¤\95रà¥\88तकाल पुनर्निर्देश नै छोडी",
        "right-upload": "सञ्चिकासभ उपारोपित करी",
        "right-reupload": "वर्तमान सञ्चिकासभक पुनर्लेखन करी",
        "right-reupload-own": "अपन उपारोपित पन्नासभक पुनर्लेखन करी",
        "right-undelete": "पन्ना फेरसँ आनी",
        "right-suppressrevision": "संचालकसँ नुकाएल संशोधनकेँ पुनरीक्षित करी आ फेरसँ आनी",
        "right-viewsuppressed": "कोनो प्रयोक्ताके नुकाएल संसोधन देखु",
-       "right-suppressionlog": "वà¥\8dयà¤\95à¥\8dतिà¤\97त à¤µà¥\83तà¥\8dतलà¥\87à¤\96 देखी",
+       "right-suppressionlog": "निà¤\9cà¥\80 à¤²à¥\8cà¤\97 देखी",
        "right-block": "दोसर प्रयोक्ताकेँ सम्पादनसँ रोकी",
        "right-blockemail": "प्रयोक्ताकेँ ई-पत्र पठेबासँ रोकी",
        "right-hideuser": "एकटा प्रयोक्तानामकेँ प्रतिबन्धित करू, लोकसँ एकरा नुका कऽ",
        "right-noratelimit": "दरक सीमासँ प्रभावित नै",
        "right-import": "दोसर विकीसँ पन्ना लिअ",
        "right-importupload": "पन्नासभकेँ संचिका उपारोपणसँ आनू",
-       "right-patrol": "दà¥\8bसराà¤\95 à¤¸à¤®à¥\8dपादनà¤\95à¥\87à¤\81 à¤¸à¤\82à¤\9aालित à¤¦à¥\87à¤\96ाà¤\89",
-       "right-autopatrol": "अपन सम्पादनकेँ स्वचालित रूपेँ संचालित देखाउ",
+       "right-patrol": "à¤\85नà¥\8dय à¤¸à¤¦à¤¸à¥\8dयसभà¤\95 à¤¸à¤®à¥\8dपादन à¤ªà¤°à¥\80à¤\95à¥\8dषित à¤\9aिनà¥\8dहित à¤\95रà¥\80",
+       "right-autopatrol": "अपन सम्पादन स्वचालित रूपसँ परीक्षित चिन्हित करी",
        "right-patrolmarks": "हालक परिवर्तनमे संचालन चेन्ह देखू",
        "right-unwatchedpages": "एहन पृष्ठसभक सूची देखी जे केकरो ध्यानसूचीमे नै अछि",
-       "right-mergehistory": "पनà¥\8dनाà¤\95 à¤\87तिहास à¤¸à¤­à¤\95à¥\87à¤\81 à¤®à¤¿à¤\9cà¥\8dà¤\9dर à¤\95रà¥\82",
+       "right-mergehistory": "पनà¥\8dनाà¤\95 à¤\87तिहास à¤\8fà¤\95तà¥\8dरित à¤\95रà¥\80",
        "right-userrights": "सभटा प्रयोक्ता अधिकारकेँ सम्पादित करू",
        "right-userrights-interwiki": "दोसर विकीपर प्रयोक्ताक प्रयोक्ता अधिकारक सम्पादन करी",
        "right-siteadmin": "दत्तनिधिकेँ प्रतिबन्धित करू आ फेर प्रतिबन्ध हटाउ",
        "grant-uploadeditmovefile": "फाइल अपलोड, बदलनाए, स्थानान्तरण करनाए",
        "grant-uploadfile": "नव सञ्चिकासभ उपारोपित करी",
        "grant-basic": "सामान्य अधिकार",
-       "grant-viewdeleted": "हटाएल फाइल व पृष्ठ देखी",
+       "grant-viewdeleted": "मà¥\87टाएल फाइल व पृष्ठ देखी",
        "grant-viewmywatchlist": "अपन साकांक्षसूची देखी",
        "newuserlogpage": "प्रयोक्ता रचना लग",
        "newuserlogpagetext": "ई प्रयोक्ता निर्माणक वृत्तलेख अछि।",
-       "rightslog": "पà¥\8dरयà¥\8bà¤\95à¥\8dता à¤\85धिà¤\95ार à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "rightslog": "पà¥\8dरयà¥\8bà¤\95à¥\8dता à¤\85धिà¤\95ार à¤²à¥\8cà¤\97",
        "rightslogtext": "ई प्रयोक्ता अधिकार परिवर्तन सभक वृतलेख छी।",
        "action-read": "ई पन्ना पढी",
        "action-edit": "ई पन्नाक सम्पादित करी",
        "action-createtalk": "ई वार्ता पन्ना बनाबी",
        "action-createaccount": "ई प्रयोक्ता खाता बनाबी",
        "action-autocreateaccount": "स्वतः बाहरी सदस्य खाता बनाबी",
-       "action-history": "पनà¥\8dनाà¤\95 à¤\87तिहास à¤®à¤¿à¤\9cà¥\8dà¤\9dर à¤\95री",
+       "action-history": "à¤\88 à¤ªà¥\83षà¥\8dठà¤\95 à¤\87तिहास à¤¦à¥\87à¤\96ी",
        "action-minoredit": "ऐ सम्पादनके मामूली कही",
        "action-move": "ई पृष्ठके स्थानान्तरित करी",
        "action-move-subpages": "ई पन्ना आ एकर उपपन्नाके स्थानान्तरित करी",
        "action-rollback": "कृपा कऽ अन्तिम प्रयोक्ताक सम्पादनकेँ प्रत्यावर्तित करू जे एक खास पन्नाकेँ सम्पादित केलन्हि",
        "action-import": "ऐ पन्नाकेँ दोसर विकीसँ आनू",
        "action-importupload": "ऐ पन्नाकेँ संचिका उपारोपणसँ आनू",
-       "action-patrol": "दà¥\8bसराà¤\95 à¤¸à¤®à¥\8dपादनà¤\95à¥\87à¤\81 à¤¸à¤\82à¤\9aालित à¤¦à¥\87à¤\96ाà¤\89",
-       "action-autopatrol": "अपन सम्पादनकेँ संचालित देखाउ",
+       "action-patrol": "à¤\85नà¥\8dय à¤¸à¤¦à¤¸à¥\8dयसभà¤\95 à¤¸à¤®à¥\8dपादन à¤ªà¤°à¥\80à¤\95à¥\8dषित à¤\95रà¥\80",
+       "action-autopatrol": "अपन सम्पादन स्वचालित रूपसँ परीक्षित करी",
        "action-unwatchedpages": "बिना संचालित पन्ना सभक सूचीकेँ देखू",
-       "action-mergehistory": "पनà¥\8dनाà¤\95 à¤\87तिहासà¤\95à¥\87à¤\81 à¤®à¤¿à¤\9cà¥\8dà¤\9dर à¤\95रà¥\82",
+       "action-mergehistory": "à¤\88 à¤ªà¥\83षà¥\8dठà¤\95 à¤\87तिहास à¤\8fà¤\95तà¥\8dरित à¤\95रà¥\80",
        "action-userrights": "सभटा प्रयोक्ता अधिकारकेँ सम्पादित करू",
        "action-userrights-interwiki": "दोसर विकीपर प्रयोक्ताक प्रयोक्ता अधिकारक सम्पादन करू",
        "action-siteadmin": "दत्तनिधिकेँ प्रतिबन्धित करू आ फेर प्रतिबन्ध हटाउ",
        "action-editmywatchlist": "काँच साकांक्षसूची संपादित करू",
        "action-viewmywatchlist": "अपन काँच साकांक्षसूची देखु",
        "action-viewmyprivateinfo": "अपन व्यक्तिगत जानकारी देखु",
-       "action-editmyprivateinfo": "à¤\85पन à¤µà¥\8dयà¤\95à¥\8dतिà¤\97त à¤\9cानà¤\95ारà¥\80 à¤¸à¤®à¥\8dपादित à¤\95रà¥\81",
+       "action-editmyprivateinfo": "à¤\85पन à¤µà¥\8dयà¤\95à¥\8dतिà¤\97त à¤\9cानà¤\95ारà¥\80 à¤¸à¤®à¥\8dपादित à¤\95रà¥\80",
        "action-editcontentmodel": "एक पन्ना के सामग्री मॉडल कें सम्पादन।",
        "action-managechangetags": "ट्याग बनाबी आ सक्षम (असक्षम) करी",
        "action-applychangetags": "आहाँ के बदलाव के साथ टैग जोडू।",
        "enhancedrc-history": "इतिहास",
        "recentchanges": "लगक परिवर्तनसभ",
        "recentchanges-legend": "नव परिवर्तन सम्बन्धी विकल्प",
-       "recentchanges-summary": "à¤\88 à¤ªà¤¨à¥\8dनापर à¤µà¤¿à¤\95à¥\80मà¥\87 à¤­à¥\87ल à¤¸à¤­ à¤¸à¤\81 à¤\85दà¥\8dयतन à¤ªà¤°à¤¿à¤µà¤°à¥\8dतनपर à¤¨à¤\9cरि à¤°à¤¾à¤\96à¥\80।",
+       "recentchanges-summary": "à¤\88 à¤µà¤¿à¤\95िमà¥\87 à¤­à¥\87ल à¤¸à¤¨à¥\8dनिà¤\95à¤\9f à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\88 à¤ªà¥\83षà¥\8dठपर à¤¦à¥\87à¤\96ल à¤\9cा à¤¸à¤\95à¥\88त à¤\85à¤\9bि।",
        "recentchanges-noresult": "इ अवधिके दौरान इ मापदंडके पूर्ण करेत समय कोनो परिवर्तन नै केएल गेल अछि।",
        "recentchanges-feed-description": "ई सूचना-तंत्रांशमे विकीमे भेल सभसँ लगक परिवर्तन ताकी।",
        "recentchanges-label-newpage": "ई सम्पादन एकटा नव पन्नाक निर्माण केलक।",
        "recentchanges-label-minor": "ई एकटा लघु सम्पादन छी",
        "recentchanges-label-bot": "ई सम्पादन यान्त्रिक छल।",
-       "recentchanges-label-unpatrolled": "à¤\90 à¤¸à¤®à¥\8dपादनà¤\95 à¤ªà¥\81नरà¥\80à¤\95à¥\8dषण à¤\85à¤\96न à¤§à¤°à¤¿ à¤¨à¥\88 à¤\95à¤\8fल à¤\97à¥\87ल à¤\85à¤\9bि।",
+       "recentchanges-label-unpatrolled": "à¤\88 à¤¸à¤®à¥\8dपादन à¤\85à¤\96न à¤\9cाà¤\81à¤\9aल à¤¨à¥\88 à¤\97à¥\87ल à¤\85à¤\9bि",
        "recentchanges-label-plusminus": "पन्ना आकार ई बाइट सङ्ख्या सँ बदलल गेल",
        "recentchanges-legend-heading": "<strong>कुञ्जी:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|नव पन्नसभक सूची]] सेहो देखी)",
        "upload-permitted": "अनुमतित फाइल  {{PLURAL:$2|प्रकार}}: $1।",
        "upload-preferred": "पसन्दिदा फाइल {{PLURAL:$2|प्रकार|प्रकारसभ}}: $1।",
        "upload-prohibited": "प्रतिबन्धित सञ्चिका {{PLURAL:$2|प्रकार|प्रकारसभ}}:$1 ।",
-       "uploadlogpage": "à¤\89पारà¥\8bपण à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "uploadlogpage": "à¤\89पारà¥\8bपण à¤²à¥\8cà¤\97",
        "uploadlogpagetext": "नीचाँ अद्यतन सञ्चिका उपारोपणक वर्णन अछि।\nदेखी [[Special:NewFiles|नव सञ्चिकाक बखारी]] बेसी स्पष्ट समुच्चा दृश्य लेल।",
        "filename": "सञ्चिका नाम",
        "filedesc": "संक्षेप",
        "file-thumbnail-no": "संचिकानाम शुरू होइए <strong>$1</strong> सँ।\nलगैए जे ई छोट आकारक ''(लघुचित्र)'' क चित्र अछि।\nजँ अहाँ लग पूर्ण आनन्तर्यक चित्र अछि तँ से उपारोपित करू, नै तँ संचिकानाम बदलू।",
        "fileexists-forbidden": "ऐ नामक एकटा संचिका पहिनहियेसँ अछि, आ फेरसँ ओ पुनर्लेखित नै कएल जा सकैए।\nजँ अहाँ तैयो अपन संचिका उपारोपित करए चाहै छी तँ कृपा कऽ पाछाँ जाउ आ एकटा नव नाम चुनू।\n[[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "ऐ नामसँ एकटा संचिका साझी संचिका बखारीमे पहिनहियेसँ अछि।\nजँ अहाँ अखनो अपन संचिका उपारोपित करए चाहै छी, कृपा कऽ पाछाँ जाउ आ एकटा नव नाम चुनू।\n[[File:$1|thumb|center|$1]]",
-       "file-exists-duplicate": "à¤\88 à¤«à¤¾à¤\87ल à¤\8fà¤\95र {{PLURAL:$1|file|files}} à¤¦à¥\8dवितà¥\80यà¤\95 अछि:",
+       "file-exists-duplicate": "à¤\88 à¤«à¤¾à¤\87ल à¤¨à¤¿à¤®à¥\8dनलिà¤\96ित {{PLURAL:$1|फाà¤\87ल|फाà¤\87लसभ}}à¤\95 à¤ªà¥\8dरति अछि:",
        "file-deleted-duplicate": "ऐ संचिका ([[:$1]]) सँ मेल खाइत संचिका पहिनहिये मेटा देल गेल अछि।\nअहाँ ओइ संचिकाक मेटाएल जएबाक इतिहास फेरसँ उपारोपित करबासँ पहिने देखू।",
        "file-deleted-duplicate-notitle": "ऐ स पहिले इ फाइलके अहिने एगो फाइलके हटाएल गेल अछि , आर शीर्षक नुकाएल गेल अछि।\nएकरा फेर स अपलोड करै स पहिले अहाँ कोनो एहन व्यक्ति स स्थितिके  समीक्षा करै लेल कहु जेकरा लंग नुकाएल गेल फाइल देखवाक क्षमता अछि।",
        "uploadwarning": "उपारोपण चेतौनी",
        "filedelete-nofile-old": "'''$1''' एकर कोनो संचित संस्करण खास गुणक संग नै अछि।",
        "filedelete-otherreason": "दोसर/ अतिरिक्त कारण:",
        "filedelete-reason-otherlist": "दोसर कारण",
-       "filedelete-reason-dropdown": "* à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dय à¤¹à¤\9fà¥\87बाà¤\95 à¤\95ारण\n** à¤¸à¤°à¥\8dवाधिà¤\95ार à¤\89लà¥\8dलà¤\82à¤\98न\n** à¤¦à¥\8dवितà¥\80यà¤\95 à¤¸à¤\82à¤\9aिà¤\95ा",
+       "filedelete-reason-dropdown": "* à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dय à¤¹à¤\9fà¥\87बाà¤\95 à¤\95ारण\n** à¤¸à¤°à¥\8dवाधिà¤\95ार à¤\89लà¥\8dलà¤\99à¥\8dà¤\98न\n** à¤ªà¥\8dरतिलिपि à¤«à¤¾à¤\87ल",
        "filedelete-edit-reasonlist": "मेटेबाक कारणक सम्पादन करू",
        "filedelete-maintenance": "सुस्थापन कालमे संचिकाकेँ मेटएबाक आ फेरसँ अनबाक क्रिया कनी काल लेल अशक्त कएल गेल अछि।",
        "filedelete-maintenance-title": "संचिका हटा नै सकैए",
        "mimetype": "माइम प्रकार:",
        "download": "अवारोपन",
        "unwatchedpages": "बिन ध्यान देल पन्ना",
-       "listredirects": "रसà¥\8dता à¤¬à¤¦à¤²à¥\87नक सूची",
+       "listredirects": "पà¥\81नरà¥\8dनिरà¥\8dदà¥\87शनसभक सूची",
        "listduplicatedfiles": "डुप्लिकेट के साथ फाइलसभ के सूची।",
        "listduplicatedfiles-entry": "[[:File:$1|$1]] राखैत अछि  [[$3|{{PLURAL:$2|एक प्रतिलिपि|$2 duplicates}}]] ।",
        "unusedtemplates": "बिना प्रयोगक नमूना सभ",
        "unusedtemplateswlh": "दोसर लागि सभ",
        "randompage": "अव्यवस्थित पृष्ठ",
        "randompage-nopages": "ऐमे दोसर पन्ना नै अछि {{PLURAL:$2|namespace|namespaces}}: $1 ।",
-       "randomincategory": "श्रेणी में यादृच्छिक (रैंडम) पन्ना",
+       "randomincategory": "श्रेणीमे यादृच्छिक पृष्ठ",
        "randomincategory-invalidcategory": "\"$1\" एक मान्य श्रेणी नाम नै अछि।",
        "randomincategory-nopages": "[[:Category:$1|$1]] श्रेणीमे कोनो पृष्ठ नै अछि।",
        "randomincategory-category": "श्रेणी:",
        "randomincategory-legend": "श्रेणीमे यादृच्छिक पृष्ठ",
        "randomincategory-submit": "जाए",
-       "randomredirect": "मिà¤\9cà¥\8dà¤\9dर à¤¬à¤¦à¤²à¥\87नबला à¤²à¤¾à¤\97ि",
+       "randomredirect": "à¤\95à¥\8bनà¥\8b à¤\8fà¤\95 à¤ªà¥\81नरà¥\8dनिरà¥\8dदà¥\87शन à¤ªà¤° à¤\9cाà¤\8f",
        "randomredirect-nopages": "नामस्थान \"$1\" मे कोनो बदलेनबला लागि नै अछि।",
        "statistics": "सांख्यिकी",
        "statistics-header-pages": "पन्नाक तथ्याङ्क",
        "statistics-header-hooks": "दोसर तथ्याङ्क",
        "statistics-articles": "सामग्री पृष्ठ",
        "statistics-pages": "पन्ना",
-       "statistics-pages-desc": "वारà¥\8dता à¤ªà¤¨à¥\8dना, à¤¬à¤¦à¤²à¥\87न à¤\87तà¥\8dयादि à¤¸à¤¹à¤¿à¤¤ à¤¸à¤­à¤\9fा à¤µà¤¿à¤\95ि à¤ªà¤¨à¥\8dना à¤¸à¤­।",
+       "statistics-pages-desc": "वारà¥\8dता à¤ªà¥\83षà¥\8dठ, à¤ªà¥\81नरà¥\8dनिरà¥\8dदà¥\87शन à¤\86दि à¤¸à¤®à¥\87त à¤µà¤¿à¤\95िà¤\95 à¤¸à¤­ à¤ªà¥\83षà¥\8dठ।",
        "statistics-files": "उपारोपित सञ्चिका",
        "statistics-edits": "{{SITENAME}} अएबासँ लऽ कऽ भेल पन्ना सम्पादन",
        "statistics-edits-average": "प्रति पन्ना औसत सम्पादन",
        "pageswithprop-submit": "जाए",
        "pageswithprop-prophidden-long": "लम्बा पाठक गुण नुकाएल ($1) अछि",
        "pageswithprop-prophidden-binary": "बाइनरी गुण ($1) नुकाएल अछि।",
-       "doubleredirects": "दà¥\8dवितà¥\80यà¤\95 à¤²à¤¾à¤\97à¤\8fबला à¤¬à¤¦à¤²à¥\87न",
+       "doubleredirects": "दà¥\81à¤\97à¥\81ना à¤ªà¥\81नरà¥\8dनिरà¥\8dदà¥\87श",
        "doubleredirectstext": "ई पन्ना ओइ पन्ना सभक संकलन छी जे बदलेन करैए दोसर बदलेनबला पन्नासँ।\nप्रत्येक पाँती पहिल आ दोसर बदलेनक लागि रखने अछि आ संगे दोसर बदलेनक लक्ष्य सेहो, जे वास्तवमे \"वास्तव\" लक्ष्य पन्ना अछि, जकरापर पहिल बदलेनकेँ जेबाक चाही। \n <del>Crossed out</del> प्रविष्टिक हल भेटल अछि।",
        "double-redirect-fixed-move": "[[$1]] घसकाएल गेल।\nई आब [[$2]] दिस जा रहल अछि।",
-       "double-redirect-fixed-maintenance": "द्वितीयक बदलेन [[$1]] सँ [[$2]] कएल गेल।",
-       "double-redirect-fixer": "बदलà¥\87न à¤¸à¥\8dथायितà¥\8dव",
-       "brokenredirects": "à¤\9fà¥\82à¤\9fल à¤¬à¤¦à¤²à¥\87न à¤¸à¤­",
-       "brokenredirectstext": "à¤\88 à¤¬à¤¦à¤²à¥\87न सभ नै अवस्थित पन्ना सभक दिस जाइत अछि।",
+       "double-redirect-fixed-maintenance": "[[$1]] सँ [[$2]]क दुगुणा पुनर्प्रेषणक रखरखाव कार्यमे स्वतः ठीक करि रहल अछि।",
+       "double-redirect-fixer": "पà¥\81नरà¥\8dपà¥\8dरà¥\87षण à¤®à¤¿à¤¸à¥\8dतà¥\8dरà¥\80",
+       "brokenredirects": "तà¥\81à¤\9fल à¤ªà¥\81नरà¥\8dनिरà¥\8dदà¥\87शन à¤ªà¥\83षà¥\8dठ",
+       "brokenredirectstext": "à¤\88 à¤ªà¥\81नरà¥\8dनिरà¥\8dदà¥\87शनसभ नै अवस्थित पन्ना सभक दिस जाइत अछि।",
        "brokenredirects-edit": "सम्पादन करी",
        "brokenredirects-delete": "मेटाबी",
        "withoutinterwiki": "बिना भाषा लिङ्कक पन्ना",
        "prefixindex": "उपसर्गक संग सभटा पृष्ठ",
        "prefixindex-namespace": "उपसर्ग भएल सभ पृष्ठ ($1 नामस्थान)",
        "prefixindex-strip": "सूची में उपसर्ग नुकाउ",
-       "shortpages": "पनà¥\8dना à¤¸à¤­ à¤\9bाà¤\81à¤\9fà¥\82",
+       "shortpages": "à¤\9bà¥\8bà¤\9f à¤ªà¥\83षà¥\8dठसभ",
        "longpages": "नमगर पन्ना सभ",
        "deadendpages": "एकदमसँ अन्त भऽ जाएबला पन्ना सभ",
        "deadendpagestext": "ई पन्ना सभ {{SITENAME}} क दोसर पन्नासँ लागिमे नै रहत।",
        "protectedpages": "सुरक्षित पृष्ठ",
        "protectedpages-indef": "अनन्तकालिक सुरक्षा मात्र",
        "protectedpages-cascade": "तराउपड़ी सुरक्षा मात्र",
-       "protectedpages-noredirect": "बदलà¥\87न à¤¨à¥\81à¤\95ाà¤\8aà¤\81",
+       "protectedpages-noredirect": "पà¥\81नरà¥\8dनिरà¥\8dदà¥\87श à¤¨à¥\81à¤\95ाबà¥\80",
        "protectedpagesempty": "कोनो पन्ना ऐ सभ परिमिति लेल सुरक्षित नै राखल गेल अछि।",
        "protectedpages-timestamp": "समएकाल",
        "protectedpages-page": "पृष्ठ",
        "speciallogtitlelabel": "प्रयोजन (शीर्षक अथवा {{ns:user}}:प्रयोगकर्तानाम):",
        "log": "लौग",
        "logeventslist-submit": "देखाबी",
-       "all-logs-page": "सभ à¤¸à¤¾à¤°à¥\8dवà¤\9cनिà¤\95 à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "all-logs-page": "सभ à¤¸à¤¾à¤°à¥\8dवà¤\9cनिà¤\95 à¤²à¥\8cà¤\97",
        "alllogstext": "{{अन्तर्जाल}} क सभटा उपलब्ध वृत्तलेखक संयुक्त दृश्य।\nअहाँ दृश्यकेँ संकीर्ण करबा लेल वृत्तलेखक एकटा प्रकार चुनि सकै छी, प्रयोक्तानाम (ब्रह्मक्षर-लघ्वक्षर विचारणीय), वा प्रभावित पन्ना (एतौ ब्रह्मक्षर-लघ्वक्षर विचारणीय)।",
        "logempty": "वृत्तलेखमे कोनो मेल खाइबला बौस्तु नै।",
        "log-title-wildcard": "खोज शीर्षक सभ ऐ पाठसँ प्रारम्भ",
        "listusers-submit": "देखाबी",
        "listusers-noresult": "कोनो प्रयोक्ता नै",
        "listusers-blocked": "(प्रतिबन्धित)",
-       "activeusers": "सक्रिय प्रयोक्ता सभक सूची",
+       "activeusers": "सक्रिय प्रयोक्तासभक सूची",
        "activeusers-intro": "ई ओहेन प्रयोक्ता सभक सूची अछि जे पछिला $1 {{PLURAL:$1|दिन|दिन}} मे किछु सक्रियता देखेने छथि।",
        "activeusers-count": "$1 {{PLURAL:$1|कार्य}} पिछला $3 {{PLURAL:$3|दिन|दिनसभ}}मे",
        "activeusers-from": "प्रयोक्ता प्रदर्शन प्रारम्भ भेल:",
-       "activeusers-hidebots": "स्वचालक नुकाबी",
-       "activeusers-hidesysops": "प्रबन्धक नुकाबी",
        "activeusers-noresult": "कोनो प्रयोक्ता नै भेटल",
        "activeusers-submit": "सक्रिय प्रयोगकर्ता देखाबी",
        "listgrouprights": "प्रयोगकर्ता समूह अधिकार",
        "listgrants-summary": "ई प्रदान केल गेल सूची छी। सदस्य अपन खाताक अनुपयोगक द्वारा उपयोग करि सकैत अछि, मुदा मात्र किछ सीमित अधिकार धरि। ई अधिकार सदस्यद्वारा देल गेल अधिकार धरि सीमित रहैत अछि । एतय [[{{MediaWiki:Listgrouprights-helppage}}|अन्य जानकारी]] सेहो अछि, जे एक अधिकारक बारेमे बताबैत अछि।",
        "listgrants-grant": "अधिकार",
        "listgrants-rights": "अधिकार",
-       "trackingcategories": "शà¥\8dरà¥\87णà¥\80à¤\95à¥\87 à¤\9fà¥\8dरयाà¤\95 à¤\95रà¥\81",
+       "trackingcategories": "à¤\9aिहà¥\8dनित à¤¶à¥\8dरà¥\87णà¥\80सभ",
        "trackingcategories-summary": "ई पृष्ठ पर ओ जोडवाला श्रेणीसभक सूची मिलैत अछि जे स्वतः रूप सँ मिडियाविकि सफ्टवेयरद्वारा बनैत अछि। ओ सभक नाम सम्बन्धित प्रणाली सन्देस बदलै सँ {{ns:8}} नामस्थानमे बदलल जा सकैत अछि।",
        "trackingcategories-msg": "चिह्नित श्रेणी",
        "trackingcategories-name": "सन्देश नाम",
        "emailsubject": "विषय:",
        "emailmessage": "सन्देश:",
        "emailsend": "पठाबी",
-       "emailccme": "हमर à¤¸à¤¨à¥\8dदà¥\87शà¤\95 à¤¦à¥\8dवितà¥\80यà¤\95 à¤¹à¤®à¤° à¤\88-पतà¥\8dरपर पठाबी",
-       "emailccsubject": "à¤\85हाà¤\81à¤\95 à¤¸à¤\82दà¥\87शà¤\95 à¤¦à¥\8dवितà¥\80यà¤\95 $1: $2",
+       "emailccme": "हमर à¤¸à¤¨à¥\8dदà¥\87शà¤\95 à¤ªà¥\8dरति à¤¹à¤®à¤° à¤\87मà¥\87लमà¥\87 पठाबी",
+       "emailccsubject": "à¤\85हाà¤\81à¤\95 à¤\87मà¥\87लà¤\95 à¤ªà¥\8dरति à¤\9cà¥\87 $1à¤\95 à¤­à¥\87à¤\9cल à¤\97à¥\87ल: $2",
        "emailsent": "ई-पत्र पठेलौं",
        "emailsenttext": "अहाँक ई-पत्र सन्देश पठाएल गेल।",
        "emailuserfooter": "ई ई-मेल $1 {{GENDER:$1|द्वारा}} {{GENDER:$2|$2}}क भेजल गेल छल जेकर लेल \"{{int:emailuser}}\" कार्यके {{SITENAME}} पर प्रयोगमे लाबल गेल छल।",
        "enotif_impersonal_salutation": "{{SITENAME}} प्रयोगकर्ता",
        "enotif_subject_deleted": "{{SITENAME}} पन्ना $1 के {{gender:$2|$2}} हटेलक",
        "enotif_subject_created": "{{SITENAME}} पन्ना $1 को {{gender:$2|$2}} बनेलक",
-       "enotif_subject_moved": "{{SITENAME}} à¤ªà¥\83षà¥\8dठ $1 à¤\95à¥\87 {{gender:$2|$2}} à¤\98सà¤\95ेलक",
+       "enotif_subject_moved": "{{SITENAME}} à¤ªà¥\83षà¥\8dठ $1 à¤\95à¥\87 {{gender:$2|$2}} à¤¸à¥\8dथानानà¥\8dतरित à¤\95रि à¤¦ेलक",
        "enotif_subject_restored": "{{SITENAME}} पृष्ठ $1 के {{gender:$2|$2}}द्वारा पुनर्स्थापित करल गेल अछि",
        "enotif_subject_changed": "{{SITENAME}} पृष्ठ $1 के {{gender:$2|$2}}द्वारा परिवर्तित केल गेल अछि",
        "enotif_body_intro_deleted": "{{SITENAME}} पृष्ठ $1 के {{gender:$2|$2}}द्वारा $PAGEEDITDATE क मेटाए देलक, देखी $3।",
        "actioncomplete": "क्रिया पूर्ण",
        "actionfailed": "कार्य नै भेल",
        "deletedtext": "\"$1\" केँ मेटा देल गेल अछि।\nदेखू $2 हालक मेटाएल सामिग्रीक अभिलेख लेल।",
-       "dellogpage": "मà¥\87à¤\9fाà¤\8fल à¤¸à¤¾à¤®à¤¿à¤\97à¥\8dरà¥\80à¤\95 à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "dellogpage": "मà¥\87à¤\9fाà¤\8fल à¤²à¥\8cà¤\97",
        "dellogpagetext": "नीचाँ एकदम लगक मेटाएल पन्नाकऽ सूची छी।",
-       "deletionlog": "मà¥\87à¤\9fाà¤\8fल à¤¸à¤¾à¤®à¤¿à¤\97à¥\8dरà¥\80à¤\95 à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "deletionlog": "मà¥\87à¤\9fाà¤\8fल à¤²à¥\8cà¤\97",
        "reverted": "पुरान कोनो संशोधन धरि घुराउ",
        "deletecomment": "कारण:",
        "deleteotherreason": "दोसर/ अतिरिक्त कारण:",
        "undeletedpage": "'''$1 के पुनर्स्थापित करल गेल अछि'''\n\nलग पास में हटाओल गेल आ पुनर्स्थापित कएल गेल पन्ना सभके जानकारी के लेल [[Special:Log/delete|हटाओल गेल लग]] देखु।",
        "undelete-header": "हालक मेटाएल पन्ना के लेल [[Special:Log/delete|हटाएल लग]] देखू।",
        "undelete-search-title": "मेटाएल गेल पृष्ठ ताकी",
-       "undelete-search-box": "मेटाएल पन्ना सभकेँ ताकू",
+       "undelete-search-box": "मेटाएल पन्नासभ ताकी",
        "undelete-search-prefix": "से शुरु भेल पन्ना देखाबू.",
        "undelete-search-submit": "ताकू",
        "undelete-no-results": "एहेन पन्ना मेटाएल पेटारमे नै भेटल।",
        "sp-contributions-newbies": "मात्र नव खाताक योगदान देखाबी",
        "sp-contributions-newbies-sub": "नब प्रयोक्ताकऽ लेल",
        "sp-contributions-newbies-title": "नब प्रयोक्ताकऽ योगदान",
-       "sp-contributions-blocklog": "पà¥\8dरतिबनà¥\8dधित à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "sp-contributions-blocklog": "पà¥\8dरतिबनà¥\8dधित à¤²à¥\8cà¤\97",
        "sp-contributions-suppresslog": "{{GENDER:$1|प्रयोगकर्ता}} योगदान दबाबी",
        "sp-contributions-deleted": "{{GENDER:$1|प्रयोगकर्ता}}क मेटाएल योगदान",
        "sp-contributions-uploads": "उपारोपण",
-       "sp-contributions-logs": "वà¥\83तà¥\8dतलà¥\87à¤\96 à¤¸à¤­",
+       "sp-contributions-logs": "लà¥\8cà¤\97",
        "sp-contributions-talk": "वार्त्ता",
        "sp-contributions-userrights": "प्रयोक्ता अधिकारकऽ प्रबन्धन",
        "sp-contributions-blocked-notice": "ई प्रयोक्ता अखन प्रतिबन्धित अछि।\nनव प्रतिबन्धित वृत्तलेख लेख सन्दर्भ नीचाँ देल अछि:",
        "sp-contributions-blocked-notice-anon": "ई अनिकेत अखन प्रतिबन्धित अछि।\nअद्यतन प्रतिबन्धित  वृत्तलेख लेखा सन्दर्भ नीचाँ देल अछि:",
        "sp-contributions-search": "अवदानक लेल ताकू",
        "sp-contributions-username": "अनिकेत संकेत वा प्रयोक्तानाम:",
-       "sp-contributions-toponly": "मात्र ओइ सम्पादनकेँ देखाउ जे अद्यतन संशोधन छी।",
+       "sp-contributions-toponly": "मात्र ओइ सम्पादन देखाबी जे अद्यतन संशोधन छी।",
        "sp-contributions-newonly": "मात्र ओइ सम्पादन देखाउ जे पृष्ठ निर्मित भेल अछि",
        "sp-contributions-hideminor": "अल्प सम्पादन नुकाबी",
        "sp-contributions-submit": "ताकू",
        "contribslink": "योगदान",
        "emaillink": "ई-पत्र पठाउ",
        "autoblocker": "अहाँक अनिकेत \"[[User:$1|$1]]\" द्वारा प्रयोगक कारण स्वचालित रूपेँ प्रतिबन्धित भऽ गेल।\n$1 एकर प्रतिबन्धक कारण अछि : \"$2\"",
-       "blocklogpage": "पà¥\8dरतिबनà¥\8dधित à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "blocklogpage": "पà¥\8dरतिबनà¥\8dधित à¤²à¥\8cà¤\97",
        "blocklog-showlog": "ऐ प्रयोक्ताकेँ पहिनहिये प्रतिबन्धित कऽ देल गेल अछि।\nप्रतिबन्धक वृत्तलेख सन्दर्भ लेल नीचाँ देल जा रहल अछि:",
        "blocklog-showsuppresslog": "ऐ प्रयोक्ताकेँ पहिनहिये प्रतिबन्धित आ अदृश्य कऽ देल गेल अछि।\nदबाएल वृत्तलेख सन्दर्भ लेल नीचाँ देल जा रहल अछि:",
        "blocklogentry": "प्रतिबन्धित [[$1]] एकर अन्तिम तिथि अछि $2 $3",
        "movepage-page-moved": "पन्ना $1 केँ $2 लग घसका देल गेल अछि।",
        "movepage-page-unmoved": "पन्ना $1 केँ $2 लग नै घसकाएल जा सकैए।",
        "movepage-max-pages": "बेसी सें बेसी $1 पृष्ठ बदलि के {{PLURAL:$1| क देल गेल अछि|क देल गेल अछि}}, आब आर पृष्ठ अपने आप नहि बदलत.",
-       "movelogpage": "स्थानान्तरण लग",
+       "movelogpage": "सà¥\8dथानानà¥\8dतरण à¤²à¥\8cà¤\97",
        "movelogpagetext": "नाम बदलल गेल लेख कऽ सूचि नीचां देल गेल अछि",
        "movesubpage": "{{PLURAL:$1|उप पन्ना|उप पन्ना}}",
        "movesubpagetext": "नीचां $1 {{PLURAL:$1| पन्ना देखाओल गएल अछि, जे अहि पन्नाकऽ उप पन्ना अछि|पन्ना देखावोल गएल अछि, जे अहि पन्नाकऽ उप पन्ना अछि}}।",
        "allmessages-prefix": "उपसर्गक आधारपर छाँटू:",
        "allmessages-language": "भाषा:",
        "allmessages-filter-submit": "चलू",
-       "allmessages-filter-translate": "à¤\85नà¥\81वाद à¤\95रà¥\81",
+       "allmessages-filter-translate": "à¤\85नà¥\81वाद à¤\95रà¥\80",
        "thumbnail-more": "पैग",
        "filemissing": "संचिका हेराएल",
        "thumbnail_error": "लघुचित्र निर्माण कालमे भ्रम:$1",
        "import-rootpage-nosubpage": "दयाल गेल उपसर्ग पन्ना \"$1\" के नामस्थान में उप-पन्ना नै बनाबाल जा सकएत अछि ।",
        "importlogpage": "आयात सूची",
        "importlogpagetext": "पन्ना सभक प्रशासनिक आयात दोसर विकीक सम्पादन इतिहासक संग।",
-       "import-logentry-upload-detail": "$1 {{PLURAL:$1|सुधार|सुधार सभ}}",
+       "import-logentry-upload-detail": "$1 अवतरण आयात {{PLURAL:$1|केलक|कएल गेल}}",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|सुधार|सुधार सभ}} $2 सँ",
        "javascripttest": "जावास्क्रिप्ट परिक्षण",
        "javascripttest-pagetext-unknownaction": "अज्ञात क्रिया \"$1\" ।",
        "tooltip-t-permalink": "पृष्ठक ई संस्करणक स्थायी लिङ्क",
        "tooltip-ca-nstab-main": "सामग्री वाला पृष्ठ देखी",
        "tooltip-ca-nstab-user": "प्रयोक्ता पन्ना देखी",
-       "tooltip-ca-nstab-media": "मà¥\80डिया à¤ªà¥\83षà¥\8dठ à¤¦à¥\87à¤\96à¥\82",
+       "tooltip-ca-nstab-media": "मिडिया à¤ªà¥\83षà¥\8dठ à¤¦à¥\87à¤\96à¥\80",
        "tooltip-ca-nstab-special": "ई एकटा विशिष्ट पन्ना छी, आ अहाँ एकरा सम्पादित नै कऽ सकै छी",
        "tooltip-ca-nstab-project": "परियोजना पन्ना देखी",
        "tooltip-ca-nstab-image": "सञ्चिकाक पृष्ठ देखी",
        "tooltip-ca-nstab-mediawiki": "प्रणालीक सन्देश देखी",
        "tooltip-ca-nstab-template": "नमूना देखी",
-       "tooltip-ca-nstab-help": "सहायता à¤ªà¥\83षà¥\8dठ à¤¦à¥\87à¤\96à¥\82",
+       "tooltip-ca-nstab-help": "सहायता à¤ªà¥\83षà¥\8dठ à¤¦à¥\87à¤\96à¥\80",
        "tooltip-ca-nstab-category": "श्रेणी पन्ना देखी",
        "tooltip-minoredit": "एकरा मामली सम्पादन चिन्हित करू",
        "tooltip-save": "अपन परिवर्तन सुरक्षित करी",
        "pageinfo-protect-cascading-from": "सुरक्षा-विकल्प व्यापक भऽ रहल अछि स्थान-सऽ",
        "pageinfo-category-info": "संवर्ग जानकारी",
        "pageinfo-category-total": "सम्पादनक संख्या",
-       "pageinfo-category-pages": "पà¥\83षà¥\8dठ à¤¸à¤\82ख्या",
+       "pageinfo-category-pages": "पà¥\83षà¥\8dठ à¤¸à¤\99à¥\8dख्या",
        "pageinfo-category-subcats": "उपसंवर्ग के संख्या",
        "pageinfo-category-files": "फाइल सभके संख्या",
        "markaspatrolleddiff": "जाँच सम्पन्न करी",
        "markedaspatrollederror-noautopatrol": "अहाँ अपन कएल संशोधनकेँ संचालित नै कहि सकै छी।",
        "markedaspatrollednotify": "$1 पृष्ठ में कएल गएल ऐ परिवर्तन जाँचल गेल चिन्हासी कएल गेल।",
        "markedaspatrollederrornotify": "जाँचल चिन्हासी असफल भेल।",
-       "patrol-log-page": "सà¤\82à¤\9aालन à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
-       "patrol-log-header": "à¤\88 à¤¸à¤\82à¤\9aालित à¤¸à¤\82शà¥\8bधन à¤¸à¤­à¤\95 à¤µà¥\83तà¥\8dतलà¥\87à¤\96 छी।",
-       "log-show-hide-patrol": "$1 à¤¨à¤¿à¤°à¥\80à¤\95à¥\8dषण à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "patrol-log-page": "परà¥\80à¤\95à¥\8dषण à¤²à¥\8cà¤\97",
+       "patrol-log-header": "à¤\88 à¤ªà¤°à¥\80à¤\95à¥\8dषित à¤\85वतरणसभà¤\95 à¤²à¥\8cà¤\97 छी।",
+       "log-show-hide-patrol": "$1 à¤¨à¤¿à¤°à¥\80à¤\95à¥\8dषण à¤²à¥\8cà¤\97",
        "log-show-hide-tag": "$1 ट्याग लग",
        "deletedrevision": "पुरान संशोधन $1 हटा देलौं",
        "filedeleteerror-short": "संचिका मेटेबामे भ्रम : $1",
        "exif-orientation-1": "सामान्य",
        "exif-orientation-2": "अनुदैर्घ्य मिज्झर",
        "exif-orientation-3": "180° पर घुमायल गेल",
-       "exif-orientation-4": "à¤\85नà¥\81पà¥\8dरसà¥\8dथ à¤®à¤¿à¤\9cà¥\8dà¤\9dर",
+       "exif-orientation-4": "भरà¥\8dà¤\9fिà¤\95लà¥\80 à¤«à¥\8dलिप à¤\95रà¥\80",
        "exif-orientation-5": "90° सी.सी.डब्लू. घुमाओल गेल आ अनुप्रस्थ रूपेँ मिज्झर कएल गेल",
        "exif-orientation-6": "९०° सी.सी.डब्लू. घुमाएल गेल",
        "exif-orientation-7": "९०° सी.डब्लू. घुमाओल गेल आ अनुप्रस्थ रूपेँ मिज्झर कएल गेल",
        "exif-customrendered-0": "सामान्य प्रक्रिया",
        "exif-customrendered-1": "वैकल्पिक प्रक्रिया",
        "exif-exposuremode-0": "स्वयं देखबैत",
-       "exif-exposuremode-1": "सà¤\82à¤\9aालित à¤¦à¥\87à¤\96ाà¤\8fब",
+       "exif-exposuremode-1": "मà¥\88नà¥\8dयà¥\81à¤\85ल à¤\8fà¤\95à¥\8dपà¥\8bà¤\9cर",
        "exif-exposuremode-2": "स्वचालित कोष्ठक",
        "exif-whitebalance-0": "स्वचालित उज्जर सन्तुलन",
        "exif-whitebalance-1": "संचालित उज्जर सन्तुलन",
        "descending_abbrev": "जानकारी",
        "table_pager_next": "अगला पृष्ठ",
        "table_pager_prev": "पहिलुका पृष्ठ",
-       "table_pager_first": "पहला पृष्ठ",
+       "table_pager_first": "पहिल पृष्ठ",
        "table_pager_last": "अन्तिम पृष्ठ",
        "table_pager_limit": "एक पृष्ठ पर $1 सामग्री देखाबी",
        "table_pager_limit_label": "सामग्री प्रति पृष्ठ",
        "autosumm-blank": "पृष्ठ खाली कएल गेल",
        "autosumm-replace": "\"$1\" सहित पाठ परिवर्तित भेल",
        "autoredircomment": "[[$1]] के अनुप्रेषित",
-       "autosumm-new": "'$1' à¤¸à¤\82à¤\97 à¤¨à¤¬ पृष्ठ बनाओल गेल",
+       "autosumm-new": "'$1' à¤¸à¤\82à¤\97 à¤¨à¤µ पृष्ठ बनाओल गेल",
        "autosumm-newblank": "खालि पन्ना बनाओल गेल",
        "lag-warn-normal": "$1 सँ नव बदलल गेल {{PLURAL:$1|सेकेण्ड|सेकेण्ड}} ऐ सूचीमे नै देखाएल गेल।",
        "lag-warn-high": "उच्च दत्तनिधि वितरक देरीक कारण, $1 सँ नव परिवर्तन {{PLURAL:$1|सेकेण्ड|सेकेण्ड}} ऐ सूचीमे नै देखाएल जा सकल।",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 शीर्षक छल|$1शीर्षक सभ रहए}} जोड़ल गेल:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 शीर्षक छल|$1शीर्षक सभ रहए}} हटाएल गेल:",
        "watchlistedit-clear-title": "ध्यानसूची खाली करी",
-       "watchlistedit-clear-legend": "साà¤\95ाà¤\82à¤\95à¥\8dष-सà¥\82à¤\9aà¥\80 à¤®à¥\87à¤\9fाà¤\89",
+       "watchlistedit-clear-legend": "साà¤\95ाà¤\82à¤\95à¥\8dष-सà¥\82à¤\9aà¥\80 à¤®à¥\87à¤\9fाबà¥\80",
        "watchlistedit-clear-explain": "एही ठाम रहल सभ शिर्षक अहाँक साकांक्ष-सूची से मेटा जाएत",
        "watchlistedit-clear-titles": "शीर्षक",
        "watchlistedit-clear-submit": "साकांक्ष-सूची मेटाउ (ई स्थायी छि!)",
        "watchlistedit-clear-done": "अहाँक साकांक्ष-सूची मेटाओल गेल।",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 शीर्षक छल|$1शीर्षक सभ रहए}} हटाएल गेल:",
-       "watchlistedit-too-many": "à¤\8fतà¥\87à¤\95 à¤¬à¤¹à¥\81त à¤°à¤¾à¤¸ à¤ªà¤¨à¥\8dना à¤¸à¤­ à¤¦à¥\87à¤\96ावà¥\8bल à¤\9cाà¤\8fत।",
-       "watchlisttools-clear": "साà¤\95ाà¤\82à¤\95à¥\8dष-सà¥\82à¤\9aà¥\80 à¤®à¥\87à¤\9fाà¤\89",
+       "watchlistedit-too-many": "à¤\8fतय à¤¦à¤°à¥\8dशावà¥\88à¤\95 à¤²à¥\87ल à¤\85तà¥\8dयधिà¤\95 à¤ªà¥\83षà¥\8dठ à¤\85à¤\9bि।",
+       "watchlisttools-clear": "साà¤\95ाà¤\82à¤\95à¥\8dष-सà¥\82à¤\9aà¥\80 à¤®à¥\87à¤\9fाबà¥\80",
        "watchlisttools-view": "सम्बन्धित परिवर्तन सभकेँ देखी",
        "watchlisttools-edit": "साकांक्षसूची देखी आ सम्पादित करी",
        "watchlisttools-raw": "काँच साकांक्षसूची सम्पादित करी",
        "redirect-file": "फाइल नाम",
        "redirect-logid": "प्रवेश आइडी",
        "redirect-not-exists": "बैनर नैं मिल्ल",
-       "fileduplicatesearch": "दà¥\8dवितà¥\80यà¤\95 à¤¸à¤\82à¤\9aिà¤\95ा à¤¤à¤¾à¤\95à¥\82",
-       "fileduplicatesearch-summary": "हà¥\88श à¤®à¤¾à¤¨à¤\95 à¤\86धारपर à¤¦à¥\8dवितà¥\80यà¤\95 à¤¸à¤\82à¤\9aिà¤\95ा à¤¤à¤¾à¤\95à¥\82।",
+       "fileduplicatesearch": "पà¥\8dरतिलिपि à¤«à¤¾à¤\87ल à¤¤à¤¾à¤\95à¥\80",
+       "fileduplicatesearch-summary": "हà¥\8dयाश à¤®à¤¾à¤¨à¤\95 à¤\86धारपर à¤ªà¥\8dरतिलà¥\8dपà¥\80 à¤«à¤¾à¤\87ल à¤¤à¤¾à¤\95à¥\80।",
        "fileduplicatesearch-filename": "संचिकानाम:",
        "fileduplicatesearch-submit": "ताकू",
        "fileduplicatesearch-info": "$1 × $2 चित्राणु<br /> फाइल आकार: $3<br /> माइम प्रकार: $4",
-       "fileduplicatesearch-result-1": "सà¤\82à¤\9aिà¤\95ा \"$1\" à¤²à¥\87ल à¤\95à¥\8bनà¥\8b à¤¤à¤¾à¤¦à¤¾à¤¤à¥\8dमà¥\8dय à¤¦à¥\8dवितà¥\80यà¤\95 à¤¨à¥\88।",
-       "fileduplicatesearch-result-n": "सà¤\82à¤\9aिà¤\95ा \"$1\" à¤\95à¥\87à¤\81 à¤\9bà¥\88 {{PLURAL:$2|1 à¤¤à¤¾à¤¦à¤¾à¤¤à¥\8dमà¥\8dय à¤¦à¥\8dवितà¥\80यà¤\95|$2तादातà¥\8dमà¥\8dय à¤¦à¥\8dवितà¥\80यà¤\95}}.",
+       "fileduplicatesearch-result-1": "फाà¤\87ल \"$1\" à¤®à¥\87 à¤\95à¥\8bनà¥\8b à¤ªà¥\8dरतिलिपि à¤¨à¥\88 à¤\85à¤\9bि।",
+       "fileduplicatesearch-result-n": "फाà¤\87ल \"$1\" à¤®à¥\87 {{PLURAL:$2|1 à¤¤à¤¾à¤¦à¤¾à¤¤à¥\8dमà¥\8dय à¤¦à¥\8dवितà¥\80यà¤\95|$2 à¤¤à¤¾à¤¦à¤¾à¤¤à¥\8dमà¥\8dय à¤¦à¥\8dवितà¥\80यà¤\95}} à¤­à¥\87à¤\9fल à¤\85à¤\9bि।",
        "fileduplicatesearch-noresults": "कोनो \"$1\" नाम्ना संचिका नै।",
        "specialpages": "विशेष पन्नासभ",
        "specialpages-note-top": "कुंजी",
        "specialpages-group-maintenance": "सुस्थापन प्रतिवेदन",
        "specialpages-group-other": "दोसर विशेष पन्ना",
        "specialpages-group-login": "सम्प्रवेश/ सम्प्रवेश आवेदन",
-       "specialpages-group-changes": "हालà¤\95 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\86 à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "specialpages-group-changes": "सनà¥\8dनिà¤\95à¤\9f à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\86 à¤²à¥\8cà¤\97",
        "specialpages-group-media": "मीडिया प्रतिवेदन आ उपारोपण",
        "specialpages-group-users": "प्रयोक्ता आ अधिकार",
-       "specialpages-group-highuse": "बà¥\87सà¥\80 à¤ªà¥\8dरयà¥\8bà¤\97बला à¤ªà¤¨à¥\8dना à¤¸à¤­",
+       "specialpages-group-highuse": "à¤\85तà¥\8dयधिà¤\95 à¤\89पयà¥\8bà¤\97à¥\80 à¤ªà¥\83षà¥\8dठ",
        "specialpages-group-pages": "पन्ना सभक सूची",
        "specialpages-group-pagetools": "पन्नाक औजार सभ",
        "specialpages-group-wiki": "विकी दत्तांश आ औजार सभ",
        "tags-title": "चेन्ह सभ",
        "tags-intro": "ई पन्ना चेन्ह सभकेँ सूचित करैए जे तंत्रांश सम्पादनसँ चिन्हित करए, आ ओकर अर्थ सेहो।",
        "tags-tag": "चेन्हक नाम",
-       "tags-display-header": "परिवरà¥\8dतन à¤¸à¥\82à¤\9aà¥\80 à¤¸à¤­à¤\95 à¤°à¥\82परà¤\82à¤\97",
+       "tags-display-header": "परिवरà¥\8dतन à¤¸à¥\82à¤\9aिसभमà¥\87 à¤ªà¥\8dरदरà¥\8dशन",
        "tags-description-header": "अर्थक पूर्ण विवरण",
        "tags-source-header": "स्रोत",
        "tags-active-header": "सक्रिय?",
        "tags-edit-title": "ट्याग सम्पादन",
        "tags-edit-manage-link": "ट्याग व्यवस्थापन",
        "tags-edit-revision-selected": "[[:$2]] {{PLURAL:$1|क|के}} चयनित अवतरण:",
-       "tags-edit-logentry-selected": "{{PLURAL:$1|à¤\9aà¥\81नल à¤µà¥\83तà¥\8dतलà¥\87à¤\96 à¤\98à¤\9fना|à¤\9aà¥\81नल à¤µà¥\83तà¥\8dतलà¥\87à¤\96 à¤\98à¤\9fना सभ}}:",
+       "tags-edit-logentry-selected": "{{PLURAL:$1|à¤\9aà¥\81नल à¤²à¥\8cà¤\97 à¤\98à¤\9fना|à¤\9aà¥\81नल à¤²à¥\8cà¤\97 à¤\98à¤\9fनासभ}}:",
        "tags-edit-existing-tags-none": "<em>कोनो नै</em>",
        "tags-edit-new-tags": "नव ट्याग:",
        "tags-edit-add": "इ ट्यागसभ जोडी:",
        "htmlform-cloner-delete": "हटाउ",
        "logentry-delete-delete": "$1 पृष्ठ $3 {{GENDER:$2|मेटौलक}}",
        "logentry-delete-restore": "$1 {{GENDER:$2|restored}} page $3",
-       "logentry-delete-event": "$1 {{GENDER:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा वृत्तलेख|$5 वृत्तलेख}}  $3: $4 केँ",
+       "logentry-delete-event": "$1द्वारा $3 पृष्ठक लौग {{PLURAL:$5|प्रविष्टि|प्रविष्टिसभ}}क दृश्यता {{GENDER:$2|परिवर्तित केलक}}: $4",
        "logentry-delete-revision": "$1 द्वारा $3 पृष्ठक {{PLURAL:$5|एक अवतरण|$5 अवतरणसभ}}क दृश्यता {{GENDER:$2|परिवर्तित}}: $4",
-       "logentry-delete-event-legacy": "$1 {{GENDER:$2|changed}}  $3 पर वृत्तलेख दृश्य",
-       "logentry-delete-revision-legacy": "$1 {{GENDER:$2|changed}}  $3 पर वृत्तलेख संशोधन",
+       "logentry-delete-event-legacy": "$1द्वारा $3 पृष्ठ पर लौग क्रियासभक दृश्यता {{GENDER:$2|परिवर्तित केलक}}",
+       "logentry-delete-revision-legacy": "$1द्वारा $3 पृष्ठ पर अवतरणसभक दृश्यता {{GENDER:$2|परिवर्तित केलक}}",
        "logentry-suppress-delete": "$1 {{GENDER:$2|दबाएल}} page $3",
        "logentry-suppress-event": "$1 चोरिसँ {{GENDER:$2|परिवर्तन कियल गैल}} एकर दृश्य{{PLURAL:$5| एकटा वृत्तलेख|$5 वृत्तलेख}}  $3: $4 पर",
        "logentry-suppress-revision": "$1 चोरिसँ {{GENDER:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा संशोधन|$5 संशोधन}}  $3: $4 पर",
-       "logentry-suppress-event-legacy": "$1 नुका क {{GENDER:$2|परिवर्तन}}  $3 पर वृत्तलेख दृश्य",
+       "logentry-suppress-event-legacy": "$1द्वारा गुप्त रूपसँ $3 पृष्ठ पर लौग क्रियासभक दृश्यता {{GENDER:$2|परिवर्तित केलक}}",
        "logentry-suppress-revision-legacy": "$1 नुका कऽ {{GENDER:$2|changed}}  $3 पर संशोधन दृश्य",
        "revdelete-content-hid": "सामिग्री नुकाएल",
        "revdelete-summary-hid": "नुकाएल सारांश सम्पादन",
        "revdelete-restricted": "संचालक लेल प्रायोगिक प्रतिबन्ध",
        "revdelete-unrestricted": "संचालक लेल हटाओल प्रतिबन्ध",
        "logentry-import-upload": "$1 {{GENDER:$2|आयात केल गेल}} $3 संचिका उपारोपन के माध्यम सँ",
-       "logentry-import-interwiki": "$1 {{GENDER:$2|à¤\86यात à¤\95à¥\87ल à¤\97à¥\87ल}} $3 à¤\95à¥\8bनà¥\8b à¤\94र à¤µà¤¿à¤\95ि सँ",
+       "logentry-import-interwiki": "$1 {{GENDER:$2|à¤\86यात à¤\95à¤\8fल à¤\97à¥\87ल}} $3 à¤\95à¥\8bनà¥\8b à¤\94र à¤µà¤¿à¤\95िसँ",
        "logentry-merge-merge": "$1 {{GENDER:$2|विलय केल गेल}} $3 के $4 में (संशोधन $5 धरि)",
        "logentry-move-move": "$1द्वारा $3 पृष्ठ $4 पर {{GENDER:$2|स्थानान्तरित}} कएलक",
        "logentry-move-move-noredirect": "$1 द्वारा $3 पर पुनर्निर्देशन नै छोडि ओकरा $4 पर {{GENDER:$2|स्थानान्तरित}} केलक",
        "feedback-back": "पाछां",
        "feedback-bugcheck": "बहुत निक! जांच करु कि [ $1 known bugs] पहिले स त नै अछि ।",
        "feedback-bugnew": "हम जाँच केलौ। एक नव बग रिपोर्ट करी",
-       "feedback-cancel": "रदà¥\8dद à¤\95रà¥\81",
+       "feedback-cancel": "रदà¥\8dद à¤\95रà¥\80",
        "feedback-close": "भ गेल",
-       "feedback-error-title": "त्रुटि",
        "feedback-error1": "त्रुटि: नै पहचानल गेल परिणाम एपीआईसँ",
        "feedback-error2": "त्रुटि: संपादन विफल भेल",
        "feedback-error3": "त्रुटि:एपीआईसँग कोनो प्रतिक्रिया नै",
        "pagelang-use-default": "डिफल्ट भाषा प्रयोग करी",
        "pagelang-select-lang": "भाषा चुनु",
        "pagelang-submit": "भेजी",
-       "right-pagelang": "पà¥\83षà¥\8dठ à¤\95à¥\87 à¤­à¤¾à¤·à¤¾ à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\95रà¥\82",
-       "action-pagelang": "पà¥\83षà¥\8dठ à¤\95à¥\87 à¤­à¤¾à¤·à¤¾ à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\95रà¥\82",
+       "right-pagelang": "पà¥\83षà¥\8dठ à¤­à¤¾à¤·à¤¾ à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\95रà¥\80",
+       "action-pagelang": "पà¥\83षà¥\8dठ à¤­à¤¾à¤·à¤¾ à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\95रà¥\80",
        "log-name-pagelang": "भाषा परिवर्तन लग",
        "log-description-pagelang": "ई पृष्ठ भाषासभमे परिवर्तनक लग छी।",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|बदलि देल गेल}} पृष्ठ भाषा $3 क लेल $4 सँ $5।",
index 2cc972a..fe20055 100644 (file)
        "yourpasswordagain": "Balèni tembung sandhi:",
        "createacct-yourpasswordagain": "Konfirmasi tembung sandhi",
        "createacct-yourpasswordagain-ph": "Lebokna tembung sandhi maning",
-       "remembermypassword": "Emutna data login-ne inyong nang peramban kiye (kanggo paling suwe $1 {{PLURAL:$1|dina|dina}})",
        "userlogin-remembermypassword": "Jorna ben Inyong tetep mlebu log",
        "userlogin-signwithsecure": "Gunakna koneksi aman",
        "cannotloginnow-title": "Ora teyeng mlebu siki",
index 31ca464..3a309a5 100644 (file)
        "yourname": "Тиить лемоц:",
        "yourpassword": "Сувама валце:",
        "yourpasswordagain": "Сёрматк сувама валце омбоцекс:",
-       "remembermypassword": "Ванфтомс монь сувама лемозе тя содам машинаса (максимум $1 {{PLURAL:$1|шис|шис}})",
        "yourdomainname": "Тонь доменце:",
        "password-change-forbidden": "Сувама валхне тя викить эса аф полафтовихть",
        "externaldberror": "Лиссь эльбятькс ушеширень датабазонь вельде кемокстакшнембачк эли тондейть аф мярьгови полафнемс тонь ушеширень сёрматфтомацень.",
        "undo-failure": "Тя петнемать аш кода валхтомс ётконь петнематнень карань-каршек арафтомаснон сюнеда.",
        "undo-norev": "Тя петнемать аш кода мърдафтомс сяс мес сонь аш эли сон нардафоль.",
        "undo-summary": "Валхтт петнемась $1 конань тизе [[Special:Contributions/$2|$2]] ([[User talk:$2|Корхнема]])",
-       "cantcreateaccounttitle": "Аш кода сёрматфтомать тиемс",
        "cantcreateaccount-text": "Сёрматфтомась тя IP адреста ('''$1''') пякстазе [[User:$3|$3]].\n\n$3 макссь туфталсь - ''$2''",
        "viewpagelogs": "Няфтемс тя лопать историянц",
        "nohistory": "Тя лопать петнемань историяц аш.",
index 94699ba..74f57ae 100644 (file)
        "yourpasswordagain": "Avereno ampidirina eto ny tenimiafina",
        "createacct-yourpasswordagain": "Hamarino ny tenimiafinao",
        "createacct-yourpasswordagain-ph": "Mbola ampidiro fanindroany ny tenimiafinao",
-       "remembermypassword": "{{PLURAL:}}Tadidio ny tenimiafiko (mandritry ny $1 andro fara-fahabetsany)",
        "userlogin-remembermypassword": "Tadidio aho",
        "userlogin-signwithsecure": "Fidirana amin'ny alalan'ny fanohizana azo antoka",
        "cannotloginnow-title": "Tsy afaka miditra izao",
        "botpasswords-label-delete": "Fafàna",
        "botpasswords-label-resetpassword": "Hamerina ny tenimiafina",
        "botpasswords-label-grants": "Zo mihatra:",
-       "botpasswords-label-restrictions": "Fetran'ny fampiasana:",
        "botpasswords-label-grants-column": "Nomena",
        "botpasswords-bad-appid": "Tsy azo raisina ny anarana rôbô \"$1\".",
        "botpasswords-insert-failed": "Tsy afaka nanampy ny anarana rôbô \"$1\". Tsy efa nampiana ve ilay izy?",
        "activeusers-intro": "Ity ny lisitry ny mpikambana izay nanao zavatra iray nandritry ny andro $1 farany. {{PLURAL:}}",
        "activeusers-count": "Tao $1{{PLURAL:}} tanatin'ny $3 andro",
        "activeusers-from": "Aseho ny mpikambana hatry ny :",
-       "activeusers-hidebots": "Asitriho ny robo",
-       "activeusers-hidesysops": "Asitriho ny mpandrindra",
        "activeusers-noresult": "Tsy nahitana mpikambana.",
        "activeusers-submit": "Hanseho ny mpikambana mavitrika",
        "listgrouprights": "Fahefan'ny vondrom-pikambana",
        "htmlform-title-not-exists": "Tsy misy $1.",
        "htmlform-user-not-exists": "Tsy misy ny <strong>$1</strong>.",
        "htmlform-user-not-valid": "Tsy anaram-pikambana azo raisina <strong>$1</strong>.",
-       "sqlite-has-fts": "$1 misy fikarohan-dahatsoratra tanteraka",
-       "sqlite-no-fts": "$1 tsy misy fikarohan-dahatsoratra tanteraka",
        "logentry-delete-delete": "nofafan'i $1 ny pejy $3",
        "logentry-delete-restore": "Namerina ny pejy $3 i $1{{GENDER:$2|}}",
        "logentry-delete-event": "Nanova ny fahitana {{PLURAL:$5|laogy iray|laogy $5}} tamin'i $3 i $1: $4",
index c1006b7..8839a78 100644 (file)
@@ -10,7 +10,8 @@
                        "Сай",
                        "Санюн Вадик",
                        "아라",
-                       "Sergey Ivanov"
+                       "Sergey Ivanov",
+                       "Irus"
                ]
        },
        "tog-underline": "Кузе кылвер-влакым ӱлычын удыралаш?",
        "oct": "Шыжа",
        "nov": "Кылме",
        "dec": "Теле",
-       "pagecategories": "{{PLURAL:$1|Категорий|Категорий}}",
+       "pagecategories": "{{PLURAL:$1|Категорий|Категорий-влак}}",
        "category_header": "\"$1\" категорийыште лаштык-влак",
        "subcategories": "Ӱлылкатегорий-влак",
        "category-media-header": "\"$1\" категорийыште файл-влак",
        "category-empty": "''Ты жаплан тиде категорийыште нимоат уке.''",
        "hidden-categories": "{{PLURAL:$1|Шылтыме категорий|Шылтыме категорий-влак}}",
        "hidden-category-category": "Шылтымо категорий-влак",
-       "category-subcat-count": "{{PLURAL:$2|Тиде категорийыш ик ӱлылкатегорий гына пура.|{{PLURAL:$1|1=Тыгай $1 ӱлылкатегорий|Тыгане $1 ӱлылкатегорий-влак}} тиде категорийыште, чыла $2.}}",
-       "category-article-count": "{{PLURAL:$2|Тиде категорийыш ик лаштык гына пура.|{{PLURAL:$1|1=Тыгай $1 лаштык|Тыгане $1 лаштык-влак}} тиде категорийыште, чыла $2.}}",
+       "category-subcat-count": "{{PLURAL:$2|Тиде категорийыш ик ӱлылкатегорий гына пура.|{{PLURAL:$1|1=Тыгай лӱман $1 ӱлылкатегорий}} тиде категорийыште верланен, чылажге $2 уло.}}",
+       "category-article-count": "{{PLURAL:$2|Тиде категорийыш ик лаштык гына пура.|{{PLURAL:$1|1=$1 лаштыкым ончыктымо}} тиде категорийыште, чылажге $2 уло.}}",
        "category-file-count": "{{PLURAL:$2|Тиде категорийыш ик лаштык гына пура.|{{PLURAL:$1|1=$1 лаштык|$1 лаштык}} тиде категорийыште, чылажге $2.}}",
        "listingcontinuesabbrev": "(умбакыжым)",
        "noindex-category": "Шотыш налдыме лаштык-влак",
        "actions": "Сомылка-влак",
        "namespaces": "Лӱм-влак ора",
        "variants": "Вариант-влак",
+       "navigation-heading": "Навигаций",
        "errorpagetitle": "Йоҥылыш",
        "returnto": "$1 деке пӧртылаш.",
        "tagline": "{{SITENAME}} гыч",
        "nstab-template": "Ямдылык",
        "nstab-help": "Полыш лаштык",
        "nstab-category": "Категорий",
+       "mainpage-nstab": "Тӱҥ лаштык",
        "nosuchspecialpage": "Тыгай спецлаштык уке.",
        "error": "Йоҥылыш",
        "databaseerror-error": "Йоҥылыш: $1",
        "yourpasswordagain": "Шолыпмутым угыч пуртымаш:",
        "createacct-yourpasswordagain": "Шолыпмутым пеҥгыдемде",
        "createacct-yourpasswordagain-ph": "Шолыпмутым угыч пурто",
-       "remembermypassword": "Тиде компьютерыште мыйым шарнаш (эн шуко $1 {{PLURAL:$1|1=кечылан|кечылан}})",
        "yourdomainname": "Тендан домен:",
        "login": "Шке денет палдаре",
        "nav-login-createaccount": "Пураш/Регистрацийым эрте",
        "preview": "Ончылгоч ончымаш",
        "showpreview": "Ончылгоч ончымаш",
        "showdiff": "Тӧрлатымашым ончыкташ",
-       "anoneditwarning": "'''Тӱткӧ лий:''': Тый авторизацийым эртен отыл. Тыйын IP-адресет лаштыкын вашталтымаш эртымгорныштыжо возалт кодеш.",
+       "anoneditwarning": "'''Тӱткӧ лий:''': Тый авторизацийым эртен отыл. Тыйын IP-адресет лаштыкын вашталтымаш историйыштыже возалт кодеш. Шке лӱмет ден пурет але регистрацийым эртет гын, шкаланет пашам ышташ йӧнлырак лиеш.",
        "summary-preview": "Тӧрлатымаш нерген ончылгоч ончымаш:",
        "accmailtitle": "Шолыпмут колтымо.",
        "newarticle": "(У)",
        "newarticletext": "Тыгай лӱман лаштык уке.\nЛаштыкым ышташлан ӱлнӧ возаш тӱҥал (сайынрак палашлан [$1 полшыкым] ончал).\nТый тышке йонгылыш логалынат гын, браузерыште '''шенгек''' полдышым темдал.",
-       "noarticletext": "Ð\9aÑ\8bзÑ\8bÑ\82Ñ\81е Ð¶Ð°Ð¿Ð»Ð°Ð½ Ñ\82иде Ð»Ð°Ñ\88Ñ\82Ñ\8bкÑ\8bÑ\88Ñ\82е Ð½Ð¸Ð¼Ð¾Ð¼ Ð²Ð¾Ð·Ñ\8bмо Ð¾Ð³Ñ\8bл.\nТÑ\8bй Ñ\82иде Ð»Ð°Ñ\88Ñ\82Ñ\8bкÑ\8bн Ð»Ó±Ð¼Ð¶Ñ\8bм Ð²ÐµÑ\81 Ð»Ð°Ñ\88Ñ\82Ñ\8bк-влакÑ\8bÑ\88Ñ\82е [[Special:Search/{{PAGENAME}}|кÑ\8bÑ\87алÑ\8bн]] ÐºÐµÑ\80Ñ\82аÑ\82, Ð°Ð»Ðµ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} Ð¶Ñ\83Ñ\80нал-влакÑ\8bÑ\88Ñ\82е ÐºÑ\8bÑ\87алÑ\8bн] ÐºÐµÑ\80Ñ\82аÑ\82, Ð°Ð»Ðµ [{{fullurl:{{FULLPAGENAME}}|action=edit}} Ñ\82Ñ\8bгай Ð»Ó±Ð¼Ð°Ð½ Ð»Ð°Ñ\88Ñ\82Ñ\8bкÑ\8bм Ñ\8bÑ\88Ñ\82аÑ\88] кертат</span>.",
+       "noarticletext": "Ð\9aÑ\8bзÑ\8bÑ\82Ñ\81е Ð¶Ð°Ð¿Ð»Ð°Ð½ Ñ\82иде Ð»Ð°Ñ\88Ñ\82Ñ\8bкÑ\8bÑ\88Ñ\82е Ð½Ð¸Ð¼Ð¾Ð¼ Ð²Ð¾Ð·Ñ\8bмо Ð¾Ð³Ñ\8bл.\nТÑ\8bй Ñ\82иде Ð»Ð°Ñ\88Ñ\82Ñ\8bкÑ\8bн Ð»Ó±Ð¼Ð¶Ñ\8bм Ð²ÐµÑ\81 Ð»Ð°Ñ\88Ñ\82Ñ\8bк-влакÑ\8bÑ\88Ñ\82е [[Special:Search/{{PAGENAME}}|кÑ\8bÑ\87алÑ\8bн]] ÐºÐµÑ\80Ñ\82аÑ\82, Ð°Ð»Ðµ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} Ð¶Ñ\83Ñ\80нал-влакÑ\8bÑ\88Ñ\82е ÐºÑ\8bÑ\87алÑ\8bн] ÐºÐµÑ\80Ñ\82аÑ\82, Ð°Ð»Ðµ [{{fullurl:{{FULLPAGENAME}}|action=edit}} Ñ\82Ñ\8bгай Ð»Ó±Ð¼Ð°Ð½ Ð»Ð°Ñ\88Ñ\82Ñ\8bкÑ\8bм Ñ\8bÑ\88Ñ\82ен] кертат</span>.",
        "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:''' Выберите очистку кэша в меню ''Инструменты → Настройки''",
        "previewnote": "'''Тиде ончылгоч ончымаш гына;\nвашталтыш-влакым эше аралыме огыл!'''",
        "editing": "Тӧрлаталтеш $1",
        "templatesusedpreview": "Тиде лаштыкыште кучылтмо {{PLURAL:$1|1=ямыдылык|ямдылык-влак}}:",
        "template-protected": "(тӧрлаташ чарыме)",
        "template-semiprotected": "(верын аралыме)",
-       "hiddencategories": "Тиде лаштык $1 {{PLURAL:$1|1=шылтыме категорийыш|шылтыме категорийыш}} лектеш:",
-       "permissionserrorstext-withaction": "Тыйын '''$2''' кертмашет шагал. Тиде {{PLURAL:$1|1=амал ден|амал дене}}:",
+       "hiddencategories": "Тиде лаштык $1 {{PLURAL:$1|1=шылтыме категорий-влак}} радамыш пура:",
+       "permissionserrorstext-withaction": "'''$2''' пашам ыштен от керт. {{PLURAL:$1|1=Амалже}} тыгай:",
        "recreate-moveddeleted-warn": "'''Йолташ, тиде лаштыкым тиддеч ончыч шӧреныт.''' Тудым илаҥдарыме деч ончыч, тыгай лаштык кӱлешак мо - тергыман. Ӱлнырак шӧрымаш да лӱм вашталтымаш журнал-влакым шергал лекташ лиеш.",
        "moveddeleted-notice": "Тиде лаштык шӧралтын.\nЛаштыклан шӧрымӧ да кусарыме нерген журнал ӱлнӧ ончыктымо.",
        "viewpagelogs": "Тиде лаштыклан журнал-влакым ончыкташ",
        "currentrev": "Кызытсе версий",
        "currentrev-asof": "$1 кызытсе версий",
        "revisionasof": "$1 версий",
-       "revision-info": "$1; $2 деч версий",
+       "revision-info": "$1 деч версий; {{GENDER:$6|$2}}$7",
        "previousrevision": "← Ончычсо версий",
        "nextrevision": "Весе →",
        "currentrevisionlink": "Кызытсе",
        "prevn": "кодшо {{PLURAL:$1|$1}}",
        "nextn": "весе {{PLURAL:$1|$1}}",
        "prevn-title": "Кодшо $1 {{PLURAL:$1|результат}}",
-       "nextn-title": "Ð\92еÑ\81е $1 {{PLURAL:$1|лекÑ\82Ñ\8bÑ\88|лекÑ\82Ñ\8bÑ\88}}",
-       "shown-title": "Лаштыкыште $1 {{PLURAL:$1|1=возымаш|возымашым}} ончыкташ",
+       "nextn-title": "ЭÑ\88е $1 {{PLURAL:$1|лаÑ\88Ñ\82Ñ\8bкÑ\8bм}}",
+       "shown-title": "Лаштыкыште $1 {{PLURAL:$1|1=возымашым}} ончыкташ",
        "viewprevnext": "Ончал ($1 {{int:pipe-separator}} $2) ($3)",
-       "searchmenu-new": "'''Тиде вики-проектыште «[[:$1]]» лӱман лаштыкым ышташ!'''",
+       "searchmenu-new": "<strong>'''Тиде вики-проектыште «[[:$1]]» лӱман лаштыкым ышташ!'''</strong>\n{{PLURAL:$2|0=|Тыйын йодмет почеш кычалын муымо лаштыкым ончал.}}",
        "searchprofile-articles": "Возымо лаштык-влак",
        "searchprofile-images": "Мультимедий",
        "searchprofile-everything": "Чыла",
        "searchprofile-advanced-tooltip": "Искать в заданных пространствах имён",
        "search-result-size": "$1 ({{PLURAL:$2|1 мут|$2 мут}})",
        "search-result-category-size": "$1 {{PLURAL:$1|вхождение|вхождения|вхождений}} ($2 {{PLURAL:$2|подкатегория|подкатегории|подкатегорий}}, $3 {{PLURAL:$3|файл|файла|файлов}}).",
-       "search-redirect": "($1 Ð²ÐµÑ\81 Ð²ÐµÑ\80е ÐºÐ¾Ð»Ñ\82Ñ\8bмаÑ\88)",
+       "search-redirect": "($1 Ð³Ñ\8bÑ\87 ÐºÐ¾Ð»Ñ\82Ñ\8bмо)",
        "search-section": "(ужаш $1)",
        "search-suggest": "Але те $1 возынеда ыле",
        "search-interwiki-caption": "Родо проект-влак",
        "recentchanges-label-bot": "Тиде тӧрлатымашым бот ыштен",
        "recentchanges-label-unpatrolled": "Тиде тӧрлатымашым нигӧ терген огыл",
        "recentchanges-legend-heading": "<strong>Легенде:</strong>",
-       "recentchanges-legend-newpage": "$1 - у лаштык",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (тыгак [[Special:NewPages|у лаштык-влак лӱмерым]] ончо)",
        "rcnotefrom": "Ниже перечислены изменения с '''$2''' (не более '''$1''').",
        "rclistfrom": "$3 $2 гыч тӱҥалын у вашталтымашым ончыкташ",
        "rcshowhideminor": "Изи тӧрлатымашым $1",
        "rcshowhideminor-hide": "шылташ",
        "rcshowhidebots": "Бот-влакым $1",
        "rcshowhidebots-show": "ончыкташ",
-       "rcshowhideliu": "Шолып пайдаланыше-влакым $1",
+       "rcshowhideliu": "$1 шолып пайдаланыше",
        "rcshowhideliu-hide": "шылташ",
        "rcshowhideanons": "Ончыкталтше пайдаланыше-влакым $1",
        "rcshowhideanons-hide": "шылташ",
        "filehist-filesize": "Файлын кугытшо",
        "filehist-comment": "Файл нерген:",
        "imagelinks": "Файлым кучылтмаш",
-       "linkstoimage": "Тиде {{PLURAL:$1|1=$1 лаштык саде файл дене кылдалтын|$1 лаштык-влак саде файл дене кылдалтыныт}}:",
+       "linkstoimage": "Тиде {{PLURAL:$1|1=$1 лаштык саде файл дене кылдалтын}}:",
        "nolinkstoimage": "Тиде файл дене кылдалтше ик лаштыкат уке.",
        "sharedupload": "Тиде файлын верже: $1, туге гынат, тудым моло веренат кучылташ лиеш.",
        "uploadnewversion-linktext": "Тиде файлын у версийжым пурташ",
        "brokenredirects-edit": "тӧрлаташ",
        "brokenredirects-delete": "шӧраш",
        "withoutinterwiki-submit": "ончыкташ",
-       "nbytes": "$1 {{PLURAL:$1|байт|байт}}",
-       "nmembers": "$1 {{PLURAL:$1|1=лаштык|лаштык-влак}}",
+       "nbytes": "$1 {{PLURAL:$1|байт}}",
+       "nmembers": "$1 {{PLURAL:$1|1=лаштык}}",
        "lonelypages": "Тулык лаштык-влак",
        "wantedcategories": "Ыштыман категорий-влак",
        "wantedpages": "Ыштышаш лаштык-влак",
        "listusers-blocked": "(йӧн петырыме)",
        "activeusers": "Чӱчкыдын пайдаланыше-влак",
        "activeusers-count": "Пытартыш $3 {{PLURAL:$3|1=кечыште|кечылаште}} $1 {{PLURAL:$1|1=тӧрлатымаш|тӧрлатымаш-влак}}",
-       "activeusers-hidebots": "Бот-влакым шылташ",
-       "activeusers-hidesysops": "Сайтвиктарыше-влакым шылташ",
        "activeusers-submit": "ончыкташ",
        "listgrouprights-members": "(тӱшкаште улшо-влак)",
        "emailuser": "Пайдаланыше дек серыш",
        "whatlinkshere-next": "{{PLURAL:$1|вес|$1 вес}}",
        "whatlinkshere-links": "← кылвер-влак",
        "whatlinkshere-hideredirs": "вес вере колтымаш-влакым $1",
-       "whatlinkshere-hidetrans": "пуртымашым $1",
-       "whatlinkshere-hidelinks": "кылвер-влакым $1",
+       "whatlinkshere-hidetrans": "$1 пуртымаш",
+       "whatlinkshere-hidelinks": "$1 кылвер",
        "whatlinkshere-hideimages": "сӱрет деке кылвер-влакым $1",
        "whatlinkshere-filters": "Фильтр-влак",
        "blockip": "Пайдаланышылан йӧным петыраш",
        "allmessages-filter-all": "Чыла",
        "thumbnail-more": "Кугемдаш",
        "thumbnail_error": "Изи сӱретым ыштыме годым йоҥылыш: $1",
-       "tooltip-pt-userpage": "Тыйын лаштыкет",
-       "tooltip-pt-mytalk": "Тыйын каҥашымаш лаштыкет",
-       "tooltip-pt-preferences": "Мыйын келыштарымашем",
+       "tooltip-pt-userpage": "{{GENDER:|Тыйын}} лаштыкет",
+       "tooltip-pt-mytalk": "{{GENDER:|Тыйын}} каҥашымаш лаштыкет",
+       "tooltip-pt-preferences": "{{GENDER:|Тыйын}} келыштарымашет",
        "tooltip-pt-watchlist": "Мыйын эскерыме лаштык-влак лӱмер",
-       "tooltip-pt-mycontris": "Тыйын пашатым эскерыме лаштык",
+       "tooltip-pt-mycontris": "{{GENDER:|Тыйын}} пашатым эскерыме лаштык",
        "tooltip-pt-login": "Тыште регистрацийым эртен кертат. Регистраций деч поснаат пашам ышташ лиеш.",
        "tooltip-pt-logout": "Системе гыч лекташ",
+       "tooltip-pt-createaccount": "Ме тыланда регистрацийым эрташ да системыш пураш темлена.",
        "tooltip-ca-talk": "Лаштыкыште возымым каҥашаш",
-       "tooltip-ca-edit": "Тый тиде лаштыкым тӧрлатен кертат. Лаштыкым аралыме деч ончыч тудым тергаш ит мондо.",
+       "tooltip-ca-edit": "Тиде лаштыкым тӧрлаташ",
        "tooltip-ca-addsection": "У ужашым тӱҥалаш",
        "tooltip-ca-viewsource": "Тиде лаштыкым аралыме.\nТый тудын тӱҥалтыш текстшым ончалын кертат.",
        "tooltip-ca-history": "Лаштыкын ондаксе тӧрлатымаш",
        "tooltip-t-recentchangeslinked": "Тиде лаштык дене кылдалтше пытартыш тӧрлатымаш-влак",
        "tooltip-feed-rss": "Тиде лаштыклан RSS-кыл",
        "tooltip-feed-atom": "Тиде лаштыклан Atom-кыл",
-       "tooltip-t-contributions": "Пайдаланышын ыштыме пашажым ончалаш",
+       "tooltip-t-contributions": "{{GENDER:$1|Пайдаланышын ыштыме пашажым}} ончалаш",
        "tooltip-t-emailuser": "Тиде пайдаланышылан электрон серышым возаш",
        "tooltip-t-upload": "Файл-влакым пурташ",
        "tooltip-t-specialpages": "Лӱмын ыштыме лаштык-влак",
        "tooltip-t-permalink": "Тиде лашткыш кондышо кылвер (ссылка)",
        "tooltip-ca-nstab-main": "Лаштыкыште возымым ончыкташ",
        "tooltip-ca-nstab-user": "Пайдаланышын лаштыкшым ончалаш",
-       "tooltip-ca-nstab-special": "Тиде лӱмын ыштыме лаштык, тудым тый тӧрлатен от керт",
+       "tooltip-ca-nstab-special": "Тиде спецлаштык, тый тудым тӧрлатен от керт",
        "tooltip-ca-nstab-project": "Проект нерген лаштыкым ончыкташ",
        "tooltip-ca-nstab-image": "Файлын лаштыкшым ончалаш",
        "tooltip-ca-nstab-template": "Ямдылыкым ончыкташ",
        "tooltip-watch": "Тиде лаштыкым эскерымаш лаштыкышкет ешараш",
        "tooltip-rollback": "\"Пӧртылаш\" ик темдалтыш дене пытартыш пайдаланышын тӧрлатымашым мӧҥгешла пӧртылеш",
        "tooltip-undo": "\"Чараш\" тиде тӧрлатымашым мӧҥгешла пӧртыла да ончылгоч ончымашым почеш.\nТый тӧрлатымаш амалже нерген возымо верыште  возын кертат.",
+       "pageinfo-toolboxlink": "Лаштык нерген",
        "previousdiff": "← Ончычсо тӧрлатымаш-влак",
        "nextdiff": "Вес тӧрлатымаш →",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|1=лаштык|лаштык}}",
        "file-info-size": "$1 × $2 пиксел, файлын кугытшо: $3, MIME-тип: $4",
        "file-nohires": "Кугурак чаплык уке.",
        "svg-long-desc": "SVG файл, шкенжын кугытшо: $1 × $2 пиксел, файлын кугытшо: $3",
-       "show-big-image": "ШкенжÑ\8bн Ñ\87аплÑ\8bкÑ\88е",
+       "show-big-image": "ТӱҥалÑ\82Ñ\8bÑ\88 Ñ\84айл",
        "show-big-image-size": "$1 × $2 пиксел",
        "newimages-legend": "Фильтр",
        "ilsubmit": "Кычал",
        "specialpages-group-pagetools": "Лаштык ӱзгар-влак",
        "specialpages-group-redirects": "Вес вере колтышо спецлаштык-влак",
        "external_image_whitelist": " #Оставьте эту строчку такой, как она есть<pre>\n#Разместите здесь фрагменты регулярных выражений (ту часть, что находится между //)\n#они будут соотнесены с URL внешних изображений.\n#Подходящие будут показаны как изображения, остальные будут показаны как ссылки на изображения.\n#Строки, начинающиеся с # считаются комментариями.\n#Строки не чувствительны к регистру\n\n#Размещайте фрагменты регулярных выражений над этой строчкой. Оставьте эту строчку такой, как она есть.</pre>",
+       "logentry-delete-delete": "$1 {{GENDER:$2|лыктын|лыктын}} странице $3",
        "revdelete-summary": "тӧрлатымаш-влакым возен ончыктымаш",
        "searchsuggest-search": "Кычалаш",
        "expand_templates_ok": "Йӧра",
index 868df89..a41205a 100644 (file)
        "yourpasswordagain": "Ulang baliak kato sandi:",
        "createacct-yourpasswordagain": "Konfirmasi kato sandi",
        "createacct-yourpasswordagain-ph": "Masuakan lai kato sandi",
-       "remembermypassword": "Ingek log masuak denai di paramban ko (salamo $1 {{PLURAL:$1|hari}})",
        "userlogin-remembermypassword": "Biakan ambo tetap masuak",
        "userlogin-signwithsecure": "Gunoan server aman",
        "yourdomainname": "Domain Sanak:",
        "listusers-blocked": "(tasakek)",
        "activeusers": "Daftar pangguno aktif",
        "activeusers-from": "Tunjuakan pangguno mulai dari:",
-       "activeusers-hidebots": "Suruakan bot",
-       "activeusers-hidesysops": "Suruakan panguruih",
        "activeusers-noresult": "Pangguno indak basobok",
        "listgrouprights": "Daftar kalompok pangguno",
        "listgrouprights-summary": "Barikuik ko adolah daftar kalompok pangguno nan ado di wiki ko, jo daftar hak aksesnyo masiang-masiang. Informasi labih lanjuik masalah hak masiang-masiang dapek dijumpoi di [[{{MediaWiki:Listgrouprights-helppage}}|laman bantuan hak pangguno]].",
index de1353c..b28c0d1 100644 (file)
        "botpasswords-label-delete": "Избриши",
        "botpasswords-label-resetpassword": "Ставете нова лозинка",
        "botpasswords-label-grants": "Применливи доделувања:",
-       "botpasswords-help-grants": "Секое Ð´Ð¾Ð´ÐµÐ»Ñ\83ваÑ\9aе Ð´Ð°Ð²Ð° Ð¿Ñ\80иÑ\81Ñ\82ап Ð´Ð¾ Ñ\81пиÑ\81ок Ð´Ð¾ Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¸ Ð¿Ñ\80ава Ñ\88Ñ\82о Ð²ÐµÑ\9cе Ð³Ð¸ Ð¸Ð¼Ð° ÐºÐ¾Ñ\80иÑ\81ниÑ\87каÑ\82а Ñ\81меÑ\82ка. Ð\9fовеÑ\9cе Ñ\9cе Ð½Ð°Ñ\98деÑ\82е Ð½Ð° [[Special:ListGrants|Ñ\82абелаÑ\82а Ñ\81о доделувања]].",
+       "botpasswords-help-grants": "Ð\94оделÑ\83ваÑ\9aаÑ\82а Ð²Ð¸ Ð´Ð°Ð²Ð°Ð°Ñ\82 Ð¿Ñ\80иÑ\81Ñ\82ап Ð´Ð¾ Ð¿Ñ\80ава ÐºÐ¾Ð¸ Ð²ÐµÑ\9cе Ð³Ð¸ Ð¸Ð¼Ð° Ð²Ð°Ñ\88аÑ\82а Ñ\81меÑ\82ка. Ð\9eвозможÑ\83ваÑ\98Ñ\9cи Ð´Ð¾Ð´ÐµÐ»Ñ\83ваÑ\9aе Ñ\82Ñ\83ка, Ð½Ðµ Ð´Ð¾Ð±Ð¸Ð²Ð°Ñ\82е Ð½Ð¸ÐºÐ°ÐºÐ²Ð¸ Ð¿Ñ\80ава Ñ\88Ñ\82о Ð²ÐµÑ\9cе Ð³Ð¸ Ð½ÐµÐ¼Ð° Ñ\81меÑ\82каÑ\82а. Ð\9fовеÑ\9cе Ð¸Ð½Ñ\84оÑ\80маÑ\86ии Ñ\9cе Ð½Ð°Ñ\98деÑ\82е Ð½Ð° [[Special:ListGrants|Ñ\82абелаÑ\82а Ð½Ð° доделувања]].",
        "botpasswords-label-grants-column": "Доделено",
        "botpasswords-bad-appid": "Името на ботот „$1“ е неважечко.",
        "botpasswords-insert-failed": "Не успеав да го додадам името на ботот „$1“. Да не е веќе додадено?",
        "passwordreset-nocaller": "Мора да се укаже повикувач",
        "passwordreset-nosuchcaller": "Повикувачот не постои: $1",
        "passwordreset-ignored": "Менувањето на лозинката не успеа. Можеби не е поставен услужник?",
-       "passwordreset-invalideamil": "Неважечка е-пошта",
+       "passwordreset-invalidemail": "Неважечка е-пошта",
        "passwordreset-nodata": "Немате укажано ни корисничко име, ни е-пошта.",
        "changeemail": "Смени или отстрани е-пошта",
        "changeemail-header": "Пополнете го образецов за да ја смените е-поштата. Ако сакате да ја отстраните адресата од вашата сметка, оставете го празно полето за нова е-пошта.",
        "page_first": "прв",
        "page_last": "последен",
        "histlegend": "Разлика помеѓу преработките: Означете ги преработките што сакате да ги споредите и притиснете на Enter или копчето на дното од страницата.<br />\nЛегенда: '''({{int:cur}})''' = разлика со последна преработка, '''({{int:last}})''' = разлика со претходна преработка, '''{{int:minoreditletter}}''' = ситна промена.",
-       "history-fieldset-title": "Ð\9fÑ\80елиÑ\81Ñ\82Ñ\83ваÑ\9aе Ð½Ð° Ð¸Ñ\81Ñ\82оÑ\80иÑ\98а",
+       "history-fieldset-title": "Ð\9fÑ\80еглед Ð½Ð° Ð¸Ñ\81Ñ\82оÑ\80иÑ\98аÑ\82а",
        "history-show-deleted": "Само избришани",
        "histfirst": "најстари",
        "histlast": "најнови",
        "searchprofile-advanced-tooltip": "Пребарување во именски простори по избор",
        "search-result-size": "$1 ({{PLURAL:$2|еден збор|$2 збора}})",
        "search-result-category-size": "{{PLURAL:$1|1 член|$1 членови}} ({{PLURAL:$2|1 поткатегорија|$2 поткатегории}}, {{PLURAL:$3|1 податотека|$3 податотеки}})",
-       "search-redirect": "(пренасочување $1)",
+       "search-redirect": "(пренасочување од $1)",
        "search-section": "(пасус $1)",
        "search-category": "(категорија $1)",
        "search-file-match": "(се совпаѓа со содржината на податотеката)",
        "grant-basic": "Основни права",
        "grant-viewdeleted": "Преглед на избришани податотеки и страници",
        "grant-viewmywatchlist": "Преглед на вашите набљудувања",
+       "grant-viewrestrictedlogs": "Погл. ограничени дневнички ставки",
        "newuserlogpage": "Дневник на регистрирања на корисници",
        "newuserlogpagetext": "Ова е дневник на регистрирани корисници.",
        "rightslog": "Дневник на корисничките права",
        "upload-dialog-disabled": "Подигањето на податотеки со помош на овој дијалог е оневозможено на ова вики.",
        "upload-dialog-title": "Подигни податотека",
        "upload-dialog-button-cancel": "Откажи",
+       "upload-dialog-button-back": "Назад",
        "upload-dialog-button-done": "Готово",
        "upload-dialog-button-save": "Зачувај",
        "upload-dialog-button-upload": "Подигни",
        "apisandbox-results-fixtoken-fail": "Не успеав да ја добијам шифрата „$1“.",
        "apisandbox-alert-page": "Полињата на страницава се неважечки.",
        "apisandbox-alert-field": "Вредноста на полево е неважечка.",
+       "apisandbox-continue": "Продолжи",
+       "apisandbox-continue-clear": "Исчисти",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} ќе [https://www.mediawiki.org/wiki/API:Query#Continuing_queries продолжи] со последното барање; „{{int:apisandbox-continue-clear}}“ ќе ги исчисти параметрите поврзани со продолжување.",
+       "apisandbox-param-limit": "Внесете <kbd>max</kbd> за да ја користите најгорната граница.",
        "booksources": "Печатени извори",
        "booksources-search-legend": "Пребарување на извори за книга",
        "booksources-isbn": "ISBN:",
        "booksources-search": "Пребарај",
        "booksources-text": "Ова е список на врски кон други мрежни места кои продаваат нови и користени книги, и тие може\nда имаат повеќе информации за книгите што ги баравте:",
        "booksources-invalid-isbn": "Наведениот ISBN се чини неправилен. Проверете да не настанала некоја грешка при копирањето од изворот.",
+       "magiclink-tracking-rfc": "Страници со волшебни врски за барања за коментирање",
+       "magiclink-tracking-rfc-desc": "Страницава користи волшебни врски за барања за коментирање (RFC). Погл. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] за да дознаете како да ги преселите.",
+       "magiclink-tracking-pmid": "Страници со со волшебни врски за PMID",
+       "magiclink-tracking-pmid-desc": "Страницава користи волшебни врски за PMID. Погл. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] за да дознаете како да ги преселите.",
+       "magiclink-tracking-isbn": "Страници со волшебни врски за ISBN",
+       "magiclink-tracking-isbn-desc": "Страницава користи волшебни врски за ISBN. Погл. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] за да дознаете како да ги преселите.",
        "specialloguserlabel": "Изведувач:",
        "speciallogtitlelabel": "Цел (наслов или {{ns:user}}:корисничко име на корисникот):",
        "log": "Дневници",
        "activeusers-intro": "Ова е список на корисници кои биле на некој начин активни во последните {{PLURAL:$1|еден ден|$1 дена}}.",
        "activeusers-count": "$1 {{PLURAL:$1|дејство|дејства}} {{PLURAL:$3|денес|во последните $3 дена}}",
        "activeusers-from": "Прикажи корисници почнувајќи од:",
-       "activeusers-hidebots": "Скриј ботови",
-       "activeusers-hidesysops": "Скриј администратори",
+       "activeusers-groups": "Прикажи ги корисниците кои членуваат во групите:",
        "activeusers-noresult": "Не пронајдов ниеден корисник.",
        "activeusers-submit": "Прикажи активни корисници",
        "listgrouprights": "Права на кориснички групи",
        "modifiedarticleprotection": "изменет степен на заштита за „[[$1]]“",
        "unprotectedarticle": "отстранета заштитата на „[[$1]]“",
        "movedarticleprotection": "преместени нагодувања за заштита од „[[$2]]“ во „[[$1]]“",
+       "protectedarticle-comment": "{{GENDER:$2|Заштитена}} „[[$1]]“",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Изменет степенот на заштита}} на „[[$1]]“",
+       "unprotectedarticle-comment": "{{GENDER:$2|Отстранета заштитата}} на „[[$1]]“",
        "protect-title": "Измена на степенот на заштита на „$1“",
        "protect-title-notallowed": "Преглед на степенот на заштита на „$1“",
        "prot_1movedto2": "[[$1]] преместена како [[$2]]",
        "sp-contributions-newbies-title": "Придонеси на нови корисници",
        "sp-contributions-blocklog": "Дневник на блокирања",
        "sp-contributions-suppresslog": "притаени придонесите на {{GENDER:$1|корисникот|корисничката}}",
-       "sp-contributions-deleted": "избришани придонесите на {{GENDER:$1|корисникот|корисничката}}",
+       "sp-contributions-deleted": "избришани придонеси на {{GENDER:$1|корисникот}}",
        "sp-contributions-uploads": "подигања",
        "sp-contributions-logs": "дневници",
        "sp-contributions-talk": "разговор",
        "movelogpagetext": "Подолу е наведен список на преместени страници.",
        "movesubpage": "{{PLURAL:$1|Потстраница|Потстраници}}",
        "movesubpagetext": "Оваа страница има $1 {{PLURAL:$1|потстраница прикажана|потстраници прикажани}} подолу.",
+       "movesubpagetalktext": "Оваа страница има $1 {{PLURAL:$1|потстраница прикажана|потстраници прикажани}} подолу.",
        "movenosubpage": "Оваа страница нема потстраници.",
        "movereason": "Причина:",
        "revertmove": "врати",
        "pageinfo-category-pages": "Број на страници",
        "pageinfo-category-subcats": "Број на поткатегории",
        "pageinfo-category-files": "Број на податотеки",
+       "pageinfo-user-id": "Корисничка назнака",
        "markaspatrolleddiff": "Означи како проверена верзија",
        "markaspatrolledtext": "Означи ја верзијата како проверена",
        "markaspatrolledtext-file": "Означи ја верзијава како испатролирана",
        "patrol-log-header": "Ова е дневник на патролирани преработки.",
        "log-show-hide-patrol": "$1 дневник на патролирање",
        "log-show-hide-tag": "$1 дневник на ознаки",
+       "confirm-markpatrolled-button": "ОК",
+       "confirm-markpatrolled-top": "Да ја означан преработката $3 на $2 како испатролирана?",
        "deletedrevision": "Избришана стара преработка $1.",
        "filedeleteerror-short": "Грешка при бришење на податотека: $1",
        "filedeleteerror-long": "Се појавија грешки при бришењето на податотеката:\n\n$1",
        "newimages-showbots": "Прикажувај подигања од ботови",
        "newimages-hidepatrolled": "Сокриј испатролриани подигања",
        "noimages": "Нема ништо.",
+       "gallery-slideshow-toggle": "Преод на минијатури",
        "ilsubmit": "Барај",
        "bydate": "по датум",
        "sp-newimages-showfrom": "Прикажи нови податотеки од $2, $1",
        "htmlform-cloner-create": "Додај уште",
        "htmlform-cloner-delete": "Отстрани",
        "htmlform-cloner-required": "Се бара барем една вредност.",
+       "htmlform-date-placeholder": "ГГГГ-ММ-ДД",
+       "htmlform-time-placeholder": "ЧЧ:ММ:СС",
+       "htmlform-datetime-placeholder": "ГГГГ-ММ-ДД ЧЧ:ММ:СС",
+       "htmlform-date-invalid": "Не можам да ја препознаам внесената вредност. Користете го форматот ГГГГ-ММ-ДД.",
+       "htmlform-time-invalid": "Не можам да ја препознаам внесената вредност за време. Користете го форматот ЧЧ:ММ:СС.",
+       "htmlform-datetime-invalid": "Не можам да ја препознаам внесената вредност за датум и време. Користете го форматот ГГГГ-ММ-ДД ММ:СС.",
+       "htmlform-date-toolow": "Укажаната вредност е пред најраниот допуштен датум — $1.",
+       "htmlform-date-toohigh": "Укажаната вредност е по најдоцниот допуштен датум — $1.",
+       "htmlform-time-toolow": "Укажаната вредност е пред најраното допуштено време — $1.",
+       "htmlform-time-toohigh": "Укажаната вредност е по најдоцното допуштено време — $1.",
+       "htmlform-datetime-toolow": "Укажаната вредност е пред најраниот допуштен датум и време — $1.",
+       "htmlform-datetime-toohigh": "Укажаната вредност е по најдоцниот допуштен датум и време — $1.",
        "htmlform-title-badnamespace": "[[:$1]] не се наоѓа во именскиот простор „{{ns:$2}}“.",
        "htmlform-title-not-creatable": "Насловот „$1“ не може да се создава",
        "htmlform-title-not-exists": "$1 не постои.",
        "feedback-external-bug-report-button": "Поднеси техничка задача",
        "feedback-dialog-title": "Поднеси мислење",
        "feedback-dialog-intro": "Послужете се со едноставниот образец подолу за да го поднесете вашето мислење. Коментарот ќе ви биде додаден на страницата „$1“, заедно со вашето корисничко име.",
-       "feedback-error-title": "Грешка",
        "feedback-error1": "Грешка: Непрепознаен резултат од извршникот",
        "feedback-error2": "Грешка: Уредувањето не успеа",
        "feedback-error3": "Грешка: Извршникот не одговара",
        "feedback-thanks": "Благодариме! Вашиот одѕив е објавен на страницата „[$2 $1]“.",
        "feedback-thanks-title": "Ви благодариме!",
        "feedback-useragent": "Кориснички вршител:",
-       "searchsuggest-search": "Пребарување",
+       "searchsuggest-search": "Пребарајте по {{SITENAME}}",
        "searchsuggest-containing": "содржи...",
        "api-error-autoblocked": "Вашата IP-адреса е автоматски блокирана бидејќи ја има користено блокиран корисник.",
        "api-error-badaccess-groups": "Не ви е дозволено да подигате податотеки на ова вики.",
        "authmanager-authn-autocreate-failed": "Автоматското создавање на месна сметка не успеа: $1",
        "authmanager-change-not-supported": "Укажаните најавни податоци не можат да се изменат, бидејќи тогаш ништо нема да ги користи.",
        "authmanager-create-disabled": "Создавањето на сметки е оневозможено.",
-       "authmanager-create-from-login": "За да направите сметка, пополнете ги полињата подолу.",
+       "authmanager-create-from-login": "За да направите сметка, пополнете ги полињата.",
        "authmanager-create-not-in-progress": "Создавањето на сметката не е во тек, или има губиток на седничките податоци. Почнете одново.",
        "authmanager-create-no-primary": "Укажаните најавни податоци не можат да се употребат во создавање на сметка.",
        "authmanager-link-no-primary": "Укажаните најавни податоци не можат да се употребат во поврзување на сметка.",
        "usercssispublic": "Напомена: потстраниците со CSS не треба да содржат дсоверливи податоци бидејќи истите се видливи и за други корисници.",
        "restrictionsfield-badip": "Неважечки IP-дијапазон на адреси: $1",
        "restrictionsfield-label": "Допуштени IP-опсези:",
-       "restrictionsfield-help": "Една IP-адреса или CIDR-опсег по ред. За да овозможите сè, користете<br><code>0.0.0.0/0</code><br><code>::/0</code>"
+       "restrictionsfield-help": "Една IP-адреса или CIDR-опсег по ред. За да овозможите сè, користете<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Грешка: $1",
+       "edit-error-long": "Грешки:\n\n$1"
 }
index 389d307..cbb7d06 100644 (file)
@@ -57,7 +57,7 @@
        "tog-enotifminoredits": "ചെറുതിരുത്തുകൾക്കും എനിക്ക് ഇമെയിൽ അയയ്ക്കുക",
        "tog-enotifrevealaddr": "അറിയിപ്പ് മെയിലുകളിൽ എന്റെ ഇമെയിൽ വിലാസം വെളിവാക്കാൻ അനുവദിക്കുക",
        "tog-shownumberswatching": "ശ്രദ്ധിക്കുന്ന ഉപയോക്താക്കളുടെ എണ്ണം കാണിക്കുക",
-       "tog-oldsig": "നിലവിലുള്ള ഒപ്പ്:",
+       "tog-oldsig": "താà´\99àµ\8dà´\95à´³àµ\81à´\9fàµ\86 à´¨à´¿à´²à´µà´¿à´²àµ\81à´³àµ\8dà´³ à´\92à´ªàµ\8dà´ªàµ\8d:",
        "tog-fancysig": "ഒപ്പ് ഒരു വിക്കി എഴുത്തായി പരിഗണിക്കുക (കണ്ണി സ്വയം ചേർക്കേണ്ടതില്ല)",
        "tog-uselivepreview": "തത്സമയ പ്രിവ്യൂ ഉപയോഗപ്പെടുത്തുക",
        "tog-forceeditsummary": "തിരുത്തുകളുടെ ചുരുക്കം നൽകിയില്ലെങ്കിൽ എന്നെ ഓർമ്മിപ്പിക്കുക",
        "yourpasswordagain": "രഹസ്യവാക്ക് ഒരിക്കൽക്കൂടി:",
        "createacct-yourpasswordagain": "രഹസ്യവാക്ക് സ്ഥിരീകരിക്കുക",
        "createacct-yourpasswordagain-ph": "രഹസ്യവാക്ക് വീണ്ടും നൽകുക",
-       "remembermypassword": "എന്റെ പ്രവേശനം ഈ ബ്രൗസറിൽ ({{PLURAL:$1|ഒരു ദിവസം|$1 ദിവസം}}) ഓർത്തുവെക്കുക",
        "userlogin-remembermypassword": "ഞാൻ പ്രവേശിച്ചതായിത്തന്നെ ഓർത്തിരിക്കുക",
        "userlogin-signwithsecure": "സുരക്ഷിത കണക്ഷൻ ഉപയോഗിക്കുക",
        "cannotloginnow-title": "ഇപ്പോൾ പ്രവേശിക്കാൻ കഴിയില്ല",
        "botpasswords-label-delete": "മായ്ക്കുക",
        "botpasswords-label-resetpassword": "രഹസ്യവാക്ക് പുനഃക്രമീകരിക്കുക",
        "botpasswords-label-grants": "ബാധകമായ അനുമതികൾ:",
-       "botpasswords-label-restrictions": "ഉപയോഗത്തിന്റെ പരിമിതപ്പെടുത്തലുകൾ:",
        "botpasswords-label-grants-column": "അനുവദിച്ചിരിക്കുന്നവ",
        "resetpass_forbidden": "രഹസ്യവാക്കുകൾ മാറ്റുന്നത് അനുവദിക്കുന്നില്ല",
        "resetpass-no-info": "ഈ താൾ നേരിട്ടു കാണുന്നതിന് താങ്കൾ ലോഗിൻ ചെയ്തിരിക്കണം.",
        "activeusers-intro": "ഇത് കഴിഞ്ഞ {{PLURAL:$1|ദിവസം|$1 ദിവസങ്ങളിൽ}} ഏതെങ്കിലും വിധത്തിലുള്ള പ്രവർത്തനങ്ങൾ ചെയ്ത ഉപയോക്താക്കളുടെ പട്ടികയാണ്.",
        "activeusers-count": "കഴിഞ്ഞ {{PLURAL:$3|ഒരു ദിവസം|$3 ദിവസങ്ങളിൽ}} {{PLURAL:$1|ഒരു പ്രവൃത്തി|$1 പ്രവൃത്തികൾ}}",
        "activeusers-from": "ഇങ്ങനെ തുടങ്ങുന്ന ഉപയോക്താക്കളെ കാട്ടുക:",
-       "activeusers-hidebots": "യന്ത്രങ്ങളെ മറയ്ക്കുക",
-       "activeusers-hidesysops": "കാര്യനിർവാഹകരെ മറയ്ക്കുക",
        "activeusers-noresult": "ഉപയോക്താക്കളില്ല",
        "activeusers-submit": "സജീവ ഉപയോക്താക്കളെ പ്രദർശിപ്പിക്കുക",
        "listgrouprights": "ഉപയോക്തൃവിഭാഗത്തിന്റെ അവകാശങ്ങൾ",
        "htmlform-title-not-exists": "$1 നിലവിലില്ല.",
        "htmlform-user-not-exists": "<strong>$1</strong> നിലവിലില്ല.",
        "htmlform-user-not-valid": "<strong>$1</strong> സാധുതയുള്ള ഉപയോക്തൃനാമമല്ല.",
-       "sqlite-has-fts": "പൂർണ്ണ-എഴുത്ത് തിരച്ചിൽ പിന്തുണയുള്ള $1",
-       "sqlite-no-fts": "പൂർണ്ണ-എഴുത്ത് തിരച്ചിൽ പിന്തുണയില്ലാത്ത $1",
        "logentry-delete-delete": "$3 എന്ന താൾ $1 {{GENDER:$2|മായ്ച്ചിരിക്കുന്നു}}",
        "logentry-delete-restore": "$3 എന്ന താൾ $1 {{GENDER:$2|പുനഃസ്ഥാപിച്ചിരിക്കുന്നു}}",
        "logentry-delete-event": "$3 എന്ന {{PLURAL:$5|രേഖയിലെ മാറ്റത്തിന്റെ|രേഖയിലെ $5 മാറ്റങ്ങളുടെ}} ദർശനീയത $1 {{GENDER:$2|മാറ്റിയിരിക്കുന്നു}}: $4",
        "feedback-external-bug-report-button": "ഒരു സാങ്കേതിക കർത്തവ്യം ചേർക്കുക",
        "feedback-dialog-title": "അഭിപ്രായം സമർപ്പിക്കുക",
        "feedback-dialog-intro": "താങ്കളുടെ അഭിപ്രായം സമർപ്പിക്കാൻ താങ്കൾക്ക് താഴെയുള്ള ലളിതമായ ഫോം ഉപയോഗിക്കാം. താങ്കളുടെ കുറിപ്പ് \"$1\" എന്ന താളിൽ താങ്കളുടെ ഉപയോക്തൃനാമത്തോടൊപ്പം ചേർക്കപ്പെടുന്നതാണ്.",
-       "feedback-error-title": "പിഴവ്",
        "feedback-error1": "പിഴവ്: എ.പി.ഐ.യിൽ നിന്നും തിരിച്ചറിയാനാകാത്ത ഫലം",
        "feedback-error2": "പിഴവ്: തിരുത്തൽ പരാജയപ്പെട്ടു",
        "feedback-error3": "പിഴവ്: എ.പി.ഐ.യിൽ നിന്നും യാതൊരു പ്രതികരണവുമില്ല",
index b7fd888..bacd0d3 100644 (file)
@@ -14,7 +14,8 @@
                        "아라",
                        "Sembuk",
                        "Munkhzaya.E",
-                       "Macofe"
+                       "Macofe",
+                       "Irus"
                ]
        },
        "tog-underline": "Линкүүдийн доогуур зураас зур:",
        "yourpasswordagain": "Нууц үгээ дахин оруулах:",
        "createacct-yourpasswordagain": "Нууц үгээ баталгаажуулна уу",
        "createacct-yourpasswordagain-ph": "Нууц үгээ дахиж оруулна уу",
-       "remembermypassword": "Энэ компьютер дээрх миний нэвтрэлтийг сана (хамгийн дээд талдаа $1 {{PLURAL:$1|өдрийн|өдрийн}} туршид)",
        "userlogin-remembermypassword": "Намайг сана",
        "userlogin-signwithsecure": "Хамгаалалттай сүлжээ хэрэглэнэ үү",
        "yourdomainname": "Таны домэйн:",
        "passwordreset-emailtext-user": "{{SITENAME}} дээрх $1 хэрэглэгч {{SITENAME}} ($4) дээр өөрийн тань бүртгэл дээр сануулга хүссэн байна. \nДараах {{PLURAL:$3|бүртгэл|бүртгэлүүд}} уг е-шуудантай холбоотой байна:\n\n$2\n\nЭнэ {{PLURAL:$3|түр нууц үг|түр нууц үгс}} {{PLURAL:$5|нэг өдрийн дараа|$5 өдрийн дараа}} устах болно.\nТүүгээр нэвтэрч ороод нууц үгээ шинэчилнэ үү. Энэ сануулгыг өөр хэн нэгэн хийсэн, эсвэл та\nнууц үгээ санаж байгаа бол энэ захиаг анхааралгүйгээр хуучнаараа ороход болно.",
        "passwordreset-emailelement": "Хэрэглэгчийн нэр: \n$1\n\nТүр зуурын нууц үг: \n$2",
        "passwordreset-emailsentemail": "Нууц үг солин емайл илгээсэн.",
-       "passwordreset-emailsent-capture": "Доор харагдаж байгаа нь танируу илгээсэн нууц үг ресет хийх емайл.",
-       "passwordreset-emailerror-capture": "Доор харагдаж байгаа нууц үг ресет хийх емайл үүссэх боловч {{GENDER:$2|хэрэглэгчид}} илгээхэд алдаа гарлаа : $1",
        "changeemail": "Цахим шуудангийн хаяг солих",
        "changeemail-header": "Цахим шуудангийн бүртгэлийн хаяг солих",
        "changeemail-no-info": "Энэ хуудсыг үзэхэд хэрэглэгчийн нэрээр орсон байх шаардлагатай.",
        "undo-nochange": "Энэ өөрчлөлтийг буцаасан байна.",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|Яриа]]) хэрэглэгчийн $1 засварыг цуцлах",
        "undo-summary-username-hidden": "$1 залруулгыг далд хэрэглэгчээр буцаах",
-       "cantcreateaccounttitle": "Хэрэглэгчийн бүртгэлийг үүсгэж чадсангүй.",
        "cantcreateaccount-text": "[[User:$3|$3]] нь энэ IP хаягаас ('''$1''') бүртгэл үүсгэх эрхийг түгжсэн байна.\n\n$3-н тодорхойлсон шалтгаан нь ''$2''",
        "viewpagelogs": "Энэ хуудасны логийг үзэх",
        "nohistory": "Хуудсанд засвар хийсэн түүх байхгүй байна.",
        "activeusers-intro": "Энэ нь сүүлийн $1 {{PLURAL:$1|өдөрт|өдөрт}} ямар нэг байдлаар үйлдэл хийсэн хэрэглэгчдийн жагсаалт юм.",
        "activeusers-count": "Сүүлийн {{PLURAL:$3|нэг өдөрт|$3 өдөрт}} $1 {{PLURAL:$1|засвар|засвар}}",
        "activeusers-from": "Хамгийн эхэлж харуулах хэрэглэгч:",
-       "activeusers-hidebots": "роботуудыг нуух",
-       "activeusers-hidesysops": "Администраторуудыг нуух",
        "activeusers-noresult": "Хэрэглэгч олдсонгүй.",
        "listgrouprights": "Хэрэглэгчийн бүлгийн эрхүүд",
        "listgrouprights-summary": "Дараах нь энэ вики дээрх хэрэглэгчийн бүлгүүд болон тэдгээрийн эрх, зөвшөөрлүүдийн жагсаалт юм.\nЭрх бүрийн талаар [[{{MediaWiki:Listgrouprights-helppage}}|нэмэлт мэдээлэл]] байж магадгүй.",
        "htmlform-submit": "Явуулах",
        "htmlform-reset": "Өөрчлөлтүүдийг цуцлах",
        "htmlform-selectorother-other": "Бусад",
-       "sqlite-has-fts": "$1 (бүх текстээрх хайлтыг дэмждэг)",
-       "sqlite-no-fts": "$1 (бүх текстээрх хайлтыг дэмждэггүй)",
        "logentry-delete-delete": "$3 хуудсыг $1 устгасан",
        "logentry-delete-restore": "$3 хуудсыг $1 сэргээв",
        "revdelete-restricted": "системийн операторуудад тавигдсан хязгаарлалтууд",
        "revdelete-unrestricted": "системийн операторуудаас авч хаясан хязгаарлалтууд",
+       "logentry-newusers-create": "$1 хэрэглэгч шинээр {{GENDER:$2|элслээ}}",
        "logentry-rights-rights": "$1 $3 дахь грүпийн гишүүнчлэлээ $4 ээс $5 руу шилжүүллээ",
        "logentry-rights-rights-legacy": "$1 $3 дэхь грүпийн гишүүнчлэлээ сольсон",
        "logentry-rights-autopromote": "$1 $4 аас $5 руу автоматаар дэвшигдлээ",
index 533ebef..ddc46f0 100644 (file)
@@ -77,7 +77,7 @@
        "tog-enotifminoredits": "मला पानांच्या आणि संचिकांच्या छोट्या बदलांकरीता सुद्धा विरोप पाठवा",
        "tog-enotifrevealaddr": "सूचना विरोपात माझा विरोपाचा (ई-मेल ) पत्ता दाखवा",
        "tog-shownumberswatching": "पहारा देणाऱ्या सदस्यांचा आकडा दाखवा",
-       "tog-oldsig": "सध्याची सही:",
+       "tog-oldsig": "à¤\86पलà¥\80 à¤¸à¤§à¥\8dयाà¤\9aà¥\80 à¤¸à¤¹à¥\80:",
        "tog-fancysig": "सही विकिसंज्ञा म्हणून वापरा (आपोआप दुव्याशिवाय)",
        "tog-uselivepreview": "सजीव झलक दाखवा",
        "tog-forceeditsummary": "जर ’बदलांचा आढावा’ दिला नसेल तर मला सूचित करा",
@@ -94,7 +94,7 @@
        "tog-showhiddencats": "लपविलेले वर्ग दाखवा",
        "tog-norollbackdiff": "द्रुतमाघार घेतल्यास बदल वगळा",
        "tog-useeditwarning": "जर मी संपादित करीत असलेल्या पानावरील माझे संपादिलेले बदल जतन न केल्यास मला इशारा द्या",
-       "tog-prefershttps": "सनोंद प्रवेशतांना प्रत्येक वेळी  सुरक्षित अनुबंध वापरा",
+       "tog-prefershttps": "सनà¥\8bà¤\82द à¤ªà¥\8dरवà¥\87शित à¤\85सताà¤\82ना à¤ªà¥\8dरतà¥\8dयà¥\87à¤\95 à¤µà¥\87ळà¥\80  à¤¸à¥\81रà¤\95à¥\8dषित à¤\85नà¥\81बà¤\82ध à¤µà¤¾à¤ªà¤°à¤¾",
        "underline-always": "नेहमी",
        "underline-never": "कधीच नाही",
        "underline-default": "त्वचा अथवा न्याहाळक अविचल (स्कीन अथवा ब्राऊजर डिफॉल्ट)",
        "category-file-count-limited": "खालील {{PLURAL:$1|संचिका|$1 संचिका}} या वर्गात आहेत.",
        "listingcontinuesabbrev": "पुढे चला",
        "index-category": "अनुक्रमित पाने",
-       "noindex-category": "अनुक्रम नसलेली पाने",
+       "noindex-category": "अनुक्रमित नसलेली पाने",
        "broken-file-category": "तुटलेल्या संचिका दुव्यांसह असलेली पाने",
        "about": "च्या विषयी",
        "article": "आशयाचे पान",
        "newwindow": "(नवीन खिडकीत उघडते.)",
        "cancel": "रद्द करा",
        "moredotdotdot": "अजून...",
-       "morenotlisted": "हà¥\80 à¤¯à¤¾à¤¦à¥\80 à¤ªà¥\82रà¥\8dण à¤¨à¤¾à¤¹à¥\80.",
+       "morenotlisted": "हà¥\80 à¤¯à¤¾à¤¦à¥\80 à¤\85पà¥\82रà¥\8dण à¤\85सà¥\82 à¤¶à¤\95तà¥\87.",
        "mypage": "पान",
        "mytalk": "चर्चा",
        "anontalk": "चर्चा पान",
        "talk": "चर्चा",
        "views": "दृष्ये",
        "toolbox": "साधने",
+       "tool-link-emailuser": "{{GENDER:$1|सदस्याला}} विपत्र पाठवा",
        "userpage": "सदस्य पृष्ठ",
        "projectpage": "प्रकल्प पान पहा",
        "imagepage": "संचिका पृष्ठ पहा",
        "createacct-yourpasswordagain-ph": "पुन्हा परवलीचा शब्द टाका",
        "userlogin-remembermypassword": "मला नोंदीकृतच(लॉग्ड-ईन) ठेवा",
        "userlogin-signwithsecure": "सुरक्षित अनुबंध(सेक्युअर कनेक्शन) वापरा",
+       "cannotlogin-title": "सनोंद प्रवेश करु शकत नाही",
        "cannotloginnow-title": "आता सनोंद प्रवेश घेऊ शकत नाही",
        "cannotloginnow-text": "$1 वापरत असतांना सनोंद प्रवेश करणे शक्य नाही.",
        "yourdomainname": "तुमचे क्षेत्र (डोमेन) :",
        "eauthentsent": "नमूद केलेल्या ई-मेल पत्त्यावर एक निश्चितता स्वीकारक ई-मेल पाठविला गेला आहे.\nखात्यावर कोणताही इतर ई-मेल पाठविण्यापूर्वी - तो ई-मेल पत्ता तुमचाच आहे, हे सुनिश्चित करण्यासाठी - तुम्हाला त्या ई-मेल मधील सूचनांचे पालन करावे लागेल.",
        "throttled-mailpassword": "मागील {{PLURAL:$1|तासात|$1 तासांत}} परवलीचा शब्द बदलण्यासाठीची सूचना विपत्राद्वारे पाठविलेली आहे. दुरुपयोग टाळण्यासाठी, {{PLURAL:$1|एका तासामध्ये|$1 तासांमध्ये}} फक्त एकदाच सूचना दिली जाईल.",
        "mailerror": "विपत्र पाठवण्यात त्रुटी: $1",
-       "acct_creation_throttle_hit": "à¤\86पला à¤\85à¤\82à¤\95पतà¥\8dता à¤µà¤¾à¤ªà¤°à¥\81न à¤¯à¤¾ à¤µà¤¿à¤\95िस à¤­à¥\87à¤\9f à¤¦à¥\87णाऱà¥\8dयाà¤\82नà¥\80 à¤\95ाल {{PLURAL:$1|१ à¤\96ातà¥\87|$1 à¤\96ातà¥\80}} à¤\89à¤\98डलà¥\80 à¤\86हà¥\87त à¤¤à¥\80 à¤¯à¤¾ à¤\95ालावधà¥\80तà¥\80ल à¤®à¤¹à¤¤à¥\8dतम à¤\86हà¥\87त.\n\nतà¥\8dयाà¤\9aा à¤ªà¤°à¤¿à¤ªà¤¾à¤\95 à¤®à¥\8dहणà¥\82न à¤¸à¤§à¥\8dया à¤¹à¤¾ à¤\85à¤\82à¤\95पतà¥\8dता à¤µà¤¾à¤ªà¤°à¥\81न à¤­à¥\87à¤\9f à¤¦à¥\87णाऱà¥\8dयास अधिक खाते उघडता येणार नाहीत.",
+       "acct_creation_throttle_hit": "à¤\86पला à¤\85à¤\82à¤\95पतà¥\8dता à¤µà¤¾à¤ªà¤°à¥\81न à¤¯à¤¾ à¤µà¤¿à¤\95िस à¤­à¥\87à¤\9f à¤¦à¥\87णाऱà¥\8dयाà¤\82नà¥\80 à¤®à¤¾à¤\97à¥\80ल $2 à¤®à¤§à¥\8dयà¥\87 {{PLURAL:$1|१ à¤\96ातà¥\87|$1 à¤\96ातà¥\80}} à¤\89à¤\98डलà¥\80 à¤\86हà¥\87त à¤¤à¥\80 à¤¯à¤¾ à¤\95ालावधà¥\80तà¥\80ल à¤®à¤¹à¤¤à¥\8dतम à¤\86हà¥\87त.\n\nतà¥\8dयाà¤\9aा à¤ªà¤°à¤¿à¤ªà¤¾à¤\95 à¤®à¥\8dहणà¥\82न à¤¸à¤§à¥\8dया à¤¹à¤¾ à¤\85à¤\82à¤\95पतà¥\8dता à¤µà¤¾à¤ªà¤°à¥\81न à¤­à¥\87à¤\9f à¤¦à¥\87णाऱà¥\8dयाला अधिक खाते उघडता येणार नाहीत.",
        "emailauthenticated": "तुमचा विपत्रपत्ता $2 ला $3 यावेळी तपासण्यात आला आहे.",
        "emailnotauthenticated": "तुमच्या ई-मेल पत्त्याची अद्याप निश्चिती झालेली नाही. खालील कोणत्याही फिचर्ससाठी ई-मेल पाठविला जाणार नाही.",
        "noemailprefs": "खालील सुविधा कार्यान्वित करण्यासाठी,पसंतीक्रमात ई-मेल पत्ता नमूद करा.",
        "botpasswords-label-resetpassword": "परवलीच्या शब्दाची पुनर्स्थापना करा",
        "botpasswords-label-grants": "लागू अनुदाने:",
        "botpasswords-help-grants": "प्रत्येक अनुदान हे सदस्य खात्यास आधीच असलेल्या यादीकृत सदस्य अधिकारास पोहोच देते.अधिक माहितीसाठी [[Special:ListGrants|अनुदानांचा तक्ता]] हे बघा.",
-       "botpasswords-label-restrictions": "वापराचे प्रतिबंध:",
        "botpasswords-label-grants-column": "मंजूर",
        "botpasswords-bad-appid": "\"$1\" हे सांगकाम्याचे नाव वैध नाही.",
        "botpasswords-insert-failed": "\"$1\" हे सांगकाम्याचे नाव जोडण्यात अयशस्वी. ते पूर्वीच जोडले होते काय?",
        "searchprofile-advanced-tooltip": "पारंपरित(कस्टम) नामविश्वांमध्ये शोधा",
        "search-result-size": "$1 ({{PLURAL:$2|१ शब्द|$2 शब्द}})",
        "search-result-category-size": "{{PLURAL:$1|१ सदस्य|$1 सदस्य}} ({{PLURAL:$2|१ उपवर्ग|$2 उपवर्ग}}, {{PLURAL:$3|1 संचिका|$3 संचिका}})",
-       "search-redirect": "(पुनर्निर्देशन $1)",
+       "search-redirect": "($1 पासून पुनर्निर्देशन)",
        "search-section": "(विभाग $1)",
        "search-category": "(वर्ग $1)",
        "search-file-match": "(संचिका आशयाशी अनुरुपते)",
        "upload-dialog-disabled": "हा डायलॉग वापरून  या विकिवर संचिका अपभारण अक्षम केले आहे.",
        "upload-dialog-title": "संचिकेचे अपभारण करा",
        "upload-dialog-button-cancel": "रद्द करा",
+       "upload-dialog-button-back": "परत जा",
        "upload-dialog-button-done": "झाले",
        "upload-dialog-button-save": "जतन करा",
        "upload-dialog-button-upload": "अपभारण करा",
        "activeusers-intro": "शेवटच्या $1 {{PLURAL:$1|दिवसात}} काम केलेल्या सदस्यांची यादी येथे मिळेल",
        "activeusers-count": "शेवटच्या {{PLURAL:$3|दिवसात|$3 दिवसांत}} $1 {{PLURAL:$1|क्रिया}}",
        "activeusers-from": "पुढील शब्दापासून सुरू होणारे सदस्य दाखवा:",
-       "activeusers-hidebots": "सांगकामे लपवा",
-       "activeusers-hidesysops": "प्रचालक लपवा",
        "activeusers-noresult": "एकही सदस्य सापडला नाही.",
        "activeusers-submit": "सक्रिय सदस्य दर्शवा",
        "listgrouprights": "सदस्य गट अधिकार",
        "movelogpagetext": "स्थानांतरित केलेल्या पानांची यादी.",
        "movesubpage": "{{PLURAL:$1|उपपान|उपपाने}}",
        "movesubpagetext": "या पानास $1 {{PLURAL:$1|उपपान|उपपाने}} असून ती पुढे दर्शवली आहेत:",
+       "movesubpagetalktext": "संबंधित चर्चा पानाची $1 {{PLURAL:$1|उपपान|उपपाने}} खाली दर्शविली आहेत.",
        "movenosubpage": "या पानात उपपाने नाहीत.",
        "movereason": "कारण:",
        "revertmove": "पूर्वपदास न्या",
        "pageinfo-article-id": "पृष्ठ-परिचय",
        "pageinfo-language": "पानाच्या मजकूराची भाषा",
        "pageinfo-content-model": "पान आशय नमूना",
+       "pageinfo-content-model-change": "बदला",
        "pageinfo-robot-policy": "यंत्रमानवाद्वारे अनुक्रमन",
        "pageinfo-robot-index": "अनुमती दिली",
        "pageinfo-robot-noindex": "अनुमती दिल्या जात नाही",
        "tag-filter": "[[Special:Tags|खूणपताका]] गाळक:",
        "tag-filter-submit": "गाळक",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|खूणपताका}}]]: $2)",
-       "tags-title": "खुणा",
-       "tags-intro": "प्रणालीतून विशिष्ट संपादनांच्या अर्थासहित  खुणांची  यादी नमूद करणारे पान",
+       "tags-title": "à¤\96à¥\81णपताà¤\95ा",
+       "tags-intro": "प्रणालीतून, विशिष्ट संपादनांच्या अर्थासहित  खुणपताकांची  यादी नमूद करणारे पान",
        "tags-tag": "खूण नाव",
        "tags-display-header": "बदल सुचीवर कसे दिसेल",
        "tags-description-header": "अर्थाची पूर्ण माहिती",
        "tags-hitcount": "$1 {{PLURAL:$1|बदल|बदल}}",
        "tags-manage-blocked": "आपण प्रतिबंधित असतांना बदल खूणपताकांचे व्यवस्थापन करु शकत नाही.",
        "tags-create-heading": "नवीन बिल्ला तयार करा",
+       "tags-create-explanation": "अविचलरित्या, नविन तयार केलेल्या खुणपताका सदस्यांना व सांगकाम्यांना वापरासाठी उपलब्ध होतील.",
        "tags-create-tag-name": "खूणपताकेचे नाव:",
        "tags-create-reason": "कारण:",
        "tags-create-submit": "निर्मित करा",
        "htmlform-cloner-create": "अधिक जोडा",
        "htmlform-cloner-delete": "हटवा",
        "htmlform-cloner-required": "किमान एक किंमत हवी",
+       "htmlform-date-placeholder": "वववव-मम-दिदि",
+       "htmlform-time-placeholder": "ताता:मिमि:सेसे",
+       "htmlform-datetime-placeholder": "वववव-मम-दिदि ताता:मिमि:सेसे",
+       "htmlform-date-invalid": "आपण नमूद केलेली किंमत ही अनोळखी दिनांक आहे. वववव-मम-दिदि प्रारुपणाचा वापर करण्याबाबत विचार करा.",
+       "htmlform-time-invalid": "आपण नमूद केलेली किंमत ही अनोळखी आहे. ताता:मिमि:सेसे प्रारुपणाचा वापर करण्याबाबत विचार करा.",
+       "htmlform-datetime-invalid": "आपण नमूद केलेली किंमत ही अनोळखी दिनांक व वेळ आहे. वववव-मम-दिदि ताता:मिमि:सेसे प्रारुपणाचा वापर करण्याबाबत विचार करा.",
+       "htmlform-time-toohigh": "आपण नमूद केलेली किंमत ही $1च्या परवानगी असलेल्या वेळ मर्यादेबाहेर आहे.",
+       "htmlform-datetime-toohigh": "आपण नमूद केलेली किंमत ही $1च्या परवानगी असलेल्या दिनांक व वेळ मर्यादेबाहेर आहे.",
        "htmlform-title-badnamespace": "[[:$1]] हे \"{{ns:$2}}\" नामविश्वात नाही.",
        "htmlform-title-not-creatable": "\"$1\" हे पान तयार करण्यासाठीचे शीर्षक नाही",
        "htmlform-title-not-exists": "$1 अस्तीत्वात नाही.",
        "htmlform-user-not-exists": "<strong>$1</strong> अस्तीत्वात नाही.",
        "htmlform-user-not-valid": "<strong>$1</strong> हे वैध सदस्यनाम नाही.",
-       "sqlite-has-fts": "पूर्ण-मजकूर शोध समर्थनासहित $1",
-       "sqlite-no-fts": "पूर्ण-मजकूर शोध समर्थनाविरहित $1",
        "logentry-delete-delete": "$1 {{GENDER:$2|वगळलेले पान}} $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|पुनर्स्थापित पृष्ठ}} $3",
        "logentry-delete-event": "$1 ने $3 वर{{PLURAL:$5|नोंद-प्रसंग|$5 नोंद प्रसंगांची}} दृष्यता{{GENDER:$2|बदलली}}:$4",
        "feedback-cancel": "रद्द करा",
        "feedback-close": "झाले",
        "feedback-dialog-title": "प्रतिक्रिया सादर करा",
-       "feedback-error-title": "चूक",
        "feedback-error1": "चूक: API कडून अनोळखी परिणाम",
        "feedback-error2": "त्रुटी: संपादन रद्द",
        "feedback-error3": "त्रुटी:एपीआय तर्फे काहीच प्रत्युत्तर नाही",
        "feedback-thanks": " \"[$2 $1]\" या पानात आपला पश्चप्रदाय (फिडबॅक) टाकत आहोत.",
        "feedback-thanks-title": "आपणास धन्यवाद!",
        "feedback-useragent": "सदस्य प्रतिनीधी:",
-       "searchsuggest-search": "शोधा",
+       "searchsuggest-search": "शोधा {{SITENAME}}",
        "searchsuggest-containing": ".......हे असलेले",
        "api-error-badaccess-groups": "आपणास ह्या विकिवर संचिका चढवण्याची परवानगी नाही",
        "api-error-badtoken": "अंतर्गत चूक: अयोग्य टोकन",
        "randomrootpage": "अविशिष्ट मूळ पान",
        "log-action-filter-suppress-block": "रोधामार्फत सदस्य दाबणे",
        "changecredentials": "अधिकारपत्रे (क्रेडेंटियल्स)बदला",
-       "removecredentials": "अधिकारपत्रे (क्रेडेंटियल्स) हटवा"
+       "removecredentials": "अधिकारपत्रे (क्रेडेंटियल्स) हटवा",
+       "edit-error-short": "त्रुटी: $1",
+       "edit-error-long": "त्रुटी:$1"
 }
index 305228d..0a5267d 100644 (file)
        "yourpasswordagain": "Ulangi kata laluan:",
        "createacct-yourpasswordagain": "Sahkan kata laluan",
        "createacct-yourpasswordagain-ph": "Isikan kata laluan semula",
-       "remembermypassword": "Ingat log masuk saya pada pelayar ini (tidak melebihi $1 {{PLURAL:$1|hari|hari}})",
        "userlogin-remembermypassword": "Biar saya kekal log masuk",
        "userlogin-signwithsecure": "Gunakan sambungan terlindung",
        "yourdomainname": "Domain anda:",
        "activeusers-intro": "Yang berikut ialah senarai pengguna yang bergiat sejak {{PLURAL:$1|semalam|$1 hari lalu}}.",
        "activeusers-count": "$1 tindakan sejak {{PLURAL:$3|semalam|$3 hari lalu}}",
        "activeusers-from": "Tunjukkan pengguna bermula pada:",
-       "activeusers-hidebots": "Sorokkan bot",
-       "activeusers-hidesysops": "Sorokkan penyelia",
        "activeusers-noresult": "Tiada pengguna dijumpai.",
        "listgrouprights": "Hak kumpulan pengguna",
        "listgrouprights-summary": "Berikut adalah senarai kumpulan pengguna yang ditubuhkan di wiki ini, dengan hak-hak mereka masing-masing.\nMungkin terdapat [[{{MediaWiki:Listgrouprights-helppage}}|maklumat tambahan]] mengenai setiap hak.",
        "htmlform-cloner-create": "Tambah lebih",
        "htmlform-cloner-delete": "Buang",
        "htmlform-cloner-required": "Sekurang-kurangnya satu nilai diperlukan.",
-       "sqlite-has-fts": "$1 dengan sokongan carian teks penuh",
-       "sqlite-no-fts": "$1 tanpa sokongan carian teks penuh",
        "logentry-delete-delete": "$1 telah {{GENDER:$2|menghapuskan}} laman $3",
        "logentry-delete-restore": "$1 telah {{GENDER:$2|memulihkan}} laman $3",
        "logentry-delete-event": "$1 telah {{GENDER:$2|mengubah}} keterlihatan $5 peristiwa log di $3: $4",
        "feedback-external-bug-report-button": "Failkan tugas teknikal",
        "feedback-dialog-title": "Hantar maklum balas",
        "feedback-dialog-intro": "Anda boleh menggunakan borang yang mudah di bawah untuk menyerahkan maklum balas. Ulasan anda akan disiarkan pada laman \"$1\" di samping nama pengguna anda.",
-       "feedback-error-title": "Ralat",
        "feedback-error1": "Perhatian: Hasil dari API tidak dikenali",
        "feedback-error2": "Perhatian: Penyuntingan gagal",
        "feedback-error3": "Perhatian: Tiada gerak balas dari API",
index 9df4ea2..db52b06 100644 (file)
@@ -12,7 +12,8 @@
                        "Leli Forte",
                        "Macofe",
                        "Matma Rex",
-                       "MTSap"
+                       "MTSap",
+                       "Nemo bis"
                ]
        },
        "tog-underline": "Ħoloq sottolinjati:",
        "yourpasswordagain": "Erġa' ikteb il-password:",
        "createacct-yourpasswordagain": "Ikkonferma l-password",
        "createacct-yourpasswordagain-ph": "Erġa' daħħal il-password",
-       "remembermypassword": "Ftakar il-login tiegħi fuq dan il-kompjuter (għal massimu ta' {{PLURAL:$1|ġurnata|$1 ġurnata}})",
        "userlogin-remembermypassword": "Żommni fil-kont",
        "userlogin-signwithsecure": "Uża konnessjoni sigura",
        "yourdomainname": "Id-dominju tiegħek:",
        "passwordreset-emailtext-user": "{{PLURAL:$3|Din il-password temporanja se tiskadi|Dawn il-passwords temporanji se jiskadu}} fi żmien {{PLURAL:$5|ġurnata|$5 jum}}. Inti għadek tidħol fil-kont tiegħek u tagħżel password ġdida issa. Jekk xi ħadd ieħor għamel din ir-rikjesta, jew jekk ftakart il-password oriġinali, u m'għadikx trid tbiddilha, inti tista' tinjora dan il-messaġġ u tibqa' tuża' l-password il-qadima.",
        "passwordreset-emailelement": "Isem tal-utent: \n$1\n\nPassword temporanja: \n$2",
        "passwordreset-emailsentemail": "Intbagħtet ittra-e għall-issettjar mill-ġdid tal-password.",
-       "passwordreset-emailsent-capture": "Intbagħtet ittra-e għall-ssettjar mill-ġdid tal-password u l-kontenut jidher hawn taħt.",
-       "passwordreset-emailerror-capture": "Ġiet ġenerata ittra-e ta' tfakkira, li l-kontenut tagħha jidher hawn taħt. Madanakollu, il-posta ma ntbagħtitx lill-utent: $1",
        "changeemail": "Biddel l-indirizz elettroniku",
        "changeemail-header": "Biddel l-indirizz elettroniku tal-kont",
        "changeemail-no-info": "Trid tkun dħalt fil-kont tiegħek sabiex taċċessa direttament din il-paġna.",
        "continue-editing": "Mur fil-kaxxa tal-editjar",
        "previewconflict": "Din il-previżjoni turi l-kliem li jinsab fiż-żona ta' modifika superjuri u turi kif tidher kieku l-paġna kella tiġi modifikata.",
        "session_fail_preview": "'''Jiddispjaċina imma l-modifika tiegħek ma setgħetx tiġi pproċessata minħabba li ntilfet l-informazzjoni tas-sessjoni.\nJekk jogħġbok, erġa' pprova. Jekk xorta tibqa' ma taħdimx, ipprova [[Special:UserLogout|oħroġ]] u erġa' idħol.'''",
-       "session_fail_preview_html": "'''Jiddispjaċina imma l-modifika tiegħek ma setgħetx tiġi pproċessata minħabba li ntilfet l-informazzjoni tas-sessjoni.'''\n\n''Peress li {{#ifeq: {{SITENAME}} | translatewiki.net | fuq {{SITENAME}} | fil-{{SITENAME}}}} huwa possibbli l-użu tal-HTML mingħajr limitazzjonijiet (''raw HTML''), id-dehra proviżorja tiġi moħbija bħala prekawzjoni kontra l-attakki tal-JavaScript.''\n\n'''Jekk dan huwa attentat leġittmu ta' modifika, jekk jogħġbok erġa' pprova. Jekk tibqa' ma taħdimx, ipprova [[Special:UserLogout|oħroġ]] u erġa' idħol.'''",
+       "session_fail_preview_html": "'''Jiddispjaċina imma l-modifika tiegħek ma setgħetx tiġi pproċessata minħabba li ntilfet l-informazzjoni tas-sessjoni.'''\n\n''Peress li fil-{{SITENAME}} huwa possibbli l-użu tal-HTML mingħajr limitazzjonijiet (''raw HTML''), id-dehra proviżorja tiġi moħbija bħala prekawzjoni kontra l-attakki tal-JavaScript.''\n\n'''Jekk dan huwa attentat leġittmu ta' modifika, jekk jogħġbok erġa' pprova. Jekk tibqa' ma taħdimx, ipprova [[Special:UserLogout|oħroġ]] u erġa' idħol.'''",
        "token_suffix_mismatch": "'''Il-modifika tiegħek ma ġietx aċċettata minħabba li klijent tiegħek tertaq l-karratri tal-ortografija fit-token tal-modifika.\nDin il-modifika ma ġietx aċċettata sabiex ma jkunx hemm żballji fit-test tal-paġna. Dan xi kultant jiġri minħabba li qiegħed tuża servizz difettuż anonimu li huwa bbażat fuq il-web ta' prokura.'''",
        "edit_form_incomplete": "'''Ċerti parti tal-formola tal-modifika ma laħqux is-server; iċċekkja jekk il-modifiki tiegħek humiex intatti u erġa' pprova.'''",
        "editing": "Modifika ta' $1",
        "undo-failure": "Huwa impossibbli li tiġi annullata l-modifika, minħabba kunflitt ta' modifiki intermedji.",
        "undo-norev": "Il-modifika ma tistax tiġi annullata peress li ma teżistix jew inkella għax ġiet diġà imħassra.",
        "undo-summary": "Neħħi r-reviżjoni $1 ta' [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskussjoni]])",
-       "cantcreateaccounttitle": "Il-kont ma jistax jinħoloq",
        "cantcreateaccount-text": "Ħolqien tal-kont minn dan l-indirizz IP ('''$1''') ġie imblukkat minn [[User:$3|$3]].\n\nIr-raġuni li ngħatat minħabba l-blokk mingħand $3 kienet ''$2''",
        "viewpagelogs": "Ara r-reġistri ta' din il-paġna",
        "nohistory": "M'hemm l-ebda kronoloġija ta' modifika f'din il-paġna.",
        "activeusers-intro": "Din hija lista ta' utenti li kellhom xi tip ta' attività f'dawn l-aħħar $1 {{PLURAL:$1|ġurnata|ġurnata}}.",
        "activeusers-count": "$1 {{PLURAL:$1|modifika|modifika}} fl-aħħar {{PLURAL:$3|jum|$3 jum}}",
        "activeusers-from": "Uri utenti li jibdew minn:",
-       "activeusers-hidebots": "Aħbi l-bots",
-       "activeusers-hidesysops": "Aħbi amministraturi",
        "activeusers-noresult": "L-ebda utent ma nstab.",
        "listgrouprights": "Drittijiet tal-grupp tal-utenti",
        "listgrouprights-summary": "Hawn taħt hawn elenkati l-gruppi tal-utenti għal din il-wiki, bid-drittijiet ta' aċċess rispettiv.\nJista' jkun hemm [[{{MediaWiki:Listgrouprights-helppage}}|aktar informazzjoni]] fuq id-drittjiet individwali.",
        "htmlform-cloner-create": "Żid aktar",
        "htmlform-cloner-delete": "Neħħi",
        "htmlform-cloner-required": "Minn tal-anqas valur wieħed huwa bżonnjuż.",
-       "sqlite-has-fts": "$1 bil-possibilità ta' tfittxija kompluta fit-test",
-       "sqlite-no-fts": "$1 mingħajr il-possibilità ta' tfittxija kompluta fit-test",
        "logentry-delete-delete": "$1 {{GENDER:$2|ħassar|ħassret}} il-paġna $3",
        "logentry-delete-restore": "$1 reġġa' lura l-paġna $3",
        "logentry-delete-event": "$1 biddel il-viżibilità ta' {{PLURAL:$5|azzjoni tar-reġistru|$5 azzjonijiet tar-reġistru}} ta' $3: $4",
        "feedback-external-bug-report-button": "Irrapporta problema teknika",
        "feedback-dialog-title": "Ibgħat ir-rispons",
        "feedback-dialog-intro": "Tista' tuża din il-formola sabiex tibgħat ir-rispons tiegħek. Il-kumment tiegħek jiġi miżjuda mal-paġna \"$1\", flimkien mal-isem tal-utent.",
-       "feedback-error-title": "Żball",
        "feedback-error1": "Żball: Riżultat mhux rikonoxxut mill-API",
        "feedback-error2": "Żball: Modifika mhux esegwita",
        "feedback-error3": "Żball: L-ebda risposta mill-API",
        "special-characters-group-lao": "Lao",
        "special-characters-group-khmer": "Khmer",
        "mw-widgets-dateinput-placeholder-day": "SSSS-XX-ĠĠ",
-       "mw-widgets-dateinput-placeholder-month": "SSSS-XX",
-       "api-error-blacklisted": "Jekk jogħġbok agħżel titlu differenti u deskrittiv."
+       "mw-widgets-dateinput-placeholder-month": "SSSS-XX"
 }
index 56e90a0..41c6a59 100644 (file)
        "yourname": "Nome de Outelizador",
        "yourpassword": "Palabra chabe",
        "yourpasswordagain": "Repite la tue palabra-chabe",
-       "remembermypassword": "Lhembrar-se de mi neste cumputador (for a maximum of $1 {{PLURAL:$1|day|days}})",
        "yourdomainname": "L tou domínio",
        "login": "Antrar",
        "nav-login-createaccount": "Antrar / criar cuonta",
index e2b8e1b..f0376cb 100644 (file)
        "activeusers": "တက်ကြွလှုပ်ရှားသည့် အသုံးပြုသူစာရင်း",
        "activeusers-intro": "ဤသည်မှာ နောက်ဆုံး $1 {{PLURAL:$1|ရက်|ရက်}}အတွင်း တက်ကြွလှုပ်ရှားသည့် အသုံးပြုသူများ စာရင်း ဖြစ်သည်။",
        "activeusers-from": "ဤမှစသော အသုံးပြုသူများကို ပြရန် -",
-       "activeusers-hidebots": "ဘော့များကို ဝှက်ရန်",
-       "activeusers-hidesysops": "အက်ဒမင်များကို ဝှက်ရန်",
        "activeusers-noresult": "အသုံးပြုသူ မတွေ့ပါ။",
        "listgrouprights": "အသုံးပြုသူအုပ်စု အခွင့်အရေးများ",
        "listgrouprights-group": "အုပ်စု",
index 97f653d..2a102ec 100644 (file)
@@ -13,7 +13,8 @@
                        "Игорь Бродский",
                        "아라",
                        "Denö",
-                       "Macofe"
+                       "Macofe",
+                       "Rueter"
                ]
        },
        "tog-underline": "Сюлмавома петнень алга черькстамс:",
        "category-file-count-limited": "{{PLURAL:$1|Те файлась|Неть $1 файлатне}} вановиця категориянтень кандови.",
        "listingcontinuesabbrev": "поладксозо моли",
        "index-category": "Индекс марто лопатне",
-       "noindex-category": "Индекстэме лопатне",
+       "noindex-category": "Индекстэме лопат",
        "broken-file-category": "Лопат, конатнесэ файлань яжазь сюлмавомапеть",
        "about": "Эстедензэ",
        "article": "Потмокслопа",
        "nstab-template": "Лопа парцун",
        "nstab-help": "Лезкс лопа",
        "nstab-category": "Категория",
+       "mainpage-nstab": "Прявтлопа",
        "nosuchaction": "Истямо тев арась",
        "nosuchspecialpage": "Истямо башка лопа арась",
        "nospecialpagetext": "<strong>Лопась, конань вешик, арась.</strong>\n\nВант те лемрисьменть [[Special:SpecialPages|{{int:specialpages}}]].",
        "yourpasswordagain": "Омбоцеде сёрмадык кирдицянь леметь:",
        "createacct-yourpasswordagain": "Кемекстык салававалонть",
        "createacct-yourpasswordagain-ph": "Совавтык салававалонть одов",
-       "remembermypassword": "Кирдемс мельсэ совамо валом те бравзерсэнть (сех кувать $1 {{PLURAL:$1|чи|чить}})",
        "userlogin-remembermypassword": "Кирдемизь совавтозекс",
        "userlogin-signwithsecure": "Нолдак тевс ванстозь сюлмавкс",
        "yourdomainname": "Эсеть доменэть:",
        "preview": "Васнянь неевтезэ",
        "showpreview": "Максомс васнянь невтевкс",
        "showdiff": "Невтемс мезе полавтовсь",
-       "anoneditwarning": "'''Ванок:''' Зярс эзить сова. IP адресэть совавтови те лопанть витнема-петнема икелькс умантень.",
+       "anoneditwarning": "<strong>Ванок!</strong> Зярс эзить сова. IP адресэть карми неявомо весенень карминдерят витнеме-петнеме. <strong>[$1 Совиндерят]</strong> эли <strong>[$2 шкиндерят совамо тарка]</strong>, весе витнема-петнема теветь аравтовить совамовалот лемс истя кода и лия изнявксоткак.",
        "missingcommenttext": "Инеськеть мелеть-арьсемат путта тезэнь алов.",
        "summary-preview": "Цётомань седеикелев вановкс:",
        "subject-preview": "Темань/коняксонь васнянь невтема:",
        "post-expand-template-argument-warning": "'''Ванок''': Те лопасонть ули лопапарцунонь вейке эли седе ламо аргумент, конась вельть покш. Сеть аргументтнэ нардазь.",
        "post-expand-template-argument-category": "Лопатнесэ улить лопа парцунонь нардань аргументт",
        "parser-template-loop-warning": "Лопа парцунсто \"чары реве\" муевсь: [[$1]]",
-       "cantcreateaccounttitle": "Сёрмадома таркынесь а тееви",
        "viewpagelogs": "Ванномс те лопас совамодо-лисемадо тевть",
        "nohistory": "Те лопанть витнемадо-петнемадо икелькс умазо арась.",
        "currentrev": "Тевате лиякстомтома",
        "searchprofile-advanced-tooltip": "Вешнемс башка теезь лемпотмотнестэ",
        "search-result-size": "$1 ({{PLURAL:$2|1 вал|$2 валт}})",
        "search-result-category-size": "{{PLURAL:$1|1 совицязо|$1 совицянзо}} ({{PLURAL:$2|1 явкскатегориязо|$2 явкскатегориянзо}}, {{PLURAL:$3|1 файла|$3 файлат}})",
-       "search-redirect": "(йутавтт $1-с)",
+       "search-redirect": "(ютавтт $1 лопасто)",
        "search-section": "(пелькс $1)",
        "search-suggest": "Истя мерикскелить: $1",
        "search-interwiki-caption": "Дугакс проектт",
        "right-upload": "Ёвкстамс файлат",
        "right-reupload": "Одонь сёрмадомга уликс файланть нардамс",
        "right-upload_by_url": "Ёвкстамс файлат URL адресстэ",
+       "right-writeapi": "Кода нолдамс тевс сёрмадома API-нть",
        "right-delete": "Нардамс лопатнень",
        "right-bigdelete": "Нардамс кувака икелькс ума марто лопатнень",
        "right-browsearchive": "Вешнемс нардань файлатнесэ",
        "newpageletter": "О",
        "boteditletter": "б",
        "rc_categories_any": "Кочказетнень эйстэ кодамо-понгсь",
+       "rc-change-size-new": "Полавтнемадонть мейле {{PLURAL:$1|байттнэде}}: $1",
        "newsectionsummary": "/* $1 */ од пелькс",
        "rc-enhanced-expand": "Невтемс седе ламо тень ланга",
        "rc-enhanced-hide": "Кекшемс келейстэ ёвтазенть",
        "listusers-noresult": "Совицязо а муеви",
        "listusers-blocked": "(саймас саезь)",
        "activeusers": "Активной теицятнеде списка",
-       "activeusers-hidebots": "Кекшемс ботатнень",
-       "activeusers-hidesysops": "Кекшемс администратортнэнь",
        "activeusers-noresult": "Якинзэ-пакинзэ арасть",
        "listgrouprights": "Теиця куронть видечинзэ",
        "listgrouprights-group": "Куро",
        "whatlinkshere-prev": "{{PLURAL:$1|седе икелень|седе икелень $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|сыця|сыця $1}}",
        "whatlinkshere-links": "← сюлмавомапеть",
-       "whatlinkshere-hideredirs": "$1 ютавты козонь-козонь",
-       "whatlinkshere-hidetrans": "$1 сюлмавозь пелькстнэнь",
-       "whatlinkshere-hidelinks": "$1 сюлмавома петь",
+       "whatlinkshere-hideredirs": "лияв-лияв ютавтовкстнэде $1",
+       "whatlinkshere-hidetrans": "сюлмавозь пелькстнэде $1",
+       "whatlinkshere-hidelinks": "сюлмавома петнеде $1",
        "whatlinkshere-hideimages": "$1 файланть сюлмавомапензэ",
        "whatlinkshere-filters": "Фильтрат",
        "block": "Аравтомс теицянть саймас",
        "tooltip-pt-mycontris": "Мезесэ лездынь мезе путынь",
        "tooltip-pt-login": "Совавтовлить эсь прят тезэнь, арась мелеть, иля.",
        "tooltip-pt-logout": "Лисемс",
+       "tooltip-pt-createaccount": "Меревлинек тонеть совамо таркань шкамодо-совамодо, арась мелеть, иля",
        "tooltip-ca-talk": "Кортавтома пек паро лопадонть",
        "tooltip-ca-edit": "Витнемс-петнемс те лопанть",
        "tooltip-ca-addsection": "Ушодомс од явкс.",
        "tooltip-ca-nstab-main": "Ваномс потмо лопанзо",
        "tooltip-ca-nstab-user": "Ваномс теицянь лопанть",
        "tooltip-ca-nstab-media": "Ваномс медиа лопанть",
-       "tooltip-ca-nstab-special": "Те Ð±Ð°Ñ\88ка Ñ\82евенÑ\8c Ð»Ð¾Ð¿Ð°Ñ\81Ñ\8c, Ñ\81онÑ\81Ñ\8c Ð»Ð¾Ð¿Ð°Ñ\81Ñ\8c Ð° Ð²Ð¸Ñ\82неви-пеÑ\82неви",
+       "tooltip-ca-nstab-special": "Те Ð±Ð°Ñ\88ка Ñ\82евенÑ\8c Ð»Ð¾Ð¿Ð°Ñ\81Ñ\8c, Ñ\82е Ð»Ð¾Ð¿Ð°Ð½Ñ\82Ñ\8c Ð° Ð²Ð¸Ñ\82неÑ\81ак-пеÑ\82неÑ\81ак",
        "tooltip-ca-nstab-project": "Ваннынк проетной лопанть",
        "tooltip-ca-nstab-image": "Ванык файлань лопанть",
        "tooltip-ca-nstab-mediawiki": "Ваномс системань пачтямнэнть",
        "pageinfo-subpages-name": "Те лопанть явкслопанзо",
        "pageinfo-edits": "Зяроксть витнезь-петнезь",
        "pageinfo-authors": "Весемезэ зяро авторонзо",
+       "pageinfo-toolboxlink": "Лопадо иформация",
        "markaspatrolleddiff": "Тешкстамс ванстнемань ютазекс",
        "markaspatrolledtext": "Тешкстамс те лопанть ванстнемань ютазекс",
        "markedaspatrolled": "Тешкстазь ванстнемань ютазекс",
        "file-nohires": "Арась версия покш разрешения марто.",
        "svg-long-desc": "SVG файла, $1 × $2 пиксельть, файланть покшолмазо: $3",
        "show-big-image": "Васень файла",
+       "show-big-image-size": "$1 × $2 пиксель",
        "file-info-gif-looped": "кирьксэс аравтозь",
        "file-info-png-looped": "кирьксэс аравтозь",
        "newimages": "Од файлатьнень галлереясь",
index dc66e13..a3b7c7e 100644 (file)
        "yourpasswordagain": "پسورد ره دِباره بنویس",
        "createacct-yourpasswordagain": "پسورد ره دِباره باوّین",
        "createacct-yourpasswordagain-ph": "پسورد ره دِباره باوّین",
-       "remembermypassword": "مه رمز ره (تا حداکثر $1 {{PLURAL:$1|روز|روز}}) این مرورگر سر یاد نکان",
        "userlogin-remembermypassword": "مه ره سایت دله دار",
        "yourdomainname": "شمه کاروری نوم",
        "login": "دله بوردن",
        "api-error-unknown-error": "خطای داخلی: زمونی که شما تلاش کاردنی باربی‌یشتن پرونده ره انجوم هادین، اتا چی اشتباه پیش بورده.",
        "api-error-unknown-warning": "اخطار نشناسی‌یه: $1",
        "api-error-uploaddisabled": "باربی‌یشتن این ویکی دله غیرفعاله.",
-       "api-error-verification-error": "ممکن هسته که پرونده رِقِد بورد بائه یا پسوند غلط داره.",
-       "api-error-blacklisted": "اتا عنوان توصیفی دیگه انتخاب هاکنین."
+       "api-error-verification-error": "ممکن هسته که پرونده رِقِد بورد بائه یا پسوند غلط داره."
 }
index d60887a..e61e6d7 100644 (file)
@@ -11,7 +11,8 @@
                        "아라",
                        "Fitoschido",
                        "Taresi",
-                       "Macofe"
+                       "Macofe",
+                       "Akapochtli"
                ]
        },
        "tog-underline": "Mokìnxòîkuilòtzàswis tzòwilistìn:",
        "thu": "Mācuililhui",
        "fri": "6 ilhui",
        "sat": "7 ilhui",
-       "january": "Ic cē mētztli",
-       "february": "Ic ōmemētztli",
-       "march": "Ic ēyi mētztli",
+       "january": "Icce metztli",
+       "february": "Icome metztli",
+       "march": "3 Metz",
        "april": "Ic nāuhtetl mētztli",
        "may_long": "Ic mācuīlli mētztli",
        "june": "Ic chicuacē mētztli",
-       "july": "Ic chicōme mētztli",
-       "august": "Ic chicuēyi mētztli",
-       "september": "Ic chiucnāhui mētztli",
-       "october": "Ic mahtlāctli mētztli",
-       "november": "Ic mahtlāctli oncē mētztli",
-       "december": "Ic mahtlāctli omōme mētztli",
+       "july": "7 Metz",
+       "august": "8 Metz",
+       "september": "9 Metz",
+       "october": "10 Metz",
+       "november": "11 Metz",
+       "december": "12 Metz",
        "january-gen": "Ic cē mētztli",
        "february-gen": "Īcōmemētztli",
        "march-gen": "Īcyēyimētztli",
@@ -89,7 +90,7 @@
        "november-gen": "Īcmahtlāctetloncēmētztli",
        "december-gen": "Īcmahtlāctetlomōmemētztli",
        "jan": "Ic cē",
-       "feb": "Ic ōme",
+       "feb": "2 Metz",
        "mar": "Ic ēyi",
        "apr": "Nāhui",
        "may": "Mācuilli",
        "october-date": "Īcmahtlactlimētztli $1",
        "november-date": "Īcmahtlactlioncēmētztli $1",
        "december-date": "Īcmahtlactliomōmemētztli $1",
-       "pagecategories": "{{PLURAL:$1|Tlaìxmatkàyòtlàlilòtl|Tlaìxmatkàyòtlàlilòme}}",
+       "pagecategories": "{{PLURAL:$1|Neneuhcayotl|Neneuhcayomeh}}",
        "category_header": "Tlâkuilòlpiltin ìpan tlaìxmatkàtlàlilòtl \"$1\"",
        "subcategories": "Tlaìxmatkàtlàlilòpilòmë",
        "category-media-header": "Media \"$1\" neneuhcāyōc",
        "category-empty": "''Cah ahtlein inīn neneuhcāyōc.''",
        "hidden-categories": "{{PLURAL:$1|tlatlàtìlli tlaìxmatkàyòtlàlilòtl|tlatlàtìltìn tlaìxmatkàyòtlàlilòme}}",
        "hidden-category-category": "Tlatlàtìlkàtlaìxmatkàtlàlilòmë",
-       "category-subcat-count": "{{PLURAL:$2|Inìn tlaìxmatkàyòtlàlilòtl kipia san inìn tlaìxmatkàyòtlàlilòpilli.|Inìn tlaìxmatkàyòtlàlilòtl {{PLURAL:$1|kipia inìn tlaìxmatkàyòtlàlilòpilli|kimpia inîke $1 tlaìxmatkàyòtlàlilòpiltìn}}, ìpan $2.}}",
+       "category-subcat-count": "{{PLURAL:$2|Inin neneuhcayotl zan quipiya in tetoquilli tlani-neneuhcayotl.|Inn neneuhcayotl {{PLURAL:$1|quipiya intetoquilli tlani-neneuhcayotl|in tetoquiltin $1 tlani-neneuhcayomeh}}, itech tlacecempohualoni $2.}}",
        "category-subcat-count-limited": "Inīn {{PLURAL:$1|neneuhcāyōtzintli cah|$1 neneuhcāyōtzintli cateh}} inīn neneuhcāyōc.",
-       "category-article-count": "{{PLURAL:$2|Inìn tlaìxmatkàyòtlàlilòtl san kipia|Inìn tlaìxmatkàyòtlàlilòtl kimpia {{PLURAL:$1|inìn tlaìxtlapalli|inîke $1 tlaìxtlapaltìn}}, ìwikpa $2.}}",
+       "category-article-count": "{{PLURAL:$2|Inin neneuhcayotl zan quipiya in tetoquilli tlahcuilolli.|{{PLURAL:$1|In tetoquilli tlahcuilolli itech pohui|In tetoquiltin $1 tlahcuiloltin itech pohui}}, inin neneuhcayotl itech tlacecempohualoni ipan $2.}}",
        "category-article-count-limited": "Inīn {{PLURAL:$1|zāzanilli cah|$1 zāzanilli cateh}} inīn neneuhcāyōc.",
        "category-file-count": "{{PLURAL:$2|Inìn tlaìxmatkàyòtlàlilòtl san kipia|Inìn tlaìxmatkàyòtlalilòtl kimpia {{PLURAL:$1|inìn èwalli|inîke $1 èwaltìn}}, ìwikpa $2.}}",
        "category-file-count-limited": "{{PLURAL:$1|Inìn tlâkuilòlèwalli kä|Inîkë $1 tlâkuilòlèwaltìn katêkë}} ìpan inìn tlaìxmatkàtlàlilòtl.",
        "about": "Ītechcopa",
        "article": "Tlâkuilòpilli",
        "newwindow": "(Motlapoāz cē yancuīc tlanexillōtl)",
-       "cancel": "Xiccāhua",
+       "cancel": "Moxitiniz",
        "moredotdotdot": "Huehca ōmpa...",
        "mypage": "Noāmauh",
-       "mytalk": "Nozānīl",
+       "mytalk": "Teixnamiquiliztli",
        "anontalk": "Tēixnāmiquiliztli",
        "navigation": "Nēnemōhualiztli",
-       "and": "&#32;īhuān",
+       "and": "&#32;ihuan",
        "qbfind": "Xicahci",
        "qbbrowse": "Xitlatepotztoca",
        "qbedit": "Xicpatla",
        "faq": "Zan īc tētlatlanīliztli",
        "faqpage": "Project:FAQ",
        "actions": "Āyiliztli",
-       "namespaces": "Tōcātlacāuhtli",
+       "namespaces": "Tocatlacauhtli",
        "variants": "Nepāpan",
-       "navigation-heading": "Nemiliztlahtōlpōhualāmatl",
+       "navigation-heading": "Nemiliztlahtolpohualamatl",
        "errorpagetitle": "Aiuhcāyōtl",
        "returnto": "Ximocuepa īhuīc $1.",
-       "tagline": "Īhuīcpa {{SITENAME}}",
-       "help": "Tēpalēhuiliztli",
-       "search": "Mà motèmo",
-       "searchbutton": "Tictēmōz",
+       "tagline": "Itechcopa {{SITENAME}}",
+       "help": "Tepalehuiliztli",
+       "search": "Tlatemoliztli",
+       "searchbutton": "Tlatemoliztli",
        "go": "Xiyauh",
        "searcharticle": "Xiyauh",
        "history": "Tlaīxtli ītlahtōllo",
-       "history_short": "Tlahtōllōtl",
+       "history_short": "Tlahtollotl",
        "updatedmarker": "ōmoyancuīx īhuīcpa xōcoyōc notlahpololiz",
-       "printableversion": "Tepoztlahcuilōlli",
+       "printableversion": "Tepoztlahcuilolli",
        "permalink": "Mochipa tzonhuiliztli",
        "print": "Xictepoztlahcuilo",
        "view": "Xiquitta",
        "unprotectthispage": "Xicpatla inīn tlaīxtli ītlapiyaliz",
        "newpage": "Yancuic tlaīxtli",
        "talkpage": "Xictlahto inīn tlaīxtli ītechcopa",
-       "talkpagelinktext": "Nenônòtzalistli",
+       "talkpagelinktext": "Teixnamiquiliztli",
        "specialpage": "Nònkuâkìskàtlaìxtlapalli",
        "personaltools": "In tlein nitēquitiltilia",
        "articlepage": "Xiquitta in tlamantlaīxtli",
-       "talk": "Zānīlli",
+       "talk": "Teixnamiquiliztli",
        "views": "Tlachiyaliztli",
-       "toolbox": "Tequitīhuani",
+       "toolbox": "Tequitihualoni",
        "userpage": "Xiquitta tlatequitiltilīlli zāzanilli",
        "projectpage": "Xiquitta tlachīhualiztli zāzanilli",
        "imagepage": "Xiquitta in zāzanilli īāma",
        "otherlanguages": "Occequīntīn tlahtōlcopa",
        "redirectedfrom": "(Ōmotlacuep īhuīcpa $1)",
        "redirectpagesub": "Ōmotlacuep zāzanilli",
-       "lastmodifiedat": "Inīn zāzanilli ōtlapatlac catca īpan $2, $1.",
+       "lastmodifiedat": "Inin tlahcuilolli omopatlac immanin $1, ipan $2.",
        "viewcount": "Inīn zāzanilli quintlapōhua {{PLURAL:$1|cē tlahpololiztli|$1 tlahpololiztli}}.",
        "protectedpage": "Ōmoquīxtix zāzanilli",
        "jumpto": "Īhuīcpa ticholōz:",
        "jumptonavigation": "nēnemōhualiztli",
-       "jumptosearch": "tlatēmoliztli",
-       "aboutsite": "Ītechcopa {{SITENAME}}",
-       "aboutpage": "Project:Ītechcopa",
+       "jumptosearch": "Tlatemoliztli",
+       "aboutsite": "Itechcopa {{SITENAME}}",
+       "aboutpage": "Project:Itechcopa",
        "copyright": "In tlahcuilōlli cah tlacēcencāhuani īpan $1 tel ahmo intlā īcuepca motēnēhua.",
        "copyrightpage": "{{ns:project}}:Tlachīhualōni ītlapiyaliz",
-       "currentevents": "Āxcāncāyōtl",
+       "currentevents": "Axcancayotl",
        "currentevents-url": "Project:Āxcāncāyōtl",
-       "disclaimers": "Nahuatīllahtōl",
+       "disclaimers": "tlamamalquixtiliztli",
        "edithelp": "Tlapatlaliztechcopa tēpalēhuiliztli",
        "helppage-top-gethelp": "Tēpalēhuiliztli",
-       "mainpage": "Huēyitlaīxtli",
-       "mainpage-description": "Huēyitlaīxtli",
+       "mainpage": "Yacatlahcuilolli",
+       "mainpage-description": "Yacatlahcuilolli",
        "policy-url": "Project:Nahuatīltōn",
-       "portal": "Calīxcuātl tocalpōl",
-       "portal-url": "Project:Calīxcuātl tocalpōl",
-       "privacy": "Tlahcuilōlli piyaliznahuatīlli",
+       "portal": "Yacatlahcuilolli tocalpol",
+       "portal-url": "Project:Yacatlahcuilolli tocalpol",
+       "privacy": "Tlahcuilolli piyaliznahuatilli",
        "privacypage": "Project:Tlahcuilōlpiyaliztechcopa nahuatīltōn",
        "badaccess": "Tlahuelītiliztechcopa ahcuallōtl",
        "badaccess-group0": "Tehhuātl ahmo tiquichīhua inōn tiquiēlēhuia.",
        "retrievedfrom": "Ōquīzqui ītech  \"$1\"",
        "youhavenewmessages": "Tiquimpiya $1 ($2).",
        "youhavenewmessagesmulti": "Tiquimpiya yancuīc tlahcuilōlli īpan $1",
-       "editsection": "xicpatla",
+       "editsection": "Ticpatlaz",
        "editold": "xicpatla",
        "viewsourceold": "xiquitta mēyalli",
-       "editlink": "xicpatla",
-       "viewsourcelink": "xiquitta mēyalli",
-       "editsectionhint": "Xicpatla in: $1",
-       "toc": "Inīn tlahcuilōlco",
+       "editlink": "ticpatlaz",
+       "viewsourcelink": "Tiquittaz itzintiliz",
+       "editsectionhint": "Ticpatlaz in: $1",
+       "toc": "In tlein quipiya inin tlahcuilolli",
        "showtoc": "xicnēxti",
        "hidetoc": "xictlāti",
        "collapsible-collapse": "Motlàtìs",
        "site-atom-feed": "$1 Atom huelītiliztli",
        "page-rss-feed": "\"$1\" RSS huelītiliztli",
        "page-atom-feed": "\"$1\" RSS huelītiliztli",
-       "red-link-title": "$1 (ayāc in centlaīxtli)",
-       "nstab-main": "Tlaīxtli",
+       "red-link-title": "$1 (ahmo oncah tlahcuilolli)",
+       "nstab-main": "Tlahcuilolli-amatl",
        "nstab-user": "Tlatequitiltilīlli",
        "nstab-media": "Mēdiatl",
-       "nstab-special": "Nònkuâkìskàtlaìxtlapalli",
+       "nstab-special": "Noncuahquizqui tlahcuilolli",
        "nstab-project": "Ìtlaìxtlapal in tlayẻkàntekitl",
-       "nstab-image": "Ihcuilōlli",
+       "nstab-image": "Tlahcuilolpiyalli",
        "nstab-mediawiki": "Tlahcuilōltzintli",
        "nstab-template": "Nemachiòtl",
        "nstab-help": "Tèpalèwilistli",
-       "nstab-category": "Tlaìxmatkàyòtlàlilòtl",
-       "mainpage-nstab": "Huēyitlaīxtli",
+       "nstab-category": "Neneuhcayotl",
+       "mainpage-nstab": "Yacatlahcuilolli",
        "nosuchaction": "Ahmo ia tlachīhualiztli",
        "nosuchspecialpage": "Âmò ka inòn nònkuâkìskàtlaìxtlapalli",
        "nospecialpagetext": "<strong>Tiknẻki sè nònkuâkìskàtlaìxtlapalli tlèn âmò kä.</strong>\n\nKualli tikỉtas sè ìntlapòpòwaltekpànal in nònkuâkìskàtlaìxtlapaltìn ìpan [[Special:SpecialPages|{{int:specialpages}}]].",
        "welcomeuser": "Ximopanōlti, $1!",
        "yourname": "Tequihuihcātōcāitl:",
        "userlogin-yourname": "Tequihuihcātōcāitl",
+       "userlogin-yourname-ph": "Xiquihcuilo motoca iuhqui tequitihuani",
        "yourpassword": "Motlahtōlichtacāyo",
+       "userlogin-yourpassword": "Ichtacamachiyotl",
+       "createacct-yourpassword-ph": "Xictlali centetl ichtacamachiyotl",
        "yourpasswordagain": "Motlahtōlichtacāyo occeppa",
-       "remembermypassword": "Ticpiyāz motlacalaquiliz inīn chīuhpōhualhuazco (īxquich {{PLURAL:$1|tōnalli}})",
+       "createacct-yourpasswordagain": "Xicneltilia in ichtacamachiyotl",
+       "createacct-yourpasswordagain-ph": "Occepa xictlali in ichtacamachiyotl",
        "yourdomainname": "Moāxcāyō",
        "login": "Xicalaqui",
        "nav-login-createaccount": "Ximocalaqui / ximomachiyōmaca",
        "createaccount": "Xicchīhua tlapōhualli",
        "gotaccount": "¿Ye ticpiya cē tlapōhualli? '''$1'''.",
        "gotaccountlink": "Ximocalaqui",
+       "createacct-email-ph": "xiquihcuilo mocorreo electrónico",
        "createaccountmail": "Ticnemītīz ahmo cemihcac zāzoichtacātlahtōlli nō in tiquēhualtīz in maltzinteyōtl monetitlanizyeyān",
        "createaccountreason": "Tleīpampa:",
        "createacct-reason": "Tleīpampa",
        "loginlanguagelabel": "Tlahtōlli: $1",
        "pt-login": "Xicalaqui",
        "pt-login-button": "Xicalaqui",
-       "pt-createaccount": "Xicchīhua motlapōhual",
+       "pt-createaccount": "Xicchihua motlapohual",
+       "pt-userlogout": "Tiquizaz",
        "changepassword": "Xicpatla motlahtōlichtacāyo",
        "resetpass_header": "Xicpatla motlahtōlichtacāyo",
        "oldpassword": "Huēhueh motlahtōlichtacayo:",
        "subject": "Ītechpa:",
        "minoredit": "Ca tepitōn inīn tlapatlaliztli",
        "watchthis": "Xicpiya inīn tlaīxtli",
-       "savearticle": "Xicpiya tlaīxtli",
+       "savearticle": "Xicpiya tlahcuilolli",
        "preview": "Xiquitta achtochīhualiztli",
        "showpreview": "Xiquitta achtochīhualiztli",
        "showdiff": "Xicnēxti tlapatlaliztli",
        "revertmerge": "Tiquīxipehuaz",
        "history-title": "«$1» ītlaceppahuiliztlahtōllo",
        "lineno": "Pāntli $1:",
-       "editundo": "Tichuelōz",
-       "searchresults": "Tlatēmoliztli",
-       "searchresults-title": "«$1» tlatēmōliztli īmochīhualiz",
+       "editundo": "Ticxitiniz",
+       "searchresults": "motlatemoliz itlananquilizhuan",
+       "searchresults-title": "«$1» tlatemoliztli imochihualiz",
        "prevn": "{{PLURAL:$1|$1}} achtopa",
        "nextn": "niman {{PLURAL:$1|$1}}",
        "shown-title": "Quinēxiltīz $1 {{PLURAL:$1|mochīhualiztli}} cece āmac",
        "searchprofile-images-tooltip": "Tiquintēmōz tlahcuilōlli",
        "searchprofile-everything-tooltip": "Tictēmōz mochi tlapiyalizpan (mopiyah tēixnāmiquiliztli zāzanilli)",
        "search-result-size": "$1 ({{PLURAL:$2|1 tlahtōl|$2 tlahtōltin}})",
-       "search-redirect": "(tlacuepaliztli $1)",
+       "search-redirect": "(ixquichca ompa mitzhuica $1)",
        "search-section": "(tlahtōltzintli $1)",
        "search-category": "(tlaìxmatkàyòtlàlilòtl $1)",
        "search-suggest": "Ahnōceh tiquihtōznequiya: $1",
        "action-block": "tiquitzacuilīz inīn tlatequitiltilīlli",
        "action-userrights": "tiquimpatlāz mochi tlatequitiltilīlli huelītiliztli",
        "nchanges": "$1 {{PLURAL:$1|tlapatlaliztli}}",
-       "enhancedrc-history": "tlahtōllōtl",
+       "enhancedrc-history": "Tlahtollotl",
        "recentchanges": "Yancuic tlapatlaliztli",
        "recentchanges-legend": "Yancuīc tlapatlaliztechcopa tlanequiliztli",
        "recentchanges-summary": "Xiquinttāz in achi yancuīc ahmo occequīntīn tlapatlaliztli huiquipan inīn zāzanilpan.",
        "rcshowhidemine": "$1 notlahcuilōl",
        "rcshowhidemine-show": "Xicnēxti",
        "rclinks": "Xiquintta xōcoyōc $1 tlapatlaliztli xōcoyōc $2 tōnalpan.<br />$3",
-       "diff": "ahneneuh",
-       "hist": "tlahtōl",
+       "diff": "ahneneuhqui",
+       "hist": "tlahtollotl",
        "hide": "Tiquintlātīz",
        "show": "Xicnēxti",
        "minoreditletter": "p",
        "newsectionsummary": "Yancuīc tlahtōltzintli: /* $1 */",
        "recentchangeslinked": "Tlapatlaliztli tzonhuilizpan",
        "recentchangeslinked-feed": "Tlapatlaliztli tzonhuilizpan",
-       "recentchangeslinked-toolbox": "Tlapatlaliztli tzonhuilizpan",
+       "recentchangeslinked-toolbox": "Itloc itlapatlalizhuan",
        "recentchangeslinked-title": "Tlapatlaliztli \"$1\" ītechcopa",
        "recentchangeslinked-page": "Tlaīxtli ītōcā:",
-       "upload": "Tlahcuilōlquetza",
+       "upload": "Tlahcuilolquetzaliztli",
        "uploadbtn": "Tlahcuilōlquetza",
        "uploadnologin": "Ahmo ōtimocalac",
        "uploaderror": "Tlaquetzaliztli ahcuallōtl",
        "filehist-thumb": "Īxiptlahtōn",
        "filehist-user": "Tequihuihqui",
        "filehist-dimensions": "Octacayōtl",
-       "filehist-comment": "TlahtōIcaquiliztīlōni",
-       "imagelinks": "Ihcuilōlli ītequiuh",
+       "filehist-comment": "TlahtoIcaquiliztiloni",
+       "imagelinks": "In canin oquitlalihqueh",
        "linkstoimage": "Inīn {{PLURAL:$1|zāzanilli motzonhuilia|$1 zāzanilli motzonhuiliah}} inīn tlahcuilōlhuīc:",
        "nolinkstoimage": "Ahmo cateh zāzaniltin tlein tzonhuiliah inīn tlahcuilōlhuīc.",
        "morelinkstoimage": "Tiquinttāz [[Special:WhatLinksHere/$1|achi tzonhuiliztli]] inīn tlahcuilōlhuīc.",
        "blanknamespace": "(Huēyi)",
        "contributions": "In {{GENDER:$1|tlatequitiltilīlli}} ītlahcuilōl",
        "contributions-title": "Tlatequitiltilīlli $1 ītlahcuilōl",
-       "mycontris": "Notlahcuilōl",
+       "mycontris": "Notlahcuilol",
        "contribsub2": "$1 ($2)",
        "uctop": "(āxcān tlapatlaliztli)",
        "month": "Īhuīcpa mētztli (auh achtopa):",
        "sp-contributions-search": "Tiquintlatēmōz tlapatlaliztli",
        "sp-contributions-username": "IP nozo tlatequitiltilīlli ītōcā:",
        "sp-contributions-submit": "Tlatēmōz",
-       "whatlinkshere": "In tlein quitzonhuilia nicān",
+       "whatlinkshere": "In tlein quitzonhuilia nican",
        "whatlinkshere-title": "Zāzaniltin quitzonhuiliah $1",
        "whatlinkshere-page": "Zāzanilli:",
        "linkshere": "Inīn zāzaniltin quitzonhuiliah '''[[:$1]]''' īhuīc:",
        "infiniteblock": "ahtlamic",
        "expiringblock": "tlami īpan $1 īpan $2",
        "anononlyblock": "zan ahtōcā",
-       "blocklink": "ticzacuilīz",
+       "blocklink": "tictzacuiliz",
        "unblocklink": "ahtiquitzacuilīz",
        "change-blocklink": "Ticpatlaz tlatzacualli",
        "contribslink": "tlapatlaliztli",
        "tooltip-pt-mycontris": "{{GENDER:|Motlahcuilōl}}",
        "tooltip-pt-login": "Tihuelīti timocalaqui, tēl ahmo tihuīquilia.",
        "tooltip-pt-logout": "Tiquīzāz",
-       "tooltip-ca-talk": "Inīn tlahcuilōlli zānīllī ītechcopa",
-       "tooltip-ca-edit": "Xicpatla inīn tlaīxtli",
+       "tooltip-ca-talk": "Iteixnamiquiliz itechpa inin tlahcuilolli",
+       "tooltip-ca-edit": "Ticpatlaz inin tlahcuilolli",
        "tooltip-ca-addsection": "Tictzintīz yancuic xeliuhcāyōtl.",
        "tooltip-ca-viewsource": "Inīn zāzanilli ōmoquīxti. Tihuelīti tiquitta ītlahtōlcaquiliztilōni.",
        "tooltip-ca-history": "Achtopa āxcān zāzanilli īhuān in tlatequitiltilīlli ōquinchīuhqueh",
        "tooltip-ca-delete": "Ticpolōz inīn zāzanilli",
        "tooltip-ca-undelete": "Ahticpolōz inīn zāzanilli",
        "tooltip-ca-move": "Ticzacāz inīn zāzanilli",
-       "tooltip-ca-watch": "Ticcēntilīz inīn zāzanilli motlachiyalizhuīc",
+       "tooltip-ca-watch": "Ticcentiliz inin tlahtolli motecpanaliz",
        "tooltip-ca-unwatch": "Ahtictlachiyāz inīn zāzanilli",
-       "tooltip-search": "Tlatēmōz īpan {{SITENAME}}",
-       "tooltip-search-go": "Tiyaz in zāzanilhuīc īca inīn huel melāhuac tōcaitl intlā yez",
-       "tooltip-search-fulltext": "Tictemōz inīn tlahcuilōlli in āmac",
-       "tooltip-p-logo": "Xiquitta in tohuēyitlaīx",
-       "tooltip-n-mainpage": "Tiquittaz in huēyitlaīxtli",
-       "tooltip-n-mainpage-description": "Xiquitta in tohuēyitlaīx",
+       "tooltip-search": "Tlatemoliztli ipan {{SITENAME}}",
+       "tooltip-search-go": "Tiyaz ihuicpa tlahcuilolli ica inin huel melahuac tocaitl intla oncah",
+       "tooltip-search-fulltext": "Tictemoz inin tlahcuilolli ipan amatl",
+       "tooltip-p-logo": "Tiquittaz in yacatlahcuilolli",
+       "tooltip-n-mainpage": "Tiquittaz in yacatlahcuilolli",
+       "tooltip-n-mainpage-description": "Tiquittaz in yacatlahcuilolli",
        "tooltip-n-portal": "Tlachīhualiztechcopa, inōn tihuelīti titlachīhua, tlatēmoyān",
        "tooltip-n-recentchanges": "Yancuic īpan tlapatlaliztli in huiqui",
        "tooltip-n-randompage": "Tiquittaz centlaīxtli",
        "tooltip-n-help": "In tēmachtīlōyān",
        "tooltip-t-whatlinkshere": "Mochīntīn zāzaniltin huiquipan quitzonhuiliah nicān",
-       "tooltip-t-recentchangeslinked": "Yancuic tlapatlaliztli inīn zāzanilhuīcpa moquintzonhuilia",
+       "tooltip-t-recentchangeslinked": "Yancuic tlapatlaliztli ipan tlahcuiloltin tlein quitzonhuilia nican",
        "tooltip-feed-rss": "RSS tlachicāhualiztli inīn zāzaniltechcopa",
        "tooltip-feed-atom": "Atom tlachicāhualiztli inīn zāzaniltechcopa",
        "tooltip-t-contributions": "Tlapōhualmatl ītechpa {{GENDER:$1|inīn tlatequitiltilīlli}} ītlahcuilōl",
        "tooltip-t-emailuser": "Tiquihcuilōz inīn tlatequitiltililhuīc",
-       "tooltip-t-upload": "Tiquinquetzāz tlahcuilōlli",
-       "tooltip-t-specialpages": "Ìntlapòpòwaltekpànal mochtìn in nònkuâkìskàtlaìxtlapaltìn",
-       "tooltip-t-print": "Tepoztlahcuilōlli",
-       "tooltip-ca-nstab-main": "Xiquitta in tlamantlaīxtli",
+       "tooltip-t-upload": "Tiquinquetzaz tlahcuiloltin",
+       "tooltip-t-specialpages": "Intlahtoltecpanaliz mochtin in noncuahquizquitlahcuiloltin",
+       "tooltip-t-print": "Tepoztlahcuilolli",
+       "tooltip-ca-nstab-main": "Tiquittaz tlein quipiya in tlahcuilolli",
        "tooltip-ca-nstab-user": "Xiquitta tlatequitiltilīlli īzāzanil",
        "tooltip-ca-nstab-special": "Inīn nōncuahquīzqui āmatl, auh ahmohuelitizpatla",
        "tooltip-ca-nstab-project": "Xiquitta in tlatequipanōllaīxtli",
        "tooltip-ca-nstab-mediawiki": "Xiquitta in tlahcuilōltzin",
        "tooltip-ca-nstab-template": "Xiquitta in nemachiyōtīlli",
        "tooltip-ca-nstab-help": "Xiquitta in tēpalēhuiliztli zāzanilli",
-       "tooltip-ca-nstab-category": "Mà mỏta ìtlaìxtlapal in tlaìxmatkàyòtlàlilòtl",
+       "tooltip-ca-nstab-category": "tiquittaz neneuhcayotl itlahcuilol",
        "tooltip-minoredit": "Ticmachiyōz quemeh tlapatlalitzintli",
        "tooltip-save": "Ticpiyaz mopatlaliz",
        "tooltip-preview": "Xachtopaitta mopatlaliz ¡Timitztlahtlauhtiliah, xicchīhua yēppa mā tiquimpiya!",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:|zāzanilli|zāzanilli}}",
        "file-info-size": "$1 × $2 pixel; zāzanilli octacayōtl: $3; machiyōtl MIME: $4",
        "file-nohires": "Ahmo ia achi cualli ahmo occē īxiptli.",
-       "show-big-image": "Tzīntilicihcuilōlli",
+       "show-big-image": "Tzintiliztlahcuilolli",
        "newimages": "Yancuīc īxipcān",
        "imagelisttext": "Nicān {{PLURAL:$1|mopiya|mopiyah}} '''$1''' īxiptli $2 iuhcopa.",
        "noimages": "Ahtlein ic tlatta.",
        "fileduplicatesearch-filename": "Tlahcuilōlli ītōcā:",
        "fileduplicatesearch-submit": "Tlatēmōz",
        "fileduplicatesearch-info": "$1 × $2 pixelli<br />Tlahcuilōlli īxquichiliz: $3<br />MIME iuhcāyōtl: $4",
-       "specialpages": "Nònkuâkìskàtlaìxtlapaltìn",
+       "specialpages": "Noncuahquizqui tlahcuilolli",
        "specialpages-note": "* Yeliztli nōncuahquīzqui āmatl.\n* <span class=\"mw-specialpagerestricted\">Tlaquīxtīlli nōncuahquīzqui āmatl.</span>\n* <span class=\"mw-specialpagecached\">Tlatlātīlli nōncuahquīzqui āmatl (aocmo monemitīa).</span>",
        "specialpages-group-other": "Oksẻki nònkuâkìskàtlaìxtlapaltìn",
        "specialpages-group-login": "Ximocalaqui / ximomachiyōmaca",
        "htmlform-selectorother-other": "Occē",
        "rightsnone": "ahtlein",
        "revdelete-summary": "ticpatlāz tlahcuilōltōn",
-       "searchsuggest-search": "Mà motèmo",
+       "searchsuggest-search": "Tlatemoliztli",
        "api-error-ok-but-empty": "Tlâtek îtlakawilistli: Âmò tènankilia in tlatèmakani.",
        "api-error-overwrite": "Awel motlâkuilnepanòltis sè èwalli tlèn yi katki.",
        "api-error-stashfailed": "Tlâtek îtlakawilistli: In tlatèmakani awel òkeuh in èwalpanòni.",
index c72ae68..2b1bc3e 100644 (file)
        "newarticle": "(Sin)",
        "newarticletext": "Lí tòe 1 ê liân-kiat lâi kàu 1 bīn iáu-bōe chûn-chāi ê ia̍h. Beh khai-sí pian-chi̍p chit ia̍h, chhiáⁿ tī ē-kha ê bûn-jī keh-á lāi-té phah-jī. ([$1 Bo̍k-lio̍k] kà lí án-choáⁿ chìn-hêng.) Ká-sú lí bô-tiuⁿ-tî lâi kàu chia, ē-sai chhi̍h liû-lám-khì ê '''téng-1-ia̍h''' tńg--khì.",
        "anontalkpagetext": "----''Pún thó-lūn-ia̍h bô kò·-tēng ê kháu-chō/hō·-thâu, kan-na ū 1 ê IP chū-chí (chhin-chhiūⁿ 123.456.789.123). In-ūi bô kāng lâng tī bô kāng sî-chūn ū khó-lêng tú-hó kong-ke kāng-ê IP, lâu tī chia ê oē ū khó-lêng hō· bô kāng lâng ê! Beh pī-bián chit khoán būn-tê, ē-sái khì [[Special:UserLogin|khui 1 ê hō·-thâu a̍h-sī teng-ji̍p]].''",
-       "noarticletext": "這頁這馬無內容,你會使佇別頁[[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>。",
        "clearyourcache": "'''Chù-ì:''' Pó-chûn liáu-āu, tio̍h ē-kì leh kā liû-lám-khì ê cache piàⁿ tiāu chiah khoàⁿ-ē-tio̍h kái-piàn: *'''Firefox / Safari:''' chhi̍h tiâu \"Shift\" kâng-sî-chūn tiám-kik ''Reload/têng-sin chài-ji̍p'' a̍h-sī chhi̍h ''Ctrl-F5'' \"Ctrl-R\" kî-tiong chi̍t ê (''Command-R'' tī Mac) \n* '''Google Chrome:''' chhi̍h ''Ctrl-Shift-R'' (''Command-Shift-R'' tī Mac)\n'''Internet Explorer :'''chhi̍h tiâu \"Ctrl\" kâng-sî-chūn tiám-kek ''Refresh/têng-sin chài-ji̍p'' a̍h-sī chhi̍h \"Ctrl-F5\" \n* '''Konqueror:'''  tiám-kek ''Reload/têng-sin chài-ji̍p'' a̍h-sī chhi̍h ''F5''\n* '''Opera:''' piàⁿ-tiāu cache tī ''Tools(ke-si) → Preferences(siat-piān)''",
        "usercssyoucanpreview": "'''Phiat-pō·''': Pó-chûn chìn-chêng ē-sái chhi̍h 'Seng khoàⁿ-māi' kiám-cha sin ê CSS a̍h-sī JavaScript.",
        "userjsyoucanpreview": "'''Phiat-pō·''': Pó-chûn chìn-chêng ē-sái chhi̍h 'Seng khoàⁿ-māi' kiám-cha sin ê CSS a̍h-sī JavaScript.",
        "nextrevision": "Khah-sin ê siu-tēng-pún→",
        "currentrevisionlink": "khoàⁿ siōng sin ê siu-tēng-pún",
        "cur": "taⁿ",
-       "next": "下一个",
+       "next": "āu",
        "last": "chêng",
        "page_first": "Tùi thâu-chêng",
        "page_last": "Tùi āu-piah",
        "searchprofile-everything-tooltip": "Chhoē choân-pō͘ (pau-koat thó-lūn-ia̍h)",
        "searchprofile-advanced-tooltip": "佇你家己設的名空間內底揣",
        "search-result-size": "$1 ({{PLURAL:$2|1 jī-goân|$2 jī-goân}})",
-       "search-redirect": "($1 轉)",
+       "search-redirect": "(Tùi $1 choán--kòe)",
        "search-section": "(toān-lo̍h $1)",
        "searchall": "choân-pō·",
        "showingresults": "Ē-kha tùi #<b>$2</b> khai-sí hián-sī <b>$1</b> hāng kiat-kó.",
        "filemissing": "Bô tóng-àn",
        "import": "Su-ji̍p ia̍h",
        "tooltip-pt-userpage": "{{GENDER:|Lí ê iōng-chiá}} ê ia̍h",
-       "tooltip-pt-mytalk": " ê thó-lūn ia̍h",
+       "tooltip-pt-mytalk": "{{GENDER:Lí}} ê thó-lūn ia̍h",
        "tooltip-pt-preferences": "{{GENDER:|Lí ê}} siat-tēng",
        "tooltip-pt-watchlist": "你監視的頁有改過的清單",
-       "tooltip-pt-mycontris": " ê kòng-hiàn lia̍t-toaⁿ",
+       "tooltip-pt-mycontris": "{{GENDER:|Lí}} ê kòng-hiàn lia̍t-toaⁿ",
        "tooltip-pt-login": "Hi-bāng lí teng-ji̍p; m̄-ko bô kiông-chè",
        "tooltip-pt-logout": "Teng-chhut",
        "tooltip-pt-createaccount": "Kiàn-gī lí seng khui chi̍t-ê kháu-chō (bô-it-tēng ài); chiah koh teng-ji̍p.",
        "metadata-collapse": "Am iù-chiat",
        "metadata-fields": "佇顯示圖片的頁,若掀開元資料,下跤的EXIF資料會儂看著。其他的元資料是先看無。\n* 廠商\n* 機型\n* 翕像的時陣\n* 曝光\n* 光圈\n* ISO 速率\n* 焦距\n* 作者\n* 版權\n* 說明\n* 緯度(GPS)\n* 經度(GPS)\n* 海拔(GPS)",
        "exif-software": "Sú-iōng ê nńg-thé",
+       "exif-colorspace": "Sek-chhái khong-kan",
        "namespacesall": "choân-pō·",
        "monthsall": "choân-pō͘",
        "confirmemail": "Khak-jīn e-mail chū-chí",
        "version": "Pán-pún",
        "specialpages": "Te̍k-sû-ia̍h",
        "tag-filter": "[[Special:Tags|Piau-chhiam]] chhoē mi̍h:",
-       "tag-list-wrapper": "([[Special:Tags|$1 ê piau-chhiam]]: $2)",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|piau-chhiam}}]]: $2)",
        "logentry-move-move": "$1 {{GENDER:$2|sóa}} $3 chit ia̍h khì $4",
        "logentry-newusers-create": "已經{{GENDER:$2|開好}}用者口座 $1",
-       "searchsuggest-search": "Chhoē",
+       "searchsuggest-search": "Chhoē {{SITENAME}}",
        "expandtemplates": "Khok-chhiong pang-bô͘",
        "expand_templates_input": "Su-ji̍p bûn-jī:",
        "expand_templates_output": "Kiat-kó:",
index 6d21b41..5cb16cb 100644 (file)
        "botpasswords-label-resetpassword": "Riabbìa 'a password",
        "botpasswords-label-grants": "Assegnaziune apprecabbele:",
        "botpasswords-help-grants": "Ogne assegnazione dà acciesso a 'e deritte utente elencate ca n'utenza avesse già. Vedite 'a [[Special:ListGrants|tabbella 'e ll'assegnaziune]] pe' ne mòvere cchiù nfurmaziune.",
-       "botpasswords-label-restrictions": "Restriziune d'uso:",
        "botpasswords-label-grants-column": "Assegnaziune date",
        "botpasswords-bad-appid": "'O nomme bot \"$1\" nun è bbuono.",
        "botpasswords-insert-failed": "Nun se pò azzeccà 'o nomme bot \"$1\". Fosse stato già azzeccato?",
        "passwordreset-nocaller": "Nu chiammate s'avess'a dà",
        "passwordreset-nosuchcaller": "'O chiammante nun esiste: $1",
        "passwordreset-ignored": "'A reimpustazione d' 'a password nun s'è gistita. Fosse ca nisciunu fornitore è stato mpustato?",
-       "passwordreset-invalideamil": "Indirizzo 'e posta email nun valido",
+       "passwordreset-invalidemail": "Indirizzo 'e posta email nun valido",
        "passwordreset-nodata": "Nun è stato fornito né nomme utente né indirizzo 'e posta email",
        "changeemail": "Cagna o lèva l'indirizzo e-mail",
        "changeemail-header": "Ghienchete stu modulo pe' puté cagnà 'o indirizzo e-mail d' 'o vuosto. Si vuje vulite luvà e 'o scucchià l'associazione 'e cocche cunto mail d' 'o cunto vuosto, lassate 'o cunto e-mail nuovo abbacante quanno mannarrate stu modulo.",
        "activeusers-intro": "Chest'è n'elenco d'utente c'hanno fatto cierti tipe d'attività nfin'a $1 {{PLURAL:$1|juorno|ghiuorne}} fa.",
        "activeusers-count": "$1 {{PLURAL:$1|cagnamiento|cagnamiente}} int'a l'urdeme {{PLURAL:$3|ghiuorne}}",
        "activeusers-from": "Fà vedè l'utente partenno 'a:",
-       "activeusers-hidebots": "Annascunne 'e bot",
-       "activeusers-hidesysops": "Annascunne l'ammenistrature",
        "activeusers-noresult": "Nisciun'utente truvato.",
        "activeusers-submit": "Mmusta cunte attive",
        "listgrouprights": "Deritte d' 'e gruppe utente",
        "feedback-external-bug-report-button": "Archivia na fatica tecnica",
        "feedback-dialog-title": "Manna 'o feedback",
        "feedback-dialog-intro": "Putite ausà sempricemente 'o modulo ccà abbascio pe' putè mannà 'o feedback vuosto. 'O cummento sarrà azzeccato â paggena \"$1\", nziem' 'o nomme vuosto.",
-       "feedback-error-title": "Errore",
        "feedback-error1": "Errore: Risultato nun aspettato 'a ll'API",
        "feedback-error2": "Errore: Cagnamiento scassato",
        "feedback-error3": "Errore: Ll'API nun risponne",
index fe944a7..28d1e80 100644 (file)
        "versionrequired": "MediaWiki-versjon $1 er påkrevd",
        "versionrequiredtext": "MediaWiki-versjon $1 er nødvendig for å bruke denne siden. Se [[Special:Version|versjonsiden]]",
        "ok": "OK",
+       "pagetitle": "$1 – {{SITENAME}}",
        "retrievedfrom": "Hentet fra «$1»",
        "youhavenewmessages": "Du har $1 ($2).",
        "youhavenewmessagesfromusers": "Du har $1 fra {{PLURAL:$3|en annen bruker| $3 brukere}} ($2).",
        "botpasswords-label-delete": "Slett",
        "botpasswords-label-resetpassword": "Tilbakestill passord",
        "botpasswords-label-grants": "Tilgjengelige tildelinger:",
-       "botpasswords-help-grants": "Hver tildeling gir tilgang til opplistede brukerrettigheter som brukerkontoen allerede har. Se [[Special:ListGrants|tildelingstabellen]] for mer informasjon.",
+       "botpasswords-help-grants": "Tildelinger gir tilgang til rettighetene som allerede innehas av brukerkontoen din. Å slå på en tildeling her gir ikke tilgang til rettigheter brukerkontoen din ikke ellers ville hatt. Se [[Special:ListGrants|tildelingstabellen]] for mer informasjon.",
        "botpasswords-label-grants-column": "Bevilget",
        "botpasswords-bad-appid": "Robotnavnet \"$1\" er ikke gyldig.",
        "botpasswords-insert-failed": "Kunne ikke legge til robotnavnet \"$1\". Har det allerede blitt lagt til?",
        "passwordreset-nocaller": "En bruker må angis",
        "passwordreset-nosuchcaller": "Brukeren finnes ikke: $1",
        "passwordreset-ignored": "Passordtilbakestillingen ble ikke håndtert. Har ingen leverandør blitt konfigurert?",
-       "passwordreset-invalideamil": "Ugyldig e-postadresse",
+       "passwordreset-invalidemail": "Ugyldig e-postadresse",
        "passwordreset-nodata": "Verken et brukernavn eller en e-postadresse ble oppgitt",
        "changeemail": "Endre eller fjerne epostadresse",
        "changeemail-header": "Fyll ut dette skjemaet for å bytte din epost-adresse. Hvis du vil fjerne epostadressen fra din konto, kan du la ny epostadresse-feltet være tomt når.",
        "grant-basic": "Grunnleggende rettigheter",
        "grant-viewdeleted": "Vise slettede filer og sider",
        "grant-viewmywatchlist": "Vise overvåkningslisten din",
+       "grant-viewrestrictedlogs": "Vis begrensede loggposter",
        "newuserlogpage": "Brukeropprettelseslogg",
        "newuserlogpagetext": "Dette er en logg over brukeropprettelser.",
        "rightslog": "Brukerrettighetslogg",
        "upload-dialog-disabled": "Filopplastinger med denne dialogen er slått av for denne wikien.",
        "upload-dialog-title": "Last opp fil",
        "upload-dialog-button-cancel": "Avbryt",
+       "upload-dialog-button-back": "Tilbake",
        "upload-dialog-button-done": "Utført",
        "upload-dialog-button-save": "Lagre",
        "upload-dialog-button-upload": "Last opp",
        "uploadnewversion-linktext": "Last opp en ny versjon av denne filen",
        "shared-repo-from": "fra $1",
        "shared-repo": "et delt fillager",
+       "filepage.css": "/* CSS som plasseres her inkluderes på filbeskrivelsessiden, og inkluderes også på andre wikier som bruker denne */",
        "upload-disallowed-here": "Du kan ikke overskrive denne filen.",
        "filerevert": "Tilbakestill $1",
        "filerevert-legend": "Tilbakestill fil",
        "listusers": "Brukerliste",
        "listusers-editsonly": "Vis bare brukere med redigeringer",
        "listusers-creationsort": "Sorter etter opprettelsesdato",
-       "listusers-desc": "Sorter i avtakende rekkefølge",
+       "listusers-desc": "Sorter i synkende rekkefølge",
        "usereditcount": "{{PLURAL:$1|én redigering|$1 redigeringer}}",
        "usercreated": "{{GENDER:$3|Opprettet}} $2 $1",
        "newpages": "Nye sider",
        "apisandbox-results-fixtoken-fail": "Henting av nøkkelen «$1» mislyktes.",
        "apisandbox-alert-page": "Felter på denne siden er ugyldige.",
        "apisandbox-alert-field": "Verdien til dette feltet er ugyldig.",
+       "apisandbox-continue": "Fortsett",
+       "apisandbox-continue-clear": "Tøm",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} vil [https://www.mediawiki.org/wiki/API:Query#Continuing_queries fortsette] forrige forespørsel; {{int:apisandbox-continue-clear}} vil tømme fortsettelsesrelaterte parametre.",
        "booksources": "Bokkilder",
        "booksources-search-legend": "Søk etter bokkilder",
        "booksources-search": "Søk",
        "booksources-text": "Under er en liste over lenker til andre sider som selger nye og brukte bøker, og kan også ha videre informasjon om bøker du leter etter:",
        "booksources-invalid-isbn": "Det gitte ISBN-nummeret er ugyldig; sjekk om du har angitt det riktig.",
+       "magiclink-tracking-rfc": "Sider som bruker magiske RFC-lenker",
+       "magiclink-tracking-rfc-desc": "Denne siden bruker magiske RFC-lenker. Se [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links MediaWiki.org] for hvordan man kan bytte.",
+       "magiclink-tracking-pmid": "Sider som bruker magiske PMID-lenker",
+       "magiclink-tracking-pmid-desc": "Denne siden bruker magiske PMID-lenker. Se [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links MediaWiki.org] for hvordan man kan bytte.",
+       "magiclink-tracking-isbn": "Sider som bruker magiske ISBN-lenker",
+       "magiclink-tracking-isbn-desc": "Denne siden bruker magiske ISBN-lenker. Se [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links MediaWiki.org] for hvordan man kan bytte.",
        "specialloguserlabel": "Utøver:",
        "speciallogtitlelabel": "Mål (tittel eller {{ns:user}}:brukernavn for brukeren):",
        "log": "Logger",
        "activeusers-intro": "Dette er en liste over brukere som har hatt en eller annen form for aktivitet innenfor {{PLURAL:$1|den siste dagen|de siste dagene}}.",
        "activeusers-count": "$1 {{PLURAL:$1|endring|endringer}} {{PLURAL:$3|det siste døgnet|de siste $3 dagene}}",
        "activeusers-from": "Vis brukere fra og med:",
-       "activeusers-hidebots": "Skjul roboter",
-       "activeusers-hidesysops": "Skjul administratorer",
+       "activeusers-groups": "Vis brukere som tilhører gruppene:",
        "activeusers-noresult": "Ingen brukere funnet.",
        "activeusers-submit": "Vis",
        "listgrouprights": "Rettigheter for brukergrupper",
        "modifiedarticleprotection": "endret beskyttelsesnivå for «[[$1]]»",
        "unprotectedarticle": "fjernet beskyttelse av «[[$1]]»",
        "movedarticleprotection": "flyttet beskyttelsesinnstillinger fra «[[$2]]» til «[[$1]]»",
+       "protectedarticle-comment": "{{GENDER:$2|Beskyttet}} «[[$1]]»",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Endret beskyttelsesnivå}} for «[[$1]]»",
+       "unprotectedarticle-comment": "{{GENDER:$2|Fjernet beskyttelsen}} av «[[$1]]»",
        "protect-title": "Låser «$1»",
        "protect-title-notallowed": "Vis beskyttelsesnivået til «$1»",
        "prot_1movedto2": "[[$1]] flyttet til [[$2]]",
        "movelogpagetext": "Her er ei liste over sider som har blitt flyttet.",
        "movesubpage": "{{PLURAL:$1|Underside|Undersider}}",
        "movesubpagetext": "Denne siden har {{PLURAL:$1|én underside|$1 undersider}} som vises nedenfor.",
+       "movesubpagetalktext": "Den tilsvarende diskusjonssiden har $1 {{PLURAL:$1|underside|undersider}} som vises nedenfor.",
        "movenosubpage": "Denne siden har ingen undersider.",
        "movereason": "Årsak:",
        "revertmove": "tilbakestill",
        "tooltip-summary": "Skriv et kort sammendrag",
        "interlanguage-link-title": "$1 – $2",
        "common.css": "/* CSS plassert i denne fila vil gjelde for alle utseender. */",
+       "print.css": "/* CSS som plasseres her vil påvirke utskriftsversjoner */",
+       "noscript.css": "/* CSS plassert her vil påvirke brukere som har slått av JavaScript */",
+       "group-autoconfirmed.css": "/* CSS plassert her vil kun påvirke autobekreftede brukere */",
+       "group-user.css": "/* CSS plassert her vil kun påvirke registrerte brukere */",
+       "group-bot.css": "/* CSS plassert her vil kun påvirke botter */",
+       "group-sysop.css": "/* CSS plassert her vil kun påvirke administratorer */",
+       "group-bureaucrat.css": "/* CSS plassert her vil kun påvirke byråkrater */",
        "common.js": "/* Javascript i denne fila vil gjelde for alle drakter. */",
+       "group-autoconfirmed.js": "/* JavaScript her vil kun lastes for autobekreftede brukere */",
+       "group-user.js": "/* JavaScript her vil kun lastes for registrerte brukere */",
+       "group-bot.js": "/* JavaScript her vil kun lastes for botter */",
+       "group-sysop.js": "/* Javascript her vil kun lastes for administratorer */",
+       "group-bureaucrat.js": "/* JavaScript her vil kun lastes for byråkrater */",
        "anonymous": "{{PLURAL:$1|Anonym bruker|Anonyme brukere}} av {{SITENAME}}",
        "siteuser": "{{SITENAME}}-bruker $1",
        "anonuser": "{{SITENAME}}s anonyme bruker $1",
        "pageinfo-category-pages": "Antall sider",
        "pageinfo-category-subcats": "Antall underkategorier",
        "pageinfo-category-files": "Antall filer",
+       "pageinfo-user-id": "Bruker-ID",
        "markaspatrolleddiff": "Merk som patruljert",
        "markaspatrolledtext": "Merk denne siden som patruljert",
        "markaspatrolledtext-file": "Merk denne filversjonen som patruljert",
        "patrol-log-header": "Dette er en logg over patruljerte sideversjoner.",
        "log-show-hide-patrol": "$1 patruljeringslogg",
        "log-show-hide-tag": "$1 merkelogg",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Merk revisjon $3 av $2 som patruljert?",
        "deletedrevision": "Slettet gammel revisjon $1.",
        "filedeleteerror-short": "Feil under filsletting: $1",
        "filedeleteerror-long": "Feil oppsto under filsletting:\n\n$1",
        "newimages-showbots": "Vis opplastinger av botter",
        "newimages-hidepatrolled": "Skjul patruljerte opplastinger",
        "noimages": "Ingenting å se.",
+       "gallery-slideshow-toggle": "Skift miniatyrbilder",
        "ilsubmit": "Søk",
        "bydate": "etter dato",
        "sp-newimages-showfrom": "Vis nye filer fra og med $2 $1",
-       "hours-abbrev": "$1t",
+       "hours-abbrev": "$1 t",
        "seconds": "{{PLURAL:$1|$1 sekund|$1 sekunder}}",
        "minutes": "{{PLURAL:$1|$1 minutt|$1 minutter}}",
        "hours": "{{PLURAL:$1|$1 time|$1 timer}}",
        "exif-compression-2": "CCITT Gruppe 3 1-dimensjonal modifisert Huffman-kjørelengdekoding",
        "exif-compression-3": "CCITT Gruppe 3 faks-koding",
        "exif-compression-4": "CCITT Gruppe 4 faks-koding",
+       "exif-compression-6": "JPEG (gammel)",
        "exif-copyrighted-true": "Opphavsrettsbeskyttet",
        "exif-copyrighted-false": "Opphavsrettstatus er ikke angitt",
+       "exif-photometricinterpretation-0": "Svart-hvitt (hvitt er 0)",
        "exif-photometricinterpretation-1": "Sort og hvitt (Sort er 0)",
+       "exif-photometricinterpretation-4": "Gjennomsiktighetsmaske",
+       "exif-photometricinterpretation-5": "Atskilt (trolig CMYK)",
+       "exif-photometricinterpretation-9": "CIE L*a*b* (ICC-koding)",
+       "exif-photometricinterpretation-10": "CIE L*a*b* (ITU-koding)",
+       "exif-photometricinterpretation-32803": "Fargefiltertabell",
+       "exif-photometricinterpretation-34892": "Lineær rå",
        "exif-unknowndate": "Ukjent dato",
        "exif-orientation-1": "Normal",
        "exif-orientation-2": "Snudd horisontalt",
        "confirm-unwatch-top": "Fjern denne siden fra overvåkningslisten din?",
        "confirm-rollback-button": "OK",
        "confirm-rollback-top": "Tilbakestill redigeringer på denne siden?",
+       "ellipsis": "…",
+       "percent": "$1&nbsp;%",
        "quotation-marks": "«$1»",
        "imgmultipageprev": "← forrige side",
        "imgmultipagenext": "neste side &rarr;",
        "autoredircomment": "Omdirigerer til [[$1]]",
        "autosumm-new": "Ny side: $1",
        "autosumm-newblank": "Opprettet tom side",
+       "size-bytes": "$1 {{PLURAL:$1|byte}}",
+       "size-pixel": "$1 {{PLURAL:$1|piksel|piksler}}",
        "lag-warn-normal": "Endringer nyere enn $1 {{PLURAL:$1|sekund|sekunder}} vises muligens ikke i denne listen.",
        "lag-warn-high": "På grunn av stor databaseforsinkelse, vil ikke endringer som er nyere enn $1 {{PLURAL:$1|sekund|sekunder}} vises i denne listen.",
        "watchlistedit-normal-title": "Rediger overvåkningsliste",
        "duplicate-defaultsort": "Advarsel: Standardsorteringen «$2» tar over for den tidligere sorteringen «$1».",
        "duplicate-displaytitle": "<strong>Advarsel:</strong> Visningstittel \"$2\" erstatter tidligere visningstittel \"$1\".",
        "restricted-displaytitle": "<strong>Advarsel:</strong> Visningstittelen «$1» ble ignorert siden den ikke tilsvarer sidens faktiske tittel.",
-       "invalid-indicator-name": "<p>Feil:</strong> Sidestatus-indikatornes <code>navn</code>-attributt kan ikke være tomt.",
+       "invalid-indicator-name": "<p>Feil:</strong> Sidestatus-indikatornes <code>name</code>-attributt kan ikke være tomt.",
        "version": "Versjon",
        "version-extensions": "Installerte utvidelser",
        "version-skins": "Installerte drakter",
        "version-entrypoints": "Inngangspunkts-URL-er",
        "version-entrypoints-header-entrypoint": "Inngangspunkt",
        "version-entrypoints-header-url": "URL",
+       "version-entrypoints-articlepath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgArticlePath Artikkelsti]",
+       "version-entrypoints-scriptpath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgScriptPath Skriptsti]",
        "version-libraries": "Installerte biblioteker",
        "version-libraries-library": "Bibliotek",
        "version-libraries-version": "Versjon",
        "htmlform-cloner-create": "Legg til mer",
        "htmlform-cloner-delete": "Fjern",
        "htmlform-cloner-required": "Minst én verdi kreves.",
+       "htmlform-date-placeholder": "ÅÅÅÅ-MM-DD",
+       "htmlform-time-placeholder": "TT:MM:SS",
+       "htmlform-datetime-placeholder": "ÅÅÅÅ-MM-DD TT:MM:SS",
+       "htmlform-date-invalid": "Verdien du anga gjenkjennes ikke som en dato. Prøv formatet ÅÅÅÅ-MM-DD.",
+       "htmlform-time-invalid": "Verdien du anga gjenkjennes ikke som et tidspunkt. Prøv formatet TT:MM:SS.",
+       "htmlform-datetime-invalid": "Verdien du anga gjenkjennes ikke som en dato og et tidspunkt. Prøv formatet ÅÅÅÅ-MM-DD TT:MM:SS.",
+       "htmlform-date-toolow": "Verdien du anga er før den tidligste tillatte datoen $1.",
+       "htmlform-date-toohigh": "Verdien du anga er etter den siste tillatte datoen $1.",
+       "htmlform-time-toolow": "Verdien du anga er før det tidligste tillatte tidspunktet $1.",
+       "htmlform-time-toohigh": "Verdien du anga er etter det siste tillatte tidspunktet $1.",
+       "htmlform-datetime-toolow": "Verdien du anga er før den tidligste tillatte datoen og tidspunktet $1.",
+       "htmlform-datetime-toohigh": "Verdien du anga er etter den siste tillatte datoen og tidspunktet $1.",
        "htmlform-title-badnamespace": "[[:$1]] er ikke i «{{ns:$2}}»-navnerommet",
        "htmlform-title-not-creatable": "«$1» er ikke en opprettbar sidetittel",
        "htmlform-title-not-exists": "$1 forefinnes ikke.",
        "feedback-external-bug-report-button": "Registrer en teknisk sak",
        "feedback-dialog-title": "Send tilbakemelding",
        "feedback-dialog-intro": "Bruk det enkle skjemaet under om du vil gi tilbakemelding. Kommentaren din vil bli lagt ut på siden «$1» sammen med brukernavnet ditt.",
-       "feedback-error-title": "Feil",
        "feedback-error1": "Feil: Ukjent resultat fra API",
        "feedback-error2": "Feil: Redigering feilet",
        "feedback-error3": "Feil: Ingen respons fra API",
        "feedback-thanks": "Din tilbakemelding til siden \"[ $2  $1 ]\" er sendt. Takk skal du ha!",
        "feedback-thanks-title": "Takk!",
        "feedback-useragent": "Brukeragent",
-       "searchsuggest-search": "Søk",
+       "searchsuggest-search": "Søk i {{SITENAME}}",
        "searchsuggest-containing": "inneholder …",
        "api-error-autoblocked": "Din IP-adresse har blitt blokkert automatisk fordi den ble brukt av en blokkert bruker.",
        "api-error-badaccess-groups": "Du har ikke tillatelse til å laste opp filer til denne wikien.",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>slått av</strong>)",
        "mediastatistics": "Mediestatistikk",
        "mediastatistics-summary": "Statistikk over opplastede filtyper. Dette inkluderer bare den nyeste versjonen av hver fil. Eldre eller slettede versjoner av filene er eksludert.",
+       "mediastatistics-nfiles": "$1 ($2&nbsp;%)",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 byte}} ($2; $3 %)",
        "mediastatistics-bytespertype": "Total filstørrelse for denne seksjonen: {{PLURAL:$1|$1 byte}} ($2; $3 %).",
        "mediastatistics-allbytes": "Total filstørrelse for alle filer: {{PLURAL:$1|$1 byte}} ($2).",
        "usercssispublic": "Merk: CSS-undersidene bør ikke inneholde konfidensielle data siden de kan ses av andre brukere.",
        "restrictionsfield-badip": "Ugyldig IP-adresse eller intervall: $1",
        "restrictionsfield-label": "Tillatte IP-intervaller:",
-       "restrictionsfield-help": "Én IP-adresse eller CIDR-intervall per linje. For å slå på alt, bruk <br /><code>0.0.0.0/0</code><br /><code>::/0</code>"
+       "restrictionsfield-help": "Én IP-adresse eller CIDR-intervall per linje. For å slå på alt, bruk <br /><code>0.0.0.0/0</code><br /><code>::/0</code>",
+       "edit-error-short": "Feil: $1",
+       "edit-error-long": "Feil:\n\n$1"
 }
index 7beefc3..14f05dc 100644 (file)
        "yourpasswordagain": "Opniej invoeren",
        "createacct-yourpasswordagain": "Wachtwoord bevestigen",
        "createacct-yourpasswordagain-ph": "Geef t wachtwoord opniej op",
-       "remembermypassword": "Vanzelf anmelden (hooguut $1 {{PLURAL:$1|dag|dagen}})",
        "userlogin-remembermypassword": "Vanzelf anmelden",
        "userlogin-signwithsecure": "Beveiligde verbiending gebruken",
        "yourdomainname": "Joew domein",
        "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": "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": "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.",
        "undo-norev": "De bewarking kon niet weerummedreid wörden, umdat t niet besteet of vortedaon is.",
        "undo-summary": "Versie $1 van [[Special:Contributions/$2|$2]] ([[User talk:$2|overleg]]) weerummedreid",
        "undo-summary-username-hidden": "Versie $1 deur n verbörgen gebruker weerummedreid",
-       "cantcreateaccounttitle": "Anmaken van n gebrukersprofiel is niet meugelik",
        "cantcreateaccount-text": "t Anmaken van gebrukers van dit IP-adres (<b>$1</b>) is eblokkeerd deur [[User:$3|$3]].\n\nDe deur $3 op-egeven reden is ''$2''",
        "viewpagelogs": "Bekiek logboeken veur disse zied",
        "nohistory": "Der bin gien eerdere versies van disse zied.",
        "activeusers-intro": "Dit is n lieste van gebrukers die de aofgeleupen $1 {{PLURAL:$1|dag|dagen}} enigszins aktief ewest hebben.",
        "activeusers-count": "$1 leste {{PLURAL:$1|haandeling|haandelingen}} in de aofeleupen {{PLURAL:$3|dag|$3 dagen}}",
        "activeusers-from": "Laot gebrukers zien vanaof:",
-       "activeusers-hidebots": "Bots verbargen",
-       "activeusers-hidesysops": "Beheerders verbargen",
        "activeusers-noresult": "Gien aktieve gebrukers evunnen.",
        "activeusers-submit": "Bekiek",
        "listgrouprights": "Rechten van gebrukersgroepen",
        "htmlform-no": "Nee",
        "htmlform-yes": "Ja",
        "htmlform-chosen-placeholder": "Kies n opsie",
-       "sqlite-has-fts": "Versie $1 mit ondersteuning veur \"full-text\" zeuken",
-       "sqlite-no-fts": "Versie $1 zonder ondersteuning veur \"full-text\" zeuken",
        "logentry-delete-delete": "$1 hef de zied $3 {{GENDER:$2|vortedaon}}",
        "logentry-delete-restore": "$1 hef de zied $3 {{GENDER:$2|weerummezet}}",
        "logentry-delete-event": "$1 hef de zichtbaorheid van {{PLURAL:$5|n logboekregel|$5 logboekregels}} van $3 {{GENDER:$2|ewiezigd}}: $4",
index 3fc66f5..b99b7eb 100644 (file)
        "userlogin-yourpassword-ph": "Passwoort ingeven",
        "createacct-yourpassword-ph": "Passwoort ingeven",
        "yourpasswordagain": "Passwoort nochmal ingeven",
-       "remembermypassword": "Mit dissen Browser duersam inloggen (för maximal $1 {{PLURAL:$1|Dag|Daag}})",
        "yourdomainname": "Diene Domään:",
        "externaldberror": "Dat geev en Fehler bi de externe Authentifizerungsdatenbank oder du dröffst dien extern Brukerkonto nich ännern.",
        "login": "Anmellen",
        "activeusers-intro": "Dit is en List von Brukers, de {{PLURAL:$1|den verleden Dag|de verleden $1 Daag}} aktiv wesen sünd.",
        "activeusers-count": "$1 {{PLURAL:$1|Ännern|Ännern}} {{PLURAL:$3|den verleden Dag|in de verleden $3 Daag}}",
        "activeusers-from": "Brukers wiesen vanaf:",
-       "activeusers-hidebots": "Bots nich wiesen",
-       "activeusers-hidesysops": "Administraters nich wiesen",
        "activeusers-noresult": "Keen Brukers funnen.",
        "listgrouprights": "Brukergruppen-Rechten",
        "listgrouprights-summary": "Dit is en List vun de Brukergruppen, de in dit Wiki defineert sünd, un de Rechten, de dor mit verbunnen sünd.\nMehr Informatschonen över enkelte Rechten staht ünner [[{{MediaWiki:Listgrouprights-helppage}}]].",
        "htmlform-submit": "Afspiekern",
        "htmlform-reset": "Ännern trüchsetten",
        "htmlform-selectorother-other": "Annere",
-       "sqlite-has-fts": "$1 mit Stöhn för Vulltext-Söök",
-       "sqlite-no-fts": "$1 ahn Stöhn för Vulltext-Söök",
        "logentry-delete-delete": "$1 {{GENDER:$2|wegsmeten}} Siet $3",
        "revdelete-restricted": "Inschränkungen för Administraters instellt",
        "revdelete-unrestricted": "Inschränkungen för Administraters rutnahmen",
index c30c40c..0039ab6 100644 (file)
@@ -21,7 +21,9 @@
                        "Nirjal stha",
                        "राम प्रसाद जोशी",
                        "Matma Rex",
-                       "जनक राज भट्ट"
+                       "जनक राज भट्ट",
+                       "Suniltheblue",
+                       "Irus"
                ]
        },
        "tog-underline": "रेखाङ्कित लिङ्क:",
        "category-file-count-limited": "निम्न  {{PLURAL:$1|फाइल|$1 फाइलहरू}} यस श्रेणीमा रहेको ।",
        "listingcontinuesabbrev": "निरन्तरता...",
        "index-category": "क्रमाङ्कित पृष्ठहरू",
-       "noindex-category": "à¤\95à¥\8dरमाà¤\99à¥\8dà¤\95न नगरिएका पृष्ठहरू",
+       "noindex-category": "à¤\85नà¥\81à¤\95à¥\8dरमण नगरिएका पृष्ठहरू",
        "broken-file-category": "टुटेको फाइल लिङ्कहरूसितको पृष्ठ",
        "about": "बारेमा",
        "article": "सामाग्री पृष्ठ",
        "qbedit": "सम्पादन गर्ने",
        "qbpageoptions": "यो पेज",
        "qbmyoptions": "मेरो पेज",
-       "faq": "धà¥\88रà¥\88 à¤¸à¥\8bधिà¤\8fà¤\95ा à¤ªà¥\8dरशà¥\8dनहरà¥\81",
-       "faqpage": "Project:धà¥\88रà¥\88 à¤¸à¥\8bधिà¤\8fà¤\95ा à¤ªà¥\8dरशà¥\8dनहरà¥\81",
+       "faq": "धà¥\88रà¥\88 à¤¸à¥\8bधिà¤\8fà¤\95ा à¤ªà¥\8dरशà¥\8dनहरà¥\82",
+       "faqpage": "Project:धà¥\88रà¥\88 à¤¸à¥\8bधिà¤\8fà¤\95ा à¤ªà¥\8dरशà¥\8dनहरà¥\82",
        "actions": "कार्यहरु",
        "namespaces": "नेमस्पेस",
        "variants": "बहुरुपहरू",
        "talk": "वार्तालाप",
        "views": "अवलोकनहरू",
        "toolbox": "औजारहरू",
+       "tool-link-userrights": "परिवर्तन {{GENDER:$1|प्रयोगकर्ता}} समूह",
+       "tool-link-emailuser": "{{GENDER:$1|प्रयोगकर्ता}} लाई इमेल गर्ने",
        "userpage": "प्रयोगकर्ता पृष्ठ हेर्ने",
        "projectpage": "आयोजना पृष्ठ हेर्ने",
        "imagepage": "फाइल पृष्ठ हेर्नुहोस्",
        "privacy": "गोपनियता नीति",
        "privacypage": "Project:गोपनीयता नीति",
        "badaccess": "अनुमतिमा त्रुटि",
-       "badaccess-group0": "तपाà¤\88à¤\81ले अनुरोध गरेको कार्य गर्न तपाईंलाई अनुमति दिइएको छैन।",
+       "badaccess-group0": "तपाà¤\88à¤\82ले अनुरोध गरेको कार्य गर्न तपाईंलाई अनुमति दिइएको छैन।",
        "badaccess-groups": "तपाईंले अनुरोध गर्नुभएको कार्य  {{PLURAL:$2|समूह |कुनै एक समूह}}: $1 मा रहेका प्रयोगकर्ताहरूले मात्र गर्नसक्छन ।",
        "versionrequired": "MediaWiki संस्करण $1 चाहिने",
        "versionrequiredtext": "यो पृष्ठ प्रयोग गर्नको लागि MediaWiki $1 संस्करण चाहिन्छ ।\nहेर्नुहोस्  [[Special:Version|version page]]",
        "backlinksubtitle": "← $1",
        "retrievedfrom": " \"$1\" बाट निकालिएको",
        "youhavenewmessages": "तपाईंको लागि ($2) मा  $1 छ ।",
-       "youhavenewmessagesfromusers": "तपाईंको लागि {{PLURAL:$3|प्रयोगकर्ता|$3 प्रयोगकर्ताहरू}} का $1 छन् । ($2)",
-       "youhavenewmessagesmanyusers": "तपाà¤\88à¤\81लाई धेरै प्रयोगकर्ताहरू($2) बाट $1 छ ।",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|तपाईंको लागि}} {{PLURAL:$3|प्रयोगकर्ता|$3 प्रयोगकर्ताहरू}}का $1 छन् । ($2)",
+       "youhavenewmessagesmanyusers": "तपाà¤\88à¤\82लाई धेरै प्रयोगकर्ताहरू($2) बाट $1 छ ।",
        "newmessageslinkplural": "{{PLURAL:$1|एउटा नयाँ सन्देश|999=नयाँ सन्देशहरू}}",
        "newmessagesdifflinkplural": "अन्तिम {{PLURAL:$1|परिवर्तन|999=परिवर्तनहरू}}",
        "youhavenewmessagesmulti": "तपाईंको लागि $1 मा  नयाँ सन्देशहरू छन्",
        "nstab-project": "आयोजना पृष्ठ",
        "nstab-image": "फाइल",
        "nstab-mediawiki": "सन्देश",
-       "nstab-template": "ढाँचा (टेम्प्लेट)",
+       "nstab-template": "ढाँचा",
        "nstab-help": "सहायता पृष्ठ",
        "nstab-category": "श्रेणी",
        "mainpage-nstab": "मुख्य पृष्ठ",
        "nosuchaction": "यस्तो कार्य हैन",
        "nosuchactiontext": "URL ले खुलाएको कार्य मान्य छैन ।\nतपाईंले URL गलत टाइपगर्नु भएको , वा गलत लिंक पछ्याउनु भएको हुनसक्छ ।\nयो{{SITENAME}}ले सफ्टवेयरमा भएको गल्ति देखाएको पनि हुनसक्छ ।",
        "nosuchspecialpage": "त्यस्तो विशेष पृष्ठ छैन",
-       "nospecialpagetext": "<strong>तपाà¤\88à¤\81ले अनुरोध गर्नुभएको विशेष पृष्ठ अमान्य छ ।</strong>\n\nमान्य पृष्ठहरूको सूची यहाँ [[Special:SpecialPages|{{int:specialpages}}]] उपलब्ध छ ।",
+       "nospecialpagetext": "<strong>तपाà¤\88à¤\82ले अनुरोध गर्नुभएको विशेष पृष्ठ अमान्य छ ।</strong>\n\nमान्य पृष्ठहरूको सूची यहाँ [[Special:SpecialPages|{{int:specialpages}}]] उपलब्ध छ ।",
        "error": "त्रुटि",
        "databaseerror": "डेटावेस त्रुटि",
        "databaseerror-text": "डेटाबेस क्वेरीमा खराबी देखा पर्‌यो ।\nयसले सफ्टवेयरमा त्रुटी रहेको इङ्गित गर्न सक्छ ।",
        "namespaceprotected": " '''$1'''  नेमस्पेसमा रहेका पृष्ठहरू सम्पादन गर्ने अनुमति यहाँलाई छैन ।",
        "customcssprotected": "तपाईंलाई यो  पृष्ठ सम्पादन गर्ने अनुमति छैन, किनकी यसमा कुनै अर्को प्रयोगकर्ताको व्यक्तिगत अभिरुचीहरू संग्रहित छन् ।",
        "customjsprotected": "तपाईंलाई यो जाभास्कृप्ट पृष्ठ सम्पादन गर्ने अनुमति छैन, किनकी यसमा कुनै अर्को प्रयोगकर्ताको व्यक्तिगत अभिरुचीहरू संग्रहित छन् ।",
-       "mycustomcssprotected": "यस CSSपà¥\83षà¥\8dठ à¤¸à¤®à¥\8dपादन à¤\97रà¥\8dनà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88à¤\81लाई अनुमति छैन ।",
-       "mycustomjsprotected": "यस JavaScript à¤ªà¥\83षà¥\8dठ à¤¸à¤®à¥\8dपादन à¤\97रà¥\8dनà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88à¤\81लाई अनुमति छैन ।",
-       "myprivateinfoprotected": "तपाà¤\88à¤\81सà¤\81à¤\97 à¤¤à¤ªà¤¾à¤\88à¤\81को निजी जानकारीहरू सम्पादन गर्ने अनुमती छैन",
-       "mypreferencesprotected": "तपाà¤\88à¤\81सà¤\81à¤\97 à¤¤à¤ªà¤¾à¤\88à¤\81को अभिरुचीहरू सम्पादन गर्ने अनुमती छैन",
+       "mycustomcssprotected": "यà¥\8b CSSपà¥\83षà¥\8dठ à¤¸à¤®à¥\8dपादन à¤\97रà¥\8dनà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88à¤\82लाई अनुमति छैन ।",
+       "mycustomjsprotected": "यà¥\8b à¤\9cावासà¥\8dà¤\95à¥\8dरिपà¥\8dà¤\9f à¤ªà¥\83षà¥\8dठ à¤¸à¤®à¥\8dपादन à¤\97रà¥\8dनà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88à¤\82लाई अनुमति छैन ।",
+       "myprivateinfoprotected": "तपाà¤\88à¤\82सà¤\81à¤\97 à¤¤à¤ªà¤¾à¤\88à¤\82को निजी जानकारीहरू सम्पादन गर्ने अनुमती छैन",
+       "mypreferencesprotected": "तपाà¤\88à¤\82सà¤\81à¤\97 à¤¤à¤ªà¤¾à¤\88à¤\82को अभिरुचीहरू सम्पादन गर्ने अनुमती छैन",
        "ns-specialprotected": "विशेष पृष्ठहरू सम्पादन गर्न सकिदैन।",
        "titleprotected": "[[User:$1|$1]]द्वारा यो शीर्षक निर्माणहुनबाट जोगाइएको छ।\nकारण <em>$2</em> हो ।",
-       "filereadonlyerror": "फाà¤\87ल \"$1\" à¤²à¤¾à¤\88 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रà¥\8dन à¤¸à¤\95िà¤\81दà¥\88न à¤\95िन à¤­à¤¨à¥\87 à¤«à¤¾à¤\87ल à¤­à¤£à¥\8dडार  \"$2\" à¤\95à¥\87वल à¤ªà¤¢à¥\8dनà¥\87 à¤¸à¥\8dथिति (read-only mode)मा à¤\9b।\n\nयसलाà¤\88 à¤¸à¥\81रà¤\95à¥\8dषित à¤\97रà¥\8dनà¥\87 à¤ªà¥\8dरवनà¥\8dधà¤\95लà¥\87  à¤¯à¥\8b à¤\95ारण à¤¦à¤¿à¤\8fà¤\95ाà¤\9bनà¥\8d : ''$3''।",
+       "filereadonlyerror": "à¤\85à¤\95à¥\8dषम à¤\97रà¥\8dन à¤ªà¤°à¤¿à¤®à¤¾à¤°à¥\8dà¤\9cन à¤«à¤¾à¤\87ल \"$1\" à¤«à¤¾à¤\87ल à¤­à¤£à¥\8dडार \"$2\" à¤®à¤¾ à¤ªà¤¢à¥\8dन-मातà¥\8dर à¤®à¥\8bड à¥¤ \n\nपà¥\8dरणालà¥\80 à¤ªà¥\8dरशासà¤\95 à¤¬à¤¨à¥\8dद à¤\97रà¥\8dनà¥\87 à¤¯à¥\8b à¤\9aढाà¤\8fà¤\95à¥\8b à¤¯à¥\8b à¤µà¥\8dयाà¤\96à¥\8dया: \"$3\".",
        "invalidtitle-knownnamespace": "नेमस्पेस \"$2\" तथा अक्षर \"$3\" सहितको अवैश शिर्षक",
        "invalidtitle-unknownnamespace": "अज्ञात नेमस्पेस अंक $1 तथा अक्षर \"$2\" भएको अवैध शिर्षक",
        "exception-nologin": "प्रवेश (लग ईन) नगरिएको",
        "virus-scanfailed": "पढाइ असफल(कोड $1)",
        "virus-unknownscanner": "अज्ञात एन्टीभाइरस:",
        "logouttext": "<strong>तपाईं अहिले बाहिर निस्कनु भएको छ।</strong>\n\nयाद राख्नुहोस् तपाईंले ब्राउजरको क्याच खालि नगर्दासम्म कुनै पृष्ठहरूमा तपाईं अझै प्रवेश गरिरखेको देखाउन सक्छ।",
+       "cannotlogoutnow-title": "अब लगआउट गर्न सकिँदैन",
+       "cannotlogoutnow-text": "लग आउट सम्भव छैन प्रयोग गर्दा $1.",
        "welcomeuser": "$1जी स्वागत छ!",
        "welcomecreation-msg": "तपाईंको खाता तयार भयो । \nतपाईंले चाहनु भएको खण्डमा {{SITENAME}} [[Special:Preferences|प्राथमिकताहरू]] परिवर्तन गर्न सक्नु हुनेछ ।",
        "yourname": "प्रयोगकर्ता नाम:",
        "userlogin-yourname": "प्रयोगकर्ता नाम",
-       "userlogin-yourname-ph": "तपाà¤\88à¤\81को प्रयोगकर्तानाम लेख्नुहोस्",
+       "userlogin-yourname-ph": "तपाà¤\88à¤\82को प्रयोगकर्तानाम लेख्नुहोस्",
        "createacct-another-username-ph": "प्रयोगकर्तानाम लेख्नुहोस्",
        "yourpassword": "पासवर्ड",
        "userlogin-yourpassword": "पासवर्ड",
-       "userlogin-yourpassword-ph": "तपाà¤\88à¤\81को पासवर्ड लेख्नुहोस्",
+       "userlogin-yourpassword-ph": "तपाà¤\88à¤\82को पासवर्ड लेख्नुहोस्",
        "createacct-yourpassword-ph": "पासवर्ड लेख्नुहोस्",
        "yourpasswordagain": "पासवर्ड फेरि टाईप गर्नुहोस्",
        "createacct-yourpasswordagain": "पासवर्ड निश्चित गर्नुहोस्",
        "createacct-yourpasswordagain-ph": "फेरि पासवर्ड लेख्नुहोस्",
        "userlogin-remembermypassword": "मलाई प्रवेश गराइराख्ने",
        "userlogin-signwithsecure": "सुक्षित जडान प्रयोग गर्ने",
+       "cannotlogin-title": "मा लग गर्न सक्दैनौं",
+       "cannotcreateaccount-title": "सिर्जना गर्न सकिँदैन खाता",
+       "cannotcreateaccount-text": "प्रत्यक्ष खाता सिर्जना सक्षम छैन on this wiki.",
        "yourdomainname": "तपाईंको ज्ञानक्षेत्र(डोमेन):",
        "password-change-forbidden": "यो विकिमा पासवर्ड परिवर्तन गर्न सक्नुहुन्न।",
        "externaldberror": "यहाँ प्रमाणिकरण डेटाबेस त्रुटि भयो या त तपाईंलाई आफ्नो बाहिरी खाता अद्यतन गर्ने अनुमति छैन।",
        "userlogin-createanother": "अर्को खाता खोल्नुहोस्",
        "createacct-emailrequired": "इमेल ठेगाना",
        "createacct-emailoptional": "इमेल ठेगाना (ऐच्छिक)",
-       "createacct-email-ph": "तपाà¤\88à¤\81को इमेल ठेगाना भर्नुहोस्",
+       "createacct-email-ph": "तपाà¤\88à¤\82को इमेल ठेगाना भर्नुहोस्",
        "createacct-another-email-ph": "इमेल ठेगाना भर्नुहोस्",
        "createaccountmail": "कुनै अस्थाई र श्रिजित पासवर्ड प्रयोग गर्ने र खुलाईएको इमेलमा पठाउने",
        "createacct-realname": "वास्तविक नाम (ऐच्छिक)",
        "createaccountreason": "कारण:",
        "createacct-reason": "कारण",
        "createacct-reason-ph": "किन तपाईं नयाँ खाता खोलिरहनु भएको हो ?",
-       "createacct-submit": "तपाà¤\88à¤\81को खाता सिर्जना गर्नुहोस",
+       "createacct-submit": "तपाà¤\88à¤\82को खाता सिर्जना गर्नुहोस",
        "createacct-another-submit": "खाता खोल्नुहोस्",
-       "createacct-benefit-heading": "{{SITENAME}} à¤¤à¤ªà¤¾à¤\88à¤\81 जस्तै मानिसहरूद्वारा सिर्जना गरिएको हो ।",
+       "createacct-benefit-heading": "{{SITENAME}} à¤¤à¤ªà¤¾à¤\88à¤\82 जस्तै मानिसहरूद्वारा सिर्जना गरिएको हो ।",
        "createacct-benefit-body1": "{{PLURAL:$1|सम्पादन|सम्पादनहरू}}",
        "createacct-benefit-body2": "{{PLURAL:$1|पृष्ठ|पृष्ठहरू}}",
        "createacct-benefit-body3": "हालैका {{PLURAL:$1|योगदानकर्ता|योगदानकर्ताहरू}}",
        "loginerror": "प्रवेश त्रुटि",
        "createacct-error": "खाता बनाउँदा त्रुटि",
        "createaccounterror": "खाता बनाउन सकिएन: $1",
-       "nocookiesnew": "तपाà¤\88à¤\81à¤\95à¥\8b à¤\96ाता à¤¬à¤¨à¤¾à¤\87यà¥\8b, à¤¤à¤° à¤¤à¤ªà¤¾à¤\88à¤\81 à¤ªà¥\8dरवà¥\87श à¤\97रà¥\8dनà¥\81भà¤\8fà¤\95à¥\8b à¤\9bà¥\88न à¥¤\n{{SITENAME}} à¤²à¥\87 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤ªà¥\8dरवà¥\87श à¤\97राà¤\89न à¤\95à¥\81à¤\95à¥\80हरà¥\82 à¤ªà¥\8dरयà¥\8bà¤\97 à¤\97रà¥\8dà¤\9b à¥¤\nतपाà¤\88à¤\81à¤\95ा à¤\95à¥\81à¤\95à¥\80हरà¥\82 à¤¨à¤¿à¤¸à¥\8dà¤\95à¥\8dरिय à¤\9bनà¥\8d।\nà¤\95à¥\83पया à¤¸à¤\95à¥\8dरिय à¤¬à¤¨à¤¾à¤\87 , à¤¨à¤¾à¤® à¤° à¤ªà¥\8dरवà¥\87शशव्द राखी प्रवेश गर्नुहोला ।",
-       "nocookieslogin": "{{SITENAME}} ले प्रयोगकर्ता प्रवेश गराउन कुकीहरू प्रयोग गर्छ । तपाईँको कुकीहरू निस्क्रिय गरिएको छ। कृपया सक्रिय बनाइ , नाम र प्रवेशशव्द राखी प्रवेश गर्नुहोला ।",
+       "nocookiesnew": "तपाà¤\88à¤\82à¤\95à¥\8b à¤\96ाता à¤¬à¤¨à¤¾à¤\87यà¥\8b, à¤¤à¤° à¤¤à¤ªà¤¾à¤\88à¤\82 à¤ªà¥\8dरवà¥\87श à¤\97रà¥\8dनà¥\81भà¤\8fà¤\95à¥\8b à¤\9bà¥\88न à¥¤\n{{SITENAME}} à¤²à¥\87 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤ªà¥\8dरवà¥\87श à¤\97राà¤\89न à¤\95à¥\81à¤\95à¥\80हरà¥\82 à¤ªà¥\8dरयà¥\8bà¤\97 à¤\97रà¥\8dà¤\9b à¥¤\nतपाà¤\88à¤\82à¤\95ा à¤\95à¥\81à¤\95à¥\80हरà¥\82 à¤¨à¤¿à¤¸à¥\8dà¤\95à¥\8dरिय à¤\9bनà¥\8d à¥¤\nà¤\95à¥\83पया à¤¸à¤\95à¥\8dरिय à¤¬à¤¨à¤¾à¤\87 , à¤¨à¤¾à¤® à¤° à¤ªà¥\8dरवà¥\87शशब्द राखी प्रवेश गर्नुहोला ।",
+       "nocookieslogin": "{{SITENAME}} ले प्रयोगकर्ता प्रवेश गराउन कुकीहरू प्रयोग गर्छ। तपाईंको कुकीहरू निष्कृय गरिएको छ। कृपया सक्रिय बनाइ पुन प्रवेश गर्नुहोला।",
        "nocookiesfornew": "प्रयोगकर्ताको खाता निर्माण गरिएन, हामीले यसको मूल स्रोत निर्धारण गर्न सकेनौं।\nनिश्चित गर्नुहोस् तपाईंले कुकी सक्रिय गर्नुभएको छ, पुनः यस पृष्ठलाई खोल्ने प्रयास गर्नुहोस्।",
        "nocookiesforlogin": "{{int:nocookieslogin}}",
        "noname": "तपाईंले सही प्रयोगकर्ता नाम दिनु भएन।",
        "loginsuccesstitle": "प्रवेश सफल",
        "loginsuccess": "'''तपाईंले {{SITENAME}}मा  \"$1\" को रुपमा प्रवेश गर्नुभएकोछ।'''",
        "nosuchuser": "\"$1\" को नामबाट कुनै पनि प्रयोगकर्ता भेटिएनन् ।\nप्रयोगकर्ता नाम वर्णसंवेदनशील हुन्छन् ।\nहिज्जे जाँच्नुहोस् , या [[Special:CreateAccount|नयाँ खाता बनाउनुहोस्]].",
-       "nosuchusershort": " \"$1\" à¤¨à¤¾à¤®à¤\95à¥\8b à¤\95à¥\81नà¥\88 à¤ªà¤¨à¤¿ à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤­à¥\87à¤\9fिà¤\8fन।\n à¤¤à¤ªà¤¾à¤\88à¤\81को हिज्जे जाँच्नुहोस् ।",
+       "nosuchusershort": " \"$1\" à¤¨à¤¾à¤®à¤\95à¥\8b à¤\95à¥\81नà¥\88 à¤ªà¤¨à¤¿ à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤­à¥\87à¤\9fिà¤\8fन।\n à¤¤à¤ªà¤¾à¤\88à¤\82को हिज्जे जाँच्नुहोस् ।",
        "nouserspecified": "तपाँईले प्रयोगकर्ताको नाम जनाउनुपर्छ।",
        "login-userblocked": "यस प्रयोगकर्तालाई रोक लगाइएको छ। प्रवेश गर्ने अनुमति छैन।",
        "wrongpassword": "पासवर्ड गलत हालियो।\nकृपया फेरि प्रयास गर्नुहोला।",
        "wrongpasswordempty": "हालिएको पासवर्ड खालि थियो।\nकृपया फेरी प्रयास गर्नुहोला।",
        "passwordtooshort": "पासवर्ड कम्तिमा {{PLURAL:$1|१ अक्षर|$1 अक्षरहरू}}को हुनुपर्छ।",
        "passwordtoolong": "पासवर्ड {{PLURAL:$1|१ अक्षर|$1 अक्षरहरू}} भन्दा लामो हुनु हुदैन ।",
-       "password-name-match": "तपाà¤\88à¤\81à¤\95à¥\8b à¤ªà¥\8dरवà¥\87शशव्द प्रयोगकर्ता नाम भन्दा फरक हुनुपर्छ ।",
-       "password-login-forbidden": "यà¥\8b à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤¨à¤¾à¤® à¤° à¤ªà¥\8dरवà¥\87श à¤¶à¤µ्द वर्जित गरिएकोछ ।",
+       "password-name-match": "तपाà¤\88à¤\82à¤\95à¥\8b à¤ªà¥\8dरवà¥\87शशब्द प्रयोगकर्ता नाम भन्दा फरक हुनुपर्छ ।",
+       "password-login-forbidden": "यà¥\8b à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤¨à¤¾à¤® à¤° à¤ªà¥\8dरवà¥\87श à¤¶à¤¬्द वर्जित गरिएकोछ ।",
        "mailmypassword": "पासवर्ड पूर्वनिर्धारित गर्नुहोस्",
        "passwordremindertitle": "{{SITENAME}}को लागि नयाँ अस्थायी पासवर्ड",
-       "passwordremindertext": "à¤\95सà¥\88लà¥\87 (सायद à¤¤à¤ªà¤¾à¤\88à¤\81, IP à¤ à¥\87à¤\97ाना $1 à¤¬à¤¾à¤\9f), {{SITENAME}}($4) à¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¨à¤¯à¤¾à¤\81 à¤ªà¥\8dरवà¥\87सशबà¥\8dद à¤\85नà¥\81रà¥\8bध à¤\97रà¥\8dनà¥\81भà¤\8fà¤\95à¥\8b à¤\9b à¥¤ à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता \"$2\" à¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¨à¤¯à¤¾à¤\81 à¤\85सà¥\8dथायà¥\80 à¤ªà¥\8dरवà¥\87सशबà¥\8dद \"$3\"तयार à¤ªà¤¾à¤°à¤¿à¤\8fà¤\95à¥\8b à¤\9b à¥¤ à¤¯à¤¦à¤¿ à¤¯à¥\8b à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤\87à¤\9aà¥\8dà¤\9bामा à¤­à¤\8fà¤\95à¥\8b à¤­à¤\8f à¤\85हिलà¥\87 à¤¤à¤ªà¤¾à¤\88à¤\81लà¥\87 à¤ªà¥\8dरवà¥\87शà¤\97रà¥\80 à¤¨à¤¯à¤¾à¤\81 à¤ªà¥\8dरवà¥\87सशबà¥\8dद à¤\9bानà¥\8dनà¥\81 à¤ªà¤°à¥\8dनà¥\87 à¤¹à¥\81नà¥\8dà¤\9b।\nतपाà¤\88à¤\82à¤\95à¥\8b à¤\85सà¥\8dथायà¥\80 à¤ªà¥\8dरवà¥\87सशबà¥\8dद  {{PLURAL:$5|à¤\8fà¤\95 à¤¦à¤¿à¤¨|$5 à¤¦à¤¿à¤¨à¤¹à¤°à¥\82 à¤ªà¤\9bि}} à¤\85मानà¥\8dय à¤¹à¥\81नà¥\87à¤\9b à¥¤\n\nयदि à¤\95à¥\8bहà¥\80 à¤\85रà¥\81लà¥\87 à¤¨à¥\88 à¤\85नà¥\81रà¥\8bध à¤\97रà¥\87à¤\95à¥\8b à¤¹à¥\8b à¤­à¤¨à¥\87 , à¤¯à¤¾ à¤¤à¤ªà¤¾à¤\88à¤\82लà¥\87 à¤\86फà¥\8dनà¥\8b à¤ªà¥\8dरवà¥\87सशबà¥\8dद à¤¸à¤®à¥\8dà¤\9dिनà¥\81 à¤­à¤¯à¥\8b à¤­à¤¨à¥\87, à¤\85थवा\nतà¥\8dयसलाà¤\88 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रà¥\8dन à¤\9aाहनà¥\81हà¥\81नà¥\8dन à¤­à¤¨à¥\87, à¤¤à¤ªà¤¾à¤\88à¤\81लà¥\87 à¤¯à¥\8b à¤¸à¤¨à¥\8dदà¥\87सà¤\95à¥\8b à¤µà¥\87वासà¥\8dता à¤\97रà¥\8dनसà¤\95à¥\8dनà¥\81हà¥\81नà¥\8dà¤\9b à¤° à¤ªà¥\81रानà¥\88 à¤ªà¥\8dरवà¥\87सशब्द प्रयोग गरिरहन सक्नुहुन्छ ।",
+       "passwordremindertext": "à¤\95सà¥\88लà¥\87 (सायद à¤¤à¤ªà¤¾à¤\88à¤\82, IP à¤ à¥\87à¤\97ाना $1 à¤¬à¤¾à¤\9f), {{SITENAME}}($4) à¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¨à¤¯à¤¾à¤\81 à¤ªà¥\8dरवà¥\87शशबà¥\8dद à¤\85नà¥\81रà¥\8bध à¤\97रà¥\8dनà¥\81भà¤\8fà¤\95à¥\8b à¤\9b à¥¤ à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता \"$2\" à¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¨à¤¯à¤¾à¤\81 à¤\85सà¥\8dथायà¥\80 à¤ªà¥\8dरवà¥\87शशबà¥\8dद \"$3\"तयार à¤ªà¤¾à¤°à¤¿à¤\8fà¤\95à¥\8b à¤\9b à¥¤ à¤¯à¤¦à¤¿ à¤¯à¥\8b à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤\87à¤\9aà¥\8dà¤\9bामा à¤­à¤\8fà¤\95à¥\8b à¤­à¤\8f à¤\85हिलà¥\87 à¤¤à¤ªà¤¾à¤\88à¤\81लà¥\87 à¤ªà¥\8dरवà¥\87शà¤\97रà¥\80 à¤¨à¤¯à¤¾à¤\81 à¤ªà¥\8dरवà¥\87शशबà¥\8dद à¤\9bानà¥\8dनà¥\81 à¤ªà¤°à¥\8dनà¥\87 à¤¹à¥\81नà¥\8dà¤\9b à¥¤\nतपाà¤\88à¤\82à¤\95à¥\8b à¤\85सà¥\8dथायà¥\80 à¤ªà¥\8dरवà¥\87शशबà¥\8dद  {{PLURAL:$5|à¤\8fà¤\95 à¤¦à¤¿à¤¨|$5 à¤¦à¤¿à¤¨à¤¹à¤°à¥\82 à¤ªà¤\9bि}} à¤\85मानà¥\8dय à¤¹à¥\81नà¥\87à¤\9b à¥¤\n\nयदि à¤\95à¥\8bहà¥\80 à¤\85रà¥\81लà¥\87 à¤¨à¥\88 à¤\85नà¥\81रà¥\8bध à¤\97रà¥\87à¤\95à¥\8b à¤¹à¥\8b à¤­à¤¨à¥\87 , à¤¯à¤¾ à¤¤à¤ªà¤¾à¤\88à¤\82लà¥\87 à¤\86फà¥\8dनà¥\8b à¤ªà¥\8dरवà¥\87शशबà¥\8dद à¤¸à¤®à¥\8dà¤\9dिनà¥\81 à¤­à¤¯à¥\8b à¤­à¤¨à¥\87, à¤\85थवा\nतà¥\8dयसलाà¤\88 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रà¥\8dन à¤\9aाहनà¥\81हà¥\81नà¥\8dन à¤­à¤¨à¥\87, à¤¤à¤ªà¤¾à¤\88à¤\82लà¥\87 à¤¯à¥\8b à¤¸à¤¨à¥\8dदà¥\87शà¤\95à¥\8b à¤µà¥\87वासà¥\8dता à¤\97रà¥\8dनसà¤\95à¥\8dनà¥\81हà¥\81नà¥\8dà¤\9b à¤° à¤ªà¥\81रानà¥\88 à¤ªà¥\8dरवà¥\87शशब्द प्रयोग गरिरहन सक्नुहुन्छ ।",
        "noemail": "प्रयोगकर्ता  \"$1\"को लागि कुनै पनि इ-मेल दर्ता गरिएको छैन ।",
        "noemailcreate": "तपाईंले सही ई-मेल ठेगाना दिनुपर्छ",
        "passwordsent": "\"$1\" को लागि दर्ता गरिएको ई-मेल ठेगानामा एक प्रवेशशव्द पठाइएको छ।\nकृपया त्यसलाई प्राप्त गरेपछि प्रवेश गर्नुहोला ।",
        "blocked-mailpassword": "तपाईंको IP ठेगानालाई सम्पादनगर्नबाट रोक लगाइएको छ, र त्यसैले दुरुपयोग रोक्नको लागि प्रवेसशब्द पुनर्लाभ प्रक्रिया प्रयोग गर्न अनुमति छैन ।",
-       "eauthentsent": "दिà¤\87à¤\8fà¤\95à¥\8b à¤\87मà¥\87ल à¤ à¥\87à¤\97ानामा à¤\87मà¥\87ल à¤ªà¤ à¤¾à¤\87à¤\8fà¤\95à¥\8b à¤\9b à¥¤\nतपाà¤\88à¤\81à¤\95à¥\8b à¤\96ातामा à¤\85रà¥\81 à¤\87मà¥\87ल à¤ªà¤ à¤\89नà¥\81 à¤\85à¤\98ि , à¤\87मà¥\87लमा à¤²à¥\87à¤\96िà¤\8fà¤\95à¥\8b à¤®à¤¾à¤°à¥\8dà¤\97दरà¥\8dशन à¤\85नà¥\81सार , à¤¤à¥\8dयà¥\8b à¤\96ाता à¤¤à¤ªà¤¾à¤\88à¤\81कै हो भनेर निश्चित गर्नु पर्नेछ ।",
+       "eauthentsent": "दिà¤\87à¤\8fà¤\95à¥\8b à¤\87मà¥\87ल à¤ à¥\87à¤\97ानामा à¤\87मà¥\87ल à¤ªà¤ à¤¾à¤\87à¤\8fà¤\95à¥\8b à¤\9b à¥¤\nतपाà¤\88à¤\82à¤\95à¥\8b à¤\96ातामा à¤\85रà¥\81 à¤\87मà¥\87ल à¤ªà¤ à¤\89नà¥\81 à¤\85à¤\98ि , à¤\87मà¥\87लमा à¤²à¥\87à¤\96िà¤\8fà¤\95à¥\8b à¤®à¤¾à¤°à¥\8dà¤\97दरà¥\8dशन à¤\85नà¥\81सार , à¤¤à¥\8dयà¥\8b à¤\96ाता à¤¤à¤ªà¤¾à¤\88à¤\82कै हो भनेर निश्चित गर्नु पर्नेछ ।",
        "throttled-mailpassword": "बितेको {{PLURAL:$1|घण्टा|$1 घण्टाहरु}} भित्र एउटा पासवर्ड अनुस्मारक पठाई सकिएको छ।\nदुरुपयोगबाट बचाउकोलागि प्रत्येक {{PLURAL:$1|घण्टा|$1 घण्टाहरु}}मा केवल एउटा पासवर्ड अनुस्मारक पठाइन्छ।",
        "mailerror": " चिठी :$1 पठाउँदा त्रुटी भयो",
        "acct_creation_throttle_hit": "तपाईंको आईपी ठेगानाबाट आएका आगन्तुकद्वारा बितेको चौबिस घण्टामा यस विकिमा {{PLURAL:$1|एउटा खाता बनाइसकिएको छ|$1 खाताहरु बनाइसकिएका छन्}}, यस समयावधिमा यति नैं अधिकतम सीमा हो।\nअतः यस समय यस आईपी ठेगानाको प्रयोग गर्ने आगन्तुकले अरु खाता खोल्न सक्नेछैनन्।",
        "emailauthenticated": "तपाईंको इमेल ठेगाना $2 को $3 मा प्रमाणित गरिएको थियो।",
-       "emailnotauthenticated": "तपाà¤\88à¤\81को इमेल ठेगाना अहिले सम्म प्रमाणित गरिएको छैन ।\nनिम्न सुविधाको लागि कुनै पनि इमेल पठाइने छैन ।",
+       "emailnotauthenticated": "तपाà¤\88à¤\82को इमेल ठेगाना अहिले सम्म प्रमाणित गरिएको छैन ।\nनिम्न सुविधाको लागि कुनै पनि इमेल पठाइने छैन ।",
        "noemailprefs": "निम्न सुविधाहरू राम्ररी काम गर्नको लागि तपाईंको अभिरुचिमा आफ्नो ई-मेल ठेगाना खुलाउनुहोस् ।",
        "emailconfirmlink": "तपाईंको ई-मेल ठेगाना पक्का गर्नुहोस्",
        "invalidemailaddress": "ई-मेल ठेगाना स्वीकार गर्न सकिएन किन भनें यो सही प्रारूपमा छैन, कृपया सही प्रारूपको  ठेगाना दिनुहोस्।",
        "user-mail-no-addy": "इमेल ठेगाना बिना नै इमेल पठाउन खोजिएको थियो।",
        "user-mail-no-body": "खाली वा ज्यादै न्युन सन्देश भएको इमेल पठाउन खोजिएको ।",
        "changepassword": "पासवर्ड परिवर्तन गर्नुहोस्",
-       "resetpass_announce": "पà¥\8dरवà¥\87श à¤ªà¥\82रा à¤\97रà¥\8dन à¤¤à¤ªà¤¾à¤\88à¤\81ले पासवर्ड परिवर्तन गर्नुपर्छ।",
+       "resetpass_announce": "पà¥\8dरवà¥\87श à¤ªà¥\82रा à¤\97रà¥\8dन à¤¤à¤ªà¤¾à¤\88à¤\82ले पासवर्ड परिवर्तन गर्नुपर्छ।",
        "resetpass_text": "<!-- Add text here -->",
        "resetpass_header": "खाताको पासवर्ड परिवर्तन गर्ने",
        "oldpassword": "पुरानो पासवर्ड:",
        "newpassword": "नयाँ पासवर्ड:",
-       "retypenew": "पà¥\8dरवà¥\87श à¤¶à¤µ्द पुन: दिनुहोस् :",
+       "retypenew": "पà¥\8dरवà¥\87श à¤¶à¤¬्द पुन: दिनुहोस् :",
        "resetpass_submit": "पासवर्ड व्यवस्थित गरी र प्रवेशगर्ने",
-       "changepassword-success": "तपाà¤\88à¤\81को पासवर्ड सफलतापूर्वक परिवर्तन भयो!",
+       "changepassword-success": "तपाà¤\88à¤\82को पासवर्ड सफलतापूर्वक परिवर्तन भयो!",
        "changepassword-throttled": "तपाईंले भर्खरै धेरै पल्ट प्रवेश (लग इन)को निम्ति प्रयास गर्नुभएको छ। \nकृपया $1 पर्खेर मात्र प्रयास गर्नुहोस्।",
        "resetpass_forbidden": "पासवर्ड परिवर्तन गर्न मिल्दैन",
-       "resetpass-no-info": "यà¥\8b à¤ªà¥\83षà¥\8dठ à¤¸à¤¿à¤§à¥\88 à¤¹à¥\87रà¥\8dनà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88à¤\81ले प्रवेश गर्नुपर्छ ।",
-       "resetpass-submit-loggedin": "पà¥\8dरवà¥\87शशव्द परिवर्तन गर्ने",
+       "resetpass-no-info": "यà¥\8b à¤ªà¥\83षà¥\8dठ à¤¸à¤¿à¤§à¥\88 à¤¹à¥\87रà¥\8dनà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88à¤\82ले प्रवेश गर्नुपर्छ ।",
+       "resetpass-submit-loggedin": "पà¥\8dरवà¥\87सशब्द परिवर्तन गर्ने",
        "resetpass-submit-cancel": "रद्द गर्ने",
-       "resetpass-wrong-oldpass": "à¤\85सà¥\8dथायà¥\80 à¤\85थवा à¤¹à¤¾à¥\8dलिà¤\8fà¤\95à¥\8b à¤ªà¥\8dरवà¥\87श à¤¶à¤µà¥\8dद à¤\85मानà¥\8dय\nतपाà¤\88à¤\82लà¥\87 à¤\85à¤\98िबाà¤\9f à¤¨à¥\88à¤\82 à¤ªà¥\8dरवà¥\87श à¤¶à¤µà¥\8dद à¤¸à¤«à¤²à¤¤à¤¾ à¤ªà¥\82रà¥\8dवà¤\95 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रिसà¤\95à¥\8dनà¥\81 à¤­à¤\8fà¤\95à¥\8b à¤¹à¥\8b à¤µà¤¾ à¤¨à¤¯à¤¾à¤\81 à¤ªà¥\8dरवà¥\87श à¤¶à¤µ्दको निम्ति निवेदन गर्नुभएकोछ।",
+       "resetpass-wrong-oldpass": "à¤\85सà¥\8dथायà¥\80 à¤\85थवा à¤¹à¤¾à¤²à¤¿à¤\8fà¤\95à¥\8b à¤ªà¥\8dरवà¥\87श à¤¶à¤¬à¥\8dद à¤\85मानà¥\8dय\nतपाà¤\88à¤\82लà¥\87 à¤\85à¤\98िबाà¤\9f à¤¨à¥\88à¤\82 à¤ªà¥\8dरवà¥\87श à¤¶à¤¬à¥\8dद à¤¸à¤«à¤²à¤¤à¤¾ à¤ªà¥\82रà¥\8dवà¤\95 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रिसà¤\95à¥\8dनà¥\81 à¤­à¤\8fà¤\95à¥\8b à¤¹à¥\8b à¤µà¤¾ à¤¨à¤¯à¤¾à¤\81 à¤ªà¥\8dरवà¥\87श à¤¶à¤¬्दको निम्ति निवेदन गर्नुभएकोछ।",
        "resetpass-recycled": "कृपया वर्तमान पासर्वड भन्दा फरक पासर्वडलाई पुनः मिलाउनुहोस् ।",
        "resetpass-temp-emailed": "तपाईं अस्थाई इमेल कोडले प्रवेश गर्नुभएको छ।\nप्रवेश सफल पार्नका लागि, तपाईंले यहाँ एउटा नयाँ पासवर्ड राख्नु पर्नेछ:",
        "resetpass-temp-password": "अस्थाइ पासवर्ड",
        "passwordreset": "प्रवेशशव्द पुनः तय गर्ने",
        "passwordreset-text-one": "इमेल मार्फल अस्थायी पासवर्ड प्राप्त गर्नको लागी यस फारमलाई पूर्ण रूपमा भर्नुहोस् ।",
        "passwordreset-text-many": "{{PLURAL:$1|कृपया यहाँ मध्ये एउटा क्षेत्र भरि अस्थाई पासवर्ड इमेल मार्फत प्राप्त गर्नुहोस।}}",
-       "passwordreset-disabled": "पà¥\8dरवà¥\87श à¤¶à¤µà¥\8dद à¤ªà¥\81नà¤\83 à¤¨à¤¿à¤°à¥\8dधारण à¤\97रà¥\8dनà¥\87 à¤µà¥\8dयवसà¥\8dथा à¤¯à¤¸ à¤µà¤¿à¤\95िमा à¤¨à¤¿à¤¸à¥\8dà¤\95à¥\8dरिय à¤ªà¤¾à¤°à¤¿à¤\8fà¤\95à¥\8b à¤\9b।",
+       "passwordreset-disabled": "पà¥\8dरवà¥\87श à¤¶à¤¬à¥\8dद à¤ªà¥\81नà¤\83 à¤¨à¤¿à¤°à¥\8dधारण à¤\97रà¥\8dनà¥\87 à¤µà¥\8dयवसà¥\8dथा à¤¯à¤¸ à¤µà¤¿à¤\95िमा à¤¨à¤¿à¤¸à¥\8dà¤\95à¥\8dरिय à¤ªà¤¾à¤°à¤¿à¤\8fà¤\95à¥\8b à¤\9b ।",
        "passwordreset-emaildisabled": "इमेल सुविधा यस विकिमा निस्क्रिय बनाइएको छ ।",
        "passwordreset-username": "प्रयोगकर्ता नाम:",
        "passwordreset-domain": "डोमेन",
        "passwordreset-capture-help": "यदि तपाईंले यो कोठामा दाग दिनुभयो भनें यो इमेल (अस्थायी पासवर्ड सहित) तपाईंलाई देखा पर्नेछ साथै प्रयोगकर्तालाई पनि पठाइनेछ।",
        "passwordreset-email": "इमेल ठेगाना:",
        "passwordreset-emailtitle": "{{SITENAME}}मा खाता विवरण",
-       "passwordreset-emailtext-ip": "कसैले (सायद तपाईंले, $1 आईपि ठेगानाबाट) {{SITENAME}} ($4)मा तपाईंको खाता विवरणको निम्ति एउटा अनुस्मारकको अनुरोध गरेको छ। निम्न प्रयोगकर्ता {{PLURAL:$3|खाता यस इमेल ठेगानासित सम्बन्धित छ|खाताहरू यस इमेल ठेगानासित सम्बन्धित छन्}}:\n\n$2\n\n{{PLURAL:$3|यो अस्थाई पासवर्डको|यी अस्थाई पासवर्डहरुको}} समय {{PLURAL:$5|एक दिन|$5 दिन}}मा सकिनेछ।\nतपाईंले प्रवेश गरेर अहिले नैं नयाँ पासवर्ड छान्नुहोस्। यदि अरु कसैले अनुरोध गरेको भए अथवा यदि तपाईंलाई मूल पासवर्ड याद भए अनि यसलाई परिवर्तन गर्न चाहनुहुन्न भने, तपाईंले यस सन्देशलाई अनदेखा गर्नुहोस् र पुरानै पासवर्डलाई चालू राख्नुहोस्।",
-       "passwordreset-emailtext-user": "{{SITENAME}} को $1 प्रयोगकर्ताले  {{SITENAME}} ($4)को लागि खाता विवरणको निम्ति एउटा अनुस्मारकको अनुरोध गरेको छ। निम्न प्रयोगकर्ता {{PLURAL:$3|खाता यस इमेल ठेगानासित सम्बन्धित छ|खाताहरू यस इमेल ठेगानासित सम्बन्धित छन्}}:\n\n$2\n\n{{PLURAL:$3|यो अस्थाई पासवर्डको|यी अस्थाई पासवर्डहरूको}} समय {{PLURAL:$5|एक दिन|$5 दिन}}मा सकिनेछ।\nतपाईंले प्रवेश गरेर अहिले नैं नयाँ पासवर्ड छान्नुहोस्। यदि अरु कसैले अनुरोध गरेको भए अथवा यदि तपाईंलाई मूल पासवर्ड याद भए अनि यसलाई परिवर्तन गर्न चाहनुहुन्न भनें, तपाईंले यस सन्देशलाई अनदेखा गर्नुहोस् र पुरानै पासवर्डलाई चालू राख्नुहोस्।",
+       "passwordreset-emailtext-ip": "कसैले (सायद तपाईंले, $1 आईपि ठेगानाबाट) {{SITENAME}} ($4)मा तपाईंको खाता विवरणको निम्ति एउटा अनुस्मारकको अनुरोध गरेको छ। निम्न प्रयोगकर्ता {{PLURAL:$3|खाता यस इमेल ठेगानासित सम्बन्धित छ|खाताहरू यस इमेल ठेगानासित सम्बन्धित छन्}}:\n\n$2\n\n{{PLURAL:$3|यो अस्थाई पासवर्डको|यी अस्थाई पासवर्डहरुको}} समय {{PLURAL:$5|एक दिन|$5 दिन}}मा सकिनेछ।\nतपाईंले प्रवेश गरेर अहिले नैं नयाँ पासवर्ड छान्नुहोस्। यदि अरु कसैले अनुरोध गरेको भए अथवा यदि तपाईंलाई मूल पासवर्ड याद भए अनि यसलाई परिवर्तन गर्न चाहनुहुन्न भने, तपाईंले यस सन्देशलाई अनदेखा गर्नुहोस् र पुरानै पासवर्डलाई चालू राख्नुहोस्।",
+       "passwordreset-emailtext-user": "{{SITENAME}} को $1 प्रयोगकर्ताले  {{SITENAME}} ($4)को लागि खाता विवरणको निम्ति एउटा अनुस्मारकको अनुरोध गरेको छ । निम्न प्रयोगकर्ता {{PLURAL:$3|खाता यस इमेल ठेगानासित सम्बन्धित छ|खाताहरू यस इमेल ठेगानासित सम्बन्धित छन् ।}}:\n\n$2\n\n{{PLURAL:$3|यो अस्थाई पासवर्डको|यी अस्थाई पासवर्डहरूको}} समय {{PLURAL:$5|एक दिन|$5 दिन}}मा सकिनेछ ।\nतपाईंले प्रवेश गरेर अहिले नैं नयाँ पासवर्ड छान्नुहोस्। यदि अरु कसैले अनुरोध गरेको भए अथवा यदि तपाईंलाई मूल पासवर्ड याद भए अनि यसलाई परिवर्तन गर्न चाहनुहुन्न भने, तपाईंले यस सन्देशलाई अनदेखा गर्नुहोस् र पुरानै पासवर्डलाई चालू राख्नुहोस् ।",
        "passwordreset-emailelement": "प्रयोगकर्ताको नाम: \n$1\n\nअस्थाई पासवर्ड: \n$2",
        "passwordreset-emailsentemail": "पासवर्ड परिवर्तनको लागि इमेल पठाइएको छ।",
        "changeemail": "इमेल ठेगाना परिवर्तन गर्नुहोस",
        "minoredit": "यो सानो सम्पादन हो",
        "watchthis": "यो पृष्ठ अवलोकन गर्नुहोस्",
        "savearticle": "सङ्ग्रह गर्ने",
+       "savechanges": "परिवर्तन सङ्ग्रह गर्नुहोस्",
        "preview": "पूर्वावलोकन",
        "showpreview": "पूर्वालोकन देखाउनुहोस्",
        "showdiff": "परिवर्तन देखाउनुहोस्",
        "missingsummary": "'''यादगर्नुहोस् :''' तपाईंले सम्पादन सारांश दिनुभएको छैन ।\nयदि तपाईंले \"{{int:savearticle}}\"  थिच्नुभयो भने , सारांश बिना नै संग्रहित गरिने छ ।",
        "selfredirect": "<strong>चेतावनी:</strong> तपाईं यस पृष्ठलाई आफुमा पुनः निर्देशित गर्दै हुनुहुन्छ।\nहुनसक्छ तपाईं अनुप्रेषितको लागि गलत लक्ष्य निर्दिष्ट गर्दै हुनुहुन्छ, वा गलत पृष्ठको सम्पादन गर्दै हुनुहुन्छ।\nतपाईं पुनः एकपटक \"{{int:savearticle}}\" क्लिक गर्नुहुन्छ, पुनः निर्देशित त्यसै पनि बनाइनेछ।",
        "missingcommenttext": "कृपया टिप्पणी प्रविष्ठ गर्नुहोस् ।",
-       "missingcommentheader": "'''याद गर्नुहोस् :''' तपाईँले टिप्पणीमा विषय /शीर्ष पंक्ति  दिनुभएको छैन ।\nतपाईँले फेरि \"{{int:savearticle}}\"  थिच्नु भएमा , तपाईंको सम्पादन यसै रुपमा संग्रहित हुनेछ ।",
+       "missingcommentheader": "<strong>याद गर्नुहोस् :</strong> तपाईंले टिप्पणीमा विषय /शीर्ष पंक्ति  दिनुभएको छैन ।\nतपाईंले फेरि \"{{int:savearticle}}\"  थिच्नु भएमा , तपाईंको सम्पादन यसै रुपमा सङ्ग्रहित हुनेछ ।",
        "summary-preview": "सारांश पूर्वालोकन:",
        "subject-preview": "विषय/शीर्षपंक्ति पूर्वरुप:",
        "previewerrortext": "तपाईंको परिवर्तनको पूर्वावलोकन बनाउन खोज्दा समस्या आएको छ ।",
        "blockedtitle": "प्रयोककर्तालाई रोक लगाइएको छ",
-       "blockedtext": "'''तपाà¤\88à¤\81à¤\95à¥\8b à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤¨à¤¾à¤® à¤¯à¤¾ IP ठेगानालाई रोक लगाइएको छ ।'''\n\nरोक लगाउने  $1.\nरोक लगाउनाको कारण ''$2''.\n\n* रोक सुरू हुने : $8\n* रोक सकिने: $6\n* रोकबाट लक्षित: $7\n\nतपाईंले  $1 वा अरु कुनै  [[{{MediaWiki:Grouppage-sysop}}|प्रवन्धक]] सँग रोकको बारेमा छलफल गर्न सम्पर्क गर्न सक्नुहुन्छ ।\nतपाईँले  'प्रयोगकर्तालाई इ-मेल गर्ने ' सुविधा मान्य इमेल ठेगाना [[Special:Preferences|अभिरुचीहरू]]मा नखुलाए सम्म प्रयोगगर्न पाउनुहुने छैन र यसको प्रयोग गर्नबाट रोक लगाइएको छैन ।\nतपाईंको IP ठेगाना $3 को, र रोक्का संख्या #$5.\nकृपया तपाईँको प्रश्नमा सबै जानकारी खुलाउनुहोला ।",
+       "blockedtext": "'''तपाà¤\88à¤\82à¤\95à¥\8b à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤¨à¤¾à¤® à¤¯à¤¾ à¤\86à¤\87 à¤ªà¥\80 ठेगानालाई रोक लगाइएको छ ।'''\n\nरोक लगाउने  $1.\nरोक लगाउनाको कारण ''$2''.\n\n* रोक सुरू हुने : $8\n* रोक सकिने: $6\n* रोकबाट लक्षित: $7\n\nतपाईंले  $1 वा अरु कुनै  [[{{MediaWiki:Grouppage-sysop}}|प्रवन्धक]] सँग रोकको बारेमा छलफल गर्न सम्पर्क गर्न सक्नुहुन्छ ।\nतपाईँले  'प्रयोगकर्तालाई इ-मेल गर्ने ' सुविधा मान्य इमेल ठेगाना [[Special:Preferences|अभिरुचीहरू]]मा नखुलाए सम्म प्रयोगगर्न पाउनुहुने छैन र यसको प्रयोग गर्नबाट रोक लगाइएको छैन ।\nतपाईंको IP ठेगाना $3 को, र रोक्का संख्या #$5.\nकृपया तपाईँको प्रश्नमा सबै जानकारी खुलाउनुहोला ।",
        "autoblockedtext": "तपाईंको IP ठेगानामाथि रोक लगाइएकोछ किन भनें यो अर्को प्रयोगकर्ताले प्रयोग गरेको थियो, जसलाई $1ले रोक लगाएका थिए। \nरोक लगाउनुको कारण:\n:''$2''  \n\n* रोकावट सुरु: $8\n* रोकावट सकिने: $6\n* रोकावटको प्रयोजन: $7\n\nतपाईं $1 सित सम्पर्क गर्न सक्नुहुन्छ अथवा कुनै [[{{MediaWiki:Grouppage-sysop}}|प्रबन्धक]]सँग रोकबारे चर्चा गर्न सक्नुहुन्छ ।\n\nध्यान दिनुहोस् कि तपाईंले यस प्रयोगकर्ताका लागि ई-मेलको प्रयोग तबसम्म गर्नसक्नुहुन्न जबसम्म तपाईंको [[Special:Preferences|अभिरुचि]] पंजिकृत गर्नु हुन्न वा यस ई-मेलको प्रयोगमाथि रोक लगाइएको हुँदैन । \n\nतपाईंको वर्तमान IP ठेगाना हो- $3, अनि रोक लगाइएको ID हो- #$5.\nकृपया कुनै बेला सोधनी गर्नु परे उपर्युक्त विवरण दर्शाउनु होला ।",
        "blockednoreason": "कारण दिइएको छैन",
        "whitelistedittext": "पाना सम्पादन गर्न तपाँईले $1 गर्नु पर्दछ।",
        "accmailtitle": "पासवर्ड पठाइयो",
        "accmailtext": "जथाभावीरूपमा सृजना गरिएको प्रवेशशब्द प्रयोगकर्ता [[User talk:$1|$1]] को  $2 मा पठाइएको छ।\n\nयो नयाँ खाताको प्रवेशशब्द  ''[[Special:ChangePassword|change password]]'' मा प्रवेश गरेर परिवर्तन गर्न सकिन्छ ।",
        "newarticle": "(नयाँ)",
-       "newarticletext": "तपाà¤\88à¤\81लà¥\87 à¤\85हिलà¥\87 à¤¸à¤®à¥\8dम à¤¨à¤­à¤\8fà¤\95à¥\8b à¤ªà¥\83षà¥\8dठà¤\95à¥\8b à¤²à¤¿à¤\82à¤\99à¥\8dà¤\95 à¤ªà¤¹à¤¿à¤²à¥\8dयाà¤\89नà¥\81 à¤­à¤\8fà¤\95à¥\8b à¤\9b।\nयà¥\8b à¤ªà¥\83षà¥\8dठ à¤¨à¤¿à¤°à¥\8dमाण à¤\97रà¥\8dन à¤¤à¤²à¤\95à¥\8b à¤\95à¥\8bषà¥\8dठमा à¤\9fाà¤\87प à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d  à¥¤(थप à¤\9cानà¤\95ारà¥\80à¤\95à¥\8b à¤²à¤¾à¤\97ि [$1 help page] à¤¹à¥\87रà¥\8dनà¥\81हà¥\8bसà¥\8d )।\nयहाà¤\81 à¤¤à¥\8dयतà¥\8dतिà¤\95à¥\88 à¤\86à¤\87पà¥\81à¤\97à¥\8dनà¥\81 à¤­à¤\8fà¤\95à¥\8b à¤¹à¥\8b à¤­à¤¨à¥\87 , à¤¬à¥\8dराà¤\89à¤\9cरà¤\95à¥\8b  '''back''' à¤¬à¤\9fन à¤¥à¤¿à¤\9aà¥\8dनà¥\81हà¥\8bस ।",
+       "newarticletext": "तपाà¤\88à¤\82लà¥\87 à¤\85हिलà¥\87 à¤¸à¤®à¥\8dम à¤¨à¤­à¤\8fà¤\95à¥\8b à¤ªà¥\83षà¥\8dठà¤\95à¥\8b à¤²à¤¿à¤\99à¥\8dà¤\95 à¤ªà¤¹à¤¿à¤²à¥\8dयाà¤\89नà¥\81 à¤­à¤\8fà¤\95à¥\8b à¤\9b।\nयà¥\8b à¤ªà¥\83षà¥\8dठ à¤¨à¤¿à¤°à¥\8dमाण à¤\97रà¥\8dन à¤¤à¤²à¤\95à¥\8b à¤\95à¥\8bषà¥\8dठमा à¤\9fाà¤\87प à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d  à¥¤(थप à¤\9cानà¤\95ारà¥\80à¤\95à¥\8b à¤²à¤¾à¤\97ि [$1 help page] à¤¹à¥\87रà¥\8dनà¥\81हà¥\8bसà¥\8d )।\nयहाà¤\81 à¤¤à¥\8dयतà¥\8dतिà¤\95à¥\88 à¤\86à¤\87पà¥\81à¤\97à¥\8dनà¥\81 à¤­à¤\8fà¤\95à¥\8b à¤¹à¥\8b à¤­à¤¨à¥\87 , à¤¬à¥\8dराà¤\89à¤\9cरà¤\95à¥\8b  '''back''' à¤¬à¤\9fन à¤¥à¤¿à¤\9aà¥\8dनà¥\81हà¥\8bसà¥\8d ।",
        "anontalkpagetext": "----''यो वार्तालाप पृष्ठ अज्ञात प्रयोगकर्ताको हो जसले अहिलेसम्म खाता बनाएकै छैन, अथवा जसले यस पृष्ठको उपयोग गर्दैन।\nयस कारण हामीले उसलाई उसको आइ पी (IP) ठेगानाले चिन्न सक्छौं। \nयस्तो आइ पी (IP) ठेगाना धेरै प्रयोगकर्ताहरूको साझा हुनसक्छ।\nयदि तपाईं अज्ञात प्रयोगकर्ता हुनुहुन्छ र तपाईंमाथि अचाहिँदो टिप्पणी भएको अनुभव गर्नुहुन्छ भने भविष्यमा अन्य अज्ञात प्रयोगकर्तासितको भ्रमबाट बाँच्न कृपया [[Special:CreateAccount|खाता खोल्नुहोस्]] अथवा [[Special:UserLogin|प्रवेश गर्नुहोस्]] ''",
        "noarticletext": "यस लेखमा अहिले केहि पनि पाठ छैन ।\nतपाईंले अन्य पृष्ठमा [[Special:Search/{{PAGENAME}}|यस पृष्ठको शीर्षकको लागि खोज]] गर्न सक्नुहुन्छ ।\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} पृष्ठ सम्बन्धित ढड्डामा खोज],\nवा [{{fullurl:{{FULLPAGENAME}}|action=edit}}  यसै पृष्ठलाई सम्पादन गर्ने]</span>.",
        "noarticletext-nopermission": "यस लेखमा अहिले कुनै पनि पाठ छैन ।\nतपाईंले अन्य पृष्ठमा [[Special:Search/{{PAGENAME}}|यस पृष्ठको शीर्षकको लागि खोज]] गर्न सक्नुहुन्छ,\nअथवा <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|पृष्ठ={{FULLPAGENAMEE}}}} सम्बन्धित लगहरू खोज्न सक्नुहुनेछ ]</span> तर तपाईंलाई नयाँ पृष्ठ बनाउने अधिकार छैन।",
        "missing-revision": "\"{{FULLPAGENAME}}\" पृष्ठको अवतरण #$1 रहेको छैन।\n\nसामान्य रूपमा यसो एउटा हटाइएको पृष्ठको पुरानो लिङ्कमा क्लिक गर्दा हुन्छ।\nअधिक जानकारीको लागि तपाईं [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} हटाएको लग] हेर्न सक्नुहुन्छ।",
-       "userpage-userdoesnotexist": "पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताà¤\95à¥\8b à¤\96ाता  \"<nowiki>$1</nowiki>\" à¤¦à¤°à¥\8dता à¤\97रिà¤\8fà¤\95à¥\8b à¤\9bà¥\88न à¥¤\nतपाà¤\88à¤\81ले पृष्ठ निर्माण/सम्पादन गर्न चाहनु भएको भए जाँच गर्नुहोस् ।",
+       "userpage-userdoesnotexist": "पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताà¤\95à¥\8b à¤\96ाता  \"<nowiki>$1</nowiki>\" à¤¦à¤°à¥\8dता à¤\97रिà¤\8fà¤\95à¥\8b à¤\9bà¥\88न à¥¤\nतपाà¤\88à¤\82ले पृष्ठ निर्माण/सम्पादन गर्न चाहनु भएको भए जाँच गर्नुहोस् ।",
        "userpage-userdoesnotexist-view": "प्रयोगकर्ता खाता \"$1\" दर्ता गरिएको छैन।",
        "blocked-notice-logextract": "यो प्रयोगकर्ता हाल प्रतिबन्धित छ।\nभर्खरैको प्रतिबन्ध लग प्रविष्टि सन्दर्भको निम्ति तल दिइन्छ:",
-       "clearyourcache": "<strong>à¤\9fिपà¥\8dपणà¥\80</strong> à¤¸à¤\99à¥\8dà¤\97à¥\8dरह à¤\97रà¥\87पà¤\9bि, à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤¹à¥\87रà¥\8dनà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88à¤\81लà¥\87 à¤\86फà¥\8dनà¥\8b à¤¬à¥\8dराà¤\89à¤\9cरà¤\95à¥\8b à¤\95à¥\8dयाà¤\9a à¤¬à¤¾à¤\88पास à¤\97रà¥\8dनà¥\81 à¤ªà¤°à¥\8dनà¥\87 à¤¹à¥\81नसà¤\95à¥\8dà¤\9b।\n*<strong>फायरफà¤\95à¥\8dस / à¤¸à¤«à¤¾à¤°à¥\80मा:</strong> <em>Shift</em> à¤\95à¥\81à¤\9eà¥\8dà¤\9cà¥\80 à¤¥à¤¿à¤\9aà¥\80 à¤°à¤¾à¤\96à¥\87र <em>Reload</em> à¤\95à¥\8dलिà¤\95 à¤\97रà¥\8dनà¥\81परà¥\8dà¤\9b, à¤µà¤¾ <em>Ctrl-F5</em> à¤µà¤¾ <em>Ctrl-R</em> à¤¦à¤¬à¤¾à¤\89नà¥\81हà¥\8bस (मà¥\8dयाà¤\95मा <em>â\8c\98-R</em>)\n*<strong>à¤\97à¥\81à¤\97ल à¤\95à¥\8dरà¥\8bम:</strong> <em>Ctrl-Shift-R</em> à¤\95à¥\81à¤\9eà¥\8dà¤\9cà¥\80 à¤¦à¤¬à¤¾à¤\89नà¥\81हà¥\8bस (मà¥\8dयाà¤\95मा <em>â\8c\98-R</em>)\n*<strong>à¤\93पà¥\87रा:</strong> <em>Tools â\86\92 Preferences</em> à¤®à¤¾ à¤\97à¤\8fर à¤\95à¥\8dयाश à¤¹à¤\9fाà¤\89नà¥\81हà¥\8bस\n*<strong>à¤\87नà¥\8dà¤\9fरनà¥\87à¤\9f à¤\8fà¤\95à¥\8dसपà¥\8dलà¥\8bरर</strong>: <em>Ctrl</em> à¤²à¤¾à¤\88 à¤¥à¤¿à¤\9aà¥\80 à¤°à¤¾à¤\96à¥\87र <em>Refresh</em> à¤\95à¥\8dलिà¤\95 à¤\97रà¥\8dनà¥\81हà¥\8bस à¤µà¤¾ <em>Ctrl-F5</em> à¤¥à¤¿à¤\9aà¥\8dनà¥\81हà¥\8bस",
+       "clearyourcache": "<strong>à¤\9fिपà¥\8dपणà¥\80</strong> à¤¸à¤\99à¥\8dà¤\97à¥\8dरह à¤\97रà¥\87पà¤\9bि, à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤¹à¥\87रà¥\8dनà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88à¤\82लà¥\87 à¤\86फà¥\8dनà¥\8b à¤¬à¥\8dराà¤\89à¤\9cरà¤\95à¥\8b à¤\95à¥\8dयाà¤\9a à¤¬à¤¾à¤\88पास à¤\97रà¥\8dनà¥\81 à¤ªà¤°à¥\8dनà¥\87 à¤¹à¥\81नसà¤\95à¥\8dà¤\9b।\n*<strong>फायरफà¤\95à¥\8dस / à¤¸à¤«à¤¾à¤°à¥\80मा:</strong> <em>Shift</em> à¤\95à¥\81à¤\9eà¥\8dà¤\9cà¥\80 à¤¥à¤¿à¤\9aà¥\80 à¤°à¤¾à¤\96à¥\87र <em>Reload</em> à¤\95à¥\8dलिà¤\95 à¤\97रà¥\8dनà¥\81परà¥\8dà¤\9b, à¤µà¤¾ <em>Ctrl-F5</em> à¤µà¤¾ <em>Ctrl-R</em> à¤¦à¤¬à¤¾à¤\89नà¥\81हà¥\8bसà¥\8d (मà¥\8dयाà¤\95मा <em>â\8c\98-R</em>)\n*<strong>à¤\97à¥\81à¤\97ल à¤\95à¥\8dरà¥\8bम:</strong> <em>Ctrl-Shift-R</em> à¤\95à¥\81à¤\9eà¥\8dà¤\9cà¥\80 à¤¦à¤¬à¤¾à¤\89नà¥\81हà¥\8bसà¥\8d (मà¥\8dयाà¤\95मा <em>â\8c\98-R</em>)\n*<strong>à¤\93पà¥\87रा:</strong> <em>Tools â\86\92 Preferences</em> à¤®à¤¾ à¤\97à¤\8fर à¤\95à¥\8dयाश à¤¹à¤\9fाà¤\89नà¥\81हà¥\8bसà¥\8d\n*<strong>à¤\87नà¥\8dà¤\9fरनà¥\87à¤\9f à¤\8fà¤\95à¥\8dसपà¥\8dलà¥\8bरर</strong>: <em>Ctrl</em> à¤²à¤¾à¤\88 à¤¥à¤¿à¤\9aà¥\80 à¤°à¤¾à¤\96à¥\87र <em>Refresh</em> à¤\95à¥\8dलिà¤\95 à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d à¤µà¤¾ <em>Ctrl-F5</em> à¤¥à¤¿à¤\9aà¥\8dनà¥\81हà¥\8bसà¥\8d",
        "usercssyoucanpreview": "<strong>सुझाव:</strong> तपाईंको नयाँ सिययस सङ्ग्रह गर्न अघि  \"{{int:showpreview}}\" बटन थिचेर जाँच्नुहोस्।",
        "userjsyoucanpreview": "<strong>सुझाव:</strong> तपाईंको नयाँ जाभा स्क्रिप्ट सङ्ग्रह गर्न अघि  \"{{int:showpreview}}\" बटन थिचेर जाँच्नुहोस्।",
-       "usercsspreview": "<strong>याद राख्नुहोस तपाईँले आफ्नो प्रयोगकर्ता सियसयसको पूर्वावलोकन मात्र हेरिरहनु भएको छ।\nयसलाई अहिले सम्म सङ्ग्रह गरिएको छैन!</strong>",
-       "userjspreview": "<strong>याद à¤°à¤¾à¤\96à¥\8dनà¥\81हà¥\8bस à¤¤à¤ªà¤¾à¤\88à¤\81ले आफ्नो प्रयोगकर्ता जाभास्क्रिप्टको पूर्वावलोकन मात्र हेरिरहनु भएको छ।\nयसलाइ अहिले सम्म सङ्ग्रह गरिएको छैन!</strong>",
-       "sitecsspreview": "<strong>याद à¤°à¤¾à¤\96à¥\8dनà¥\81हà¥\8bसà¥\8d à¤¤à¤ªà¤¾à¤\88à¤\81लà¥\87 à¤\95à¥\87वल à¤µà¤¿à¤¶à¥\8dववà¥\8dयापà¥\80 à¤¸à¤¿à¤¯à¤¸à¤¯à¤¸à¤\95à¥\8b à¤ªà¥\82रà¥\8dवावलà¥\8bà¤\95न à¤®à¤¾à¤¤à¥\8dर à¤\85वलà¥\8bà¤\95न à¤\97रà¥\8dनà¥\81भà¤\8fà¤\95à¥\8b à¤\9b।\nयसलाई अहिलेसम्म सङ्ग्रह गरिएको छैन!</strong>",
-       "sitejspreview": "<strong>याद राख्नुहोस तपाईँले केवल जाभास्क्रिप्ट कोडको पूर्वावलोकन मात्र हेरिरहनु भएको छ।\nयसलाई अहिले सम्म सङ्ग्रह गरिएको छैन!</strong>",
+       "usercsspreview": "<strong>याद राख्नुहोस् तपाईंले आफ्नो प्रयोगकर्ता सियसयसको पूर्वावलोकन मात्र हेरिरहनु भएको छ।\nयसलाई अहिले सम्म सङ्ग्रह गरिएको छैन!</strong>",
+       "userjspreview": "<strong>याद à¤°à¤¾à¤\96à¥\8dनà¥\81हà¥\8bस à¤¤à¤ªà¤¾à¤\88à¤\82ले आफ्नो प्रयोगकर्ता जाभास्क्रिप्टको पूर्वावलोकन मात्र हेरिरहनु भएको छ।\nयसलाइ अहिले सम्म सङ्ग्रह गरिएको छैन!</strong>",
+       "sitecsspreview": "<strong>याद à¤°à¤¾à¤\96à¥\8dनà¥\81हà¥\8bसà¥\8d à¤¤à¤ªà¤¾à¤\88à¤\82लà¥\87 à¤\95à¥\87वल à¤µà¤¿à¤¶à¥\8dववà¥\8dयापà¥\80 à¤¸à¤¿à¤¯à¤¸à¤¯à¤¸à¤\95à¥\8b à¤ªà¥\82रà¥\8dवावलà¥\8bà¤\95न à¤®à¤¾à¤¤à¥\8dर à¤\85वलà¥\8bà¤\95न à¤\97रà¥\8dनà¥\81भà¤\8fà¤\95à¥\8b à¤\9b ।\nयसलाई अहिलेसम्म सङ्ग्रह गरिएको छैन!</strong>",
+       "sitejspreview": "<strong>याद राख्नुहोस् तपाईंले केवल जाभास्क्रिप्ट कोडको पूर्वावलोकन मात्र हेरिरहनु भएको छ।\nयसलाई अहिले सम्म सङ्ग्रह गरिएको छैन!</strong>",
        "userinvalidcssjstitle": "<strong>चेतावनी:</strong> यहाँ कुनैपनि \"$1\" नामको खोल छैन।\nप्रचलित .css तथा .js पृष्ठहरूले निम्नपद शीर्षक प्रयोग गर्छन्, जस्तै {{ns:user}}:Foo/Vector.css को सट्टामा {{ns:user}}:Foo/vector.css",
        "updated": "नवीन",
        "note": "'''सूचना:'''",
        "hiddencategories": "यो पृष्ठ निम्न {{PLURAL:$1|1 लुकाइएको श्रेणी|$1 लुकाइएका श्रेणीहरू}}को सदस्य हो :",
        "edittools": "<!-- Text here will be shown below edit and upload forms. -->",
        "edittools-upload": "-",
-       "nocreatetext": "{{SITENAME}} à¤²à¥\87 à¤¨à¤¯à¤¾à¤\81 à¤ªà¥\83षà¥\8dठ à¤¸à¥\83à¤\9cना à¤\97रà¥\8dन à¤¸à¤\95à¥\8dनà¥\87 à¤\95à¥\8dषमतामा à¤°à¥\8bà¤\95 à¤²à¤\97ाà¤\8fà¤\95à¥\8b à¤\9b।\nतपाà¤\88à¤\81 à¤ªà¤\9bाडि à¤\9cानà¥\81 à¤­à¤\87 à¤°à¤¹à¤¿à¤\86à¤\8fà¤\95à¥\8b à¤ªà¥\83षà¥\8dठ à¤¸à¤®à¥\8dपादन à¤\97रà¥\8dनसà¤\95à¥\8dनà¥\81हà¥\81नà¥\8dà¤\9b , à¤\85थवा [[Special:UserLogin|पà¥\8dरवà¥\87श à¤\97रà¥\8dनà¥\81हà¥\8bस à¤¯à¤¾ à¤¨à¤¯à¤¾à¤\81 à¤\96ाता à¤¸à¥\83à¤\9cना à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d ]]।",
-       "nocreate-loggedin": "नयाà¤\81 à¤ªà¥\83षà¥\8dठ à¤¸à¥\83à¤\9cनाà¤\97रà¥\8dनà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88à¤\81लाई अनुमति छैन ।",
+       "nocreatetext": "{{SITENAME}} à¤²à¥\87 à¤¨à¤¯à¤¾à¤\81 à¤ªà¥\83षà¥\8dठ à¤¸à¥\83à¤\9cना à¤\97रà¥\8dन à¤¸à¤\95à¥\8dनà¥\87 à¤\95à¥\8dषमतामा à¤°à¥\8bà¤\95 à¤²à¤\97ाà¤\8fà¤\95à¥\8b à¤\9b।\nतपाà¤\88à¤\82 à¤ªà¤\9bाडि à¤\97à¤\8fर à¤¯à¤¹à¤¾à¤\81 à¤°à¤¹à¥\87à¤\95ा à¤ªà¥\83षà¥\8dठ à¤¸à¤®à¥\8dपादन à¤\97रà¥\8dनसà¤\95à¥\8dनà¥\81हà¥\81नà¥\8dà¤\9b , à¤\85थवा [[Special:UserLogin|पà¥\8dरवà¥\87श à¤\97रà¥\8dनà¥\81हà¥\8bस à¤¯à¤¾ à¤¨à¤¯à¤¾à¤\81 à¤\96ाता à¤\96à¥\8bलà¥\8dनà¥\81हà¥\8bसà¥\8d]]।",
+       "nocreate-loggedin": "नयाà¤\81 à¤ªà¥\83षà¥\8dठ à¤¸à¥\83à¤\9cनाà¤\97रà¥\8dनà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88à¤\82लाई अनुमति छैन ।",
        "sectioneditnotsupported-title": "खण्ड सम्पादन असमर्थित",
        "sectioneditnotsupported-text": "यस पृष्ठमा खण्ड सम्पादन असमर्थित",
        "permissionserrors": "अनुमति नभएको",
-       "permissionserrorstext": "तपाà¤\88à¤\81लाà¤\88 à¤¯à¤¸à¤\95à¥\8b à¤²à¤¾à¤\97ि à¤\85नà¥\81मति à¤\9bà¥\88न ,निमà¥\8dन {{PLURAL:$1|à¤\95ारण|à¤\95ारणहरà¥\81}}ले गर्दा:",
-       "permissionserrorstext-withaction": "$2 à¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88à¤\81लाà¤\88 à¤\85नà¥\81मति à¤\9bà¥\88न , à¤¨à¤¿à¤®à¥\8dन {{PLURAL:$1|à¤\95ारणलà¥\87|à¤\95ारणहरà¥\81ले}} गर्दा :",
+       "permissionserrorstext": "तपाà¤\88à¤\81लाà¤\88 à¤¯à¤¸à¤\95à¥\8b à¤²à¤¾à¤\97ि à¤\85नà¥\81मति à¤\9bà¥\88न ,निमà¥\8dन {{PLURAL:$1|à¤\95ारण|à¤\95ारणहरà¥\82}}ले गर्दा:",
+       "permissionserrorstext-withaction": "$2 à¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88लाà¤\88 à¤\85नà¥\81मति à¤\9bà¥\88न , à¤¨à¤¿à¤®à¥\8dन {{PLURAL:$1|à¤\95ारणलà¥\87|à¤\95ारणहरà¥\82ले}} गर्दा :",
        "recreate-moveddeleted-warn": "'''चेतावनी: तपाईं अघिबाट मेटिएको पृष्ठ पुनर्निर्माण गर्नुहुँदैछ'''\n\nतपाईंको विचारमा के यो उचित छ कि यसको सम्पादन जारी राखियोस्, \nयस पृष्ठको मेटिएको र सारिएको लग सुविधाको निम्ति यहाँ दिइएकोछ :",
        "moveddeleted-notice": "पृष्ठ मेटिएको छ ।\nमेटिएका तथा सारिएका पृष्ठहरूको सूची तल सन्दर्भको लागि दिइएको छ ।",
        "log-fulllog": "पूरा लग हेर्नुहोस्",
        "edit-hook-aborted": "हुकले सम्पादन बन्द गरिदियो ।\nयसले कुनै कारण दिएन ।",
        "edit-gone-missing": "पृष्ठ अद्यतन गर्न सकिएन\nयो मेटिएको जस्तो देखिन्छ ।",
        "edit-conflict": "द्वन्द्व सम्पादन गर्ने ।",
-       "edit-no-change": "तपाà¤\88à¤\81को सम्पादन वेवास्ता गरियो, किनकि कुनै पनि पाठ परिवर्तन गरिएन ।",
+       "edit-no-change": "तपाà¤\88à¤\82को सम्पादन वेवास्ता गरियो, किनकि कुनै पनि पाठ परिवर्तन गरिएन ।",
        "postedit-confirmation-created": "पृष्ठ सिर्जना गरियो ।",
        "postedit-confirmation-restored": "पृष्ठ पूर्वरूपमा फर्कायो ।",
        "postedit-confirmation-saved": "तपाईंको सम्पादन संग्रह गरिएको छ ।",
        "duplicate-args-category-desc": "पेज जस्तै तर्कहरूको नक्क्लको उपयोग गर्ने ढाँचा कल, जस्तै <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> र <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "'''चेतावनी:''' यस पृष्टका अति धेरै संख्याका महँगा पार्सर फंक्सन कल्स (expensive parser function calls)  छन्।\nयसमा $2 भन्दा कम {{PLURAL:$2|कल|कल्स}} हुनुपर्छ,  यहाँ {{PLURAL:$1|अहिले $1 कल छ|अहिले $1 कल्स छ्न्}}.",
        "expensive-parserfunction-category": "अति धेरै मेहनत पर्ने '''पार्सर फङ्सन कल'''हरू भएका पृष्ठहरू",
-       "post-expand-template-inclusion-warning": "'''à¤\9aà¥\87तावनà¥\80:''' à¤¸à¤®à¥\87à¤\9fà¥\8dनà¥\81परà¥\8dनà¥\87 à¤\9fà¥\87मà¥\8dपà¥\8dलà¥\87à¤\9f(नमà¥\81ना) à¤\86à¤\95ार à¤\85ति à¤ à¥\82लà¥\8b à¤\9b।\nà¤\95à¥\87हà¥\80 à¤\9fà¥\87मà¥\8dपà¥\8dलà¥\87à¤\9fहरà¥\81(नमà¥\81नाहरà¥\81) समेटिने छैनन् ।",
+       "post-expand-template-inclusion-warning": "'''à¤\9aà¥\87तावनà¥\80:''' à¤¸à¤®à¥\87à¤\9fà¥\8dनà¥\81परà¥\8dनà¥\87 à¤¢à¤¾à¤\81à¤\9aा (नमà¥\81ना) à¤\86à¤\95ार à¤\85ति à¤ à¥\82लà¥\8b à¤\9b à¥¤\nà¤\95à¥\87हà¥\80 à¤¢à¤¾à¤\81à¤\9aाहरà¥\82 (नमà¥\81नाहरà¥\82) समेटिने छैनन् ।",
        "post-expand-template-inclusion-category": "यस्ता पृष्ठहरू जहाँ ढाँचा (टेम्पलेट) राख्ने सिमा हुनुपर्ने भन्दा बढि छ ।",
-       "post-expand-template-argument-warning": "'''à¤\9aà¥\87तावनà¥\80:''' à¤¯à¥\8b à¤ªà¥\83षà¥\8dठà¤\95मा à¤\95मà¥\8dतिमा à¤\8fà¤\95 à¤\9fà¥\87मà¥\8dपà¥\8dलà¥\87à¤\9f à¤®à¤¾à¤¨ à¤°à¤¹à¥\87à¤\95à¥\8b à¤\9b à¤\9cसà¤\95à¥\8b à¤§à¥\87रà¥\88 à¤ à¥\82लà¥\8b à¤¬à¤¢à¥\8bतà¥\8dतरà¥\80 à¤\86à¤\95ार à¤°à¤¹à¥\87à¤\95à¥\8b à¤\9b।\nयसà¥\8dता à¤®à¤¾à¤¨à¤¹à¤°à¥\81 हटाइएका छन् ।",
+       "post-expand-template-argument-warning": "'''à¤\9aà¥\87तावनà¥\80:''' à¤¯à¥\8b à¤ªà¥\83षà¥\8dठमा à¤\95मà¥\8dतिमा à¤\8fà¤\95 à¤¢à¤¾à¤\81à¤\9aा à¤®à¤¾à¤¨ à¤°à¤¹à¥\87à¤\95à¥\8b à¤\9b à¤\9cसà¤\95à¥\8b à¤§à¥\87रà¥\88 à¤ à¥\82लà¥\8b à¤¬à¤¢à¥\8bतà¥\8dतरà¥\80 à¤\86à¤\95ार à¤°à¤¹à¥\87à¤\95à¥\8b à¤\9b à¥¤\nयसà¥\8dता à¤®à¤¾à¤¨à¤¹à¤°à¥\82 हटाइएका छन् ।",
        "post-expand-template-argument-category": "मेटिएका ढाँचाहरूसँग सम्बन्ध रहेका पृष्ठहरू",
        "parser-template-loop-warning": "ढाँचागत ग़ाँठो पर्‍यो : [[$1]]",
        "parser-template-recursion-depth-warning": "ढाँचा पुन:चक्र गहिराई सिमा ($1) भन्दा बढि भयो",
        "revdelete-nooldid-title": "अमान्य पुनरावलोकन लक्ष",
        "revdelete-nooldid-text": "यस क्रियालाई गर्नको लागि तपाईंले लक्ष्य अवतरण दिनु भएको छैन, वा तपाईंले दिएको अवतरण अस्तित्वमा छैन वा तपाईं सद्य अवतरणलाई लुकाउने प्रयत्न गर्दै हुनुहुन्छ।",
        "revdelete-no-file": "खुलाइएको पृष्ठ अस्तित्वमा छैन",
-       "revdelete-show-file-confirm": "तपाà¤\88à¤\81 $2 बाट $3 मा मेटिएको फाइल \"<nowiki>$1</nowiki>\" को पुनरावलोकन हेर्न चाहनुहुन्छ भन्ने कुरामा निश्चित हुनुहुन्छ ?",
+       "revdelete-show-file-confirm": "तपाà¤\88à¤\82 $2 बाट $3 मा मेटिएको फाइल \"<nowiki>$1</nowiki>\" को पुनरावलोकन हेर्न चाहनुहुन्छ भन्ने कुरामा निश्चित हुनुहुन्छ ?",
        "revdelete-show-file-submit": "हो",
        "revdelete-selected-text": "[[:$2]] को {{PLURAL:$1|छानिएको संशोधन|छानिएका संशोधनहरू}}:",
        "revdelete-selected-file": "[[:$2]] को {{PLURAL:$1|छानिएको फाइल संस्करण|छानिएका फाइल संस्करणहरू}}:",
        "revdelete-no-change": "'''चेतावनी:''' $2, $1मिति भइको वस्तुको पहिले नै अनुरोध गरे अनुसारको दृश्य सेटिङ्गहरु छन् ।",
        "revdelete-concurrent-change": " $2, $1 मिति गरिएको वस्तु परिवर्तन गर्न सकिएन: यसको स्थितीले तपाईंले परिवर्तन गर्नलाग्नुहुँदा कोहीअरुले नै परिवर्तन गरेजस्तो देखाउँछ\nकृपया लगहरू हेर्नुहोला ।",
        "revdelete-only-restricted": "$2, $1 मिति भएको वस्तु लुकाउदा त्रुटी भएको छ:तपाईंले वस्तुहरूलाई प्रवन्धकहरूको दृष्टीबाट दमन गर्न सक्नुहुन्न अझ कुनै पनि अरु दृष्टी विकल्पहरू नछानीकन।",
-       "revdelete-reason-dropdown": "मà¥\87à¤\9fाà¤\89नà¤\95ा à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dय à¤\95ारणहरà¥\81\n** à¤\95पà¥\80राà¤\87à¤\9f à¤\89लà¥\8dलà¤\82à¤\98न\n** à¤\85नà¥\81à¤\9aित à¤µà¥\8dयà¤\95à¥\8dतिà¤\97त à¤\9cानà¤\95ारà¥\80\n** à¤\85नà¥\81à¤\9aित à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤¨à¤¾à¤®\n** à¤¸à¤\82भावित अपमानजनक जानकारी",
+       "revdelete-reason-dropdown": "मà¥\87à¤\9fाà¤\89नà¤\95ा à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dय à¤\95ारणहरà¥\82\n** à¤\95पà¥\80राà¤\87à¤\9f à¤\89लà¥\8dलà¤\99à¥\8dà¤\98न\n** à¤\85नà¥\81à¤\9aित à¤µà¥\8dयà¤\95à¥\8dतिà¤\97त à¤\9cानà¤\95ारà¥\80\n** à¤\85नà¥\81à¤\9aित à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤¨à¤¾à¤®\n** à¤¸à¤®à¥\8dभावित अपमानजनक जानकारी",
        "revdelete-otherreason": "अन्य/थप कारण:",
        "revdelete-reasonotherlist": "अरु कारण",
        "revdelete-edit-reasonlist": "मेट्ने कार्यहरु सम्पादन गर्ने",
        "nextn": "अर्को {{PLURAL:$1|$1}}",
        "prev-page": "अघिल्लो पृष्ठ",
        "next-page": "अर्को पृष्ठ",
-       "prevn-title": "पहिलà¥\87à¤\95à¥\8b  $1 {{PLURAL:$1|नतिà¤\9cा|नतिà¤\9cाहरà¥\81}}",
-       "nextn-title": "यस à¤ªà¤\9bिà¤\95à¥\8b $1 {{PLURAL:$1|नतिà¤\9cा |नतिà¤\9cाहरà¥\81}}",
+       "prevn-title": "पहिलà¥\87à¤\95à¥\8b  $1 {{PLURAL:$1|नतिà¤\9cा|नतिà¤\9cाहरà¥\82}}",
+       "nextn-title": "यस à¤ªà¤\9bिà¤\95à¥\8b $1 {{PLURAL:$1|नतिà¤\9cा |नतिà¤\9cाहरà¥\82}}",
        "shown-title": "देखाउने $1 {{PLURAL:$1|नतिजा|नतिजाहरू}} प्रति पृष्ठ",
        "viewprevnext": "हेर्नुहोस् ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "''' \"[[:$1]]\" नाम गरेको पृष्ठ  यो विकीमा रहेको छ'''",
        "searchprofile-advanced-tooltip": "अनुकुल नेमस्पेसमा खोज्ने",
        "search-result-size": "$1 ({{PLURAL:$2|1 शब्द|$2 शब्दहरू}})",
        "search-result-category-size": "{{PLURAL:$1|एक सदस्य|$1 सदस्यहरू}} ({{PLURAL:$2|1 उपश्रेणी|$2  उपश्रेणीहरू}}, {{PLURAL:$3|एउटा फाइल|$3 फाइलहरू}})",
-       "search-redirect": "(à¤\9cानà¥\87 $1)",
+       "search-redirect": "(रिडाà¤\87रà¥\87à¤\95à¥\8dà¤\9f à¤¦à¥\87à¤\96ि $1)",
        "search-section": "(खण्ड $1)",
        "search-category": "(श्रेणी $1)",
        "search-file-match": "(भेटिएका फाइल सामाग्री)",
        "showingresults": "देखाउँदै  {{PLURAL:$1|'''१''' नतिजा|'''$1''' नतिजाहरू }} , #'''$2''' बाट सुरुहुने ।",
        "showingresultsinrange": "देखाई रहेको छ{{PLURAL:$1|<strong>1</strong> result|<strong>$1</strong> परिणाम}} सम्म पहुँच  #<strong>$2</strong> देखि #<strong>$3</strong> मा।",
        "search-showingresults": "{{PLURAL:$4|<strong>$3</strong> मा बाट <strong>$1</strong> परिणाम|<strong>$3</strong> मा बाट परिणाम <strong>$1 - $2</strong>}}",
-       "search-nonefound": "तपाà¤\88à¤\82à¤\95à¥\8b à¤\95à¥\8dवà¥\87रà¥\80सँग मेल खाने नतिजाहरू भेटिएनन्",
+       "search-nonefound": "तपाà¤\88à¤\82à¤\95à¥\8b à¤\96à¥\8bà¤\9cसँग मेल खाने नतिजाहरू भेटिएनन्",
        "powersearch-legend": "उन्नत खोज",
        "powersearch-ns": "नेमस्पेसेजहरूमा खोज्ने :",
        "powersearch-togglelabel": "जाँच्ने :",
        "prefs-resetpass": "प्रवेश शब्द परिवर्तन",
        "prefs-changeemail": "इमेल परिवर्तन गर्ने",
        "prefs-setemail": "इमेल ठेगाना प्रविष्ट गर्ने",
-       "prefs-email": "इमेल  विकल्पहरु",
+       "prefs-email": "इमेल विकल्पहरू",
        "prefs-rendering": "स्वरुप",
        "saveprefs": "संग्रह",
        "restoreprefs": "सबै पूर्वनिर्धारित स्थिती कायम गर्ने(सबै खण्डहरूमा)",
        "prefs-editing": "सम्पादन",
-       "rows": "हरफहरà¥\81 :",
-       "columns": "सà¥\8dतमà¥\8dभहरà¥\81 :",
+       "rows": "हरफहरà¥\82 :",
+       "columns": "सà¥\8dतमà¥\8dभहरà¥\82 :",
        "searchresultshead": "खोज",
        "stub-threshold": "<a href=\"#\" class=\"stub\">ठूटो</a> को लागि थ्रेसहोल्ड स्वरूपण (बाइट):",
        "stub-threshold-sample-link": "उदाहरण",
        "timezoneregion-europe": "युरोप",
        "timezoneregion-indian": "हिन्द महासागर",
        "timezoneregion-pacific": "प्राशान्त महासागर",
-       "allowemail": "à¤\85रà¥\81 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताहरà¥\81बाà¤\9f à¤ªà¥\8dरापà¥\8dत à¤¹à¥\81नà¥\87 à¤\88मà¥\87ल enable गर्नुहोस् ।",
+       "allowemail": "à¤\85रà¥\81 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताहरà¥\82बाà¤\9f à¤ªà¥\8dरापà¥\8dत à¤¹à¥\81नà¥\87 à¤\88मà¥\87ल à¤¸à¤\95à¥\8dषम गर्नुहोस् ।",
        "prefs-searchoptions": "खोज्ने",
        "prefs-namespaces": "नेमस्पेसेज",
        "default": "पूर्वनिर्धारित",
        "prefs-custom-css": "अनुकुलित CSS",
        "prefs-custom-js": "अनुकुलित JS",
        "prefs-common-css-js": "साझा CSS/जाभा स्क्रिप्ट सबै त्वचा(स्किन)को लागि:",
-       "prefs-reset-intro": "तपाà¤\88à¤\81 यो पृष्ठलाई आफ्नो अभिरुचीहरू साइट पूर्वावस्थामा फर्काउन प्रयोग गर्न सक्नुहुन्छ । त्यस पछि यसलाई रद्द गर्न सक्नुहुन्न ।",
+       "prefs-reset-intro": "तपाà¤\88à¤\82 यो पृष्ठलाई आफ्नो अभिरुचीहरू साइट पूर्वावस्थामा फर्काउन प्रयोग गर्न सक्नुहुन्छ । त्यस पछि यसलाई रद्द गर्न सक्नुहुन्न ।",
        "prefs-emailconfirm-label": "इ-मेल एकिन प्रक्रिया :",
        "youremail": "ईमेल",
        "username": "{{GENDER:$1|प्रयोगकर्ता नाम}}:",
        "yourvariant": "लेखको भाषा संस्करण:",
        "prefs-help-variant": "तपाईंको मनपरेको संस्करण वा हिज्जे यस विकि भित्र सामग्री पृष्ठहरू प्रदर्शित गर्नका निमित्त।",
        "yournick": "नयाँ हस्ताक्षर:",
-       "prefs-help-signature": "वारà¥\8dतालाप à¤ªà¥\83षà¥\8dठà¤\95ा à¤\9fिपà¥\8dपणà¥\80हरà¥\82 \"<nowiki>~~~~</nowiki>\" à¤¦à¥\8dवारा à¤¦à¤¸à¥\8dतà¤\96त à¤\97रिनà¥\81परà¥\8dà¤\9b ,à¤\9cà¥\81न à¤ªà¤\9bि à¤¤à¤ªà¤¾à¤\88à¤\81को दस्तखत र समयरेखामा रुपान्तरित हुनेछ ।",
+       "prefs-help-signature": "वारà¥\8dतालाप à¤ªà¥\83षà¥\8dठà¤\95ा à¤\9fिपà¥\8dपणà¥\80हरà¥\82 \"<nowiki>~~~~</nowiki>\" à¤¦à¥\8dवारा à¤¦à¤¸à¥\8dतà¤\96त à¤\97रिनà¥\81परà¥\8dà¤\9b ,à¤\9cà¥\81न à¤ªà¤\9bि à¤¤à¤ªà¤¾à¤\88à¤\82को दस्तखत र समयरेखामा रुपान्तरित हुनेछ ।",
        "badsig": "अमान्य कच्चा दस्तखत।\nHTML ट्यागहरु जाँच्नुहोस् ।",
        "badsiglength": "तपाईंको दस्तखत धेरै लामो छ।\nयो $1 {{PLURAL:$1|अक्षर|अक्षरहरू}} भन्दा लामो हुनु हुँदैन ।",
        "yourgender": "कसरी वताउन चाहनुहुन्छ ?",
        "prefs-help-gender": "यो जानकारी दिनु वैकल्पिक छ।\nयो सफ्टवेयरमा लिङ्गको आधारमा तपाईंको लागि सहि सम्बोधन गर्नको निमित्त हुन्छ।\nयो जानकारी सार्वजनिक गरिनेछ।",
        "email": "ईमेल",
        "prefs-help-realname": "वास्तविक नाम ऐच्छिक हो ।\nतपाईंले खुलाउनु भएको खण्डमा तपाईंको कामको श्रेय दिनको लागि यसको प्रयोग गरिने छ ।",
-       "prefs-help-email": "à¤\87मà¥\87ल à¤ à¥\87à¤\97ाना à¤\90à¤\9aà¥\8dà¤\9bिà¤\95 à¤¹à¥\8b, à¤¤à¤°  à¤ªà¥\8dरवà¥\87श à¤¶à¤µà¥\8dदà¤\95à¥\8b à¤ªà¥\81नरà¥\8dसà¥\8dथापनाà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤\86वशà¥\8dयà¤\95ता à¤\9b, à¤\95à¥\87 à¤¤à¤ªà¤¾à¤\88à¤\82लà¥\87 à¤ªà¥\8dरवà¥\87श à¤¶à¤µà¥\8dद à¤­à¥\81लà¥\8dनà¥\81 à¤¹à¥\81नà¥\8dथà¥\8dयà¥\8b।",
-       "prefs-help-email-others": "तपाà¤\88à¤\82लà¥\87 à¤¯à¥\8b à¤ªà¤¨à¤¿ à¤\9aयन à¤\97रà¥\8dन à¤¸à¤\95à¥\8dनà¥\81हà¥\81नà¥\8dà¤\9b à¤\95ि à¤\85रà¥\81हरà¥\81लà¥\87 à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤ªà¤°à¤¿à¤\9aय à¤¨à¤ªà¤¾à¤\88 à¤¤à¤ªà¤¾à¤\88à¤\82सित à¤¤à¤ªà¤¾à¤\88à¤\82à¤\95à¥\8b à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤\85थवा à¤µà¤¾à¤°à¥\8dतालाप à¤ªà¥\83षà¥\8dठà¤\95à¥\8b à¤®à¤¾à¤§à¥\8dयमलà¥\87 à¤¸à¤®à¥\8dपरà¥\8dà¤\95 à¤°à¤¾à¤\96à¥\81नà¥\8d à¥¤",
+       "prefs-help-email": "à¤\87मà¥\87ल à¤ à¥\87à¤\97ाना à¤\90à¤\9aà¥\8dà¤\9bिà¤\95 à¤¹à¥\8b, à¤¤à¤°  à¤ªà¥\8dरवà¥\87श à¤¶à¤¬à¥\8dदà¤\95à¥\8b à¤ªà¥\81नरà¥\8dसà¥\8dथापनाà¤\95ा à¤²à¤¾à¤\97ि à¤\86वशà¥\8dयà¤\95ता à¤\9b, à¤¤à¤ªà¤¾à¤\88à¤\82लà¥\87 à¤ªà¥\8dरवà¥\87श à¤¶à¤¬à¥\8dद à¤¤ à¤\95à¥\87 à¤­à¥\81लà¥\8dनà¥\81 à¤¹à¥\81नà¥\8dथà¥\8dयà¥\8b ।",
+       "prefs-help-email-others": "तपाईंले यो पनि चयन गर्न सक्नुहुन्छ कि अरुले तपाईंको परिचय नपाई तपाईंसित तपाईंको प्रयोगकर्ता अथवा वार्तालाप पृष्ठको माध्यमले सम्पर्क राखुन् ।",
        "prefs-help-email-required": "इमेल ठेगामा चाहिन्छ ।",
        "prefs-info": "साधारण जानकारी",
        "prefs-i18n": "अन्तर्राष्ट्रियकरण",
        "prefs-editor": "सम्पादक",
        "prefs-preview": "पूर्वावलोकन",
        "prefs-advancedrc": "उन्नत विकल्पहरू",
-       "prefs-advancedrendering": "à¤\89नà¥\8dनत à¤µà¤¿à¤\95लà¥\8dपहरà¥\81",
+       "prefs-advancedrendering": "à¤\89नà¥\8dनत à¤µà¤¿à¤\95लà¥\8dपहरà¥\82",
        "prefs-advancedsearchoptions": "उन्नत विकल्पहरू",
        "prefs-advancedwatchlist": "उन्नत विकल्पहरू",
        "prefs-displayrc": "प्रदर्शन विकल्पहरू",
        "right-purge": "साइटको क्याश( cache) निश्चित नगरिकनै पर्ज(Purge) गर्ने",
        "right-autoconfirmed": "आइपी दर सीमाले असर नपार्ने",
        "right-bot": "स्वाचालित कार्यको रुपमा व्यवहार गर्ने",
-       "right-nominornewtalk": "वारà¥\8dता à¤ªà¥\83षà¥\8dठहरà¥\82मा à¤¸à¤¾à¤¨à¥\8b à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रà¥\8dदा à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताहरà¥\82लाà¤\88 \"तपाà¤\88à¤\82à¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¨à¤¯à¤¾à¤\81 à¤¸à¤¨à¥\8dदà¥\87श à¤\9b\" à¤­à¤¨à¥\80 à¤¨à¥\8dदà¥\87à¤\96ाà¤\89नà¥\87",
+       "right-nominornewtalk": "वार्ता पृष्ठहरूमा सानो परिवर्तन गर्दा प्रयोगकर्ताहरूलाई \"तपाईंको लागि नयाँ सन्देश छ\" भनी देखाउने",
        "right-apihighlimits": "API खोजको लागि उच्च सीमा प्रयोग गर्नुहोस्",
        "right-writeapi": "लेखन API प्रयोग गर्ने",
        "right-delete": "पृष्ठहरू मेट्ने",
        "right-editusercssjs": "अरु प्रयोगकर्ताको CSS र JS फाइलहरू सम्पादन गर्ने",
        "right-editusercss": "अरु प्रयोगकर्ताको CSS फाइलहरू सम्पादन गर्ने",
        "right-edituserjs": "अरु प्रयोकर्ताको जाभास्क्रिप्ट फाइलहरू सम्पादन गर्ने",
-       "right-editmyusercss": "तपाà¤\88à¤\81को आफ्नो CSS फाइलहरू सम्पादन गर्नुहोस्",
-       "right-editmyuserjs": "तपाà¤\88à¤\81को आफ्नो जाभा स्क्रिप्ट फाइलहरू सम्पादन गर्ने",
-       "right-viewmywatchlist": "तपाà¤\88à¤\81à¤\95à¥\8b à¤¨à¤¿à¤\97रानà¥\80 à¤¸à¥\81ची हेर्नुहोस्",
+       "right-editmyusercss": "तपाà¤\88à¤\82को आफ्नो CSS फाइलहरू सम्पादन गर्नुहोस्",
+       "right-editmyuserjs": "तपाà¤\88à¤\82को आफ्नो जाभा स्क्रिप्ट फाइलहरू सम्पादन गर्ने",
+       "right-viewmywatchlist": "तपाà¤\88à¤\82à¤\95à¥\8b à¤¨à¤¿à¤\97रानà¥\80 à¤¸à¥\82ची हेर्नुहोस्",
        "right-editmywatchlist": "आफ्नो अबलोकन सूची सम्पादन गर्नुहोस् । ख्याल राख्नु यस अधिकार विना पनि केहि कार्यबाट पृष्ठहरू थप गर्न सकिन्छ ।",
        "right-viewmyprivateinfo": "आफ्नो व्यक्तिगत डेटा हेर्नुहोस (उदाहरण इमेल ठेगाना, सहि नाम)",
        "right-editmyprivateinfo": "आफ्नो निजी जानकारी (जस्तैः इमेल ठेगाना, बास्तविक नाम) सम्पादन गर्नुहोस्",
        "right-patrolmarks": "हालका सम्पादन पट्रोल(गस्ती) चिनो लगाउने",
        "right-unwatchedpages": "निगरानी नगरिएका पृष्ठहरूको सूची हेर्ने",
        "right-mergehistory": "पृष्ठका इतिहासहरु बुझाउने",
-       "right-userrights": "पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताà¤\95ा à¤\85धिà¤\95ारहरà¥\81 सम्पादन गर्ने",
+       "right-userrights": "पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताà¤\95ा à¤\85धिà¤\95ारहरà¥\82 सम्पादन गर्ने",
        "right-userrights-interwiki": "अरु विकिहरूमा प्रयोगकर्ताहरूको अधिकार सम्पादन गर्ने",
        "right-siteadmin": "डेटाबेसको ताल्चामार्ने र ताल्चाखोल्ने",
        "right-override-export-depth": "गहिराइ ५ सम्मको लिंक गरिएका पृष्ठहरू सहित निर्यात गर्ने",
        "action-autopatrol": "तपाईंको सम्पादनलाई गश्त रुपमा दाग दिनुहोस्",
        "action-unwatchedpages": "अवलोकन नगरिएका  पृष्ठहरूको सूची हेर्ने",
        "action-mergehistory": "यस पृष्ठको इतिहासलाई मिसाउने",
-       "action-userrights": "सबà¥\88 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताà¤\95ा à¤\85धिà¤\95ारहरà¥\81 सम्पादन गर्ने",
+       "action-userrights": "सबà¥\88 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताà¤\95ा à¤\85धिà¤\95ारहरà¥\82 सम्पादन गर्ने",
        "action-userrights-interwiki": "अरु विकिका प्रयोगकर्ताहरूको प्रयोगकर्ता अधिकारलाई सम्पादन गर्ने",
        "action-siteadmin": "डेटाबेस बन्दगर्ने वा खोल्ने",
        "action-sendemail": "इमेलहरु पठाउने",
-       "action-editmywatchlist": "तपाà¤\88à¤\81à¤\95à¥\8b à¤¨à¤¿à¤\97रानà¥\80 à¤¸à¥\81ची सम्पादन गर्नुहोस",
-       "action-viewmywatchlist": "तपाà¤\88à¤\81à¤\95à¥\8b à¤¨à¤¿à¤\97रानà¥\80 à¤¸à¥\81à¤\9aà¥\80 à¤¹à¥\87रà¥\8dनà¥\81हà¥\8bस",
-       "action-viewmyprivateinfo": "तपाà¤\88à¤\81को व्यक्तिगत जानकारी हेर्नुहोस",
-       "action-editmyprivateinfo": "तपाà¤\88à¤\81को व्यक्तिगत जानकारी सम्पादन गर्नुहोस",
+       "action-editmywatchlist": "तपाà¤\88à¤\82à¤\95à¥\8b à¤¨à¤¿à¤\97रानà¥\80 à¤¸à¥\82ची सम्पादन गर्नुहोस",
+       "action-viewmywatchlist": "तपाà¤\88à¤\82à¤\95à¥\8b à¤¨à¤¿à¤\97रानà¥\80 à¤¸à¥\82à¤\9aà¥\80 à¤¹à¥\87रà¥\8dनà¥\81हà¥\8bसà¥\8d",
+       "action-viewmyprivateinfo": "तपाà¤\88à¤\82को व्यक्तिगत जानकारी हेर्नुहोस",
+       "action-editmyprivateinfo": "तपाà¤\88à¤\82को व्यक्तिगत जानकारी सम्पादन गर्नुहोस",
        "action-editcontentmodel": "पृष्ठको सामग्री नमुना सम्पादन",
        "action-managechangetags": "डाटाबेसबाट ट्यागहरू बनाउने र मेटाउने",
        "action-applychangetags": "तपाईंको परिवर्तनसँगै ट्यागहरू लागु गर्ने",
        "destfilename": "गन्तव्य फाइलनाम :",
        "upload-maxfilesize": "अधिकतम फाइल आकार : $1",
        "upload-description": "फाइल वर्णन",
-       "upload-options": "à¤\89रà¥\8dधà¥\8dवभरण à¤µà¤¿à¤\95लà¥\8dपहरà¥\81",
+       "upload-options": "à¤\89रà¥\8dधà¥\8dवभरण à¤µà¤¿à¤\95लà¥\8dपहरà¥\82",
        "watchthisupload": "यो पृष्ठ निगरानी गर्नुहोस्",
        "filewasdeleted": "यस नामको एक फाइल पहिले पनि अपलोड गरे पछि हटाई सकिएको छ।\nपुनः अपलोड गर्नु पूर्व तपाईं $1 लाई राम्रोसँग जाँच गर्नुहोला।",
        "filename-bad-prefix": "तपाईं जुन फाइल अपलोड गर्दै हुनुहुन्छ त्यसको नाम <strong>\"$1\"</strong>बाट शुरू हुन्छ, जुन डिजिटल क्यामराद्वारा दिइएको नाम हो।\nकृपया यस फाइलको लागि कुनै दोश्रो अधिक जानकारीयुक्त नाम छान्नुहोस्।",
        "filedelete-success-old": "<strong>[[Media:$1|$1]]</strong> को संस्करणलाघ $3, $2 हुने गरि मेटाइएको छ ।",
        "filedelete-nofile": "'''$1''' अस्तित्वमा छैन ।",
        "filedelete-nofile-old": "<strong>$1</strong> को तपाईंद्वारा दिइएको विशेषताहरू सहितको सङ्ग्रहित अवतरण छैन।",
-       "filedelete-otherreason": "à¤\85नà¥\8dय/थप à¤\95ारणहरà¥\81:",
+       "filedelete-otherreason": "à¤\85नà¥\8dय/थप à¤\95ारणहरà¥\82:",
        "filedelete-reason-otherlist": "अरु कारण",
-       "filedelete-reason-dropdown": "*मà¥\87à¤\9fà¥\8dनà¥\81à¤\95ा à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dय à¤\95ारणहरà¥\81\n** कपी राइट उल्लघन\n** सारिएको फाइल",
+       "filedelete-reason-dropdown": "*मà¥\87à¤\9fà¥\8dनà¥\81à¤\95ा à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dय à¤\95ारणहरà¥\82\n** कपी राइट उल्लघन\n** सारिएको फाइल",
        "filedelete-edit-reasonlist": "मेट्नका कारण संपादन गर्नुहोस्।",
        "filedelete-maintenance": "रखरखाव चलिरहेको हुँदा अस्थायी रुपमा फाइलहरू मेटाउने र मेटाइएकोलाई पुनर्बहाली गर्न निष्क्रिय गरिएकोछ।",
        "filedelete-maintenance-title": "फाइल मेट्न सकिएन",
        "listduplicatedfiles": "दोरोएको फाइलहरूको सूची",
        "listduplicatedfiles-summary": "यो एउटा यस्तो फाइलहरूको सूची हो जसको नवीनतम संस्करण दोश्रो फाइलहरूको नवीनतम संस्करणको प्रतिलिपि हो । मात्रै स्थानीय फाइलहरूलाई विचार गरिएको छ।",
        "listduplicatedfiles-entry": "[[:File:$1|$1]] को [[$3|{{PLURAL:$2|दोहोरो फाइल|$2 दोहोरो फाइलहरू}}]] छ ।",
-       "unusedtemplates": "पà¥\8dरयà¥\8bà¤\97 à¤¨à¤\97रिà¤\8fà¤\95à¥\8b à¤\9fà¥\87मà¥\8dपà¥\8dलà¥\87à¤\9f",
+       "unusedtemplates": "पà¥\8dरयà¥\8bà¤\97 à¤¨à¤\97रिà¤\8fà¤\95à¥\8b à¤¢à¤¾à¤\81à¤\9aाहरà¥\82",
        "unusedtemplatestext": "यस पृष्ठमा {{ns:template}} नामस्थान भएको ती सबै पृष्ठ समावेश छन् जुन कुनै अन्य पृष्ठमा सामेल छैनन्। यसलाई हटाउनभन्दा पहिले यी ढाँचाहरूको र लिङ्कहरूलाई जाँच गर्नुहोला।",
        "unusedtemplateswlh": "अन्य कड़ीहरु",
        "randompage": "कुनै एक लेख",
        "uncategorizedpages": "श्रेणीकरण नभएका पृष्ठहरू",
        "uncategorizedcategories": "श्रेणीकरण नभएका श्रेणीहरू",
        "uncategorizedimages": "श्रेणीकरण नभएका फाइलहरू",
-       "uncategorizedtemplates": "शà¥\8dरà¥\87णà¥\80à¤\95रण à¤¨à¤­à¤\8fà¤\95ा à¤\9fà¥\87मà¥\8dपà¥\8dलà¥\87à¤\9fहरà¥\81",
+       "uncategorizedtemplates": "शà¥\8dरà¥\87णà¥\80à¤\95रण à¤¨à¤­à¤\8fà¤\95ा à¤¢à¤¾à¤\81à¤\9aाहरà¥\82",
        "unusedcategories": "प्रयोग नभएका श्रेणीहरू",
        "unusedimages": "प्रयोग नभएका फाइलहरू",
        "wantedcategories": "माग भएका श्रेणीहरू",
        "wantedfiletext-cat-noforeign": "निम्नलिखित फाइल प्रयोगमा छ तर यहाँ छैन। यस अतिरिक्त, पृष्ठ जुन यस गैर-अवस्थित फाइलहरूलाई सङ्ग्रह गरेका छन् त्यसको सूची [[:$1]]मा छ।",
        "wantedfiletext-nocat": "निम्न फाइलहरू प्रयोगमा छन् तर यहाँ छैन । वाह्य भण्डारहरूको फाइलहरू उपस्थित भए पनि सूचीमा हुन सक्छ। यस्तो कुनै पनि गलत प्रविष्टिहरू <del>काटिएको हुनेछ</del>।",
        "wantedfiletext-nocat-noforeign": "तलका फाइलहरू प्रयोगमा भए पनि उपलब्ध छैन् ।",
-       "wantedtemplates": "माà¤\97 à¤­à¤\8fà¤\95ा à¤\9fà¥\87मà¥\8dपà¥\8dलà¥\87à¤\9fहरà¥\81",
+       "wantedtemplates": "माà¤\97 à¤­à¤\8fà¤\95ा à¤¢à¤¾à¤\81à¤\9aाहरà¥\82",
        "mostlinked": "सबैभन्दा बढि लिंक भएको पृष्ठ",
        "mostlinkedcategories": "सबैभन्दा बढी लिंक भएका श्रेणीहरू",
        "mostlinkedtemplates": "सबैभन्दा बढि ट्रान्सक्ल्युडेड पृष्ठहरू",
        "protectedpages-submit": "पानाहरू देखाउनुहोस्",
        "protectedpages-unknown-timestamp": "अज्ञात",
        "protectedpages-unknown-performer": "अज्ञात प्रयोगकर्ता",
-       "protectedtitles": "सà¥\81रà¤\95à¥\8dषा à¤\97रिà¤\8fà¤\95ा à¤¶à¤¿à¤°à¥\8dषà¤\95हरà¥\81",
+       "protectedtitles": "सà¥\81रà¤\95à¥\8dषित à¤\97रिà¤\8fà¤\95ा à¤¶à¤¿à¤°à¥\8dषà¤\95हरà¥\82",
        "protectedtitles-summary": "यो पृष्ठ ती सबै पृष्ठहरूको सूची दिन्छ जुन अब सुरक्षित छन्। ती सबै पृष्ठहरूको सूची जान्नका लागि जुन बनाउनबाट सुरक्षित गरिएका छन्, हेर्नुहोस [[{{#special:ProtectedPages}}|{{int:protectedpages}}]]",
        "protectedtitlesempty": "दिइएको प्यारामिटर प्रयोग गरि सुरक्षा गरिएका शीर्षकहरु छैनन् ।",
        "protectedtitles-submit": "शीर्षकहरू देखाउनुहोस्",
        "activeusers-intro": "यो सूची ती प्रयोगकर्ताहरूको हो जसले विगत $1 {{PLURAL:$1|दिन| दिन}}मा  गतिविधि देखाएकाछन्।",
        "activeusers-count": "विगत {{PLURAL:$3|दिनमा|$3 दिनहरूमा}}  $1 {{PLURAL:$1|सम्पादन गरियो|सम्पादनहरू गरिए}}",
        "activeusers-from": "यहाँबाट सुरु हुने प्रयोगकर्ताहरू देखाउनुहोस्:",
-       "activeusers-hidebots": "बोटहरु लुकाउने",
-       "activeusers-hidesysops": "प्रवन्धकहरू लुकाउने",
        "activeusers-noresult": "प्रयोगकर्ताहरू भेटिएनन्।",
        "activeusers-submit": "सक्रिय प्रयोगकर्ताहरू देखाउनुहोस्",
        "listgrouprights": "प्रयोगकर्ता समूह अधिकार",
-       "listgrouprights-summary": "निमà¥\8dन à¤¸à¥\82à¤\9aà¥\80 à¤¯à¤¸ à¤µà¤¿à¤\95िमा à¤ªà¤°à¤¿à¤­à¤¾à¤·à¤¿à¤¤ à¤¸à¤®à¥\82हहरà¥\81 à¤° à¤¤à¤¿à¤¨à¥\80हरà¥\81लà¥\87 à¤ªà¥\8dरयà¥\8bà¤\97à¤\97रà¥\8dन à¤¸à¤\95à¥\8dनà¥\87 à¤¸à¤\82बदà¥\8dध  à¤\85धिà¤\95ारहरà¥\81à¤\95à¥\8b à¤¹à¥\8b।\nयसमा à¤¨à¤¿à¤\9cà¥\80 à¤\85धिà¤\95ारहरà¥\81को बारेमा [[{{MediaWiki:Listgrouprights-helppage}}|अतिरिक्त सूचना]] हुनसक्छ।",
+       "listgrouprights-summary": "निमà¥\8dन à¤¸à¥\82à¤\9aà¥\80 à¤¯à¤¸ à¤µà¤¿à¤\95िमा à¤ªà¤°à¤¿à¤­à¤¾à¤·à¤¿à¤¤ à¤¸à¤®à¥\82हहरà¥\82 à¤° à¤¤à¤¿à¤¨à¥\80हरà¥\82लà¥\87 à¤ªà¥\8dरयà¥\8bà¤\97à¤\97रà¥\8dन à¤¸à¤\95à¥\8dनà¥\87 à¤¸à¤\82बदà¥\8dध  à¤\85धिà¤\95ारहरà¥\82à¤\95à¥\8b à¤¹à¥\8b à¥¤\nयसमा à¤¨à¤¿à¤\9cà¥\80 à¤\85धिà¤\95ारहरà¥\82को बारेमा [[{{MediaWiki:Listgrouprights-helppage}}|अतिरिक्त सूचना]] हुनसक्छ।",
        "listgrouprights-key": "* <span class=\"listgrouprights-granted\">प्रदान गरिएका अधिकारहरू</span>\n* <span class=\"listgrouprights-revoked\">फिर्ता गरिएका अधिकारहरू</span>",
        "listgrouprights-group": "समूह",
-       "listgrouprights-rights": "à¤\85धिà¤\95ारहरà¥\81",
-       "listgrouprights-helppage": "Help:सामà¥\82हिà¤\95 à¤\85धिà¤\95ारहरà¥\81",
+       "listgrouprights-rights": "à¤\85धिà¤\95ारहरà¥\82",
+       "listgrouprights-helppage": "Help:सामà¥\82हिà¤\95 à¤\85धिà¤\95ारहरà¥\82",
        "listgrouprights-members": "(सदस्यहरूको सूची)",
        "listgrouprights-addgroup": "{{PLURAL:$2|समूह|समूहहरु}}: $1 थप्ने",
        "listgrouprights-removegroup": "{{PLURAL:$2|समूह|समूहहरु}}: $1 हटाउने",
        "usermaildisabledtext": "यस विकिमा तपाईं अरु प्रयोगकर्तालाई ई-मेल पठाउन सक्नुहुन्न",
        "noemailtitle": "ईमेल ठेगाना नभएको",
        "noemailtext": "प्रयोगकर्ताले सही ई-मेल ठेगाना दर्शाएको छैन।",
-       "nowikiemailtext": "यà¥\80 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dतालà¥\87 à¤\85रà¥\81 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताहरà¥\81बाट ई-मेल स्वीकार नगर्ने छनोट गरेकाछन्।",
+       "nowikiemailtext": "यà¥\80 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dतालà¥\87 à¤\85रà¥\81 à¤ªà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dताहरà¥\82बाट ई-मेल स्वीकार नगर्ने छनोट गरेकाछन्।",
        "emailnotarget": "प्राप्तकर्ताको रुपमा नभएको अथवा अमान्य प्रयोगकर्ता।",
        "emailtarget": "प्राप्तकर्ताको प्रयोगकर्ता नाम हाल्नुहोस्",
        "emailusername": "प्रयोगकर्ता-नाम:",
        "emailmessage": "सन्देश:",
        "emailsend": "पठाउनुहोस्",
        "emailccme": "मेरो सन्देशको एउटा प्रति मलाई ई-मेल गरिदिनुहोस्।",
-       "emailccsubject": "तपाà¤\88à¤\81को सन्देशको प्रतिलिपि  $1: $2लाई",
+       "emailccsubject": "तपाà¤\88à¤\82को सन्देशको प्रतिलिपि  $1: $2लाई",
        "emailsent": "इमेल पठाईयो",
        "emailsenttext": "तपाईंको ई-मेल सन्देश पठाइयो।",
        "emailuserfooter": "यो ईमेल $1 ले $2 लाई \"ई-मेल प्रयोगकर्ता\" कार्यानुरुप {{SITENAME}}मा पठाएको थियो।",
        "notvisiblerev": "पूर्वावलोकन हटाइयो",
        "watchlist-details": "तपाईंको निगरानी सूचीमा रहेका {{PLURAL:$1|$1 पृष्ठ|$1 पृष्ठहरू}} वार्तालाप पृष्ठ गनिएका छैनन्।",
        "wlheader-enotif": "ईमेल जानकारी सक्रिय गरियो ।",
-       "wlheader-showupdated": "तपाà¤\88à¤\81ले पछिल्लो पल्ट भ्रमण गरेपछि परिवर्तन भएका पृष्ठहरूलाई <strong>गाढा<strong> गरेर देखाइएको छ ।",
+       "wlheader-showupdated": "तपाà¤\88à¤\82ले पछिल्लो पल्ट भ्रमण गरेपछि परिवर्तन भएका पृष्ठहरूलाई <strong>गाढा<strong> गरेर देखाइएको छ ।",
        "wlnote": "$3 र $4 अनुसार विगत {{PLURAL:$2|घण्टामा|'''$2''' घण्टाहरूमा}} {{PLURAL:$1|गरिएको अन्तिम परिवर्तन तल दिइएकोछ|गरिएका अन्तिम  '''$1''' परिवर्तनहरू तल दिइएका छन्}}।",
        "wlshowlast": "पछिल्ला $2 दिनहरू $1 घण्टाहरू देखाउनुहोस्",
        "watchlist-hide": "लुकाउनुहोस्",
        "enotif_body_intro_created": "{{SITENAME}} पृष्ठ $1 लाई {{gender:$2|$2}} ले $PAGEEDITDATE मा बनाएको हो, वर्तमान अवतरण को लागि $3 हेर्नुहोस।",
        "enotif_body_intro_moved": "{{SITENAME}} पृष्ठ $1 लाई {{gender:$2|$2}} ले $PAGEEDITDATE मा सारेको हो, वर्तमान अवतरण को लागि $3 हेर्नुहोस।",
        "enotif_body_intro_restored": "{{SITENAME}} पृष्ठ $1 लाई {{gender:$2|$2}} ले $PAGEEDITDATE मा पुनर्स्थापित गरेको हो, वर्तमान अवतरण को लागि $3 हेर्नुहोस।",
-       "enotif_body_intro_changed": "{{SITENAME}} पृष्ठ $1 लाई {{gender:$2|$2}} ले $PAGEEDITDATE मा परिवर्तन गरेको हो, वर्तमान अवतरण को लागि $3 हेर्नुहोस।",
-       "enotif_lastvisited": "à¤\85à¤\98िलà¥\8dलà¥\8b à¤¹à¥\87राà¤\87पà¤\9bिà¤\95ा à¤¸à¤¬à¥\88 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतनहरà¥\81को निम्ति हेर्नुहोस्: $1",
+       "enotif_body_intro_changed": "{{SITENAME}} à¤ªà¥\83षà¥\8dठ $1 à¤²à¤¾à¤\88 {{gender:$2|$2}} à¤²à¥\87 $PAGEEDITDATE à¤®à¤¾ à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रà¥\87à¤\95à¥\8b à¤¹à¥\8b, à¤µà¤°à¥\8dतमान à¤\85वतरण à¤\95à¥\8b à¤²à¤¾à¤\97ि $3 à¤¹à¥\87रà¥\8dनà¥\81हà¥\8bसà¥\8d à¥¤",
+       "enotif_lastvisited": "तपाà¤\88à¤\82à¤\95à¥\8b à¤\85नà¥\8dतिम à¤¹à¥\87राà¤\87पà¤\9bिà¤\95ा à¤¸à¤¬à¥\88 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतनहरà¥\82को निम्ति हेर्नुहोस्: $1",
        "enotif_lastdiff": "यस परिवर्तनको निम्ति यो $1 हेर्नुहोस्",
        "enotif_anon_editor": "अज्ञात  प्रयोगकर्ता  $1",
        "enotif_body": "प्रिय $WATCHINGUSERNAME,\n\n\n{{SITENAME}}को पृष्ठ $PAGETITLE  $PAGEEDITDATE को दिन $PAGEEDITORद्वारा $CHANGEDORCREATED, \nहालको संशोधनको निम्ति हेर्नुहोस्  $PAGETITLE_URL ।\n\n$NEWPAGE\n\nसम्पादकको सारांश: $PAGESUMMARY $PAGEMINOREDIT\n\nसम्पादकसित सम्पर्क राख्नुहोस्:\nमेल: $PAGEEDITOR_EMAIL\nविकि: $PAGEEDITOR_WIKI\n\nतपाईं यस पृष्ठमा नगएसम्म अब उसो कुनै परिवर्तन भएका खण्डमा कुनै सूचना दिनेछैन।\nतपाईंका सम्पूर्ण निगरानी पृष्ठहरूको लागि तपाईंले सूचना पताकालाई निगरानी सूचीमा पुनर्बहाली गर्न सक्नुहुन्छ। \n\n             तपाईंको मित्र {{SITENAME}} सूचना प्रणाली\n--\nइमेल सूचना व्यवस्था परिवर्तन गर्न, जानुहोस्\n{{canonicalurl:{{#special:Preferences}}}}\n\nनिगरानी सूची व्यवस्थित गर्न, जानुहोस्\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nनिगरानी सूची मेट्न, जानुहोस्\n$UNWATCHURL\n\nप्रतिक्रिया र अन्य सहयोगको निम्ति:\n$HELPPAGE",
        "deletecomment": "कारण :",
        "deleteotherreason": "अरू/थप कारणहरू :",
        "deletereasonotherlist": "अरु कारण",
-       "deletereason-dropdown": "*मà¥\87à¤\9fà¥\8dनà¤\95ा à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dय à¤\95ारणहरà¥\81\n** à¤¸à¥\8dपà¥\8dयाम\n** à¤¹à¥\81लà¥\8dयाहापन(Vandalism) \n** à¤ªà¥\8dरतिलिपà¥\80 à¤\85धिà¤\95ार à¤\89लà¥\8dलà¤\82घन\n** लेखकको अनुरोध\n** टुटेको अनुप्रेषण",
+       "deletereason-dropdown": "*मà¥\87à¤\9fà¥\8dनà¤\95ा à¤¸à¤¾à¤®à¤¾à¤¨à¥\8dय à¤\95ारणहरà¥\82\n** à¤¸à¥\8dपà¥\8dयाम\n** à¤¹à¥\81लà¥\8dयाहापन(Vandalism) \n** à¤ªà¥\8dरतिलिपà¥\80 à¤\85धिà¤\95ार à¤\89लà¥\8dलà¤\99à¥\8dघन\n** लेखकको अनुरोध\n** टुटेको अनुप्रेषण",
        "delete-edit-reasonlist": "मेट्नुको कारण सम्पादन गर्नुहोस्",
        "delete-toobig": "यो पृष्ठको सम्पादन इतिहास धेरै र  $1 {{PLURAL:$1|पुनरावलोक|पुनरावलोकहरू}}भन्दा बढी रहेको छ।\n {{SITENAME}}मा दुर्घटनाको कारणले गडबडी आउनसक्ने कुरालाई रोक्न यस्ता पृष्ठहरूलाई मेट्नबाट निषेध गरिएको छ ।",
        "delete-warning-toobig": "This page has a large edit history, over $1 {{PLURAL:$1|revision|revisions}}.\nDeleting it may disrupt database operations of {{SITENAME}};\nproceed with caution.",
        "protectexpiry": "सकिने:",
        "protect_expiry_invalid": "सकिने समयावधि अमान्य ।",
        "protect_expiry_old": "समाप्ती समय बितिसक्यो ।",
-       "protect-unchain-permissions": "à¤\86à¤\97ामà¥\80 à¤¸à¥\81रà¤\95à¥\8dषा à¤µà¤¿à¤\95लà¥\8dपहरà¥\81 खोल्ने",
-       "protect-text": "तपाà¤\88à¤\81  यहाँ '''$1''' पृष्ठको सुरक्षा स्तर हेर्न र परिवर्तन गर्न सक्नुहुन्छ ।",
+       "protect-unchain-permissions": "à¤\86à¤\97ामà¥\80 à¤¸à¥\81रà¤\95à¥\8dषा à¤µà¤¿à¤\95लà¥\8dपहरà¥\82 खोल्ने",
+       "protect-text": "तपाà¤\88à¤\82  यहाँ '''$1''' पृष्ठको सुरक्षा स्तर हेर्न र परिवर्तन गर्न सक्नुहुन्छ ।",
        "protect-locked-blocked": "तपाईं प्रतिबन्धित भएको अवस्थामा सुरक्षा स्तरमा परिवर्तन गर्न सक्नुहुन्न।\nपृष्ठ <strong>$1</strong> को वर्तमान स्थिति यो छ:",
        "protect-locked-dblock": "डेटाबेसमा सक्रिय बन्देज भएको कारणले सुरक्षा स्तरमा कुनै परिवर्तन गर्न सकिंदैन।\nपृष्ठ <strong>$1</strong> को वर्तमान स्थिति यो छ:",
-       "protect-locked-access": "तपाà¤\88à¤\81को खातालाई पृष्ठको सुरक्षा स्तरहरू परिवर्तन गर्ने अनुमति छैन ।\n'''$1''पृष्ठको हालको स्थिति  निम्न छ :",
+       "protect-locked-access": "तपाà¤\88à¤\82को खातालाई पृष्ठको सुरक्षा स्तरहरू परिवर्तन गर्ने अनुमति छैन ।\n'''$1''पृष्ठको हालको स्थिति  निम्न छ :",
        "protect-cascadeon": "हालमा यो पृष्ठ सुरक्षित गरिएको छ किन कि यसमा निम्न {{PLURAL:$1|पृष्ठ, जसको|पृष्ठहरू, जसको}} सुरक्षामा व्यापकता कायम गरिएको छ। \nतपाईंले पृष्ठको सुरक्षा स्तर परिवर्तन गर्न सक्नुहुनेछ तर यसले व्यापक सुरक्षालाई केहि असर पार्ने छैन।",
        "protect-default": "सबै प्रयोगकर्ताहरूलाई अनुमति दिने",
        "protect-fallback": "\"$1\" वर्गमा भएका प्रयोगकर्ताहरूलाई अनुमति दिने",
        "protect-expiring-local": "समाप्ति समय $1",
        "protect-expiry-indefinite": "अनिश्चित काल",
        "protect-cascade": "यो पृष्ठमा संलग्न सुरक्षित पृष्ठहरू(लामबद्द सुरक्षा)",
-       "protect-cantedit": "तपाà¤\88à¤\81 à¤¯à¤¸ à¤ªà¥\83षà¥\8dठà¤\95à¥\8b à¤¸à¥\81रà¤\95à¥\8dषा à¤¸à¥\8dतर à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रà¥\8dन à¤¸à¤\95à¥\8dनà¥\81हà¥\81नà¥\8dन , à¤\95िन à¤\95ि à¤¤à¤ªà¤¾à¤\88à¤\81लाà¤\88 à¤¯à¤¸à¤\95à¥\8b à¤¸à¤®à¥\8dपादनà¤\95à¥\8b अनुमति छैन ।",
+       "protect-cantedit": "तपाà¤\88à¤\82 à¤¯à¤¸ à¤ªà¥\83षà¥\8dठà¤\95à¥\8b à¤¸à¥\81रà¤\95à¥\8dषा à¤¸à¥\8dतर à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रà¥\8dन à¤¸à¤\95à¥\8dनà¥\81हà¥\81नà¥\8dन , à¤\95िन à¤\95ि à¤¤à¤ªà¤¾à¤\88à¤\82लाà¤\88 à¤¯à¥\8b à¤\95ाम à¤\97रà¥\8dन अनुमति छैन ।",
        "protect-othertime": "अरु समय :",
        "protect-othertime-op": "अरु समय",
        "protect-existing-expiry": "वर्तमान समय सीमा :$3, $2",
        "protect-existing-expiry-infinity": "वर्तमान समाप्त समयः अनन्त",
-       "protect-otherreason": "à¤\85रà¥\81/थप à¤\95ारणहरà¥\81 :",
+       "protect-otherreason": "à¤\85रà¥\81/थप à¤\95ारणहरà¥\82 :",
        "protect-otherreason-op": "अरु कारण",
-       "protect-dropdown": "*सामानà¥\8dय à¤¸à¥\81रà¤\95à¥\8dषाà¤\95ा à¤\95ारणहरà¥\81\n** अत्यधिक बर्बरता\n** अत्यधिक अचाहिंदा सन्देश\n** जवाबी सम्पादन-झगडा\n** अधिकतम खोलिने पृष्ठ",
-       "protect-edit-reasonlist": "सà¥\81रà¤\95à¥\8dषाà¤\95à¥\8b à¤\95ारणहरà¥\81 सम्पादन गर्नुहोस्",
+       "protect-dropdown": "*सामानà¥\8dय à¤¸à¥\81रà¤\95à¥\8dषाà¤\95ा à¤\95ारणहरà¥\82\n** अत्यधिक बर्बरता\n** अत्यधिक अचाहिंदा सन्देश\n** जवाबी सम्पादन-झगडा\n** अधिकतम खोलिने पृष्ठ",
+       "protect-edit-reasonlist": "सà¥\81रà¤\95à¥\8dषाà¤\95à¥\8b à¤\95ारणहरà¥\82 सम्पादन गर्नुहोस्",
        "protect-expiry-options": " १ घण्टा:1 hour, १ दिन :1 day, १ हप्ता:1 week, २ हप्ता:2 weeks, १ महिना:1 month, ३ महिना:3 months,६ महिना:6 months, १ वर्ष:1 year, अनिश्चितकाल:infinite",
        "restriction-type": "अनुमति:",
        "restriction-level": "प्रतिबन्ध स्तरः",
        "sp-contributions-blocklog": "रोकावट लग",
        "sp-contributions-suppresslog": "प्रयोगकर्ताको योगदानहरू दबाइएको छ ।",
        "sp-contributions-deleted": "प्रयोगकर्ताका योगदानहरू मेटाइयो",
-       "sp-contributions-uploads": "à¤\89रà¥\8dधà¥\8dवभरणहरà¥\81",
+       "sp-contributions-uploads": "à¤\89रà¥\8dधà¥\8dवभरणहरà¥\82",
        "sp-contributions-logs": "लगहरू",
        "sp-contributions-talk": "वार्ता",
        "sp-contributions-userrights": "प्रयोगकर्ता अधिकार व्यवस्थापन",
        "moveuserpage-warning": "'''चेतावनी:''' तपाईंले प्रयोगकर्ता पृष्ठ सार्न आँट्नु भएकोछ। कृपया याद राख्नुहोस् पृष्ठ मात्र सारिने छ र प्रयोगकर्ताको अर्को नाम राख्न '''सकिंदैन'''।",
        "movecategorypage-warning": "<strong>चेतावनी:</strong> तपाईं एउटा श्रेणी पृष्ठलाई स्थानान्तरित गर्न जादै हुनुहुन्छ। याद राख्नुहोस् कि मात्रै यो पृष्ठ स्थानान्तरित हुनेछ र पुरानो श्रेणीमा सामेल पृष्ठ नयाँ श्रेणी अन्तर्गत <em>जाने</em> छैन।",
        "movenologintext": "पृष्ठ सार्नको लागि तपाईं दर्ता गरिएको र [[Special:UserLogin|प्रवेश गरेको]] प्रयोगकर्ता हुनुपर्छ ।",
-       "movenotallowed": "तपाà¤\88à¤\81लाई पृष्ठ सार्ने अनुमति छैन",
-       "movenotallowedfile": "फाà¤\87ल à¤¹à¤\9fाà¤\89नà¥\87 à¤\85नà¥\81मति à¤¤à¤ªà¤¾à¤\88à¤\81लाई  छैन।",
+       "movenotallowed": "तपाà¤\88à¤\82लाई पृष्ठ सार्ने अनुमति छैन",
+       "movenotallowedfile": "फाà¤\87ल à¤¹à¤\9fाà¤\89नà¥\87 à¤\85नà¥\81मति à¤¤à¤ªà¤¾à¤\88à¤\82लाई  छैन।",
        "cant-move-user-page": "तपाईसँग प्रयोगकर्ता पृष्ठहरू सार्न अनुमती छैन (सहपृष्ठहरू बाहेक)",
        "cant-move-to-user-page": "तपाईंलाई पृष्ठहरू प्रयोगकर्ता पृष्ठमा सार्न अनुमती छैन (प्रयोगकर्ता सहपृष्ठहरूमा बाहेक)",
        "cant-move-category-page": "तपाईंलाई श्रेणीको पृष्ठहरू सार्ने अनुमति छैन ।",
        "movepage-moved": "'''\"$1\" लाई \"$2\"मा सारिएको छ'''",
        "movepage-moved-redirect": "अनुप्रेषित पृष्ठ सृजना गरियो।",
        "movepage-moved-noredirect": "रिडाइरेक्ट पृष",
-       "articleexists": "यस नामको पृष्ठ पहिले देखि नै रहेको ,या तपाईँले छान्नु भएको नाम अमान्य छ।\nकृपया अर्कै नाम छान्नुहोस् ।",
+       "articleexists": "यस नामको पृष्ठ पहिले देखि नै रहेको छ, या तपाईंले छान्नु भएको नाम अमान्य छ । कृपया अर्कै नाम छान्नुहोस् ।",
        "cantmove-titleprotected": "तपाईं यो स्थानमा पृष्ठ सार्न सक्नुहुन्न, किनकी यो नयाँ शिर्षकलाई सिर्जना हुनबाट जोगाइएको छ",
        "movetalk": "सम्बन्धित वार्ता पृष्ठ",
        "move-subpages": "सहायक पृष्ठहरू सार्ने($1 सम्मको)",
        "import-interwiki-sourcewiki": "श्रोत विकिः",
        "import-interwiki-sourcepage": "श्रोत पृष्ठः",
        "import-interwiki-history": "यो पृष्ठकोलागि सबै इतिहास संशोधनहरू प्रतिलिपि गर्ने",
-       "import-interwiki-templates": "सबà¥\88 à¤\9fà¥\87मà¥\8dपà¥\8dलà¥\87à¤\9fहरà¥\81(नमà¥\81ना) समेट्ने",
+       "import-interwiki-templates": "सबà¥\88 à¤¢à¤¾à¤\81à¤\9aा समेट्ने",
        "import-interwiki-submit": "आयात",
        "import-mapping-default": "पूर्वनिर्धारित स्थानहरूमा आयात",
        "import-mapping-namespace": "नेमस्पेसमा आयातः",
        "javascripttest-pagetext-unknownaction": "अज्ञात कारवाही \"$1\" ।",
        "javascripttest-qunit-intro": "mediawiki.org मा [$1 जाँचको कागजात] हेर्नुहोस् ।",
        "tooltip-pt-userpage": "{{GENDER:| तपाईंको प्रयोगकर्ता}} पृष्ठ",
-       "tooltip-pt-anonuserpage": "तपाà¤\88à¤\81 जुन IP ठेगानाको रुपमा सम्पादन गर्दै हुनुहुन्छ , त्यसको प्रयोगकर्ता पृष्ठ निम्न छ :",
+       "tooltip-pt-anonuserpage": "तपाà¤\88à¤\82 जुन IP ठेगानाको रुपमा सम्पादन गर्दै हुनुहुन्छ , त्यसको प्रयोगकर्ता पृष्ठ निम्न छ :",
        "tooltip-pt-mytalk": "{{GENDER:|तपाईंको}} वार्ता पृष्ठ",
        "tooltip-pt-anontalk": "यो IP ठेगानाबाट गरिएका सम्पादनका बारेमा बार्तालाप",
        "tooltip-pt-preferences": "{{GENDER:|तपाईंका}} अभिरुचिहरू",
-       "tooltip-pt-watchlist": "पà¥\83षà¥\8dठहरà¥\82à¤\95à¥\8b à¤¸à¥\82à¤\9aà¥\80 à¤\9cसà¤\95ा à¤ªà¤°à¤¿à¤µà¤°à¥\8dतनहरà¥\82लाà¤\88 à¤¤à¤ªà¤¾à¤\88à¤\81ले निगरानी गरिरहनु भएको छ",
+       "tooltip-pt-watchlist": "पà¥\83षà¥\8dठहरà¥\82à¤\95à¥\8b à¤¸à¥\82à¤\9aà¥\80 à¤\9cसà¤\95ा à¤ªà¤°à¤¿à¤µà¤°à¥\8dतनहरà¥\82लाà¤\88 à¤¤à¤ªà¤¾à¤\88à¤\82ले निगरानी गरिरहनु भएको छ",
        "tooltip-pt-mycontris": "{{GENDER:|तपाईंका}} योगदानहरूको सूची",
        "tooltip-pt-login": "तपाईंलाई प्रवेस गर्न सुझाव दिइन्छ ; तर यो जरुरी भने छैन",
        "tooltip-pt-logout": "निर्गमन (लग आउट) गर्नुहोस्",
        "tooltip-ca-undelete": "मेटिएको भए पनि यो पृष्ठको सम्पादनहरू पुन:प्राप्त गर्नुहोस्",
        "tooltip-ca-move": "यो पृष्ठलाई सार्नुहोस्",
        "tooltip-ca-watch": "यो पृष्ठलाई तपाईंको अवलोकनसूचीमा थप्नुहोस्",
-       "tooltip-ca-unwatch": "यà¥\8b à¤ªà¥\83षà¥\8dठलाà¤\88 à¤¤à¤ªà¤¾à¤\88à¤\81को अवलोकनसूचीबाट हटाउनुहोस्",
+       "tooltip-ca-unwatch": "यà¥\8b à¤ªà¥\83षà¥\8dठलाà¤\88 à¤¤à¤ªà¤¾à¤\88à¤\82को अवलोकनसूचीबाट हटाउनुहोस्",
        "tooltip-search": "{{SITENAME}} मा खोज्नुहोस्",
        "tooltip-search-go": "यदि यो नामको पृष्ठ रहेको छ भने त्यसमा जाने",
        "tooltip-search-fulltext": "यो पाठको लागि पृष्ठहरू खोज्नुहोस्",
        "tooltip-preview": "तपाईंको परिवर्तनको पूर्वरूप , कृपया सङ्ग्रह गर्नु अघि यो प्रयोग गर्नुहोला !",
        "tooltip-diff": "तपाईंले पाठमा के के परिवर्तन गर्नुभयो भनेर देखाउने",
        "tooltip-compareselectedversions": "यस पृष्ठको छानिएका दुई पुनरावलोकन बीच फरक हेर्नुहोस्",
-       "tooltip-watch": "यà¥\8b à¤ªà¥\83षà¥\8dठलाà¤\88 à¤¤à¤ªà¤¾à¤\88à¤\81को अवलोकनसूचीमा थप्नुहोस्",
+       "tooltip-watch": "यà¥\8b à¤ªà¥\83षà¥\8dठलाà¤\88 à¤¤à¤ªà¤¾à¤\88à¤\82को अवलोकनसूचीमा थप्नुहोस्",
        "tooltip-watchlistedit-normal-submit": "शीर्षकहरू हटाउने",
        "tooltip-watchlistedit-raw-submit": "निगरानी सूची अध्यावधि गर्ने",
        "tooltip-recreate": "मेटिएको भए ता पनि यो पृष्ट पुन:निर्माण गर्नुहोस् ।",
        "yesterday-at": "हिजो $1मा",
        "bad_image_list": "(* बाट शुरु हुने पंक्ति)को  विषय सूची मात्र मान्य छ।  पंक्तिको पहिलो लिङ्क नराम्रो फाइलसित लिङ्क हुनैपर्छ । एउटै पंक्तिमा कुनै पछिबाट हुने लिंकलाई अपवाद मानिनेछ अर्थात् जुन पृष्ठमा फाइल इन-लाइन हुनसक्छ।",
        "metadata": "मेटाडेटा",
-       "metadata-help": "यस à¤«à¤¾à¤\87लमा à¤\85तिरिà¤\95à¥\8dत à¤\9cानà¤\95ारà¥\80हरà¥\82 à¤\9bनà¥\8d, à¤¯à¤¸à¤²à¤¾à¤\88 à¤¬à¤¨à¤¾à¤\89न à¤¸à¤®à¥\8dभवतà¤\83 à¤¡à¤¿à¤\9cिà¤\9fल à¤\95à¥\8dयामà¥\87रा à¤\85थवा à¤¸à¥\8dà¤\95à¥\8dयानर à¤ªà¥\8dरयà¥\8bà¤\97 à¤\97रिà¤\8fà¤\95à¥\8b à¤¹à¥\81नà¥\81परà¥\8dà¤\9b à¥¤ à¤¯à¤¦à¤¿ à¤¯à¤¸ à¤«à¤¾à¤\87ललाà¤\88 à¤®à¥\82ल à¤\85वसà¥\8dथाबाà¤\9f à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रिà¤\8fà¤\95à¥\8b à¤¹à¥\8b à¤­à¤¨à¥\87  à¤¯à¤¸ à¤«à¤¾à¤\87ललà¥\87  à¤¸à¤®à¥\8dपà¥\82रà¥\8dण à¤µà¤¿à¤µà¤°à¤£ à¤ªà¥\8dरतिबिमà¥\8dबित à¤\97रà¥\8dन à¤¸à¤\95à¥\8dनà¥\87à¤\9bà¥\88न à¥¤",
+       "metadata-help": "यस फाइलमा अतिरिक्त जानकारीहरू छन्, यसलाई बनाउन सम्भवतः डिजिटल क्यामरा अथवा स्क्यानर प्रयोग गरिएको हुनुपर्छ । यदि यस फाइललाई मूल अवस्थाबाट परिवर्तन गरिएको हो भने  यस फाइलले  सम्पूर्ण विवरण प्रतिबिम्बित गर्न सक्नेछैन ।",
        "metadata-expand": "लामो विबरण हेर्ने",
        "metadata-collapse": "लामो विवरण लुकाउने",
        "metadata-fields": "मेटाडाटा तालिकालाई लघुरूप गरियो भने यस सन्देशमा सूचीबद्ध इएक्सआयएफ मेटाडाटा जानकारिहरू छवि प्रदर्शित हुने बेला सम्मिलित गरिने छ ।\nअन्य डिफल्ट रूपसँग लुकिरहने छ ।\n* make \n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-dc-date": "मिति(हरू)",
        "exif-dc-publisher": "प्रकाशक",
        "exif-dc-relation": "सम्वन्धित मेडिया",
-       "exif-dc-rights": "à¤\85धिà¤\95ारहरà¥\81",
+       "exif-dc-rights": "à¤\85धिà¤\95ारहरà¥\82",
        "exif-dc-source": "स्रोत मेडिया",
        "exif-dc-type": "मेडियाको प्रकार",
        "exif-rating-rejected": "अस्विकृत",
        "confirmemail_invalidated": "ई मेल ठेगाना रद्द भएको पुष्टिकरण",
        "invalidateemail": "इमेल यकिन कार्य रद्द गर्नुहोस्",
        "scarytranscludedisabled": "[अन्तरविकि दस्तावेज अन्तरकरण निस्क्रिय]",
-       "scarytranscludefailed": "[ $1à¤\95à¥\8b à¤²à¤¾à¤\97ि à¤\9fà¥\87मà¥\8dपà¥\8dलà¥\87à¤\9f ल्याउन असफल]",
+       "scarytranscludefailed": "[ $1à¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¢à¤¾à¤\81à¤\9aा ल्याउन असफल]",
        "scarytranscludefailed-httpstatus": "[$1 को लागि ढाँचा पाउन सकिएन, त्रुटि: HTTP $2]",
        "scarytranscludetoolong": "[URL अति लामो छ ]",
        "deletedwhileediting": "'''चेतावनी''': तपाईंले सम्पादन सुरु गरेपछि यो पृष्ठ मेटिएकोछ!",
        "table_pager_limit": "प्रतिपृष्ठ $1 वस्तुहरु देखाउने",
        "table_pager_limit_label": "प्रति पृष्ठ सामग्री:",
        "table_pager_limit_submit": "जाउ",
-       "table_pager_empty": "नतिà¤\9cाहरà¥\81 छैन ।",
+       "table_pager_empty": "नतिà¤\9cाहरà¥\82 छैन ।",
        "autosumm-blank": "पृष्ठ खाली गरीयो",
        "autosumm-replace": "पृष्ठलाई '$1' संग हटाइदै",
        "autoredircomment": "पृष्ठ[[$1]]मा पठाइएको",
        "specialpages": "विशेष पृष्ठ",
        "specialpages-note-top": "आदर्श वाक्य",
        "specialpages-note": "* साधारण विशेष पृष्ठहरू।\n* <span class=\"mw-specialpagerestricted\">निषेधित विशेष पृष्ठहरू।</span>",
-       "specialpages-group-maintenance": "मरà¥\8dमत à¤ªà¥\8dरतिवà¥\87दनहरà¥\81",
+       "specialpages-group-maintenance": "मरà¥\8dमत à¤ªà¥\8dरतिवà¥\87दनहरà¥\82",
        "specialpages-group-other": "अरू विशेष पृष्ठहरू",
        "specialpages-group-login": "प्रवेश गर्ने / नयाँ खाता बनाउने",
        "specialpages-group-changes": "भर्खरैका परिवर्तन र लगहरू",
-       "specialpages-group-media": "मà¥\87डिया à¤ªà¥\8dरतिवà¥\87दन à¤° à¤\89रà¥\8dधà¥\8dवभरणहरà¥\81",
-       "specialpages-group-users": "पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤° à¤\85धिà¤\95ारहरà¥\81",
+       "specialpages-group-media": "मिडिया à¤ªà¥\8dरतिवà¥\87दन à¤° à¤\89रà¥\8dधà¥\8dवभरणहरà¥\82",
+       "specialpages-group-users": "पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤° à¤\85धिà¤\95ारहरà¥\82",
        "specialpages-group-highuse": "उच्च प्रयोग भएका पृष्ठहरू",
        "specialpages-group-pages": "पृष्ठहरूको सूची:",
        "specialpages-group-pagetools": "पृष्ठ उपकरणहरू",
-       "specialpages-group-wiki": "डà¥\87à¤\9fा à¤° à¤\94à¤\9cारहरà¥\81",
+       "specialpages-group-wiki": "डà¥\87à¤\9fा à¤° à¤\94à¤\9cारहरà¥\82",
        "specialpages-group-redirects": "विशेष पृष्ठमा पठाउने",
        "specialpages-group-spam": "स्पाम उपकरणहरू",
        "specialpages-group-developer": "विकासकर्ता उपकरणहरू",
        "tags-title": "ट्यागहरु",
        "tags-intro": "यो पृष्ठले पुच्छरहरु सुचीकृत गर्छ जससँग यो सफ्टवेयरले चिनो लगाउन र सम्पादन गर्न सक्छ र तिनका अर्थहरु ।",
        "tags-tag": "आन्तरिक ट्याग नाम",
-       "tags-display-header": "परिवरà¥\8dतन à¤¸à¥\82à¤\9aà¥\80हरà¥\81माथि झलक",
+       "tags-display-header": "परिवरà¥\8dतन à¤¸à¥\82à¤\9aà¥\80हरà¥\82माथि झलक",
        "tags-description-header": "पूर्ण अर्थको वर्णन",
        "tags-source-header": "स्रोत",
        "tags-active-header": "सक्रिय?",
        "tags-activate": "सक्रिय गर्ने",
        "tags-deactivate": "निष्क्रिय गर्ने",
        "tags-hitcount": "$1 {{PLURAL:$1|परिवर्तन|परिवर्तनहरू}}",
-       "tags-manage-no-permission": "à¤\9fà¥\8dयाà¤\97 à¤®à¤¿à¤²à¤¾à¤¨ à¤\97रà¥\8dनà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88à¤\81लाà¤\88 à¤\85नà¥\81मति à¤\9bà¥\88न।",
+       "tags-manage-no-permission": "à¤\9fà¥\8dयाà¤\97 à¤®à¤¿à¤²à¤¾à¤¨ à¤\97रà¥\8dनà¤\95à¥\8b à¤²à¤¾à¤\97ि à¤¤à¤ªà¤¾à¤\88à¤\82लाà¤\88 à¤\85नà¥\81मति à¤\9bà¥\88न ।",
        "tags-create-heading": "नयाँ ट्याग बनाउने",
        "tags-create-explanation": "पुनः निर्धारित रूपले, नवनिर्मित ट्याग प्रयोगकर्ताहरू र बोटहरूको लागी रहनेछ।",
        "tags-create-tag-name": "ट्याग नाम:",
        "tags-apply-no-permission": "परिवर्तन ट्यागहरूलाई आफ्नो ट्यागसँग जोड्न तपाईंलाई अनुमति छैन।",
        "tags-apply-not-allowed-one": "ट्याग \"$1\" मानवीय रूपले जोड्न सक्ने अनुमति छैन।",
        "tags-apply-not-allowed-multi": "निम्नलिखित {{PLURAL:$2|ट्यागलाई अनुमति छैन|ट्यागहरूलाई अनुमति छैन}} कि त्यसलाई मानवीय रूपले प्रयोगमा ल्याउन सकियोस: $1",
-       "tags-update-no-permission": "तपाà¤\88à¤\82लाà¤\88 à¤µà¥\8dयà¤\95à¥\8dतिà¤\97त à¤¸à¤\82शà¥\8bधनहरà¥\82 à¤µà¤¾ à¤²à¤\97 à¤ªà¥\8dरविषà¥\8dà¤\9fिहरà¥\82सà¤\81à¤\97 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\9cà¥\8bड़ने वा हटाउने अनुमति छैन।",
+       "tags-update-no-permission": "तपाà¤\88à¤\82लाà¤\88 à¤µà¥\8dयà¤\95à¥\8dतिà¤\97त à¤¸à¤\82शà¥\8bधनहरà¥\82 à¤µà¤¾ à¤²à¤\97 à¤ªà¥\8dरविषà¥\8dà¤\9fिहरà¥\82सà¤\81à¤\97 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\9cà¥\8bडà¥\8dने वा हटाउने अनुमति छैन।",
        "tags-update-add-not-allowed-one": "ट्याग \"\"$1\" लाई मानवीय रूपले जोड्न सकिंदैन।",
        "tags-update-add-not-allowed-multi": "निम्नलिखित {{PLURAL:$2|ट्याग|वा ट्यागहरू}} मानवीय रूपले जोड्न सकिंदैन: $1",
        "tags-update-remove-not-allowed-one": "ट्याग \"$1\" मेटाउने अनुमति छैन ।",
        "compare-submit": "दँजाउनुहोस्",
        "compare-invalid-title": "तपाईंले खुलाउनु भएको शिर्षक अमान्य छ।",
        "compare-title-not-exists": "तपाईंले खुलाउनु भएको शिर्षक उपलब्ध छैन ।",
-       "compare-revision-not-exists": "तपाà¤\88à¤\81ले खुलाउनु भएको संस्करण उपलब्ध छैन ।",
+       "compare-revision-not-exists": "तपाà¤\88à¤\82ले खुलाउनु भएको संस्करण उपलब्ध छैन ।",
        "dberr-problems": "क्षमा पाउँ! यो साइटमा तकनीकी गड़बड़ी आइपरेकोछ।",
        "dberr-again": "केही समय पर्खिएर पुन: लोड हुन दिनुहोस् ।",
        "dberr-info": "(डेटाबेस सर्भर: $1 सँग सम्पर्क स्थापित गर्न सकिएन)",
        "htmlform-invalid-input": "तपाईंको कुनै प्रविष्ठिहरू सही छैनन्",
        "htmlform-select-badoption": "तपाईंले खुलाउनु भएको मान मान्य विकल्प हैन ।",
        "htmlform-int-invalid": "तपाईंले खुलाउनु भएको मान कुनै इन्टिजर हैन ।",
-       "htmlform-float-invalid": "तपाà¤\88à¤\81ले जनाउनु भएको मान कुनै संख्या हैन ।",
+       "htmlform-float-invalid": "तपाà¤\88à¤\82ले जनाउनु भएको मान कुनै संख्या हैन ।",
        "htmlform-int-toolow": "तपाईंले जनाउनु भएको मान न्युनतम $1 भन्दा कम भयो ।",
        "htmlform-int-toohigh": "तपाईंले जनाउनु भएको मान अधिकतम $1 भन्दा बढी भयो ।",
        "htmlform-required": "यसको मूल्य(value) चाहिन्छ",
        "feedback-external-bug-report-button": "प्राविधिक कार्य पेश गर्नुहोस्",
        "feedback-dialog-title": "प्रतिक्रिया दिनुहोस्",
        "feedback-dialog-intro": "तपाईं तल दिइएको सरल फारमको प्रयोग गरेर आफ्नो प्रतिपुष्टि पठाउन सक्नुहुन्छ। तपाईंको टिप्पणी पृष्ठ \"$1\" स तपाईंको प्रयोगकर्तानामको अगाडी जोडिनेछ ।",
-       "feedback-error-title": "त्रुटि",
        "feedback-error1": "त्रुटीः एपिआईबाट अज्ञात परिणाम",
        "feedback-error2": "त्रुटि: सम्पादन असफल",
        "feedback-error3": "त्रुटीः एपिआईबाट कुनै प्रतिक्रिया नआएको",
        "feedback-thanks": "धन्यवाद! तपाईंको प्रतिक्रिया पृष्ठमा नियुक्त गरिएको छ \"[ $2  $1 ]\"।",
        "feedback-thanks-title": "धन्यवाद!",
        "feedback-useragent": "प्रयोगकर्ता एजेन्ट:",
-       "searchsuggest-search": "खोज",
+       "searchsuggest-search": "{{SITENAME}} मा खोज्नुहोस्",
        "searchsuggest-containing": "समावेश भएको...",
        "api-error-badaccess-groups": "यस विकिमा तपाईंलाई फाइल अपलोड गर्ने अनुमति छैन।",
        "api-error-badtoken": "आन्तरिक समस्याः खराब टोकन ।",
        "mediastatistics-header-text": "पाठ",
        "mediastatistics-header-executable": "कार्यान्वयन गर्न मिल्नेहरू",
        "mediastatistics-header-archive": "संकुचित ढाँचाहरू",
-       "mediastatistics-header-total": "सबà¥\88 à¤«à¤¾à¤\87लहरà¥\81",
+       "mediastatistics-header-total": "सबà¥\88 à¤«à¤¾à¤\87लहरà¥\82",
        "json-warn-trailing-comma": "$1 पछाडी रहेको छ {{PLURAL:$1|कोमा को|कोमाहरूको}} जेएसओएनबाट हटाइयो",
        "json-error-unknown": "जेएसओएन मा समस्या छ । समस्याः $1",
        "json-error-depth": "स्ट्याकको अधिकतम गहिराई बढी सकेको छ",
index 9839755..6a42eee 100644 (file)
@@ -79,7 +79,8 @@
                        "Dinosaur918",
                        "Jdforrester",
                        "Jeleniccz",
-                       "MrLeopold"
+                       "MrLeopold",
+                       "Hex"
                ]
        },
        "tog-underline": "Koppelingen onderstrepen:",
        "category-file-count-limited": "Deze categorie bevat {{PLURAL:$1|het volgende bestand|de volgende $1 bestanden}}.",
        "listingcontinuesabbrev": "meer",
        "index-category": "Te indexeren pagina's",
-       "noindex-category": "Niet te indexeren pagina's",
+       "noindex-category": "Niet-geïndexeerde pagina's",
        "broken-file-category": "Pagina's met onjuiste bestandskoppelingen",
        "about": "Over",
        "article": "Pagina",
        "talk": "Overleg",
        "views": "Weergaven",
        "toolbox": "Hulpmiddelen",
+       "tool-link-userrights": "{{GENDER:$1|Gebruikersgroepen}} wijzigen",
+       "tool-link-emailuser": "Deze {{GENDER:$1|gebruiker}} e-mailen",
        "userpage": "Gebruikerspagina bekijken",
        "projectpage": "Projectpagina bekijken",
        "imagepage": "Bestandspagina bekijken",
        "cannotloginnow-title": "Niet mogelijk om aan te melden",
        "cannotloginnow-text": "Aanmelden is niet mogelijk bij het gebruik van $1.",
        "cannotcreateaccount-title": "Kan geen accounts aanmaken",
+       "cannotcreateaccount-text": "Direct aanmaken van een gebruiker is niet ingeschakeld op deze wiki.",
        "yourdomainname": "Uw domein:",
        "password-change-forbidden": "U kunt uw wachtwoord niet wijzigen in deze wiki.",
        "externaldberror": "Er is een fout opgetreden bij het aanmelden bij de database of u hebt geen toestemming uw externe gebruiker bij te werken.",
        "createacct-email-ph": "Geef uw e-mailadres op",
        "createacct-another-email-ph": "Geef een e-mailadres op",
        "createaccountmail": "Gebruik een tijdelijk willekeurig wachtwoord en stuur het naar het opgegeven e-mailadres",
+       "createaccountmail-help": "Kan worden gebruikt voor het aanmaken van een gebruiker voor een andere persoon zonder het wachtwoord te leren.",
        "createacct-realname": "Echte naam (optioneel)",
        "createaccountreason": "Reden:",
        "createacct-reason": "Reden",
        "createacct-reason-ph": "Waarom u een andere account aanmaakt",
+       "createacct-reason-help": "Weergegeven bericht in het logbestand van aangemaakte gebruikers",
        "createacct-submit": "Account aanmaken",
        "createacct-another-submit": "Account aanmaken",
        "createacct-continue-submit": "Doorgaan met het maken van een account",
        "nocookiesnew": "De gebruiker is geregistreerd, maar niet aangemeld.\n{{SITENAME}} gebruikt cookies voor het aanmelden van gebruikers.\nSchakel die in en meld daarna aan met uw nieuwe gebruikersnaam en wachtwoord.",
        "nocookieslogin": "{{SITENAME}} gebruikt cookies voor het aanmelden van gebruikers.\nCookies zijn uitgeschakeld in uw browser.\nSchakel deze optie in en probeer het opnieuw.",
        "nocookiesfornew": "De gebruiker is niet gemaakt omdat de bron niet bevestigd kon worden.\nZorg ervoor dat u cookies hebt ingeschakeld, herlaad deze pagina en probeer het opnieuw.",
+       "createacct-loginerror": "De gebruiker is succesvol aangemaakt, maar u kon niet automatisch worden aangemeld. Ga naar [[Special:UserLogin|handmatig aanmelden]].",
        "noname": "U hebt geen geldige gebruikersnaam opgegeven.",
        "loginsuccesstitle": "Aangemeld",
        "loginsuccess": "<strong>U bent nu aangemeld bij {{SITENAME}} als \"$1\".</strong>",
        "eauthentsent": "Er is ter bevestiging een e-mail naar het opgegeven e-mailadres gezonden.\nVolg de aanwijzingen in de e-mail om aan te geven dat het uw e-mailadres is.\nTot die tijd worden er geen e-mails naar het e-mailadres gezonden.",
        "throttled-mailpassword": "In {{PLURAL:$1|het laatste uur|de laatste $1 uur}} is al een wachtwoordherinnering verzonden.\nOm misbruik te voorkomen wordt er slechts één wachtwoordherinnering per {{PLURAL:$1|uur|$1 uur}} verzonden.",
        "mailerror": "Fout bij het verzenden van e-mail: $1",
-       "acct_creation_throttle_hit": "Bezoekers van deze wiki met hetzelfde IP-adres als u hebben de afgelopen dag al $1 gebruiker{{PLURAL:$1||s}} geregistreerd, wat het maximale aantal in deze periode is.\nDaarom kunt u vanaf uw IP-adres op dit moment geen nieuwe gebruikers registreren.",
+       "acct_creation_throttle_hit": "Bezoekers van deze wiki met hetzelfde IP-adres als u hebben de afgelopen $2 al {{PLURAL:$1|1 gebruiker|$1 gebruikers}} geregistreerd, wat het maximale toegestane aantal is voor deze periode.\nDaarom kunt u vanaf uw IP-adres op dit moment geen nieuwe gebruikers registreren.",
        "emailauthenticated": "Uw e-mailadres is bevestigd op $2 om $3.",
        "emailnotauthenticated": "Uw e-mailadres is niet bevestigd.\nDe volgende functies verzenden nog geen e-mail.",
        "noemailprefs": "Geef een e-mailadres op in uw voorkeuren om deze functies te gebruiken.",
        "botpasswords-label-delete": "Verwijderen",
        "botpasswords-label-resetpassword": "Het wachtwoord opnieuw instellen",
        "botpasswords-label-grants": "Van toepassing zijnde rechten:",
-       "botpasswords-help-grants": "Iedere toestemming geeft toegang tot de opgegeven gebruikersrechten die de gebruiker al heeft. Zie [[Special:ListGrants|overzicht van rechten]] voor meer informatie.",
+       "botpasswords-help-grants": "Toestemmingen geven toegang tot gebruikersrechten die u al heeft. Het geven van een toestemming op deze plek geeft u geen toegang tot gebruikersrechten die u anders niet zou hebben. Zie het [[Special:ListGrants|overzicht van toestemmingen]] voor meer informatie.",
        "botpasswords-label-grants-column": "Toegewezen",
        "botpasswords-bad-appid": "De botnaam \"$1\" is niet geldig.",
        "botpasswords-insert-failed": "Toevoegen van botnaam \"$1\" mislukt. Is deze misschien al toegevoegd?",
        "botpasswords-updated-body": "Het botwachtwoord voor de bot \"$1\" van gebruiker \"$2\" is succesvol bijgewerkt.",
        "botpasswords-deleted-title": "Botwachtwoord verwijderd",
        "botpasswords-deleted-body": "Het botwachtwoord voor de bot \"$1\" van gebruiker \"$2\" is verwijderd.",
-       "botpasswords-newpassword": "Het nieuwe wachtwoord om aan te melden met <strong>$1</strong> is nu <strong>$2</strong>. <em>Bewaar dit goed voor toekomstig gebruik.</em>",
+       "botpasswords-newpassword": "Het nieuwe wachtwoord om aan te melden met <strong>$1</strong> is <strong>$2</strong>. <em>Bewaar dit goed voor toekomstig gebruik.</em> <br> (Voor oude robots die vereisen dat de loginnaam hetzelfde is als de eventuele gebruikersnaam, kan ook <strong>$3</strong> als gebruikersnaam en <strong>$4</strong> als wachtwoord worden gebruikt.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider is niet beschikbaar.",
        "botpasswords-restriction-failed": "Botwachtwoordbeperkingen maken het aanmelden onmogelijk.",
        "botpasswords-invalid-name": "De gebruikersnaam bevat niet het scheidingsteken van het botwachtwoord (\"$1\").",
        "passwordreset-emailelement": "Gebruikersnaam: \n$1\n\nTijdelijk wachtwoord: \n$2",
        "passwordreset-emailsentemail": "Als dit e-mailadres aan uw account gekoppeld is, dan wordt er een e-mail verzonden om uw wachtwoord opnieuw in te stellen.",
        "passwordreset-emailsentusername": "Als er een e-mailadres geregistreerd is voor die gebruikersnaam, dan wordt er een e-mail verzonden om uw wachtwoord opnieuw in te stellen.",
-       "passwordreset-invalideamil": "Ongeldig e-mailadres",
+       "passwordreset-emailsent-capture2": "De wachtwoordherstel-{{PLURAL:$1|e-mail is|e-mails zijn}} verzonden. {{PLURAL:$1|De gebruikersnaam en het wachtwoord worden|De lijst van gebruikersnamen en wachtwoorden wordt}} hier weergegeven.",
+       "passwordreset-emailerror-capture2": "Het e-mailen naar de {{GENDER:$2|gebruiker}} is mislukt: $1 {{PLURAL:$3|De gebruikersnaam en het wachtwoord|De lijst met gebruikersnamen en wachtwoorden}} wordt hieronder weergegeven.",
+       "passwordreset-nocaller": "Een aanroeper moet worden opgegeven",
+       "passwordreset-nosuchcaller": "Aanroeper bestaat niet: $1",
+       "passwordreset-ignored": "Opnieuw instellen van het wachtwoord niet is afgehandeld. Misschien is er geen provider geconfigureerd?",
+       "passwordreset-invalidemail": "Ongeldig e-mailadres",
        "passwordreset-nodata": "Er is geen gebruikersnaam of e-mailadres opgegeven",
        "changeemail": "E-mailadres wijzigen of verwijderen",
        "changeemail-header": "Vul dit formulier in om uw e-mailadres te wijzigen. Als u het e-mailadres wilt ontkoppelen van uw account, laat het e-mailadres dan leeg als u het formulier opslaat.",
        "invalid-content-data": "Ongeldige inhoudsgegevens",
        "content-not-allowed-here": "De inhoud \"$1\" is niet toegestaan op pagina [[$2]].",
        "editwarning-warning": "Als u deze pagina verlaat verliest u mogelijk wijzigingen die u hebt gemaakt.\nAls u bent aangemeld, kunt u deze waarschuwing uitschakelen in het tabblad \"{{int:prefs-editing}}\" in uw voorkeuren.",
+       "editpage-invalidcontentmodel-title": "Inhoudsmodel wordt niet ondersteund",
+       "editpage-invalidcontentmodel-text": "Het inhoudsmodel \"$1\" wordt niet ondersteund.",
        "editpage-notsupportedcontentformat-title": "Inhoudsformaat niet ondersteund",
        "editpage-notsupportedcontentformat-text": "Het inhoudstype $1 wordt niet ondersteund door het inhoudsmodel $2.",
        "content-model-wikitext": "wikitekst",
        "content-json-empty-object": "Leeg object",
        "content-json-empty-array": "Lege reeks",
        "deprecated-self-close-category": "Pagina's met ongeldige zelfsluitende HTML-tags",
+       "deprecated-self-close-category-desc": "De pagina bevat ongeldige zelf-afgesloten HTML-tags, zoals <code>&lt;b/&gt;</code> of <code>&lt;span/&gt;</code>. Het gedrag van deze tags zal binnenkort veranderd worden zodat dit overeenkomt met de HTML5-specificatie, dus het gebruik hiervan is verouderd en wordt afgeraden.",
        "duplicate-args-warning": "<strong>Waarschuwing:</strong> [[:$1]] roept [[:$2]] aan met meer dan één waarde voor de parameter \"$3\". Alleen de laatste waarde wordt gebruikt.",
        "duplicate-args-category": "Pagina's met dubbele sjabloonparameters",
        "duplicate-args-category-desc": "De pagina bevat aanroepen van sjablonen waarin hetzelfde argument meerdere keren wordt gebruikt, bijvoorbeeld <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> of <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "searchprofile-advanced-tooltip": "Zoeken in opgegeven naamruimten",
        "search-result-size": "$1 ({{PLURAL:$2|1 woord|$2 woorden}})",
        "search-result-category-size": "{{PLURAL:$1|1 categorielid|$1 categorieleden}} ({{PLURAL:$2|1 ondercategorie|$2 ondercategorieën}}, {{PLURAL:$3|1 bestand|$3 bestanden}})",
-       "search-redirect": "(doorverwijzing $1)",
+       "search-redirect": "(doorverwijzing vanaf $1)",
        "search-section": "(subkop $1)",
        "search-category": "(categorie $1)",
        "search-file-match": "(komt overeen met de inhoud van het bestand)",
        "prefs-help-email": "E-mailadres is optioneel, maar maakt het mogelijk om u uw wachtwoord te e-mailen als u het bent vergeten.",
        "prefs-help-email-others": "U kunt ook anderen in staat stellen per e-mail contact met u op te nemen via een koppeling op uw gebruikers- en overlegpagina zonder dat u uw identiteit prijsgeeft.",
        "prefs-help-email-required": "Hiervoor is een e-mailadres nodig.",
-       "prefs-info": "Basisinformatie",
+       "prefs-info": "Basisgegevens",
        "prefs-i18n": "Taalinstellingen",
        "prefs-signature": "Ondertekening",
        "prefs-dateformat": "Datumopmaak",
        "right-override-export-depth": "Pagina's exporteren inclusief pagina's waarnaar verwezen wordt tot een diepte van vijf",
        "right-sendemail": "E-mail versturen aan andere gebruikers",
        "right-passwordreset": "E-mails voor wachtwoord opnieuw instellen bekijken",
-       "right-managechangetags": "[[Special:Tags|Labels]] aan de database toevoegen of eruit verwijderen",
+       "right-managechangetags": "[[Special:Tags|Labels]] aanmaken en (de)activeren",
        "right-applychangetags": "[[Special:Tags|Labels]] aan bewerkingen toewijzen",
        "right-changetags": "Willekeurige [[Special:Tags|labels]] toevoegen aan en verwijderen van versies en logboekregels",
+       "right-deletechangetags": "[[Special:Tags|Labels]] uit de database verwijderen",
        "grant-generic": "Rechtengroep \"$1\"",
        "grant-group-page-interaction": "Werken met pagina's",
        "grant-group-file-interaction": "Werken met media",
        "grant-group-high-volume": "Activiteiten met hoog volume uitvoeren",
        "grant-group-customization": "Aanpassingen en voorkeuren",
        "grant-group-administration": "Beheerdershandelingen uitvoeren",
+       "grant-group-private-information": "Persoonlijke gegevens over u bekijken",
        "grant-group-other": "Diverse handelingen",
        "grant-blockusers": "Gebruikers (de)blokkeren",
        "grant-createaccount": "Accounts aanmaken",
        "grant-highvolume": "Veel bewerkingen in korte tijd maken",
        "grant-oversight": "Gebruikers en versies verbergen",
        "grant-patrol": "Wijzigingen aan pagina's controleren",
+       "grant-privateinfo": "Persoonlijke gegevens bekijken",
        "grant-protect": "Pagina's beveiligen en beveiliging opheffen",
        "grant-rollback": "Wijzigingen aan pagina's terugdraaien",
        "grant-sendemail": "E-mail verzenden aan andere gebruikers",
        "grant-basic": "Basisrechten",
        "grant-viewdeleted": "Verwijderde bestanden en pagina's bekijken",
        "grant-viewmywatchlist": "Eigen volglijst bekijken",
+       "grant-viewrestrictedlogs": "Vertrouwelijke logboekbestanden bekijken",
        "newuserlogpage": "Logboek nieuwe gebruikers",
        "newuserlogpagetext": "Hieronder staan de nieuw ingeschreven gebruikers",
        "rightslog": "Gebruikersrechtenlogboek",
        "file-thumbnail-no": "De bestandsnaam begint met <strong>$1</strong>.\nHet lijkt een verkleinde afbeelding te zijn ''(miniatuurafbeelding)''.\nAls u deze afbeelding in volledige resolutie hebt, upload die afbeelding dan.\nWijzig anders de bestandsnaam.",
        "fileexists-forbidden": "Er bestaat al een bestand met deze naam, en dat kan niet overschreven worden.\nUpload uw bestand onder een andere naam.\n[[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Er bestaat al een bestand met deze naam bij de gedeelde bestanden.\nAls u het bestand alsnog wilt uploaden, ga dan terug en kies een andere naam.\n[[File:$1|thumb|center|$1]]",
+       "fileexists-no-change": "De upload is een exacte kopie van de huidige versie van <strong>[[:$1]]</strong>.",
+       "fileexists-duplicate-version": "De upload is een exacte kopie van {{PLURAL:$2|een oudere versie|oudere versies}} van <strong>[[:$1]]</strong>.",
        "file-exists-duplicate": "Dit bestand is identiek aan {{PLURAL:$1|het volgende bestand|de volgende bestanden}}:",
        "file-deleted-duplicate": "Een bestand dat identiek is aan dit bestand ([[:$1]]) is voorheen verwijderd.\nRaadpleeg het verwijderingslogboek voordat u verder gaat.",
        "file-deleted-duplicate-notitle": "Er is een verwijderd bestand aangetroffen dat identiek is aan dit bestand, en de naam van het bestand is onderdrukt.\nVraag iemand die onderdrukte bestandsgegevens kan bekijken om de situatie opnieuw te beoordelen voordat u het bestand opnieuw toevoegt.",
        "upload-http-error": "Er is een HTTP-fout opgetreden: $1",
        "upload-copy-upload-invalid-domain": "Uploaden per kopie is niet beschikbaar vanuit dit domein.",
        "upload-foreign-cant-upload": "Deze wiki is niet geconfigureerd om bestanden te uploaden naar de bestandsrepository op een andere site.",
+       "upload-foreign-cant-load-config": "Het laden van de configuratie voor bestanduploads naar de externe opslagplaats is mislukt.",
+       "upload-dialog-disabled": "Het uploaden van bestanden met behulp van dit dialoogvenster is uitgeschakeld op deze wiki.",
        "upload-dialog-title": "Bestand uploaden",
        "upload-dialog-button-cancel": "Annuleren",
+       "upload-dialog-button-back": "Terug",
        "upload-dialog-button-done": "Afgerond",
        "upload-dialog-button-save": "Opslaan",
        "upload-dialog-button-upload": "Uploaden",
        "backend-fail-read": "Het was niet mogelijk het bestand $1 te lezen.",
        "backend-fail-create": "Het was niet mogelijk naar het bestand $1 te schrijven.",
        "backend-fail-maxsize": "Het was niet mogelijk naar het bestand $1 te schrijven omdat het groter is dan {{PLURAL:$2|één byte|$2 bytes}}.",
-       "backend-fail-readonly": "Het opslagbackend \"$1\" kan op dit moment alleen gelezen worden. De opgegeven reden was: \"$2\"",
+       "backend-fail-readonly": "Het opslagbackend \"$1\" kan op dit moment alleen gelezen worden. De opgegeven reden is: <em>$2</em>",
        "backend-fail-synced": "Het bestand \"$1\" bevindt zich in een inconsistente toestand in de interne opslagbackends.",
        "backend-fail-connect": "Het was niet mogelijk een verbinding te maken met het opslagbackend \"$1\".",
        "backend-fail-internal": "Er is een onbekende fout opgetreden in het opslagbackend \"$1\".",
        "uploadstash-summary": "Deze pagina biedt toegang tot bestanden die geüpload zijn of nog geüpload worden maar nog niet beschikbaar gemaakt zijn in de wiki. Deze bestanden zijn alleen zichtbaar voor de gebruiker die ze uploadt.",
        "uploadstash-clear": "Verborgen bestanden weggooien",
        "uploadstash-nofiles": "Er zijn geen verborgen bestanden.",
-       "uploadstash-badtoken": "Het uitvoeren van de handeling is mislukt. Dit komt mogelijk doordat uw bewerkingsreferenties zijn verlopen. Probeer het opnieuw.",
+       "uploadstash-badtoken": "Het uitvoeren van de handeling is mislukt, mogelijk doordat uw bewerkingsreferenties zijn verlopen. Probeer het opnieuw.",
        "uploadstash-errclear": "Het wissen van de bestanden is mislukt.",
        "uploadstash-refresh": "Lijst met bestanden bijwerken",
        "uploadstash-thumbnail": "miniatuurafbeelding weergeven",
+       "uploadstash-exception": "Kon de upload niet opslaan in de opslagplaats ($1): \"$2\".",
        "invalid-chunk-offset": "Ongeldige chunkoffset",
        "img-auth-accessdenied": "Toegang geweigerd",
        "img-auth-nopathinfo": "PATH_INFO ontbreekt.\nUw server is niet ingesteld om deze gegevens door te geven.\nMisschien gebruikt deze CGI, en dan wordt img_auth niet ondersteund.\nZie https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization voor meer informatie.",
        "filerevert-submit": "Terugdraaien",
        "filerevert-success": "'''[[Media:$1|$1]]''' is teruggedraaid tot de [$4 versie op $2, $3].",
        "filerevert-badversion": "Er is geen vorige lokale versie van dit bestand met het opgegeven tijdstip.",
+       "filerevert-identical": "De huidige versie van het bestand is al identiek aan de geselecteerde.",
        "filedelete": "\"$1\" verwijderen",
        "filedelete-legend": "Bestand verwijderen",
        "filedelete-intro": "U staat op het punt om het bestand '''[[Media:$1|$1]]''' te verwijderen, inclusief alle eerdere versies.",
        "apisandbox-results-fixtoken-fail": "Het ophalen van het token van type \"$1\" is mislukt.",
        "apisandbox-alert-page": "Velden op deze pagina zijn niet geldig.",
        "apisandbox-alert-field": "De waarde van dit veld is niet geldig.",
+       "apisandbox-continue": "Doorgaan",
+       "apisandbox-continue-clear": "Wissen",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} zal [https://www.mediawiki.org/wiki/API:Query#Continuing_queries doorgaan] met het laatste verzoek; {{int:apisandbox-continue-clear}} zal de voortgangsparameters wissen.",
+       "apisandbox-param-limit": "Voer <kbd>max</kbd> in om de maximale limiet te gebruiken.",
        "booksources": "Boekinformatie",
        "booksources-search-legend": "Bronnen en gegevens over een boek zoeken",
        "booksources-search": "Zoeken",
        "booksources-text": "Hieronder staat een lijst met koppelingen naar andere websites die nieuwe of gebruikte boeken verkopen, en die wellicht meer informatie over het boek dat u zoekt hebben:",
        "booksources-invalid-isbn": "Het opgegeven ISBN lijkt niet geldig te zijn.\nControleer of u wellicht een fout hebt gemaakt bij de invoer.",
+       "magiclink-tracking-rfc": "Pagina's die RFC magische koppelingen gebruiken",
+       "magiclink-tracking-rfc-desc": "Deze pagina gebruikt RFC magische koppelingen. Zie [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] over hoe te migreren.",
+       "magiclink-tracking-pmid": "Pagina's die PMID magische koppelingen gebruiken",
+       "magiclink-tracking-pmid-desc": "Deze pagina gebruikt PMID magische koppelingen. Zie [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] over hoe te migreren.",
+       "magiclink-tracking-isbn": "Pagina's die ISBN magische koppelingen gebruiken",
+       "magiclink-tracking-isbn-desc": "Deze pagina gebruikt ISBN magische koppelingen. Zie [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] over hoe te migreren.",
        "specialloguserlabel": "Uitvoerende gebruiker:",
        "speciallogtitlelabel": "Doel (paginanaam of {{ns:user}}:gebruikersnaam voor gebruiker):",
        "log": "Logboeken",
        "activeusers-intro": "Dit is een lijst met gebruikers die enige activiteit hebben laten zien in de afgelopen {{PLURAL:$1|dag|$1 dagen}}.",
        "activeusers-count": "$1 recente {{PLURAL:$1|handeling|handelingen}} in de {{PLURAL:$3|afgelopen dag|laatste $3 dagen}}",
        "activeusers-from": "Gebruikers worden weergegeven vanaf:",
-       "activeusers-hidebots": "Bots verbergen",
-       "activeusers-hidesysops": "Beheerders verbergen",
+       "activeusers-groups": "Gebruikers weergeven die horen bij de groepen:",
        "activeusers-noresult": "Geen actieve gebruikers gevonden.",
        "activeusers-submit": "Weergeven",
        "listgrouprights": "Rechten van gebruikersgroepen",
        "trackingcategories-msg": "Volgcategorie",
        "trackingcategories-name": "Berichtnaam",
        "trackingcategories-desc": "Opnamecriteria",
+       "restricted-displaytitle-ignored": "Pagina's met genegeerde weergavetitels",
+       "restricted-displaytitle-ignored-desc": "Deze pagina heeft een genegeerde <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> omdat het niet overeenkomstig is met de pagina's werkelijke titel.",
        "noindex-category-desc": "De pagina bevat het magische woord <code><nowiki>__NOINDEX__</nowiki></code> (en bevindt zich in een naamruimte waarin dat magische woord is toegestaan), en wordt niet geïndexeerd door robots.",
        "index-category-desc": "De pagina bevat het magische woord <code><nowiki>__INDEX__</nowiki></code> (en bevindt zich in een naamruimte waarin dat magische woord is toegestaan), en wordt geïndexeerd door robots, terwijl dat normaliter niet zou gebeuren.",
        "post-expand-template-inclusion-category-desc": "De pagina groter dan <code>$wgMaxArticleSize</code> na het uitbreiden van alle sjablonen, dus zijn sommige sjablonen niet uitgebreid.",
        "watchnologin": "U bent niet aangemeld",
        "addwatch": "Toevoegen aan volglijst",
        "addedwatchtext": "\"[[:$1]]\" en de bijhorende overlegpagina zijn toegevoegd aan uw [[Special:Watchlist|volglijst]].",
+       "addedwatchtext-talk": "\"[[:$1]]\" en de gerelateerde pagina zijn toegevoegd aan je [[Special:Watchlist|volglijst]].",
        "addedwatchtext-short": "De pagina \"$1\" is aan uw volglijst toegevoegd.",
        "removewatch": "Verwijderen uit volglijst",
        "removedwatchtext": "\"[[:$1]]\" en de bijhorende overlegpagina zijn verwijderd van uw [[Special:Watchlist|volglijst]].",
        "rollbacklinkcount": "{{PLURAL:$1|één bewerking|$1 bewerkingen}} terugdraaien",
        "rollbacklinkcount-morethan": "Meer dan {{PLURAL:$1|één bewerking|$1 bewerkingen}} terugdraaien",
        "rollbackfailed": "Ongedaan maken van wijzigingen mislukt.",
+       "rollback-missingparam": "Er ontbreken benodigde parameters in het verzoek.",
+       "rollback-missingrevision": "Laden van versiegegevens mislukt.",
        "cantrollback": "Ongedaan maken van wijzigingen onmogelijk: deze pagina heeft slechts 1 auteur.",
        "alreadyrolled": "Het is niet mogelijk om de bewerking van de pagina [[:$1]] door [[User:$2|$2]] ([[User talk:$2|overleg]]{{int:pipe-separator}}[[Special:Contributions/$2|bijdragen]]) ongedaan te maken.\nIemand anders heeft deze pagina al bewerkt of hersteld naar een eerdere versie.\n\nDe meest recente bewerking is gemaakt door [[User:$3|$3]] ([[User talk:$3|overleg]]{{int:pipe-separator}}[[Special:Contributions/$3|bijdragen]]).",
        "editcomment": "De bewerkingssamenvatting was: <em>$1</em>.",
        "revertpage": "Wijzigingen door [[Special:Contributions/$2|$2]] ([[User talk:$2|Overleg]]) hersteld tot de laatste versie door [[User:$1|$1]]",
        "revertpage-nouser": "Wijzigingen door een verborgen gebruiker teruggedraaid naar de laatste versie door {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "De wijzigingen door $1 zijn teruggedraaid.\nDe laatste versie van $2 is hersteld.",
+       "rollback-success-notify": "De wijzigingen door $1 zijn teruggedraaid;\nde laatste versie van $2 is hersteld. [$3 Wijzigingen weergeven]",
        "sessionfailure-title": "Sessiefout",
        "sessionfailure": "Er lijkt een probleem te zijn met uw aanmeldsessie.\nUw handeling is gestopt uit voorzorg tegen een beveiligingsrisico (dat bestaat uit mogelijke \"hijacking\" van deze sessie).\nGa een pagina terug, laad die pagina opnieuw en probeer het nog eens.",
        "changecontentmodel": "Inhoudsmodel van pagina bewerken",
        "changecontentmodel-success-text": "Het inhoudstype van [[:$1]] is gewijzigd.",
        "changecontentmodel-cannot-convert": "De inhoud van [[:$1]] kan niet worden omgezet in een type van $2.",
        "changecontentmodel-nodirectediting": "Het inhoudsmodel $1 ondersteunt direct bewerken niet",
+       "changecontentmodel-emptymodels-title": "Geen inhoudsmodellen beschikbaar",
+       "changecontentmodel-emptymodels-text": "De inhoud van [[:$1]] kan niet worden omgezet in een ander type.",
        "log-name-contentmodel": "Wijzigingenlogboek van inhoudsmodel",
        "log-description-contentmodel": "Gebeurtenissen rond het inhoudsmodel van een pagina",
+       "logentry-contentmodel-new": "$1 {{GENDER:$2|maakte}} de pagina $3 aan met behulp van een niet-standaard inhoudsmodel \"$5\"",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|heeft}} het inhoudsmodel gewijzigd van pagina $3 van \"$4\" in \"$5\"",
        "logentry-contentmodel-change-revertlink": "terugdraaien",
        "logentry-contentmodel-change-revert": "terugdraaien",
        "sp-contributions-newbies-sub": "Voor nieuwelingen",
        "sp-contributions-newbies-title": "Bijdragen van nieuwe gebruikers",
        "sp-contributions-blocklog": "blokkeerlogboek",
-       "sp-contributions-suppresslog": "onderdrukte gebruikersbijdragen",
-       "sp-contributions-deleted": "verwijderde bijdragen",
+       "sp-contributions-suppresslog": "onderdrukte {{GENDER:$1|gebruikersbijdragen}}",
+       "sp-contributions-deleted": "verwijderde {{GENDER:$1|gebruiker}}sbijdragen",
        "sp-contributions-uploads": "uploads",
        "sp-contributions-logs": "logboeken",
        "sp-contributions-talk": "overleg",
        "whatlinkshere-hideredirs": "doorverwijzingen $1",
        "whatlinkshere-hidetrans": "Transclusies $1",
        "whatlinkshere-hidelinks": "koppelingen $1",
-       "whatlinkshere-hideimages": "Bestandskoppelingen $1",
+       "whatlinkshere-hideimages": "$1 bestandskoppelingen",
        "whatlinkshere-filters": "Filters",
        "whatlinkshere-submit": "OK",
        "autoblockid": "Automatische blokkade #$1",
        "patrol-log-header": "Dit logboek bevat versies die gemarkeerd zijn als gecontroleerd.",
        "log-show-hide-patrol": "markeerlogboek $1",
        "log-show-hide-tag": "labellogboek $1",
+       "confirm-markpatrolled-button": "OK",
        "deletedrevision": "De oude versie $1 is verwijderd",
        "filedeleteerror-short": "Fout bij het verwijderen van bestand: $1",
        "filedeleteerror-long": "Er zijn fouten opgetreden bij het verwijderen van het bestand:\n\n$1",
        "watchlistedit-raw-done": "Uw volglijst is bijgewerkt.",
        "watchlistedit-raw-added": "Er {{PLURAL:$1|is 1 pagina|zijn $1 pagina's}} toegevoegd:",
        "watchlistedit-raw-removed": "Er {{PLURAL:$1|is 1 pagina|zijn $1 pagina's}} verwijderd:",
-       "watchlistedit-clear-title": "Volglijst gewist",
+       "watchlistedit-clear-title": "Volglijst wissen",
        "watchlistedit-clear-legend": "Volglijst wissen",
        "watchlistedit-clear-explain": "Alle pagina's worden van uw volglijst verwijderd",
        "watchlistedit-clear-titles": "Pagina's:",
        "tags-actions-header": "Acties",
        "tags-active-yes": "Ja",
        "tags-active-no": "Nee",
-       "tags-source-extension": "Door een uitbreiding toegevoegd",
+       "tags-source-extension": "Gedefinieerd door de software",
        "tags-source-manual": "Handmatig toegevoegd door gebruikers en bots",
        "tags-source-none": "Niet meer in gebruik",
        "tags-edit": "bewerken",
        "tags-deactivate": "deactiveren",
        "tags-hitcount": "$1 {{PLURAL:$1|wijziging|wijzigingen}}",
        "tags-manage-no-permission": "U hebt geen rechten om labels te beheren.",
-       "tags-manage-blocked": "U kunt geen labels beheren wanneer u geblokkeerd bent.",
+       "tags-manage-blocked": "U kunt geen labels beheren wanneer {{GENDER:$1|u}} geblokkeerd bent.",
        "tags-create-heading": "Een nieuw label aanmaken",
        "tags-create-explanation": "Standaard worden nieuw aangemaakte labels beschikbaar gesteld voor gebruik door gebruikers en bots.",
        "tags-create-tag-name": "Labelnaam:",
        "tags-deactivate-not-allowed": "Het is niet mogelijk het label \"$1\" te deactiveren.",
        "tags-deactivate-submit": "Deactiveren",
        "tags-apply-no-permission": "U hebt geen rechten om wijzigingslabels toe te voegen aan uw wijzigingen.",
-       "tags-apply-blocked": "U kunt geen wijzigen aanbrengen aan labels wanneer u geblokkeerd bent.",
+       "tags-apply-blocked": "U kunt geen labels toevoegen aan uw wijzigingen wanneer {{GENDER:$1|u}} geblokkeerd bent.",
        "tags-apply-not-allowed-one": "Het label \"$1\" mag niet handmatig toegevoegd worden.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|Het volgende label mag|De volgende labels mogen}} niet handmatig toegevoegd worden: $1",
        "tags-update-no-permission": "U hebt geen rechten om wijzigingslabels toe te voegen aan of te verwijderen van versies of logboekregels.",
-       "tags-update-blocked": "U kunt geen labels toevoegen of verwijderen wanneer u geblokkeerd bent.",
+       "tags-update-blocked": "U kunt geen labels toevoegen of verwijderen wanneer {{GENDER:$1|u}} geblokkeerd bent.",
        "tags-update-add-not-allowed-one": "Het label \"$1\" mag niet handmatig toegevoegd worden.",
        "tags-update-add-not-allowed-multi": " {{PLURAL:$2|Het label kan|De labels kunnen}} niet handmatig toegevoegd worden: $1",
        "tags-update-remove-not-allowed-one": "Het label \"$1\" mag niet verwijderd worden.",
        "htmlform-cloner-create": "Meer toevoegen",
        "htmlform-cloner-delete": "Verwijderen",
        "htmlform-cloner-required": "Ten minste één waarde is vereist.",
+       "htmlform-date-placeholder": "JJJJ-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "JJJJ-MM-DD HH:MM:SS",
        "htmlform-title-badnamespace": "[[:$1]] bevindt zich niet in de naamruimte \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" is geen paginanaam die aangemaakt kan worden",
        "htmlform-title-not-exists": "$1 bestaat niet.",
        "feedback-external-bug-report-button": "Een technische taak indienen",
        "feedback-dialog-title": "Terugkoppeling verzenden",
        "feedback-dialog-intro": "U kunt het eenvoudige formulier gebruiken om uw terugkoppeling in te sturen. Uw reactie wordt toegevoegd aan de pagina \"$1\" samen met uw gebruikersnaam.",
-       "feedback-error-title": "Fout",
        "feedback-error1": "Fout: onbekend resultaat uit de API",
        "feedback-error2": "Fout: de bewerking is mislukt",
        "feedback-error3": "Fout: geen reactie van de API",
        "feedback-thanks": "Bedankt! Uw terugkoppeling is op de pagina \"[$2 $1]\" geplaatst.",
        "feedback-thanks-title": "Bedankt!",
        "feedback-useragent": "Useragent:",
-       "searchsuggest-search": "Zoeken",
+       "searchsuggest-search": "Zoeken in {{SITENAME}}",
        "searchsuggest-containing": "bevat...",
        "api-error-badaccess-groups": "U mag geen bestanden uploaden in deze wiki.",
        "api-error-badtoken": "Interne fout: het token klopt niet.",
+       "api-error-blocked": "U bent geblokkeerd en kunt niet bewerken.",
        "api-error-copyuploaddisabled": "Uploaden via URL is uitgeschakeld op deze server.",
        "api-error-duplicate": "Er {{PLURAL:$1|staat al een bestand|staan al bestanden}} met dezelfde inhoud in de wiki.",
        "api-error-duplicate-archive": "Er {{PLURAL:$1|was al een ander bestand|waren al $1 andere bestanden}}  op de site met dezelfde inhoud, maar {{PLURAL:$1|dat is|die zijn}} verwijderd.",
        "api-error-nomodule": "Interne fout: er is geen uploadmodule ingesteld.",
        "api-error-ok-but-empty": "Interne fout: de server heeft geen gegevens teruggeleverd.",
        "api-error-overwrite": "Het overschrijven van een bestand bestand is niet toegestaan.",
+       "api-error-ratelimited": "U probeert meer bestanden te uploaden in een korte periode dan deze wiki toelaat.\nProbeer het over een aantal minuten opnieuw.",
        "api-error-stashfailed": "Interne fout: de server kon het tijdelijke bestand niet opslaan.",
        "api-error-publishfailed": "Interne fout: de server kon het tijdelijke bestand niet publiceren.",
        "api-error-stasherror": "Er is een fout opgetreden tijdens het uploaden van het bestand naar de tijdelijke opslagruimte.",
index f9dc952..66b151e 100644 (file)
        "talk": "Diskusjon",
        "views": "Visningar",
        "toolbox": "Verktøy",
+       "tool-link-userrights": "Endra {{GENDER:$1|brukargrupper}}",
+       "tool-link-emailuser": "Send e-post til {{GENDER:$1|brukaren}}",
        "userpage": "Vis brukarside",
        "projectpage": "Sjå prosjektsida",
        "imagepage": "Vis filside",
        "newarticle": "(Ny)",
        "newarticletext": "Du har følgt ei lenkje til ei side som ikkje finst enno.\nFor å opprette sida, kan du skrive i boksen under (sjå [$1 hjelpesida] for meir informasjon).\nHamna du her ved ein feil, klikk på '''attende'''-knappen i nettlesaren din.",
        "anontalkpagetext": "----''Dette er ei diskusjonsside for ein anonym brukar som ikkje har oppretta konto eller ikkje har logga inn.\nVi er difor nøydde til å bruke den numeriske IP-adressa til å identifisere brukaren. Same IP-adresse kan vere knytt til fleire brukarar. Om du er ein anonym brukar og meiner at du har fått irrelevante kommentarar på ei slik side, [[Special:CreateAccount|opprett ein brukarkonto]] eller [[Special:UserLogin|logg inn]] slik at vi unngår framtidige forvekslingar med andre anonyme brukarar.''",
-       "noarticletext": "Det er nett no ikkje noko tekst på denne sida.\nDu kan [[Special:Search/{{PAGENAME}}|søkja etter sidetittelen]] i andre sider, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} søkja i dei relaterte loggane]\neller [{{fullurl:{{FULLPAGENAME}}|action=edit}} endra denne sida]</span>.",
+       "noarticletext": "Det er nett no ikkje noko tekst på denne sida.\nDu kan [[Special:Search/{{PAGENAME}}|søkja etter sidetittelen]] i andre sider, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} søkja i dei relaterte loggane]\neller [{{fullurl:{{FULLPAGENAME}}|action=edit}} opprette denne sida]</span>.",
        "noarticletext-nopermission": "Der er nett no ikkje noko tekst på denne sida.\nDu kan [[Special:Search/{{PAGENAME}}|søkja etter sidetittelen]] i andre sider\neller <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} søkja i dei relaterte loggane]</span>, men du har ikkje løyve til å oppretta denne sida.",
        "missing-revision": "Versjonen #$1 av sida med namnet «{{FULLPAGENAME}}» finst ikkje.\n\nDette skriv seg som oftast frå at ei forelda historikklenkje vart fylgd til ei side som er sletta.\nDetaljar kan ein finna i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} sletteloggen].",
        "userpage-userdoesnotexist": "Brukarkontoen «<nowiki>$1</nowiki>» finst ikkje. Vil du verkeleg opprette/endre denne sida?",
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
        "content-json-empty-object": "Tomt objekt",
+       "duplicate-args-warning": "<strong>Åtvaring:</strong> [[:$1]] kallar [[:$2]] med meir enn éin verdi for argumentet «$3». Berre den sist oppgjevne verdien vert nytta.",
        "expensive-parserfunction-warning": "Åtvaring: Denne sida inneheld for mange prosesskrevande parserfunksjonar.\n\nDet burde vere færre enn {{PLURAL:$2|$2|$2}}, men er no {{PLURAL:$1|$1|$1}}.",
        "expensive-parserfunction-category": "Sider med for mange prosesskrevande parserfunksjonar",
        "post-expand-template-inclusion-warning": "Åtvaring: Storleiken på malar som er inkluderte er for stor.\nNokre malar vert ikkje inkluderte.",
        "searchprofile-advanced-tooltip": "Søk i visse namnerom",
        "search-result-size": "$1 ({{PLURAL:$2|eitt|$2}} ord)",
        "search-result-category-size": "{{PLURAL:$1|1 medlem|$1 medlemmer}} ({{PLURAL:$2|1 underkategori|$2 underkategoriar}}, {{PLURAL:$3|1 fil|$3 filer}})",
-       "search-redirect": "(omdirigering $1)",
+       "search-redirect": "(omdirigering frå $1)",
        "search-section": "(bolken $1)",
        "search-category": "(kategorien $1)",
        "search-suggest": "Meinte du: «$1»",
        "activeusers-intro": "Dette er ei liste over brukarar som har hatt ei eller anna form for aktivitet innanfor {{PLURAL:$1|den siste dagen|dei siste dagane}}.",
        "activeusers-count": "{{PLURAL:$1|Éi handling|$1 handlingar}} {{PLURAL:$3|det siste døgeret|dei siste $3 døgra}}",
        "activeusers-from": "Vis brukarar frå og med:",
-       "activeusers-hidebots": "Gøym robotar",
-       "activeusers-hidesysops": "Gøym administratorar",
        "activeusers-noresult": "Ingen brukarar funne.",
        "listgrouprights": "Rettar for brukargrupper",
        "listgrouprights-summary": "Detter ei liste som viser brukargruppene som er definerte på wikien, og kva rettar dei har. Det kan finnast [[{{MediaWiki:Listgrouprights-helppage}}|meir informasjon]]  om dei ulike rettane.",
        "days": "{{PLURAL:$1|$1 dag|$1 dagar}}",
        "weeks": "{{PLURAL:$1|$1 veke|$1 veker}}",
        "months": "{{PLURAL:$1|éin månad|$1 månader}}",
-       "years": "{{PLURAL:$1|éitt år|$1 år}}",
+       "years": "{{PLURAL:$1|eitt år|$1 år}}",
        "ago": "$1 sidan",
        "just-now": "akkurat no",
        "hours-ago": "$1 {{PLURAL:$1|time|timar}} sidan",
        "feedback-subject": "Emne:",
        "feedback-submit": "Send",
        "feedback-thanks": "Takk! Attendemeldinga di er lagd inn på sida «[$2 $1]».",
-       "searchsuggest-search": "Søk",
+       "searchsuggest-search": "Søk i {{SITENAME}}",
        "searchsuggest-containing": "som inneheld …",
        "api-error-badaccess-groups": "Du har ikkje løyve til å lasta opp filer til wikien.",
        "api-error-badtoken": "Intern feil: ugild token.",
index 79c3ea9..b3facd6 100644 (file)
        "oct": "Diphalane",
        "nov": "Dibatsela",
        "dec": "Manthole",
+       "january-date": "$1 Pherekgong",
+       "february-date": "$1 Dibokwane",
+       "march-date": "$1 Hlakola",
+       "april-date": "$1 Moranang",
+       "may-date": "$1 Mopitlo",
+       "june-date": "$1 Phupu",
+       "july-date": "$1 Mosegamanye",
+       "august-date": "$1 Phato",
+       "september-date": "$1 Lewedi",
+       "october-date": "$1 Diphalane",
+       "november-date": "$1 Dibatsela",
+       "december-date": "$1 Mathole",
        "pagecategories": "{{PLURAL:$1|Sehlopha|Dihlopha}}",
        "category_header": "Matlakala go sehlopha \"$1\"",
        "subcategories": "Dihlophana",
        "moredotdotdot": "Tše dingwe...",
        "mypage": "Letlakala",
        "mytalk": "Bolela",
-       "anontalk": "Poledišano ya IP ye",
+       "anontalk": "Poledišano",
        "navigation": "Tšwelotšo",
        "and": "&#32;le",
        "qbfind": "Humana",
+       "qbbrowse": "Leba",
        "qbedit": "Fetola",
        "qbpageoptions": "Letlakala le",
        "qbmyoptions": "Matlakala a ka",
        "updatedmarker": "fetotšwe esale ketelo yaka ya mafelelo",
        "printableversion": "''Version'' ya go gatišega",
        "permalink": "Hlomaganyo yao e tiišeditšwego",
+       "view": "Leba",
+       "view-foreign": "Leba go $1",
        "edit": "Fetola",
        "create": "Tlhoma",
        "editthispage": "Fetola letlakala  le",
        "disclaimers": "Hlapa-matsogo",
        "disclaimerpage": "Project:Hlapa-Matsogo",
        "edithelp": "Thušo ya go fetola",
+       "helppage-top-gethelp": "Thušo",
        "mainpage": "Letlakala la Pele",
        "mainpage-description": "Letlakala la Pele",
        "policy-url": "Project:Melao",
-       "portal": "''Portal'' ya badudi",
-       "portal-url": "Project:Portal ya Badudi",
+       "portal": "Sebaka sa badudi",
+       "portal-url": "Project:Sebaka sa Badudi",
        "privacy": "Melao ya praebesi",
        "privacypage": "Project:Polisi ya praefesi",
        "badaccess": "Thušo ya tumello",
        "toc": "Mateng",
        "showtoc": "bontšha",
        "hidetoc": "fihla",
+       "confirmable-yes": "Ee",
+       "confirmable-no": "Aowa",
        "thisisdeleted": "Nyakorela goba hlaphola $1?",
        "viewdeleted": "Nyakorela $1?",
        "restorelink": "{{PLURAL:$1|e tee phetogo ye phumutšwego|phetogo tše $1 tše phumutšwego}}",
        "protectedpagetext": "Letlakala le le notletšwe go thibela diphetogo.",
        "viewsourcetext": "O ka lebelela goba wa kôpiša mothapo wa letlakala le:",
        "namespaceprotected": "Ga ona tokelo ya go fetola matlakala  go  '''$1''' .",
+       "exception-nologin": "Ga wa tsena",
        "yourname": "Leina la mošomiši:",
+       "userlogin-yourname": "Leina la mošomši",
        "yourpassword": "Ditlhaka-tša-siphiri:",
        "yourpasswordagain": "Tlanya ditlhaka-tša-siphiri gape:",
-       "remembermypassword": "Gopola sedi yaka ya go tsena khomphutha ye (bogolo bja  $1 ya {{PLURAL:$1| letšatši le|matšatši a}})",
        "login": "Tsena",
        "nav-login-createaccount": "Tsena / Tlhola tšhupaleloko (''account'')",
        "userlogin": "Tsena / tlhola tšhupaleloko (''account'')",
+       "userloginnocreate": "Tsena",
        "logout": "Etšwa/Tswalela",
        "userlogout": "Etšwa/Tswalela",
        "notloggedin": "Ga wa tsena",
        "createaccountreason": "Lebaka:",
        "badretype": "Ditlhaka-tša-siphiri tše o di šomišitšego ga di swane.",
        "noname": "Gawa fana ka leina la mošomiši la go loka.",
-       "loginsuccesstitle": "O tsene ka katlego",
+       "loginsuccesstitle": "O tsene",
        "loginsuccess": "'''Bjale o tsene go {{SITENAME}} bjalo ka \"$1\".'''",
-       "nosuchuser": "Ga gona mošomiši wa leina la \"$1\".\nMaina a huduetša ke ditlhaka.\nLebele mopeleto wa gago goba [[Special:CreateAccount|o tlhome mošomiši yo mophsa]].",
+       "nosuchuser": "Ga gona mošomiši wa leina la \"$1\".\nMaina a huduetša ke seemo sa ditlhaka (case sensitive).\nLebele mopeleto wa gago goba [[Special:CreateAccount|o tlhome mošomiši yo mophsa]].",
        "nosuchusershort": "Ga gona mošomiši wa leina la \"$1\". Hlokomela mopeleto wa gago.",
        "nouserspecified": "O swanela ke go fana ka leina la mošomiši.",
        "wrongpassword": "O loketše ditlhaka-tša-siphiri tšeo e sego tšona. Ka kgopelo, leka gape.",
        "passwordremindertext": "Motho yo mongwe (goba wena, gotšwa IP atrese $1) o\nkgopetše gore re moromele Ditlhaka-tša-siphiri tše mfsa tša {{SITENAME}} ($4).\n\nDitlhaka-tša-siphiri tša  mošomiši \"$2\" go tloga bjale ke  \"$3\".\n\nDitlhaka-tša-siphiri di tla šoma {{PLURAL:$5|letšatši|matšatši a $5}}.\n\nGa eba motho yo mongwe esego wena o dirile kgopelo ye, goba o gopola Ditlhaka-tša-siphiri gomme ga o sa\nhloka gore e fetolwe, hlokomologa molaetša wo, o tšwele pele o šumiše Ditlhaka-tša-siphiri tša kgale.",
        "noemail": "Ga gona e-mail atrese ya mošomiši \"$1\".",
        "passwordsent": "\nDihlaka tša siphiri (''password'') tše mphsa di rometšwe go e-mail atrese ya \"$1\".\nRe kgopela gore o tsene ge fetša go e hwetša.",
-       "blocked-mailpassword": "IP atrese ya gago e thibetšwe go dira diphetogo, ka fao ga wa dumellwa\ngo šomiša thulusu ya go hwetša Ditlhaka-tša-siphiri go thibela go hlapanya.",
+       "blocked-mailpassword": "IP atrese ya gago e thibetšwe go dira diphetogo.\nGo thibela go hlapanya, ga wa dumellwa\ngo šomiša thulusu ya go hwetša Ditlhaka-tša-siphiri ka aterese ye.",
        "eauthentsent": "Molaetša wa go tiišetša o  rometšwe go e-mail atrese.\n\nPele re romela melaetša ye mengwe go atrese ye, o kgopelwa go latela ditaelo tšeo dilego molaetšeng go tiišetša gore atrese ke ya gago.",
        "throttled-mailpassword": "Kgopelo ya go fetola ditlhaka-tša-siphiri e rometšwe {{PLURAL:$1|iring|diiring tše $1}} tša gofeta.\nGo thibela go hlapanya/kgobošo, kgopotšo e tee ka {{PLURAL:$1|iri|diiri tše $1}} e tla romellwa.",
        "mailerror": "Gobile le phošo go romeleng molaetša  : $1",
-       "acct_creation_throttle_hit": "Ka maswabi, IP Aterese ya gago e tlhomile {{PLURAL:$1|tšhupaleloko|$1 tša ditšhupaleloko}} e se kgale.\nGa wa dumelwa go tlhoma tše dingwe ka se sebaka.",
+       "acct_creation_throttle_hit": "Ka maswabi, IP Aterese ya gago e tlhomile {{PLURAL:$1|tšhupaleloko|$1 tša ditšhupaleloko}} sebakeng sa $2.\nGa wa dumelwa go tlhoma tše dingwe ka se sebaka.",
        "emailauthenticated": "E-mail atrese ya gago e kgonthišitšwe ka $2  $3.",
        "accountcreated": "Tšhupaleloko (Account) e tlhodilwe",
        "accountcreatedtext": "Tšhupaleloko (account) ya modiri [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) e tlhodilwe.",
        "loginlanguagelabel": "Polelo: $1",
+       "pt-login": "Tsena",
+       "pt-login-button": "Tsena",
+       "pt-createaccount": "Bula tšhupaleloko",
+       "pt-userlogout": "Etšwa/Tswalela",
        "changepassword": "Fetola ditlhaka-tša-siphiri",
        "resetpass_text": "<!-- Tsenya ditlhaka mo -->",
        "oldpassword": "Ditlhaka-tša-siphiri tša kgale:",
        "newpassword": "Ditlhaka-tša-siphiri tše mpsha:",
        "retypenew": "Tlanya ditlhaka tše mphsa tša siphiri gape:",
-       "changepassword-success": "Ditlhaka tša siphiri di fetotšwe ka katlego!",
+       "resetpass_submit": "Lokela ditlhaka-tša-siphiri o tsene",
+       "changepassword-success": "Ditlhaka tša siphiri di fetotšwe!",
+       "passwordreset-username": "Leina la mošomiši:",
        "bold_sample": "Mongwalo wa '''Bold'''",
        "bold_tip": "Ditlhaka tše Bold",
        "italic_sample": "Ditlhaka tše Italic",
        "accmailtext": "Ditlhaka-tša-siphiri tša  [[User talk:$1|$1]]  di rometšwe go $2. Di ka fetolwa go letlaka la <em>[[Special:ChangePassword|go fetola ditlhaka-tša-siphiri ]]</em> ge o tsena.",
        "newarticle": "(mpsha)",
        "newarticletext": "O latetše hlomaganyo go letlakala leo le sego gona ka se sebaka.\nGo tlhola letlakala, thoma go ngwalo lepokising le letelago\n(lebelela [$1 letlakala la thušo] go hwetša šedi).\nGa eba o le fa ka phošo, o ka boela morago ka go šumiša konopo ya '''back''' go ''browser'' ya gago.",
-       "noarticletext": "Ga gona ditlhaka letlakaleng le, oka [[Special:Search/{{PAGENAME}}|fetleka leina la letlakala]] matlakaleng a mangwe, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} fetleka \"logs\"], goba [{{fullurl:{{FULLPAGENAME}}|action=edit}} wa fetola letlakala le]</span>.",
-       "noarticletext-nopermission": "Ga gona ditlhaka letlakaleng le, \noka [[Special:Search/{{PAGENAME}}|fetleka leina la letlakala]] matlakaleng a mangwe,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} fetleka \"logs\"],\n goba [{{fullurl:{{FULLPAGENAME}}|action=edit}} wa fetola letlakala le]</span>.",
+       "noarticletext": "Ga gona ditlhaka letlakaleng le.\nO ka [[Special:Search/{{PAGENAME}}|fetleka leina la letlakala]] matlakaleng a mangwe, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} fetleka \"logs\"], goba [{{fullurl:{{FULLPAGENAME}}|action=edit}} wa fetola letlakala le]</span>.",
+       "noarticletext-nopermission": "Ga gona ditlhaka letlakaleng le.\nO ka [[Special:Search/{{PAGENAME}}|fetleka leina la letlakala]] matlakaleng a mangwe,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} fetleka \"logs\"],\n goba [{{fullurl:{{FULLPAGENAME}}|action=edit}} wa fetola letlakala le]</span>.",
        "note": "'''Ela hloko:'''",
        "previewnote": "'''Elelwa gore ye ke taetšo ya sebopego sa letlakala fela.'''\nDiphetogo tša gago ga šetšo di bolokwa!",
        "editing": "O fetola $1",
        "skin-preview": "Ponopele",
        "prefs-rc": "Diphetogo tša bjale",
        "prefs-watchlist": "Lenano la tlhapetšo",
+       "prefs-rendering": "Ponagalo",
        "saveprefs": "Boloka",
        "prefs-editing": "Fetola",
        "searchresultshead": "Fetleka",
        "savedprefs": "Dikgatlhegelo tša gago di bolokilwe.",
        "allowemail": "Dumella melaetša ya e-mail go tšwa go bašomiši ba bangwe",
+       "prefs-searchoptions": "Fetleka",
        "prefs-files": "Difaele",
        "youremail": "E-Poso",
        "username": "{{GENDER:$1|Mošomiši}}:",
        "yourlanguage": "Polelo:",
        "yournick": "Tshaeno:",
        "badsiglength": "Leina la boreelo le letelele kudu.\nLe swanela goba fase ga $1 {{PLURAL:$1|ya tlhaka|tša ditlhaka}}",
-       "prefs-help-realname": "Leina la nnete gale gapeletšwe, efela ge o kgetha go fana ka lona, le tla šomišwa go bontšha diabe mešomong ya gago.",
+       "prefs-help-realname": "Leina la nnete gale gapeletšwe.\nGe o kgetha go fana ka lona, le tla šomišwa go bontšha diabe mešomong ya gago.",
        "prefs-help-email": "Aterese ya E-poso gae hlokagale, efela e ka hlokagala ge dihlaka tša sephiri di fetolwa, ge o ka lebala dihlaka tša gago tša sephiri",
        "prefs-help-email-others": "O ka kgetha gore batho ba bangwe ba bolele le wena ka  e-poso ga kgokaganyo letlakala la gago goba letlakala la dipoledišano.\nGa re fane ka e-poso ya gago go bašumiši ba bangwe ge ba polela le wena ka yona.",
        "prefs-help-email-required": "E-mail atrese eya nyakega.",
        "rightslog": "''log'' ya ditumello tša mošomiši",
        "action-edit": "Fetola letlakala  le",
        "nchanges": "$1 {{PLURAL:$1|phetogo|diphetogo}}",
+       "enhancedrc-history": "histori",
        "recentchanges": "Diphetogo tša bjale",
        "recentchanges-legend": "Dikgetho tša diphetogo tša bjale",
        "recentchanges-summary": "Lebalana diphetogo tše di mphsa-mphsa go wiki  letlakaleng le.",
        "rcnotefrom": "Tlase ke diphetogo go tloga ka <strong>$3, $4</strong> (go  fihla ka <strong>$1</strong>).",
        "rclistfrom": "Laêtša dipheto tše mfsa go thoma go $3 $2",
        "rcshowhideminor": "$1 ya diphetogo tše nnyenyane",
+       "rcshowhideminor-hide": "Fihla",
        "rcshowhidebots": "$1 bots",
+       "rcshowhidebots-show": "Bontšha",
        "rcshowhideliu": "$1 bašumiši bao batsebjawago",
+       "rcshowhideliu-hide": "Fihla",
        "rcshowhideanons": "$1 bašumiši bago se tsebege",
+       "rcshowhideanons-hide": "Fihla",
        "rcshowhidepatr": "$1 diphetogo tše ''patrolled''",
        "rcshowhidemine": "$1 diphetogo tsa ka",
+       "rcshowhidemine-hide": "Fihla",
        "rclinks": "Bontšha diphetogo tša bofelo tše $1 matšatšing a  $2  a bofelo <br />$3",
        "diff": "phapang",
        "hist": "histori",
        "blanknamespace": "(Hlogo)",
        "contributions": "Diabe tša mošomiši",
        "contributions-title": "Diabe tša mošumiši go $1",
-       "mycontris": "Diabe tša ka",
+       "mycontris": "Diabe",
        "contribsub2": "Ya $1 ($2)",
-       "uctop": "(godimo)",
+       "uctop": "(bjale)",
        "month": "Go tloga kgweding (le peleng):",
        "year": "Go tloga ngwageng (le peleng):",
        "sp-contributions-newbies": "Laetša diabe tša bašumiši ba bafsa fela",
        "tooltip-pt-login": "O a kgothatšwa gore o tsene, e efela ga se kgapeletšo.",
        "tooltip-pt-logout": "Etšwa fa/Tswalela/Log out",
        "tooltip-ca-talk": "Poledišano mabapi le letlakala le",
-       "tooltip-ca-edit": "O ka fetola letlakala le. Kgopelo ke gore o šumiše konopo ya go Laetša sebopego sa letlakala pele o le boloka.",
+       "tooltip-ca-edit": "Fetola letlakala  le",
        "tooltip-ca-addsection": "Lokela sekgao se seswa",
        "tooltip-ca-viewsource": "Letlakala le le lotilew. O ka lebelela mothopo fela.",
        "tooltip-ca-history": "Lebelela thumeletšo ya go feta ya letlakala le",
        "lastmodifiedatby": "Letlakala le  fetotšwe la mafelelo ka $2, $1 ke $3.",
        "others": "tše dingwe",
        "siteusers": "{{SITENAME}} {{PLURAL:$2|mošumiši|bašumiši}} $1",
+       "pageinfo-toolboxlink": "Tsebo ya Letlakala",
        "filedeleteerror-short": "Phošo go phumuleng faele: $1",
        "filedeleteerror-long": "Diphošo di hlagile ge go phumulwa faele:\n\n$1",
        "filedelete-missing": "Faele \"$1\" ga e phumulege ka ge e segona.",
        "specialpages": "Matlakala a kgethegilego",
        "external_image_whitelist": " #Tlogela letlakale ka mokgwa wo<pre>\n#Tsenya  \"regular expression fragments\" (parata ya magareng ga //) below\n#These will be matched with the URLs of external (hotlinked) images\n#Those that match will be displayed as images, otherwise only a link to the image will be shown\n#Lines beginning with # are treated as comments\n#This is case-insensitive\n\n#Put all regex fragments above this line. Leave this line exactly as it is</pre>",
        "tag-filter": "[[Special:Tags|Tag]] \"filter\":",
+       "searchsuggest-search": "Fetleka  {{SITENAME}}",
        "expand_templates_output": "Phetho"
 }
index 4048ef8..3493eb7 100644 (file)
@@ -33,6 +33,7 @@
        "tog-watchdefault": "Apondre las paginas que modifiqui e los fichièrs qu'impòrti a ma lista de seguiment",
        "tog-watchmoves": "Apondre las paginas e los fichièrs que tòrni nomenar a ma lista de seguiment",
        "tog-watchdeletion": "Apondre las paginas e los fichièrs que suprimissi de ma lista de seguiment",
+       "tog-watchuploads": "Apondre los novèls fichièrs qu’impòrti a ma lista de seguiment",
        "tog-watchrollback": "Apondre a ma lista de seguiment las paginas sus las qualas ai efectuat una revocacion",
        "tog-minordefault": "Considerar mas modificacions coma menoras per defaut",
        "tog-previewontop": "Far veire la previsualizacion al dessús de la zòna de modificacion",
@@ -42,7 +43,7 @@
        "tog-enotifminoredits": "M’avertir per corrièr electronic quitament en cas de modificacions menoras de las paginas o dels fichièrs",
        "tog-enotifrevealaddr": "Afichar mon adreça electronica dins la los corrièrs electronics d’avertiment",
        "tog-shownumberswatching": "Afichar lo nombre d'utilizaires que seguisson aquesta pagina",
-       "tog-oldsig": "Signatura existenta :",
+       "tog-oldsig": "Vòstra signatura existenta :",
        "tog-fancysig": "Tractar la signatura coma de wikitèxte (sens ligam automatic)",
        "tog-uselivepreview": "Utilizar l’apercebut rapid",
        "tog-forceeditsummary": "M'avertir quand ai pas completat lo contengut de la bóstia de comentaris",
@@ -59,7 +60,7 @@
        "tog-showhiddencats": "Afichar las categorias amagadas",
        "tog-norollbackdiff": "Afichar pas lo diff aprèp aver revocat",
        "tog-useeditwarning": "M’avisar quand quiti una pagina de modificacion sens publicar los cambiaments",
-       "tog-prefershttps": "Utilizar totjorn una connexion securizada en essent connectat",
+       "tog-prefershttps": "Utilizatz totjorn una connexion securizada per vos connectar",
        "underline-always": "Totjorn",
        "underline-never": "Pas jamai",
        "underline-default": "Valor per defaut del navigador o del tèma",
        "newwindow": "(dobrís una fenèstra novèla)",
        "cancel": "Anullar",
        "moredotdotdot": "E mai...",
-       "morenotlisted": "Aquesta lista es pas completa.",
+       "morenotlisted": "Aquesta lista pòt èsser incompleta.",
        "mypage": "Pagina",
        "mytalk": "Discussion",
        "anontalk": "Discussion",
        "talk": "Discussion",
        "views": "Afichatges",
        "toolbox": "Aisinas",
+       "tool-link-userrights": "Modificar los gropes de {{GENDER:$1|l’utilizaire|l’utilizaira}}",
+       "tool-link-emailuser": "Mandar un corrièr electronic a {{GENDER:$1|l’utilizaire|l’utilizaira}}",
        "userpage": "Pagina d'utilizaire",
        "projectpage": "Pagina meta",
        "imagepage": "Veire la pagina del fichièr",
        "virus-unknownscanner": "antivirús desconegut :",
        "logouttext": "'''Ara, sètz desconnectat.'''\n\nNotatz que d'unas paginas pòdon èsser encara afichadas coma s'eratz encara connectat, fins al moment qu'escafaretz l'escondedor de vòstre navigador.",
        "cannotlogoutnow-title": "Impossible de se desconnectar ara",
+       "cannotlogoutnow-text": "La desconnexion es pas possibla en utilizant $1.",
        "welcomeuser": "Benvenguda, $1&nbsp;!",
        "welcomecreation-msg": "Vòstre compte d'utilizaire es estat creat.\nDoblidetz pas de modificar [[Special:Preferences|vòstras preferéncias per {{SITENAME}}]].",
        "yourname": "Nom d'utilizaire :",
        "createacct-yourpasswordagain-ph": "Entratz lo senhal tornarmai",
        "userlogin-remembermypassword": "Gardar ma session activa",
        "userlogin-signwithsecure": "Utilizar una connexion securizada",
+       "cannotlogin-title": "Impossible de se connectar",
+       "cannotlogin-text": "La connexion es pas possibla.",
        "cannotloginnow-title": "Impossible de se connectar ara",
+       "cannotloginnow-text": "La connexion es pas possibla en utilizant $1.",
+       "cannotcreateaccount-title": "Creacion de comptes impossibla",
+       "cannotcreateaccount-text": "La creacion dirècta de comptes d'utilizaires es pas activada sus aqueste wiki.",
        "yourdomainname": "Vòstre domeni",
        "password-change-forbidden": "Podètz pas modificar los senhals sus aqueste wiki.",
        "externaldberror": "Siá una error s’es produita amb la basa de donadas d’autentificacion extèrna, siá sètz pas autorizat a metre a jorn vòstre compte extèrne.",
        "login": "Identificacion",
+       "login-security": "Verificar vòstra identitat",
        "nav-login-createaccount": "Crear un compte o se connectar",
        "userlogin": "Crear un compte o se connectar",
        "userloginnocreate": "Connexion",
        "userlogin-resetpassword-link": "Senhal doblidat ?",
        "userlogin-helplink2": "Ajuda a la connexion",
        "userlogin-loggedin": "Sètz ja connectat en tant que {{GENDER:$1|$1}}.\nUtilizatz lo formulari çaijós per vos connectar amb un autre utilizaire.",
+       "userlogin-reauth": "Vos cal vos reconnectar per verificar que sètz {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Crear un autre compte",
        "createacct-emailrequired": "Adreça electronica",
        "createacct-emailoptional": "Adreça de corrièr electronic (facultativa)",
        "createacct-reason-ph": "Perqué creatz un autre compte",
        "createacct-submit": "Creatz vòstre compte",
        "createacct-another-submit": "Crear un compte",
+       "createacct-continue-submit": "Contunhar la creacion de compte",
+       "createacct-another-continue-submit": "Contunhar la creacion de compte",
        "createacct-benefit-heading": "{{SITENAME}} es escrit per de monde coma vos.",
        "createacct-benefit-body1": "{{PLURAL:$1|cambiament|cambiaments}}",
        "createacct-benefit-body2": "{{PLURAL:$1|pagina|paginas}}",
        "createacct-another-realname-tip": "Lo nom vertadièr es opcional.\nSe decidissètz de lo provesir, serà utilizat per atribuir a l’utilizaire sos trabalhs.",
        "pt-login": "Se connectar",
        "pt-login-button": "Se connectar",
+       "pt-login-continue-button": "Contunhar la connexion",
        "pt-createaccount": "Crear un compte",
        "pt-userlogout": "Se desconnectar",
        "php-mail-error-unknown": "Error desconeguda dins la foncion mail() de PHP.",
        "changepassword-success": "Vòstre senhal es estat modificat !",
        "changepassword-throttled": "Avètz ensajat un tròp grand nombre de connexions darrièrament.\nEsperatz $1 abans d’ensajar tornarmai.",
        "botpasswords": "Senhals de robòts",
+       "botpasswords-label-appid": "Nom del robòt :",
+       "botpasswords-label-create": "Crear",
+       "botpasswords-label-update": "Metre a jorn",
+       "botpasswords-label-cancel": "Anullar",
+       "botpasswords-label-delete": "Suprimir",
+       "botpasswords-label-resetpassword": "Reïnicializar lo senhal",
+       "botpasswords-label-grants": "Dreits aplicables :",
+       "botpasswords-label-grants-column": "Acordat",
+       "botpasswords-bad-appid": "Lo nom del robòt «$1» es pas valid.",
        "resetpass_forbidden": "Los senhals pòdon pas èsser cambiats",
        "resetpass-no-info": "Vos cal èsser connectat per aver accès a aquesta pagina.",
        "resetpass-submit-loggedin": "Modificar lo senhal",
        "history-feed-description": "Istoric per aquesta pagina sul wiki",
        "history-feed-item-nocomment": "$1 lo $2",
        "history-feed-empty": "La pagina demandada existís pas.\nBenlèu es estada escafada o renomenada.\nEnsajatz de [[Special:Search|recercar sul wiki]] per trobar de paginas en rapòrt.",
+       "history-edit-tags": "Modificar las balisas de las versions seleccionadas",
        "rev-deleted-comment": "(resumit de comentari suprimit)",
        "rev-deleted-user": "(nom d’utilizaire suprimit)",
        "rev-deleted-event": "(detalhs de l'entrada suprimida)",
        "mergehistory-empty": "Cap de revision pòt pas èsser fusionada.",
        "mergehistory-done": "$3 version{{PLURAL:$3||s}} de $1 {{PLURAL:$3|es estada fusionada|son estada fusionadas}} dins [[:$2]].",
        "mergehistory-fail": "Impossible de procedir a la fusion dels istorics. Seleccionatz  tornamai la pagina e mai los paramètres de data.",
+       "mergehistory-fail-bad-timestamp": "L’orodatatge es pas valid.",
        "mergehistory-fail-toobig": "Impossible d’efectuar la fusion de l’istoric perque un nombre de {{PLURAL:$1|revisions}} superior al limit de $1 deuriá èsser desplaçat.",
        "mergehistory-no-source": "La pagina d'origina $1 existís pas.",
        "mergehistory-no-destination": "La pagina de destinacion $1 existís pas.",
        "searchprofile-advanced-tooltip": "Recercar dins d'espacis de noms personalizats",
        "search-result-size": "$1 ({{PLURAL:$2|1 mot|$2 mots}})",
        "search-result-category-size": "$1 membre{{PLURAL:$1||s}} ($2 soscategoria{{PLURAL:$2||s}}, $3 fichièr{{PLURAL:$3||s}})",
-       "search-redirect": "(redireccion cap a $1)",
+       "search-redirect": "(redireccion dempuèi $1)",
        "search-section": "(seccion $1)",
        "search-category": "(categoria $1)",
        "search-file-match": "(correspond al contengut del fichièr)",
        "activeusers-intro": "Aquò es una lista dels utilizaires qu'an exerçat una activitat quina que siá al cors {{PLURAL:$1|de la darrièra jornada|dels $1 darrièrs jorns}}.",
        "activeusers-count": "$1 {{PLURAL:$1|accion|accions}} al moment {{PLURAL:$3|del darrièr jorn|dels $3 darrièrs jorns}}",
        "activeusers-from": "Afichar los utilizaires dempuèi :",
-       "activeusers-hidebots": "Amagar los robòts",
-       "activeusers-hidesysops": "Amagar los administrators",
        "activeusers-noresult": "Cap d'utilizaire pas trobat.",
        "listgrouprights": "Dreits dels gropes d'utilizaires",
        "listgrouprights-summary": "Aquesta pagina conten una lista de gropes definits sus aqueste wiki e mai los dreits d'accès qu'i son associats.\nI pòt aver [[{{MediaWiki:Listgrouprights-helppage}}|d'entresenhas complementàrias]] a prepaus dels dreits.",
        "htmlform-cloner-create": "Apondre encara",
        "htmlform-cloner-delete": "Suprimir",
        "htmlform-cloner-required": "Una valor al mens es obligatòria.",
-       "sqlite-has-fts": "$1 amb recèrca en tèxte integral suportada",
-       "sqlite-no-fts": "$1 sens recèrca en tèxte integral suportada",
        "logentry-delete-delete": "$1 {{GENDER:$2|a suprimit}} la pagina $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|a restablit}} la pagina $3",
        "logentry-delete-event": "$1 {{GENDER:$2|a modificat}} la visibilitat {{PLURAL:$5|d'un eveniment del jornal|de $5 eveniments del jornal}} sus $3 : $4",
        "feedback-close": "Fait",
        "feedback-external-bug-report-button": "Senhalar un bug tecnic",
        "feedback-dialog-title": "Sometre un comentari",
-       "feedback-error-title": "Error",
        "feedback-error1": "Error : Resultat de l'IPA pas reconegut",
        "feedback-error2": "Error : la modificacion a fracassat",
        "feedback-error3": "Error : pas cap de responsa de l'API",
        "feedback-thanks": "Mercé ! Vòstre comentari es estat publicat sus la pagina \"[$2 $1]\".",
        "feedback-thanks-title": "Mercés !",
        "feedback-useragent": "Agent utilizaire :",
-       "searchsuggest-search": "Recercar",
+       "searchsuggest-search": "Recercar sus {{SITENAME}}",
        "searchsuggest-containing": "que conten...",
        "api-error-badaccess-groups": "Sètz pas autorizat a cargar de fichièrs sus aqueste wiki.",
        "api-error-badtoken": "Error intèrna : marrit « geton ».",
index 750bc46..b77db9d 100644 (file)
@@ -50,7 +50,7 @@
        "tog-showhiddencats": "Ozuta peitetyt kategouriet",
        "tog-norollbackdiff": "Älä ozuta eroloi, konzu olet ottanuh järilleh aijemban versien järilleh tuondu -toimindol",
        "tog-useeditwarning": "Ollen lähtemäs sivulpäi iäre tallendamattah muutoksii, huomaita minuu",
-       "tog-prefershttps": "Käytä ainos suojattuu yhtevytty ku olet kirjutannuhes",
+       "tog-prefershttps": "Käytä ainos suojattuu yhtevytty, ku olet kirjutannuhes",
        "underline-always": "Ainos",
        "underline-never": "Nikonzu",
        "underline-default": "Käytä livaimen piäazetuksii",
        "minoredit": "Tämä on pieni kohendus",
        "watchthis": "Tarkaile tädä sivuu",
        "savearticle": "Tallenda sivu",
+       "savechanges": "Tallenda muutokset",
        "preview": "Ezikačo",
        "showpreview": "Ezikačo",
        "showdiff": "Luajitut kohendukset",
        "content-model-text": "perustekstu",
        "content-model-javascript": "JavaScript",
        "content-json-empty-object": "Tyhjy objektu",
-       "cantcreateaccounttitle": "Ei voi luadie tunnustu",
        "cantcreateaccount-text": "Tunnuksien luadimine täs IP-adressaspäi ('''$1''') on estetty. Estäjänny on [[User:$3|$3]].\n\nKäyttäjän $3 annettu syy on ''$2''",
        "cantcreateaccount-range-text": "Tunnuksien luadimine IP-adressilois adressualovehel <strong>$1</strong>, kuduah kuuluu sinungi käytetty IP-adressu(<strong>$4</strong>), on estetty. Eston on azetannuh [[User:$3|$3]].\n\nKäyttäjän $3 annettu syy estole on \"$2\".",
        "viewpagelogs": "Ozuta tämän sivun lougat",
        "searchprofile-everything-tooltip": "Eči kaikil sivuloil (dai paginois)",
        "searchprofile-advanced-tooltip": "Eči nämmien nimitiloin keskes",
        "search-result-size": "$1 ({{PLURAL:$2|1 sana|$2 sanua}})",
-       "search-redirect": "(siirretty $1)",
+       "search-redirect": "(siirretty sivus $1)",
        "search-section": "(alalugu $1)",
        "search-category": "(kategourii $1)",
        "search-suggest": "Tarkoititgo: $1",
index 34ac95f..1f25b38 100644 (file)
        "unprotectthispage": "ଏହି ପୃଷ୍ଠା ପାଇଁ ସୁରକ୍ଷାର ପ୍ରକାର ବଦଳାଇବେ",
        "newpage": "ନୂଆ ପୃଷ୍ଠା",
        "talkpage": "ପୃଷ୍ଠାକୁ ଆଲୋଚନା କରନ୍ତୁ",
-       "talkpagelinktext": "à¬\95ଥାଭାଷା",
+       "talkpagelinktext": "à¬\86ଲà­\8bà¬\9aନା",
        "specialpage": "ବିଶେଷ ପୃଷ୍ଠା",
        "personaltools": "ନିଜର ଟୁଲ",
        "articlepage": "ସୂଚୀ ପୃଷ୍ଠାଟି ଦେଖାଇବେ",
        "cannotdelete-title": "\"$1\" ପୃଷ୍ଠାଟି ଲିଭଯାଇପାରିବ ନାହିଁ",
        "delete-hook-aborted": "ସମ୍ପାଦନା ଏକ ହୁକ (hook) ଦେଇ ବାରଣ କରାଗଲା ।\nଏହା କିଛି ବି କାରଣ ଦେଇନାହିଁ ।",
        "no-null-revision": "\"$1\" ପୃଷ୍ଠାଟି ପାଇଁ ଫାଙ୍କା ସଂସ୍କରଣଟିଏ ତିଆରି କରିପାରିଲୁ ନାହିଁ",
-       "badtitle": "à¬\96ରାପ à¬¨à¬¾à¬\86à¬\81",
+       "badtitle": "à¬\96ରାପ à¬¨à¬¾à¬®",
        "badtitletext": "ଆପଣ ଅନୁରୋଧ କରିଥିବା ପୃଷ୍ଠାଟି ଭୁଲ, ଖାଲି ଅଛି ବା ବାକି ଭାଷା ସାଙ୍ଗରେ ଭୁଲରେ ଯୋଡ଼ା ଯାଇଛି ବା ଭୁଲ ଇଣ୍ଟର ଉଇକି ନାମ ଦିଆଯାଇଛି ।\nଏଥିରେ ଥିବା ଗୋଟିଏ ବା ଦୁଇଟି ଅକ୍ଷର ଶିରୋନାମା ଭାବରେ ବ୍ୟବହାର କରାଯାଇ ପାରିବ ନାହିଁ ।",
        "title-invalid-empty": "ଅନୁରୋଧ କରାଯାଇଥିବା ପୃଷ୍ଠାର ଶର୍ଷକଟି ଖାଲି ଅଛି କିମ୍ବା ନେମସ୍ପସର ନାମ ଅଛି ।",
        "title-invalid-utf8": "ଅନୁରୋଧ କରାଯାଇଥିବା ପୃଷ୍ଠାର ଶର୍ଷକରେ ଅବୈଧ UTF-8 ଧାରା ଅଛି ।",
        "minoredit": "ଏହା ଏକ ସାମାନ୍ୟ ସମ୍ପାଦନା",
        "watchthis": "ଏହି ପୃଷ୍ଠାଟିକୁ ଦେଖିବେ",
        "savearticle": "ସାଇତିବେ [Save]",
+       "savechanges": "ସାଇତିବେ [Save]",
        "preview": "ସାଇତିବା ଆଗରୁ ଦେଖନ୍ତୁ",
        "showpreview": "ଦେଖଣା [Preview]",
        "showdiff": "ବଦଳଗୁଡ଼ିକ ଦେଖାଇବେ",
        "newarticle": "(ନୁଆ)",
        "newarticletext": "ଆପଣ ଖୋଲିଥିବା ଲିଙ୍କଟିରେ ଏଯାଏଁ କିଛିବି ପୃଷ୍ଠା ନାହିଁ ।\nଏହି ପୃଷ୍ଠାଟିକୁ ତିଆରି କରିବା ପାଇଁ ତଳ ବାକ୍ସରେ ଟାଇପ କରନ୍ତୁ (ଅଧିକ ଜାଣିବା ପାଇଁ [$1 ସାହାଯ୍ୟ ପୃଷ୍ଠା] ଦେଖନ୍ତୁ) ।\nଯଦି ଆପଣ ଏଠାକୁ ଭୁଲରେ ଆସିଯାଇଥାନ୍ତି ତେବେ ଆପଣଙ୍କ ବ୍ରାଉଜରର '''Back''' ପତିଟି ଦବାନ୍ତୁ ।",
        "anontalkpagetext": "----''ଏହା ଏକ ଖାତା ଖୋଲିନଥିବା ବା ଖାତା ବ୍ୟବହାର କରିନଥିବା ଜଣେ ବେନାମି ସଭ୍ୟଙ୍କର ଆଲୋଚନା ପୃଷ୍ଠା ।''\nତେଣୁ ଆମ୍ଭେ ସଂଖ୍ୟା ଦେଇ ସୂଚୀତ IP ଠିକଣା ଦେଇ ତାଙ୍କୁ ଜାଣିବା ।\nଏହି ପ୍ରକାରର ଗୋଟିଏ IP ଠିକଣା ବହୁ ସଭ୍ୟଙ୍କ ଦେଇ ବ୍ୟବହାର କରାଯାଇପାରେ । \nଯଦି ଆପଣ ଜଣେ ଅଜଣା ସଭ୍ୟ ଓ ଭାବୁଛନ୍ତି ଇଆଡୁ ସିଆଡୁ ମତାମତ ସବୁ ଆପଣଙ୍କ ପାଇଁ ଦିଆଯାଇଛି ତେବେ ଦୟାକରି [[Special:CreateAccount|ନୂଆ ଖାତାଟିଏ ଖୋଲନ୍ତୁ]] କିମ୍ବା [[Special:UserLogin|ଆଗରୁ ଥିବା ଖାତାରେ ଲଗ ଇନ କରନ୍ତୁ]] ଯାହା ବେନାମି ସଭ୍ୟଙ୍କୁ ନେଇ ଉପୁଜିଥିବା ଦ୍ଵନ୍ଦର ସମାଧାନ କରିବ ।",
-       "noarticletext": "à¬\8fହି à¬ªà­\83ଷà­\8dଠାà¬\9fିରà­\87 à¬\95ିà¬\9bି à¬¬à¬¿ à¬²à­\87à¬\96ା à¬¨à¬¾à¬¹à¬¿à¬\81 à¥¤\nà¬\86ପଣ [[Special:Search/{{PAGENAME}}|à¬\8fହି à¬²à­\87à¬\96ାà¬\9fିର à¬¨à¬¾à¬\86à¬\81]] à¬¬à¬¾à¬\95ି à¬ªà­\83ଷà­\8dଠାମାନà¬\99à­\8dà¬\95ରà­\87 à¬\96à­\8bà¬\9cି à¬ªà¬¾à¬°à¬¨à­\8dତି,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}ରà­\87 à¬¯à­\8bଡ଼ାଯାà¬\87ଥିବା à¬¬à¬¾à¬\95ି à¬ªà­\83ଷà­\8dଠାସବà­\81à¬\95à­\81 à¬\96à­\8bà¬\9cି à¬ªà¬¾à¬°à¬¨à­\8dତି],\nà¬\95ିମà­\8dବା [{{fullurl:{{FULLPAGENAME}}|action=edit}} à¬\8fହି à¬ªà­\83ଷà­\8dଠାà¬\9fିà¬\95à­\81 à¬¬à¬¦à¬³à¬¾à¬\87 ପାରନ୍ତି]</span> ।",
+       "noarticletext": "à¬\8fହି à¬ªà­\83ଷà­\8dଠାà¬\9fିରà­\87 à¬\95à­\8cଣସି à¬²à­\87à¬\96ା à¬¨à¬¾à¬¹à¬¿à¬\81 à¥¤\nà¬\86ପଣ [[Special:Search/{{PAGENAME}}|à¬\8fହି à¬²à­\87à¬\96ାà¬\9fିର à¬¨à¬¾à¬®]] à¬¬à¬¾à¬\95ି à¬ªà­\83ଷà­\8dଠାମାନà¬\99à­\8dà¬\95ରà­\87 à¬\96à­\8bà¬\9cିପାରନà­\8dତି,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}ରà­\87 à¬¯à­\8bଡ଼ାଯାà¬\87ଥିବା à¬¬à¬¾à¬\95ି à¬ªà­\83ଷà­\8dଠାସବà­\81à¬\95à­\81 à¬\96à­\8bà¬\9cି à¬ªà¬¾à¬°à¬¨à­\8dତି],\nà¬\95ିମà­\8dବା [{{fullurl:{{FULLPAGENAME}}|action=edit}} à¬\8fହି à¬ªà­\83ଷà­\8dଠାà¬\9fି à¬¤à¬¿à¬\86ରି à¬\95ରିପାରନ୍ତି]</span> ।",
        "noarticletext-nopermission": "ଏବେ ଏହି ପୃଷ୍ଠାଟିରେ କିଛି ବି ଲେଖା ନାହିଁ ।\nଆପଣ [[Special:Search/{{PAGENAME}}|ଏହି ଲେଖାଟିର ନାଆଁ]] ବାକି ପୃଷ୍ଠାମାନଙ୍କରେ ଖୋଜି ପାରନ୍ତି, କିମ୍ବା\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}ରେ ଯୋଡ଼ାଯାଇଥିବା ବାକି ପୃଷ୍ଠାସବୁକୁ ଖୋଜି ପାରନ୍ତି]\n</span>, କିନ୍ତୁ ଏହି ପୃଷ୍ଠାଟିକୁ ଆପଣ ତିଆରି କରିପାରିବେ ନାହିଁ ।",
        "missing-revision": "\"{{FULLPAGENAME}}\" ନାମରେ ଥିବା ପୃଷ୍ଠାଟିର #$1 ପୁନରାବୃତ୍ତି ନାହିଁ ।\n\nପୁରୁଣା ହୋଇଯାଇଥିବା ଇତିହାସ ଲିଙ୍କ ଯାହା ଏକ ଲିଭାଯାଇଥିବା ପୃଷ୍ଠାକୁ ଦିଆଯାଇଥିବାରୁ ଏହା ସାଧାରଣତଃ ହୋଇଥାଏ ।\nଅଧିକ ବିବରଣୀ [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log]ରେ ମିଳିପାରିବ ।",
        "userpage-userdoesnotexist": "ଇଉଜର ଖାତା \"$1\" ଟି ତିଆରି କରାଯାଇନାହିଁ ।\nଆପଣ ଏହି ପୃଷ୍ଠାଟିକୁ ତିଆରି କରିବାକୁ ଚାହାନ୍ତି କି ନାହିଁ ଦୟାକରି ପରଖି ନିଅନ୍ତୁ ।",
        "sectioneditnotsupported-text": "ଏହି ପୃଷ୍ଠାରେ ବିଭାଗ ସମ୍ପାଦନା କାମ କରିବ ନାହିଁ ।",
        "permissionserrors": "ଅନୁମତି ମିଳିବାରେ ଅସୁବିଧା",
        "permissionserrorstext": "ତଳଲିଖିତ {{PLURAL:$1|କାରଣ|କାରଣସବୁ}} ପାଇଁ ଆପଣଙ୍କୁ ଏହା କରିବା ନିମନ୍ତେ ଅନୁମତି ନାହିଁ:",
-       "permissionserrorstext-withaction": "ତଳଲିଖିତ {{PLURAL:$1|କାରଣ|କାରଣସବୁ}} ପାଇଁ ଆପଣଙ୍କୁ $2 ଭିତରକୁ ଅନୁମତି ନାହିଁ:",
+       "permissionserrorstext-withaction": "ତଳଲିଖିତ {{PLURAL:$1|କାରଣ|କାରଣସବୁ}} ପାଇଁ ଆପଣଙ୍କୁ $2ରେ ଅନୁମତି ନାହିଁ:",
        "recreate-moveddeleted-warn": "'''ସୂଚନା: ଆଗରୁ ଲିଭାଯାଇଥିବା ପୃଷ୍ଠାଟିଏକୁ ଆପଣ ଆଉଥରେ ତିଆରୁଛନ୍ତି ।'''\n\nଆପଣ ଏହି ପୃଷ୍ଠାଟିକୁ ସମ୍ପାଦନା କରିବା ଉଚିତ କି ନୁହେଁ ବିଚାର କରିବା ଦରକାର ।\nଏହି ପୃଷ୍ଠାର ଲିଭାଇବା ଓ ଘୁଞ୍ଚାଇବା ଇତିହାସ ଏଠାରେ ସୁବିଧା ନିମନ୍ତେ ଦିଆଗଲା ।:",
-       "moveddeleted-notice": "à¬\8fହି à¬ªà­\83ଷà­\8dଠାà¬\9fିà¬\95à­\81 à¬²à¬¿à¬­à¬¾à¬\87 à¬¦à¬¿à¬\86ଯାà¬\87à¬\85à¬\9bି à¥¤\nà¬\8fହାର à¬²à¬¿à¬­à¬¾à¬\87ବା à¬\93 à¬\98à­\81à¬\9eà­\8dà¬\9aାà¬\87ବା à¬\87ତିହାସ à¬\86ଧାର à¬¨à¬¿à¬®à¬¨à­\8dତà­\87 à¬¤à¬³à­\87 à¬¦à¬¿à¬\86à¬\97ଲା à¥¤",
+       "moveddeleted-notice": "ଏହି ପୃଷ୍ଠାଟିକୁ ଲିଭାଇ ଦିଆଯାଇଛି ।\nଏହାର ଲିଭାଇବା ଓ ଘୁଞ୍ଚାଇବା ଇତିହାସ ଆଧାର ନିମନ୍ତେ ତଳେ ଦିଆଗଲା ।",
        "log-fulllog": "ପୁରା ଲଗ ଇତିହାସ ଦେଖନ୍ତୁ",
        "edit-hook-aborted": "ସମ୍ପାଦନା ଏକ ହୁକ (hook) ଦେଇ ବାରଣ କରାଗଲା ।\nଏହା କିଛି ବି କାରଣ ଦେଇନାହିଁ ।",
        "edit-gone-missing": "ଏହି ପୃଷ୍ଠାଟିକୁ ସତେଜ କରାଯାଇପାରିବ ନାହିଁ ।\nଏହାକୁ ଲିଭାଇ ଦିଆଗଲା ପରି ମନେ ହେଉଛି ।",
        "mergelog": "ମିଶ୍ରଣ ଲଗ୍",
        "revertmerge": "ମିଶାଇବା ନାହିଁ",
        "mergelogpagetext": "ତଳେ ସବୁଠାରୁ ନଗଦ ଯୋଡ଼ାଯାଇଥିବା ପୃଷ୍ଠାର ଇତିହାସ ଆଉ ଗୋଟିଏ ସହ ଦିଆଯାଇଅଛି ।",
-       "history-title": "\"$1\" à¬° à¬ªà­\81ନରାବà­\83ତି ଇତିହାସ",
+       "history-title": "\"$1\" à¬° à¬ªà­\81ନରà­\8dସà¬\82ସà­\8dà¬\95ରଣ ଇତିହାସ",
        "difference-title": "\"$1\" ପୃଷ୍ଠାର ସଂସ୍କରଣ‌ଗୁଡ଼ିକ ମଧ୍ୟରେ ତଫାତ",
        "difference-title-multipage": "ପୃଷ୍ଠା \"$1\" ଏବଂ \"$2\" ମଧ୍ୟରେ ଥିବା ପାର୍ଥକ୍ୟ",
        "difference-multipage": "(ପୃଷ୍ଠା ଭିତରେ ଥିବା ତଫାତ)‌",
        "searchprofile-advanced-tooltip": "ନିଜେ ତିଆରିକରିହେବା ଭଳି ନେମସ୍ପେସରେ ଖୋଜିବେ",
        "search-result-size": "$1 ({{PLURAL:$2|ଗୋଟେ ଶବ୍ଦ|$2 ଟି ଶବ୍ଦ}})",
        "search-result-category-size": "{{PLURAL:$1|ଜଣେ ସଭ୍ୟ|$1 ଜଣ ସଭ୍ୟ}} ({{PLURAL:$2|ଗୋଟିଏ ଶ୍ରେଣୀy|$2ଟି ଶ୍ରେଣୀ ସମୂହ}}, {{PLURAL:$3|ଗୋଟିଏ ଫାଇଲ|$3ଟି ଫାଇଲ}})",
-       "search-redirect": "($1 à¬\95à­\81 à¬\86à¬\97à¬\95à­\81 à¬¬à¬¢à­\87à¬\87ନିà¬\85 )",
+       "search-redirect": "($1 à¬°à­\81 à¬²à­\87à¬\89à¬\9fାଣି)",
        "search-section": "(ଭାଗ $1)",
        "search-category": "(ଶ୍ରେଣୀ $1)",
        "search-file-match": "(ଫାଇଲରେ ଥିବା ବିଷୟବସ୍ତୁ ସାଙ୍ଗେ ମେଳ)",
        "rcshowhidemine": "ମୋର ସମ୍ପାଦନା $1",
        "rcshowhidemine-show": "ଦେଖାଇବେ",
        "rcshowhidemine-hide": "ଲୁଚାଇବେ",
+       "rcshowhidecategorization": "$1 ପୃଷ୍ଠା ଶ୍ରେଣୀବିଭାଗ",
        "rclinks": "ଗଲା $2 ଦିନର $1 ବଦଳଗୁଡ଼ିକୁ ଦେଖାଇବେ<br />$3",
        "diff": "ଅଦଳ ବଦଳ",
        "hist": "ଇତିହାସ",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|ସଭ୍ୟ|ସଭ୍ୟଗଣା}}ଙ୍କୁ ଦେଖୁଅଛି]",
        "rc_categories": "ଶ୍ରେଣୀସମୂହ ପାଇଁ ସୀମା ( \"|\" ଦେଇ ଅଲଗା କରିବେ)",
        "rc_categories_any": "ଯେ କୌଣସି",
-       "rc-change-size-new": "ବଦଳ ପରେ $1 {{PLURAL:$1|ବାଇଟ|ବାଇଟ}}",
+       "rc-change-size-new": "ବଦଳ ପରେ $1 {{PLURAL:$1|ବାଇଟ|ବାଇଟସବୁ}}",
        "newsectionsummary": "/* $1 */ ନୂଆ ଭାଗ",
        "rc-enhanced-expand": "ସବିଶେଷ ଦେଖାନ୍ତୁ",
        "rc-enhanced-hide": "ବେଶି କଥାସବୁ ଲୁଚାଇଦିଅ",
        "activeusers-intro": "ବିଗତ $1 {{PLURAL:$1|ଦିନ|ଦିନ}} ଭିତରେ କିଛି ପ୍ରକାରର କାମ କରିଥିବା ସଭ୍ୟମାନଙ୍କର ତାଲିକା ।",
        "activeusers-count": "ବିଗତ {{PLURAL:$3|ଦିନ|$3 ଦିନରେ}}ରେ $1ଟି {{PLURAL:$1|ସମ୍ପାଦନା|ସମ୍ପାଦନାଗୁଡିକ}}",
        "activeusers-from": "ଏହି ନାମରେ ଆରମ୍ଭ ହେଉଥିବା ସଭ୍ୟମାନଙ୍କୁ ଦେଖାଇବେ:",
-       "activeusers-hidebots": "ଆପେଆପେ ଚାଳିତ ସଭ୍ୟମାନଙ୍କୁ ଲୁଚାନ୍ତୁ",
-       "activeusers-hidesysops": "ପରିଚାଳକମାନଙ୍କୁ ଲୁଚାଇବେ",
        "activeusers-noresult": "ଜଣେ ବି ସଭ୍ୟ ମିଳିଲେ ନାହିଁ ।",
        "listgrouprights": "ସଭ୍ୟ ଗୋଠ ଅଧିକାରସମୂହ",
        "listgrouprights-summary": "ତଳେ ଉଇକି ସ୍ଥିର କରାଯାଇଥିବା ଏକ ଏକ ବ୍ୟବହାରକାରୀ ଗୋଠର ତାଲିକା ଦିଆଯାଇଛି, ସେଥିରେ ସେମାନଙ୍କ ବ୍ୟବହାର ଅଧିକାର ବାବଦରେ ମଧ୍ୟ ଦିଆଯାଇଛି ।\nସେଥିରେ ବୋଧେ [[{{MediaWiki:Listgrouprights-helppage}}|ଅଧିକ ବ୍ୟକ୍ତିଗତ ବିବରଣୀ ଥାଇପାରେ]] ।",
        "wlheader-showupdated": "ଆପଣ ଶେଷଥର ଦେଖିଥିବା ପୃଷ୍ଠାଗୁଡ଼ିକ '''ମୋଟା ଅକ୍ଷର'''ରେ ଦେଖାଯାଉଅଛି ।",
        "wlnote": "$3, $4 ଅନୁସାରେ ବିଗତ {{PLURAL:$2|ଘଣ୍ଟାକରେ|<strong>$2</strong> ଘଣ୍ଟାରେ}}{{PLURAL:$1|ଶେଷ ବଦଳ|ଶେଷ <strong>$1</strong> ବଦଳ ତଳେ ଦିଆଗଲା}} ।",
        "wlshowlast": "ଗତ $1 ଘଣ୍ଟା $2 ଦିନ ଦେଖାନ୍ତୁ",
+       "wlshowhidecategorization": "ପୃଷ୍ଠା ଶ୍ରେଣୀବିଭାଗ",
        "watchlist-options": "ଦେଖଣା ବିକଳ୍ପସବୁ",
        "watching": "ଦେଖୁଛି...",
        "unwatching": "ଦେଖୁନାହିଁ...",
        "deleting-backlinks-warning": "''' ଚେତାବନୀ:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|ବାକି ପୃଷ୍ଠା]] ଆପଣ ଲିଭାଇବାକୁ ଯାଉଥିବା ପୃଷ୍ଠାଟି ସହିତ ଲିଙ୍କ କରନ୍ତୁ କିମ୍ବା ତାହାକୁ କାଢ଼ନ୍ତୁ ।",
        "rollback": "ପୁରାପୁରି ପଛକୁ ଫେରିବା ବଦଳ",
        "rollbacklink": "ପୂରାପୂରି ପଛକୁ ଫେରିଯିବେ",
-       "rollbacklinkcount": "{{PLURAL:$1|edit|edits}} $1 ପଛକୁ ଫେରାଇବେ",
+       "rollbacklinkcount": "$1ଟି {{PLURAL:$1|ସମ୍ପାଦନା|ସମ୍ପାଦନା ସବୁ}} ପଛକୁ ଫେରାଇବେ",
        "rollbacklinkcount-morethan": "{{PLURAL:$1|edit|edits}} $1ରୁ ଅଧିକ ପଛକୁ ଫେରାଇବେ",
        "rollbackfailed": "ପୁରାପୁରି ପଛକୁ ଫେରିବା ବିଫଳ ହେଲା",
        "cantrollback": "ବଦଳକୁ ପଛକୁ ଫେରାଇ ପାରିବେ ନାହିଁ;\nଶେଷ ଦାତାଜଣଙ୍କ ଏହି ପୃଷ୍ଠାର ଜଣେମାତ୍ର ଦାତା ।",
        "whatlinkshere-prev": "{{PLURAL:$1|ଆଗ|ଆଗ $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|ପର|ପର $1}}",
        "whatlinkshere-links": "← ଲିଙ୍କ",
-       "whatlinkshere-hideredirs": "$1 କୁ ଲେଉଟାଣି",
-       "whatlinkshere-hidetrans": "$1 ଆଧାର ସହ ଭିତରେ ରଖିବା",
-       "whatlinkshere-hidelinks": "$1 ଟି ଲିଙ୍କ",
+       "whatlinkshere-hideredirs": "$1ଟି ଲେଉଟାଣି",
+       "whatlinkshere-hidetrans": "$1ଟି ବାଦ ଦିଆଯାଇଛି",
+       "whatlinkshere-hidelinks": "$1ଟି ଲିଙ୍କ",
        "whatlinkshere-hideimages": "$1 ଫାଇଲର ଲିଙ୍କସବୁ",
        "whatlinkshere-filters": "ଛଣା",
        "autoblockid": "#$1ଙ୍କୁ ଆପେଆପେ ଅଟକାଇଦେବେ",
        "tooltip-watchlistedit-raw-submit": "ଦେଖଣା ତାଲିକାକୁ ଅପଡ଼େଟ କରିବେ",
        "tooltip-recreate": "ଏହି ପୃଷ୍ଠାଟି ଲିଭାଇଦିଆଯାଇଥିଲେ ବି ଆଉଥରେ ତିଆରି କରନ୍ତୁ",
        "tooltip-upload": "ଅପଲୋଡ଼ କରନ୍ତୁ",
-       "tooltip-rollback": "\"ଫà­\87ରିବା\" à¬\8fହି à¬«à¬°à¬¦à¬°à­\87 à¬¶à­\87ଷ à¬¦à¬¾à¬¤à¬¾à¬\99à­\8dà¬\95 à¬¦à­\87à¬\87 à¬\95ରାଯାà¬\87ଥିବା à¬¸à¬¬à­\81ଯାà¬\95 à¬¬à¬¦à¬³à¬\95à­\81  à¬\8fà¬\95ାଥରà¬\95ରà­\87 à¬ªà¬\9bà¬\95à­\81 à¬«à­\87ରାà¬\87ଦà­\87ବ",
+       "tooltip-rollback": "\"ଫà­\87ରିବା\" à¬\8fହି à¬ªà­\83ଷà­\8dଠାରà­\87 à¬¶à­\87ଷ à¬\85ବଦାନà¬\95ାରà­\80à¬\99à­\8dà¬\95 à¬¦à­\87à¬\87 à¬\95ରାଯାà¬\87ଥିବା à¬¸à¬¬à­\81ଯାà¬\95 à¬¬à¬¦à¬³à¬\95à­\81  à¬\8fà¬\95ାଥରà¬\95ରà­\87 à¬ªà¬\9bà¬\95à­\81 à¬«à­\87ରାà¬\87ଦିà¬\8f",
        "tooltip-undo": "\"କରନାହିଁ\" ଦବାଇଲେ ଆଗରୁ ହୋଇଥିବା ସମ୍ପାଦନାଟିଏ ପଛକୁ ଲେଉଟିଯାଏ ଓ ତାହା ସମ୍ପାଦନା ପୃଷ୍ଠାଟିକୁ '''ଦେଖଣା''' ଭାବେ ଖୋଲେ । ଆପଣଙ୍କୁ ଏହା ସାରକଥାରେ କାରଣଟିଏ ଲେଖିବାର ସୁଯୋଗ ଦିଏ ।",
        "tooltip-preferences-save": "ଆପଣା ପସନ୍ଦ ସାଇତିବେ",
        "tooltip-summary": "ଛୋଟ ସାରକଥାଟିଏ ଦିଅନ୍ତୁ",
        "pageinfo-magic-words": "ଚମତ୍କାର {{PLURAL:$1|word|words}} ($1)",
        "pageinfo-hidden-categories": "{{PLURAL:$1|category|categories}} ($1) ଲୁଚାଗଲା",
        "pageinfo-templates": "{{PLURAL:$1|template|templates}} ($1) ଯୋଡିହେଇଥିବା",
-       "pageinfo-transclusions": "{{PLURAL:$1|Page|Pages}} ($1)ରେ ଯୋଡାଗଲା",
+       "pageinfo-transclusions": "{{PLURAL:$1|ପୃଷ୍ଠା|ପୃଷ୍ଠାସବୁ}} ($1)ରେ ଯୋଡାଗଲା",
        "pageinfo-toolboxlink": "ପୃଷ୍ଠା ସୂଚନା",
        "pageinfo-redirectsto": "କୁ ଲେଉଟାଣି",
        "pageinfo-redirectsto-info": "ସୂଚନା",
        "tags": "ବୈଧ ସମ୍ପାଦନା ଚିହ୍ନ",
        "tag-filter": "[[Special:Tags|ଟାଗ]] ଛଣା:",
        "tag-filter-submit": "ଛାଣିବା",
-       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ଟ୍ୟାଗ|ଟ୍ୟାଗ}}]]: $2)",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ଟ୍ୟାଗ|ଟ୍ୟାଗସବୁ}}]]: $2)",
        "tags-title": "ସୂଚକ",
        "tags-intro": "ଏହି ପୃଷ୍ଠା ସଫ୍ଟୱାର ଏକ ବଦଳ ଭାବେ ଚିହ୍ନିତ କରୁଥିବା ଚିହ୍ନସବୁର ମାନେ ସହ ତାଲିକା ତିଆରି କରିଥାଏ ।",
        "tags-tag": "ଚିହ୍ନ ନାମ",
        "feedback-bugornote": "ଦୟାକରି ଆପଣ ଏକ କାରିଗରି ଅସୁବିଧାଟିଏ ଜଣାଇବା ପାଇଁ ଚାହୁଁଥିଲେ ଦୟାକରି [$1 ଏଠାରେ ଅସୁବିଧାଟି ଜଣାନ୍ତୁ] । \nଅଥବା, ଆପଣ ତଳେ ଠିଆ ସହଜ ଆବେଦନ ପତ୍ରଟି ପୁରଣ କରିପାରିବେ ।  ଆପଣଙ୍କ ବ୍ୟବହାରକାରୀ ନାମ ଓ ଆପଣ ବ୍ୟବହାର କରୁଥିବା ବ୍ରାଉଜର ଅନୁସାରେ ଆପଣଙ୍କ ମତାମତ \"[$3 $2]\"ରେ ଯୋଡ଼ାଯିବ ।",
        "feedback-cancel": "ନାକଚ",
        "feedback-close": "ହୋଇଗଲା",
-       "feedback-error-title": "ଅସୁବିଧା",
        "feedback-error1": "ଭୁଲ: API ରୁ ଅଚିହ୍ନା ଫଳାଫଳ",
        "feedback-error2": "ଅସୁବିଧା: ସମ୍ପାଦନା ବିଫଳ ହେଲା",
        "feedback-error3": "ଅସୁବିଧା: API ରୁ କିଛି ଉତ୍ତର ମିଳିଲା ନାହିଁ",
index 8c42878..bdc8b77 100644 (file)
        "yourpasswordagain": "Пароль ногæй бафысс:",
        "createacct-yourpasswordagain": "Сбæлвырд кæн пароль",
        "createacct-yourpasswordagain-ph": "Пароль ногæй бафысс",
-       "remembermypassword": "Бахъуыды мæ кæнæд ацы браузеры (максимум $1 {{PLURAL:$1|бонмæ}})",
        "userlogin-remembermypassword": "Системæйы мæ дар",
        "userlogin-signwithsecure": "Æдас бастдзинадæй",
        "yourdomainname": "Дæ домен:",
        "passwordreset-emailtext-user": "{{grammar:genitive|{{SITENAME}}}} архайæг $1 æрдомдта дæ {{grammar:genitive|{{SITENAME}}}} ($4) аккаунты пароль ногæй сæвæрын. Ацы архайæджы {{PLURAL:$3|аккаунт баст у|аккаунттæ баст сты}} ацы электрон посты адрисимæ:\n\n$2\n\n{{PLURAL:$3|Ацы рæстæгмæ пароль|Ацы рæстæгмæ паролтæ}} кусдзысты {{PLURAL:$5|иу бон|$5 боны}}.\nНыр ды хъуамæ бахизай системæмæ æмæ равзарай ног пароль. Кæд ай æндæр чидæр æрдомдта, кæнæ кæд дæ пароль æрхъуыды кодтай æмæ дæ нал фæды фæивай йæ, уæд дæ бон у мацæмæ дарай ацы фыстæг æмæ дарддæр архайай дæ зæронд паролæй.",
        "passwordreset-emailelement": "Фæсномыг: \n$1\n\nРæстæгмæ пароль: \n$2",
        "passwordreset-emailsentemail": "Ног пароль сæвæрыны фыстæг æрвыст æрцыд.",
-       "passwordreset-emailsent-capture": "Ног пароль сæвæрыны фыстæг æрвыст æрцыд æмæ бындæр æвдыст у.",
-       "passwordreset-emailerror-capture": "Ног пароль сæвæрыны фыстæг арæзт æрцыд æмæ бындæр æвдыст у. Фæлæ йæ {{grammar:allative|{{GENDER:$2|user}}}} арвитын нæ бантыстис: $1",
        "changeemail": "E-mail адрис фæивын",
        "changeemail-header": "Аккаунты e-mail адрис фæивын",
        "changeemail-no-info": "Ды хъуамæ системæмæ хызт уай, цæмæй ацы фарсмæ комкоммæ бавналай.",
        "post-expand-template-argument-warning": "'''Сындæг:''' Ацы фарсы ис уæддæр иу хуызæджы аргумент, кæй райтынг у æгæр стыр.\nУыцы аргументтæ уагъд æрцыдысты.",
        "post-expand-template-argument-category": "Фæрстæ, кæдоны ис хуызæджы уагъд аргумент",
        "parser-template-loop-warning": "Хуызæгты цасм ссардæуыд: [[$1]]",
-       "cantcreateaccounttitle": "Аккаунт саразæн нæй",
        "viewpagelogs": "Ацы фарсæн йæ логтæ равдисын",
        "nohistory": "Ацы фарсæн ивдтыты истори нæй.",
        "currentrev": "Фæстаг фæлтæр",
        "listusers-noresult": "Иу архайæг дæр не ссардæуыд.",
        "listusers-blocked": "(хъодыгонд)",
        "activeusers": "Активон архайджыты номхыгъд",
-       "activeusers-hidebots": "Боттæ бамбæхс",
-       "activeusers-hidesysops": "Радгæсты бамбæхс",
        "activeusers-noresult": "Иу архайæг дæр не ссардæуыд.",
        "listgrouprights": "Къордты архайджыты бартæ",
        "listgrouprights-group": "Къорд",
        "feedback-back": "Фæстæмæ",
        "feedback-cancel": "Ныууадзын",
        "feedback-close": "Æххæст",
-       "feedback-error-title": "Рæдыд",
        "feedback-error1": "Рæдыд: Æнæзонгæ фæстиуæг API-йæ",
        "feedback-error2": "Рæдыд: Ивд нæ фæрæстмæ",
        "feedback-error3": "Рæдыд: API дзуапп нæ дæтты",
index 829bb0e..0156bdb 100644 (file)
        "yourpasswordagain": "ਪਾਸਵਰਡ ਮੁੜ ਲਿਖੋ:",
        "createacct-yourpasswordagain": "ਪਾਸਵਰਡ ਪੁਸ਼ਟੀ",
        "createacct-yourpasswordagain-ph": "ਪਾਸਵਰਡ ਫੇਰ ਦਿਉ",
-       "remembermypassword": "ਇਸ ਕੰਪਿਊਟਰ ’ਤੇ ਮੇਰਾ ਦਾਖ਼ਲਾ ਯਾਦ ਰੱਖੋ (ਵੱਧ ਤੋਂ ਵੱਧ $1 {{PLURAL:$1|ਦਿਨ|ਦਿਨਾਂ}} ਲਈ)",
        "userlogin-remembermypassword": "ਮੈਨੂੰ ਲਾਗਇਨ ਰੱਖੋ",
        "userlogin-signwithsecure": "ਸੁਰੱਖਿਅਤ ਕੁਨੈਕਸ਼ਨ ਰੱਖੋ",
        "yourdomainname": "ਤੁਹਾਡਾ ਡੋਮੇਨ:",
        "passwordreset-emailtext-user": "{{SITENAME}} 'ਤੇ User $1 ਨੇ ਤੁਹਾਡੇ {{SITENAME}} ($4) ਉਤਲੇ ਪਛਾਣ-ਸ਼ਬਦ ਨੂੰ ਮੁੜ-ਬਣਾਉਣ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਹੈ। ਇਸ ਈਮੇਲ ਪਤੇ ਨਾਲ਼ ਹੇਠ ਲਿਖੇ {{PLURAL:$3|ਖਾਤੇ|ਖਾਤਿਆਂ}} ਦਾ ਵਾਸਤਾ ਹੈ:\n\n$2\n\n{{PLURAL:$3|ਇਸ ਆਰਜ਼ੀ ਪਛਾਣ-ਸ਼ਬਦ|ਇਹਨਾਂ ਆਰਜ਼ੀ ਪਛਾਣ-ਸ਼ਬਦਾਂ}} ਦੀ ਮਿਆਦ {{PLURAL:$5|ਇੱਕ ਦਿਨ|$5 ਦਿਨਾਂ}} 'ਚ ਮੁੱਕ ਜਾਵੇਗੀ।\nਤੁਹਾਨੂੰ ਹੁਣੇ ਦਾਖ਼ਲ ਹੋ ਕੇ ਕੋਈ ਨਵਾਂ ਪਛਾਣ-ਸ਼ਬਦ ਬਣਾ ਲੈਣਾ ਚਾਹੀਦਾ ਹੈ। ਜੇਕਰ ਕਿਸੇ ਹੋਰ ਨੇ ਇਹ ਬੇਨਤੀ ਕੀਤੀ ਹੈ ਜਾਂ ਤੁਹਾਨੂੰ ਆਪਣਾ ਪਹਿਲਾ ਪਛਾਣ-ਸ਼ਬਦ ਯਾਦ ਆ ਗਿਆ ਹੈ ਅਤੇ ਹੁਣ ਤੁਸੀਂ ਉਹਨੂੰ ਬਦਲ਼ਨਾ ਨਹੀਂ ਲੋਚਦੇ ਤਾਂ ਤੁਸੀਂ ਇਸ ਸੁਨੇਹੇ ਨੂੰ ਅਣਡਿੱਠਾ ਕਰ ਕੇ ਆਪਣਾ ਪੁਰਾਣਾ ਪਛਾਣ-ਸ਼ਬਦ ਵਰਤਦੇ ਰਹਿ ਸਕਦੇ ਹੋ।",
        "passwordreset-emailelement": "ਯੂਜ਼ਰ-ਨਾਂ: \n$1\n\nਆਰਜ਼ੀ ਪਾਸਵਰਡ: \n$2",
        "passwordreset-emailsentemail": "ਇੱਕ ਪਾਸਵਰਡ ਮੁੜ-ਸੈੱਟ ਈ-ਮੇਲ ਭੇਜੀ ਜਾ ਚੁੱਕੀ ਹੈ।",
-       "passwordreset-invalideamil": "ਗ਼ਲਤ ਈਮੇਲ ਪਤਾ",
+       "passwordreset-invalidemail": "ਗ਼ਲਤ ਈਮੇਲ ਪਤਾ",
        "changeemail": "ਈ-ਮੇਲ ਸਿਰਨਾਵਾਂ ਬਦਲੋ ਜਾੰ ਹਟਾਓ",
        "changeemail-header": "ਖਾਤੇ ਵਾਲਾ ਈ-ਮੇਲ ਸਿਰਨਾਵਾਂ ਬਦਲੋ",
        "changeemail-no-info": "ਇਸ ਸਫ਼ੇ ਨੂੰ ਸਿੱਧੇ ਹੀ ਵੇਖਣ ਲਈ ਤੁਹਾਨੂੰ ਲਾਗਇਨ ਕਰਨਾ ਪਵੇਗਾ।",
        "activeusers-intro": "ਇਹ ਓਹਨਾਂ ਮੈਂਬਰਾਂ ਦੀ ਲਿਸਟ ਹੈ ਜਿੰਨ੍ਹਾਂ ਨੇ ਆਖ਼ਰੀ $1 {{PLURAL:$1|ਦਿਨ|ਦਿਨਾਂ}} ਵਿਚ ਕਿਸੇ ਤਰ੍ਹਾਂ ਦਾ ਕੋਈ ਕੰਮ ਕੀਤਾ ਹੈ।",
        "activeusers-count": "ਆਖ਼ਰੀ {{PLURAL:$3|ਦਿਨ|$3 ਦਿਨਾਂ}} ਵਿਚ $1 {{PLURAL:$1|ਸੋਧ|ਸੋਧਾਂ}}",
        "activeusers-from": "ਇਸਤੋਂ ਸ਼ੁਰੂ ਹੋਣ ਵਾਲ਼ੇ ਮੈਂਬਰ ਵਖਾਓ:",
-       "activeusers-hidebots": "ਬੌਟਾਂ ਨੂੰ ਲੁਕਾਓ",
-       "activeusers-hidesysops": "ਪ੍ਰਸ਼ਾਸਕ ਲੁਕਾਓ",
        "activeusers-noresult": "ਕੋਈ ਵਰਤੋਂਕਾਰ ਨਹੀਂ ਲੱਭਾ।",
        "activeusers-submit": "ਚਾਲੂ ਵਰਤੋਂਕਾਰ ਦਿਖਾਓ",
        "listgrouprights": "ਵਰਤੋਂਕਾਰ ਸਮੂਹਾਂ ਦੇ ਹੱਕ",
        "feedback-bugnew": "ਮੈਂ ਚੈੱਕ ਕੀਤਾ। ਇੱਕ ਨਵੇਂ ਦੋਸ਼ ਦੀ ਰਿਪੋਰਟ ਕਰੋ",
        "feedback-cancel": "ਰੱਦ ਕਰੋ",
        "feedback-close": "ਹੋ ਗਿਆ",
-       "feedback-error-title": "ਗ਼ਲਤੀ",
        "feedback-error2": "ਦੋਸ਼:ਸੋਧ ਫੇਲ੍ਹ ਹੋਈ",
        "feedback-error3": "ਦੋਸ਼:API ਵੱਲੋਂ ਕੋਈ ਜੁਆਬ ਨਹੀਂ",
        "feedback-message": "ਸੁਨੇਹਾ:",
index a2de392..95af027 100644 (file)
        "yourname": "Lagyung talagamit (Username):",
        "yourpassword": "Kekang password:",
        "yourpasswordagain": "Pakisulat meng pasibayu ing password:",
-       "remembermypassword": "Tandanan me ing login ku king computer a ini (for a maximum of $1 {{PLURAL:$1|day|days}})",
        "yourdomainname": "Ing kekang karinan (domain):",
        "externaldberror": "Mapalyaring mika pamagkamali king external authentication (pamagpatutung panlual) ning database, o ala kang paintulut a i-update ya ing kekang account a panlual (external account).",
        "login": "Mag log in",
        "undo-failure": "E maliaring iurung ing edit a ini uling e la mipapareu deng minunang me-edit.",
        "undo-norev": "E maliaring iurung ing edit a ini uling ala yu o mebura ya.",
        "undo-summary": "Iurung ya ing miyalilan $1 nang [[Special:Contributions/$2|$2]] ([[User talk:$2|Talk]])",
-       "cantcreateaccounttitle": "E makalalang account",
        "cantcreateaccount-text": "Sebat neng [[User:$3|$3]] ing pamaglalang account manibat kaniting IP address ('''$1''').\n\nIni ing sangkan a binie nang $3: ''$2''",
        "viewpagelogs": "Lon la reng log para king bulung a ini",
        "nohistory": "Alang amlat ning pamag-edit (edit history) para king bulung a ini.",
        "rightsnone": "(ala)",
        "revdelete-summary": "sampulung da reng mibayu (edit summary)",
        "feedback-back": "Mibalik",
-       "feedback-error-title": "Mali",
        "feedback-submit": "I-sumiti",
        "feedback-thanks-title": "Salamat pu!",
        "headline-anchor-title": "Ing suglung king seksyun a ini",
index 4a376c8..d96cf90 100644 (file)
        "yourname": "nom d'uzeu:",
        "yourpassword": "Mot d'passe:",
        "yourpasswordagain": "Intrer à nouvieu ch'mot d'passe:",
-       "remembermypassword": "Intrer oùtonmatiquemint l'prochaine fouos (pour un maximum éd $1 {{PLURAL:$1|jour|jours}})",
        "yourdomainname": "Vote donmène:",
        "login": "Intrer",
        "nav-login-createaccount": "Intrer / créer vote conpte",
index 608b0d1..74d9bb6 100644 (file)
        "linksearch-ok": "Uffgucke",
        "listusers-submit": "Zeig",
        "listusers-noresult": "Ken Yuuser gfunne.",
-       "activeusers-hidebots": "Waddefresser verschwinne losse",
-       "activeusers-hidesysops": "Verwalter verschwinne losse",
        "listgrouprights": "Rechte vun Yuuser-Druppe",
        "listgrouprights-group": "Druppe",
        "listgrouprights-rights": "Rechte",
index 5c0ab95..8722398 100644 (file)
        "yourpasswordagain": "Kennword nomol oigewe:",
        "createacct-yourpasswordagain": "Password bschdedische",
        "createacct-yourpasswordagain-ph": "Bschdedisch doi Password",
-       "remembermypassword": "Moi Kennword uffm Brausa merge (hegschdns fa $1 {{PLURAL:$1|Daach|Daach}})",
        "userlogin-remembermypassword": "Oagmeld blaiwe",
        "login": "Oamelde",
        "nav-login-createaccount": "Oamelde / Kondo oaleesche",
        "post-expand-template-argument-warning": "'''Baßma uff:''' Die Said hodd wenigschdns ä Vorlach midä Kenngreeß, wu groß werre dud. Die Kenngreeß wead do nedd õgeguggd.",
        "post-expand-template-argument-category": "Saide, wu wegfallene Vorlachewead hawen.",
        "undo-nochange": "Die Ännarung isch schunmol rigg'gängisch g'machd worre.",
-       "cantcreateaccounttitle": "Konn kä Kondo mache",
        "viewpagelogs": "Lochbischa fa die Said oagugge",
        "nohistory": "Vunde Said hodds kä Gschischd.",
        "currentrev": "Ledschdi Änarung",
index ce00a81..5abf99c 100644 (file)
        "eauthentsent": "Potwierdzenie zostało wysłane na adres e‐mail.\nZanim jakiekolwiek inne wiadomości zostaną wysłane na ten adres, należy wykonać zawarte w mailu instrukcje. Potwierdzisz w ten sposób, że ten adres e‐mail należy do Ciebie.",
        "throttled-mailpassword": "Przypomnienie hasła zostało już wysłane w ciągu {{PLURAL:$1|ostatniej godziny|ostatnich $1 godzin}}.\nAby zapobiec nadużyciom nadużyć możliwość wysyłania przypomnień została ograniczona do jednego na {{PLURAL:$1|godzinę|$1 godziny|$1 godzin}}.",
        "mailerror": "W trakcie wysyłania wiadomości e‐mail wystąpił błąd: $1",
-       "acct_creation_throttle_hit": "Z adresu IP, z którego korzystasz {{PLURAL:$1|ktoś już utworzył dziś konto|utworzono dziś $1 konta|utworzono dziś $1 kont}}, co jest maksymalną dopuszczalną liczbą w tym czasie.\nW związku z tym, osoby korzystające z tego adresu IP w chwili obecnej nie mogą założyć kolejnego.",
+       "acct_creation_throttle_hit": "Z adresu IP, z którego korzystasz {{PLURAL:$1|ktoś już utworzył dziś konto|utworzono dziś $1 konta|utworzono dziś $1 kont}} w ciągu ostatnich $2, co jest maksymalną dopuszczalną liczbą w tym czasie.\nW związku z tym, osoby korzystające z tego adresu IP w chwili obecnej nie mogą założyć kolejnego.",
        "emailauthenticated": "Twój adres e‐mail został potwierdzony $2 o $3.",
        "emailnotauthenticated": "Twój adres '''e‐mail nie został potwierdzony'''.\nPoniższe funkcje poczty nie działają.",
        "noemailprefs": "Podaj adres e‐mail w preferencjach, by skorzystać z tych funkcji.",
        "botpasswords-updated-body": "Hasło bota \"$1\" użytkownika \"$2\" zostało zaktualizowane.",
        "botpasswords-deleted-title": "Hasło bota usunięte",
        "botpasswords-deleted-body": "Hasło bota \"$1\" użytkownika \"$2\" zostało usunięte.",
-       "botpasswords-newpassword": "Nowe hasło do zalogowania przez <strong>$1</strong> to <strong>$2</strong>. <em>Proszę je zapisać w celu wykorzystania w przyszłości.</em>",
+       "botpasswords-newpassword": "Nowe hasło do zalogowania się przez <strong>$1</strong> to <strong>$2</strong>. <em>Proszę je zapisać w celu wykorzystania w przyszłości.</em> <br> (Dla starszych botów, które wymagają loginu takiego samego jak ewentualna nazwa użytkownika można użyć <strong>$3</strong> jako nazwę użytkownika i <strong>$4</strong> jako hasło.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider nie jest dostępne.",
        "botpasswords-restriction-failed": "Logowanie nie powiodło się z powodu ograniczeń na hasło bota.",
        "botpasswords-invalid-name": "Określona nazwa użytkownika nie zawiera separatora hasła bota (\"$1\").",
        "passwordreset-emailelement": "Nazwa użytkownika: \n$1\n\nTymczasowe hasło: \n$2",
        "passwordreset-emailsentemail": "Jeśli ten adres e‐mail jest przypisany do Twojego konta, zostanie na niego wysłany e-mail do odzyskiwania hasła.",
        "passwordreset-emailsentusername": "Jeśli z tym kontem powiązany jest adres e‐mail, zostanie na niego wysłany e-mail do odzyskiwania hasła.",
-       "passwordreset-emailsent-capture2": "{{PLURAL:$1|Został wysłany e-mail|Zostały wysłane e-mail}} z informacjami o resetowaniu hasła. {{PLURAL:$1|Użytkownik i hasło jest pokazany|Lista użytkowników i haseł jest pokazana}} poniżej.",
-       "passwordreset-emailerror-capture2": "Wysyłanie e-maila do {{GENDER:$2|użytkownika|użytkowniczki}} nie powiodło się: $1 {{PLURAL:$3|Użytkownik i hasło jest pokazany|Lista użytkowników i haseł jest pokazana}} poniżej.",
+       "passwordreset-emailsent-capture2": "{{PLURAL:$1|Został wysłany e-mail|Zostały wysłane e-maile}} z informacjami o resetowaniu hasła. {{PLURAL:$1|Użytkownik i hasło jest pokazany|Lista użytkowników i haseł jest pokazana}} tutaj.",
+       "passwordreset-emailerror-capture2": "Wysyłanie e-maila do {{GENDER:$2|użytkownika|użytkowniczki}} nie powiodło się: $1 {{PLURAL:$3|Użytkownik i hasło jest pokazany|Lista użytkowników i haseł jest pokazana}} tutaj.",
        "passwordreset-nocaller": "Musi być podany wywołujący",
        "passwordreset-nosuchcaller": "Wywołujący nie istnieje: $1",
-       "passwordreset-invalideamil": "Nieprawidłowy adres e-mail",
+       "passwordreset-invalidemail": "Nieprawidłowy adres e-mail",
        "passwordreset-nodata": "Nie podano ani nazwy użytkownika, ani adresu e-mail",
        "changeemail": "Zmiana lub usunięcie adresu e‐mail",
        "changeemail-header": "Wypełnij ten formularz, aby zmienić swój adres e-mail. Jeśli chcesz usunąć swój adres e-mail, to przy wypełnianiu formularza pozostaw puste pole nowego adresu e-mail.",
        "userpage-userdoesnotexist": "Użytkownik „<nowiki>$1</nowiki>” nie jest zarejestrowany.\nUpewnij się, czy na pewno zamierza{{GENDER:|łeś|łaś|sz}} utworzyć lub zmodyfikować właśnie tę stronę.",
        "userpage-userdoesnotexist-view": "Konto użytkownika „$1” nie jest zarejestrowane.",
        "blocked-notice-logextract": "{{GENDER:$1|Ten użytkownik|Ta użytkowniczka}} jest obecnie {{GENDER:$1|zablokowany|zablokowana}}.\nOstatni wpis rejestru blokad jest pokazany poniżej.",
-       "clearyourcache": "<strong>Uwaga:</strong> aby zobaczyć zmiany po zapisaniu, może zajść potrzeba wyczyszczenia pamięci podręcznej przeglądarki.\n* <strong>Firefox / Safari:</strong> Przytrzymaj <em>Shift</em> podczas klikania <em>Odśwież bieżącą stronę</em>, lub naciśnij klawisze <em>Ctrl+F5</em> lub <em>Ctrl+R</em> (<em>⌘-R</em> na komputerze Mac)\n* <strong>Google Chrome:</strong> Naciśnij <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> na komputerze Mac)\n* <strong>Internet Explorer:</strong> Przytrzymaj <em>Ctrl</em>, jednocześnie klikając <em>Odśwież</em>, lub naciśnij klawisze <em>Ctrl+F5</em>\n* <strong>Opera:</strong> Wyczyść pamięć podręczną w <em>Narzędzia → Preferencje</em>",
+       "clearyourcache": "<strong>Uwaga:</strong> aby zobaczyć zmiany po zapisaniu, może zajść potrzeba wyczyszczenia pamięci podręcznej przeglądarki.\n* <strong>Firefox / Safari:</strong> Przytrzymaj <em>Shift</em> podczas klikania <em>Odśwież bieżącą stronę</em>, lub naciśnij klawisze <em>Ctrl+F5</em> lub <em>Ctrl+R</em> (<em>⌘-R</em> na komputerze Mac)\n* <strong>Google Chrome:</strong> Naciśnij <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> na komputerze Mac)\n* <strong>Internet Explorer:</strong> Przytrzymaj <em>Ctrl</em>, jednocześnie klikając <em>Odśwież</em>, lub naciśnij klawisze <em>Ctrl+F5</em>\n* <strong>Opera:</strong> Przejdź do <em>Menu → Ustawienia</em> (<em>Opera → Preferencje</em> w Mac), a następnie <em>Prywatność i bezpieczeństwo → Wyczyść dane przeglądania → Opróżnij pamięć podręczną</em>.",
        "usercssyoucanpreview": "'''Podpowiedź:''' Użyj przycisku „Podgląd”, aby przetestować nowy arkusz stylów CSS przed jego zapisaniem.",
        "userjsyoucanpreview": "'''Podpowiedź:''' Użyj przycisku „Podgląd”, aby przetestować nowy kod JavaScript przed jego zapisaniem.",
        "usercsspreview": "'''Pamiętaj, że to tylko podgląd arkusza stylów CSS – nic jeszcze nie zostało zapisane!'''",
        "mergehistory-fail-bad-timestamp": "Znacznik czasu jest nieprawidłowy.",
        "mergehistory-fail-invalid-source": "Strona źródłowa jest nieprawidłowa.",
        "mergehistory-fail-invalid-dest": "Strona docelowa jest nieprawidłowa.",
+       "mergehistory-fail-no-change": "Łączenie historii nie połączyło żadnych wersji. Proszę ponownie sprawdzić stronę i parametry czasowe.",
        "mergehistory-fail-permission": "Brak uprawnień, aby połączyć historię.",
        "mergehistory-fail-self-merge": "Strona źródłowa i docelowa są takie same.",
        "mergehistory-fail-toobig": "Nie można połączyć historii, gdyż wymagałoby to przeniesienia więcej niż maksymalnej dopuszczalnej liczby $1 {{PLURAL:$1|wersji}}.",
        "searchprofile-advanced-tooltip": "Szukanie w wybranych przestrzeniach nazw",
        "search-result-size": "$1 ({{PLURAL:$2|1 słowo|$2 słowa|$2 słów}})",
        "search-result-category-size": "{{PLURAL:$1|1 element|$1 elementy|$1 elementów}} ({{PLURAL:$2|1 kategoria|$2 kategorie|$2 kategorii}}, {{PLURAL:$3|1 plik|$3 pliki|$3 plików}})",
-       "search-redirect": "(przekierowanie $1)",
+       "search-redirect": "(przekierowanie $1)",
        "search-section": "(sekcja $1)",
        "search-category": "(kategoria $1)",
        "search-file-match": "(odpowiada zawartości pliku)",
        "action-applychangetags": "wprowadzania znaczników wraz z własnymi zmianami",
        "action-changetags": "dodawania i usuwania dowolnych znaczników z poszczególnych wersji i wpisów w rejestrze",
        "action-deletechangetags": "usuwania znaczników z bazy danych",
+       "action-purge": "wyczyść pamięć podręczną tej strony",
        "nchanges": "$1 {{PLURAL:$1|zmiana|zmiany|zmian}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|od ostatniej wizyty}}",
        "enhancedrc-history": "historia",
        "file-thumbnail-no": "Nazwa pliku zaczyna się od <strong>$1</strong>.\nWydaje się, że jest to pomniejszona grafika ''(miniaturka)''.\nJeśli posiadasz tę grafikę w pełnym rozmiarze – prześlij ją. Jeśli chcesz wysłać tę – zmień nazwę przesyłanego obecnie pliku.",
        "fileexists-forbidden": "Plik o tej nazwie już istnieje i nie może zostać nadpisany.\nJeśli chcesz przesłać plik cofnij się i prześlij go pod inną nazwą. [[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Plik o tej nazwie już istnieje we współdzielonym repozytorium plików.\nCofnij się i załaduj plik pod inną nazwą. [[File:$1|thumb|center|$1]]",
+       "fileexists-no-change": "Przesyłany plik jest identyczny z aktualną wersją <strong>[[:$1]]</strong>.",
        "fileexists-duplicate-version": "{{PLURAL:$2|Przesłany plik jest dokładną kopią starszej wersji pliku|Przesłane pliki są dokładnymi kopiami starszych wersji plików}} <strong>[[:$1]]</strong>.",
        "file-exists-duplicate": "Ten plik jest kopią {{PLURAL:$1|pliku|następujących plików}}:",
        "file-deleted-duplicate": "Identyczny do tego plik ([[:$1]]) został wcześniej usunięty.\nSprawdź historię usunięć tamtego pliku zanim prześlesz go ponownie.",
        "upload-dialog-disabled": "Przesyłanie plików przy pomocy tego okna jest wyłączone na tej wiki.",
        "upload-dialog-title": "Prześlij plik",
        "upload-dialog-button-cancel": "Anuluj",
+       "upload-dialog-button-back": "Wstecz",
        "upload-dialog-button-done": "Gotowe",
        "upload-dialog-button-save": "Zapisz",
        "upload-dialog-button-upload": "Prześlij",
        "filerevert-submit": "Przywróć",
        "filerevert-success": "Plik '''[[Media:$1|$1]]''' został cofnięty do [$4 wersji z $3, $2].",
        "filerevert-badversion": "Brak poprzedniej lokalnej wersji tego pliku z podaną datą.",
+       "filerevert-identical": "Aktualna wersja pliku już jest identyczna z wybraną.",
        "filedelete": "Usuwanie „$1”",
        "filedelete-legend": "Usuń plik",
        "filedelete-intro": "Chcesz usunąć plik '''[[Media:$1|$1]]''' razem z całą jego historią.",
        "apisandbox-results-fixtoken-fail": "Nie udało się pobrać tokena „$1”.",
        "apisandbox-alert-page": "Pola na tej stronie są nieprawidłowe.",
        "apisandbox-alert-field": "Wartość tego pola jest nieprawidłowa.",
+       "apisandbox-continue": "Kontynuuj",
+       "apisandbox-continue-clear": "Wyczyść",
+       "apisandbox-param-limit": "Wpisz <kbd>max</kbd>, aby wykorzystać maksymalny limit.",
        "booksources": "Książki",
        "booksources-search-legend": "Szukaj informacji o książkach",
        "booksources-search": "Szukaj",
        "booksources-text": "Poniżej znajduje się lista odnośników do innych witryn, które pośredniczą w sprzedaży nowych i używanych książek, a także mogą posiadać dalsze informacje na temat poszukiwanej przez Ciebie książki.",
        "booksources-invalid-isbn": "Podany numer ISBN został rozpoznany jako nieprawidłowy. Sprawdź czy podany numer zgadza się z numerem zaczerpniętym ze źródła.",
+       "magiclink-tracking-rfc": "Strony używające magicznych linków RFC",
+       "magiclink-tracking-rfc-desc": "Ta strona zawiera magiczne linki do RFC. Zobacz w [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org], jak dokonać migracji.",
+       "magiclink-tracking-pmid": "Strony używające magicznych linków PMID",
+       "magiclink-tracking-pmid-desc": "Ta strona zawiera magiczne linki do PMID. Zobacz w [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org], jak dokonać migracji.",
+       "magiclink-tracking-isbn": "Strony używające magicznych linków ISBN",
+       "magiclink-tracking-isbn-desc": "Ta strona zawiera magiczne linki do ISBN. Zobacz w [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org], jak dokonać migracji.",
        "specialloguserlabel": "Kto:",
        "speciallogtitlelabel": "Co (tytuł lub {{ns:user}}:nick użytkownika):",
        "log": "Rejestr operacji",
        "activeusers": "Lista aktywnych użytkowników",
        "activeusers-intro": "Poniżej znajduje się lista użytkowników, którzy byli aktywni w ciągu {{PLURAL:$1|ostatniego dnia|ostatnich $1 dni}}.",
        "activeusers-count": "w ciągu {{PLURAL:$3|ostatniego dnia|ostatnich $3 dni}} {{GENDER:$2|wykonał|wykonała|wykonał}} $1 {{PLURAL:$1|operację|operacje|operacji}}",
-       "activeusers-from": "Pokaż użytkowników zaczynając od:",
-       "activeusers-hidebots": "Ukryj boty",
-       "activeusers-hidesysops": "Ukryj administratorów",
+       "activeusers-from": "Wyświetl użytkowników, zaczynając od:",
+       "activeusers-groups": "Wyświetl użytkowników należących do grup:",
        "activeusers-noresult": "Nie odnaleziono żadnego użytkownika.",
        "activeusers-submit": "Wyświetl aktywnych użytkowników",
        "listgrouprights": "Uprawnienia grup użytkowników",
        "changecontentmodel-success-text": "Typ zawartości [[:$1]] został zmieniony.",
        "changecontentmodel-cannot-convert": "Zawartość [[:$1]] nie może być przekształcona do typu $2.",
        "changecontentmodel-nodirectediting": "Model zawartości $1 nie obsługuje bezpośredniego edytowania",
+       "changecontentmodel-emptymodels-title": "Nie ma dostępnych modeli treści",
        "changecontentmodel-emptymodels-text": "Zawartość [[:$1]] nie może być przekształcona do żadnego typu.",
        "log-name-contentmodel": "Rejestr zmian modelu zawartości",
        "log-description-contentmodel": "Wydarzenia związane z modelami zawartości stron",
        "modifiedarticleprotection": "zmienił(a) stopień zabezpieczenia „[[$1]]”",
        "unprotectedarticle": "odbezpieczył(a) „[[$1]]”",
        "movedarticleprotection": "przeniósł ustawienia zabezpieczeń z [[$2]] do [[$1]]",
+       "protectedarticle-comment": "{{GENDER:$2|Zabezpieczył|Zabezpieczyła}} „[[$1]]”",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Zmienił|Zmieniła}} poziom zabezpieczenia „[[$1]]”",
+       "unprotectedarticle-comment": "{{GENDER:$2|Usunął|Usunęła}} zabezpieczenie z „[[$1]]”",
        "protect-title": "Zmiana stopnia zabezpieczenia „$1”",
        "protect-title-notallowed": "Podgląd stopnia zabezpieczenia „$1”",
        "prot_1movedto2": "stronę [[$1]] przeniósł do [[$2]]",
        "pageinfo-category-pages": "Liczba stron",
        "pageinfo-category-subcats": "Liczba podkategorii",
        "pageinfo-category-files": "Liczba plików",
+       "pageinfo-user-id": "ID użytkownika",
        "markaspatrolleddiff": "oznacz edycję jako „sprawdzoną”",
        "markaspatrolledtext": "Oznacz tę stronę jako „sprawdzoną”",
        "markaspatrolledtext-file": "Oznacz tę wersję pliku jako „sprawdzoną”",
        "patrol-log-header": "Poniżej znajduje się rejestr patrolowania stron.",
        "log-show-hide-patrol": "$1 rejestr sprawdzania",
        "log-show-hide-tag": "$1 rejestr znaczników",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Oznaczyć wersję $3 strony $2 jako sprawdzoną?",
        "deletedrevision": "Usunięto poprzednie wersje $1",
        "filedeleteerror-short": "Błąd przy usuwaniu pliku $1",
        "filedeleteerror-long": "Wystąpiły błędy przy usuwaniu pliku:\n\n$1",
        "newimages-showbots": "Pokaż pliki przesłane przez boty",
        "newimages-hidepatrolled": "Ukryj sprawdzone pliki",
        "noimages": "Brak plików do pokazania.",
+       "gallery-slideshow-toggle": "Przełączanie miniatur",
        "ilsubmit": "Szukaj",
        "bydate": "według daty",
        "sp-newimages-showfrom": "pokaż nowe pliki począwszy od $2, $1",
        "blankpage": "Pusta strona",
        "intentionallyblankpage": "Tę stronę umyślnie pozostawiono pustą.",
        "external_image_whitelist": " #Pozostaw tę linię dokładnie tak, jak jest.<pre>\n#Wstaw poniżej fragmenty wyrażeń regularnych (tylko to, co znajduje się między //).\n#Wyrażenia te zostaną dopasowane do adresów URL zewnętrznych (bezpośrednio linkowanych) grafik.\n#Dopasowane adresy URL zostaną wyświetlone jako grafiki, w przeciwnym wypadku będzie pokazany jedynie link do grafiki.\n#Linie zaczynające się od # są traktowane jako komentarze.\n#We wpisach ma znaczenie wielkość znaków.\n\n#Wstaw wszystkie deklaracje wyrażeniami regularnymi poniżej tej linii. Pozostaw tę linię dokładnie tak, jak jest.</pre>",
-       "tags": "Sprawdź zmiany w oparciu o wzorce tekstu",
+       "tags": "Znaczniki zmian",
        "tag-filter": "Filtr [[Special:Tags|znaczników]]:",
        "tag-filter-submit": "Filtr",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Znacznik|Znaczniki}}]]: $2)",
+       "tag-mw-contentmodelchange": "zmiana modelu zawartości",
+       "tag-mw-contentmodelchange-description": "Edycje, które [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel zmieniają model zawartości] strony",
        "tags-title": "Znaczniki",
        "tags-intro": "Na tej stronie znajduje się lista znaczników, którymi oprogramowanie może oznaczyć edycje, oraz ich opisy.",
        "tags-tag": "Nazwa znacznika",
        "tags-deactivate": "dezaktywuj",
        "tags-hitcount": "$1 {{PLURAL:$1|zmiana|zmiany|zmian}}",
        "tags-manage-no-permission": "Nie masz uprawnień do zarządzania znacznikami.",
-       "tags-manage-blocked": "Nie możesz zarządzać znacznikami zmian, kiedy jesteś zablokowany.",
+       "tags-manage-blocked": "Nie możesz zarządzać znacznikami zmian, gdy jesteś {{GENDER:$1|zablokowany|zablokowana}}.",
        "tags-create-heading": "Utwórz nowy znacznik",
        "tags-create-explanation": "Nowe znaczniki będą dostępne domyślnie dla użytkowników i botów.",
        "tags-create-tag-name": "Nazwa znacznika:",
        "tags-deactivate-not-allowed": "Nie można dezaktywować znacznika „$1”.",
        "tags-deactivate-submit": "Dezaktywuj",
        "tags-apply-no-permission": "Nie masz uprawnień do wprowadzania znaczników wraz z własnymi zmianami.",
-       "tags-apply-blocked": "Nie możesz stosować znaczników do swoich zmian, gdy jesteś zablokowany.",
+       "tags-apply-blocked": "Nie możesz stosować znaczników do swoich zmian, gdy jesteś {{GENDER:$1|zablokowany|zablokowana}}.",
        "tags-apply-not-allowed-one": "Znacznik „$1” nie może zostać wprowadzony ręcznie.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|Następujący znacznik nie może zostać wprowadzony ręcznie|Następujące znaczniki nie mogą zostać wprowadzone ręcznie}}: $1",
        "tags-update-no-permission": "Nie masz uprawnień do dodawania lub usuwania znaczników z poszczególnych wersji lub wpisów w rejestrze.",
-       "tags-update-blocked": "Nie możesz dodawać i usuwać znaczników zmian, kiedy jesteś zablokowany.",
+       "tags-update-blocked": "Nie możesz dodawać i usuwać znaczników zmian, gdy jesteś {{GENDER:$1|zablokowany|zablokowana}}.",
        "tags-update-add-not-allowed-one": "Znacznik „$1” nie może zostać dodany ręcznie.",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|Następujący znacznik nie może zostać dodany ręcznie|Następujące znaczniki nie mogą zostać dodane ręcznie}}: $1",
        "tags-update-remove-not-allowed-one": "Znacznika „$1” nie można usunąć.",
        "htmlform-cloner-create": "Dodaj więcej",
        "htmlform-cloner-delete": "Usuń",
        "htmlform-cloner-required": "Wymagana jest co najmniej jedna wartość.",
+       "htmlform-date-placeholder": "RRRR-MM-DD",
+       "htmlform-time-placeholder": "GG:MM:SS",
+       "htmlform-datetime-placeholder": "RRRR-MM-DD GG:MM:SS",
+       "htmlform-date-invalid": "Podana przez Ciebie wartość nie jest rozpoznawana jako data. Spróbuj użyć formatu RRRR-MM-DD.",
+       "htmlform-time-invalid": "Podana przez Ciebie wartość nie jest rozpoznawana jako czas. Spróbuj użyć formatu GG:MM:SS.",
+       "htmlform-datetime-invalid": "Podana przez Ciebie wartość nie jest rozpoznawana jako data i czas. Spróbuj użyć formatu RRRR-MM-DD GG:MM:SS.",
+       "htmlform-date-toolow": "Podana przez Ciebie wartość jest wcześniejsza niż dozwolona data $1.",
+       "htmlform-date-toohigh": "Podana przez Ciebie wartość jest późniejsza niż dozwolona data $1.",
+       "htmlform-time-toolow": "Podana przez Ciebie wartość jest wcześniejsza niż dozwolony czas $1.",
+       "htmlform-time-toohigh": "Podana przez Ciebie wartość jest późniejsza niż dozwolony czas $1.",
+       "htmlform-datetime-toolow": "Podana przez Ciebie wartość jest wcześniejsza niż dozwolona data i czas $1.",
+       "htmlform-datetime-toohigh": "Podana przez Ciebie wartość jest późniejsza niż dozwolona data i czas $1.",
        "htmlform-title-badnamespace": "[[:$1]] nie znajduje się w przestrzeni nazw „{{ns:$2}}”.",
        "htmlform-title-not-creatable": "Nie można użyć „$1” do utworzenia tytułu strony",
        "htmlform-title-not-exists": "$1 nie istnieje.",
        "feedback-external-bug-report-button": "Zgłoś problem techniczny",
        "feedback-dialog-title": "Prześlij opinię",
        "feedback-dialog-intro": "Możesz użyć tego prostego formularza w celu zgłoszenia swojej opinii. Twój komentarz, wraz z Twoją nazwą użytkownika (albo numerem IP) pojawi się na stronie $1.",
-       "feedback-error-title": "Błąd",
        "feedback-error1": "Błąd – nierozpoznana odpowiedź API",
        "feedback-error2": "Błąd – edycja nieudana",
        "feedback-error3": "Błąd – brak odpowiedzi API",
        "feedback-thanks": "Dziękujemy! Twoja opinia została opublikowana na stronie \"[$2 $1]\".",
        "feedback-thanks-title": "Dziękujemy!",
        "feedback-useragent": "Aplikacja klienta:",
-       "searchsuggest-search": "Szukaj",
+       "searchsuggest-search": "Przeszukaj {{GRAMMAR:B.lp|{{SITENAME}}}}",
        "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.",
        "log-action-filter-suppress-reblock": "Ukrycie użytkownika poprzez ponowną blokadę",
        "log-action-filter-upload-upload": "Nowe przesłane",
        "log-action-filter-upload-overwrite": "Przesłane ponownie",
+       "authmanager-authn-autocreate-failed": "Automatyczne tworzenie lokalnego konta nie powiodło się: $1",
        "authmanager-create-disabled": "Utworzenie konta jest wyłączone.",
-       "authmanager-create-from-login": "Aby utworzyć konto, wypełnij poniższe pola.",
+       "authmanager-create-from-login": "Aby utworzyć konto, wypełnij odpowiednie pola.",
+       "authmanager-create-not-in-progress": "Tworzenie konta nie jest wykonywane lub dane sesji zostały utracone. Zacznij od początku.",
        "authmanager-authplugin-setpass-failed-title": "Zmiana hasła nie powiodła się",
        "authmanager-authplugin-setpass-failed-message": "Wtyczka do uwierzytelniania uniemożliwiła zmianę hasła.",
        "authmanager-authplugin-create-fail": "Wtyczka do uwierzytelniania uniemożliwiła utworzenie konta.",
        "authmanager-provider-password-domain": "Uwierzytelnianie na podstawie hasła i domeny",
        "authmanager-provider-temporarypassword": "Hasło tymczasowe",
        "authprovider-confirmlink-success-line": "$1: Połączono.",
+       "authprovider-confirmlink-ok-help": "Kontynuuj po wyświetleniu komunikatów o błędach linkowania.",
        "authprovider-resetpass-skip-label": "Pomiń",
        "authprovider-resetpass-skip-help": "Pomiń resetowanie hasła.",
        "authform-newtoken": "Brakujący token. $1",
        "linkaccounts-success-text": "Konto zostało połączone.",
        "linkaccounts-submit": "Połącz konta",
        "unlinkaccounts": "Odłącz konta",
-       "unlinkaccounts-success": "Konta zostały odłączone."
+       "unlinkaccounts-success": "Konta zostały odłączone.",
+       "userjsispublic": "Uwaga: Podstrony z kodem JavaScript są widoczne publicznie i nie powinny zawierać poufnych danych.",
+       "usercssispublic": "Uwaga: Podstrony z kodem CSS są widoczne publicznie i nie powinny zawierać poufnych danych.",
+       "restrictionsfield-badip": "Nieprawidłowy adres IP lub zakres adresów: $1",
+       "restrictionsfield-label": "Dozwolone zakresy adresów IP:",
+       "restrictionsfield-help": "Jeden adres IP lub zakres CIDR w wierszu. Aby zaznaczyć wszystkie, użyj<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Błąd: $1",
+       "edit-error-long": "Błędy:\n\n$1"
 }
index e0b4667..fe7db17 100644 (file)
        "yourpasswordagain": "Che a bata torna soa ciav:",
        "createacct-yourpasswordagain": "Ch'a confirma la ciav",
        "createacct-yourpasswordagain-ph": "Ch'a buta torna la ciav",
-       "remembermypassword": "Visesse ëd mia ciav ansima a 's navigador (për al pi $1 {{PLURAL:$1|di}})",
        "userlogin-remembermypassword": "Ten-me andrinta al sistema",
        "userlogin-signwithsecure": "Dovré na conession sigura",
        "yourdomainname": "Sò domini:",
        "activeusers-intro": "Costa a l'é na lista d'utent ch'a l'han avù n'atività qualsëssìa ant j'ùltim $1 {{PLURAL:$1|di|di}}.",
        "activeusers-count": "$1 {{PLURAL:$1|assion}} ant {{PLURAL:$3|l'ùltim di|j'ùltim $3 di}}",
        "activeusers-from": "Smon-me j'utent a parte da:",
-       "activeusers-hidebots": "Stërmé ij trigomiro",
-       "activeusers-hidesysops": "Stërmé j'aministrator",
        "activeusers-noresult": "Pa gnun utent trovà.",
        "listgrouprights": "Drit dël grup d'utent",
        "listgrouprights-summary": "Ambelessì a-i é na lista dle partìe d'utent definìe ansima a costa wiki, con ij sò drit d'acess associà.\nA peulo ess-ie d'[[{{MediaWiki:Listgrouprights-helppage}}|anformassion adissionaj]] ansima a dij drit individuaj.",
        "htmlform-cloner-create": "Gionté 'd pi",
        "htmlform-cloner-delete": "Gavé",
        "htmlform-cloner-required": "A-i é damanca d'almanch un valor.",
-       "sqlite-has-fts": "$1 con arserca an test pien mantnùa",
-       "sqlite-no-fts": "$1 sensa arserca an test pien mantnùa",
        "logentry-delete-delete": "$1 a l'ha {{GENDER:$2|scancelà}} la pàgina $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|a l'ha ripristinà}} la pàgina $3",
        "logentry-delete-event": "$1 {{GENDER:$2|a l'ha modificà}} la visibilità ëd {{PLURAL:$5|n'event dël registr|$5 event dël registr}} dzora $3: $4",
        "feedback-external-bug-report-button": "Presenta un travaj tècnich",
        "feedback-dialog-title": "Spedì ij coment",
        "feedback-dialog-intro": "A peul dovré ël formolari sempi sì-sota për spedì ij sò coment. Ij sò coment a saran giontà a la pàgina «$1», ansema a sò stranòm.",
-       "feedback-error-title": "Eror",
        "feedback-error1": "Eror: Arzultà ëd l'API nen arconossù",
        "feedback-error2": "Eror: Modìfica falìa",
        "feedback-error3": "Eror: gnun-e rispòste da l'API",
index 15b5bee..33d0afe 100644 (file)
        "activeusers-intro": "اے اوناں ورتن والیاں دی لسٹ اے جنان پچھلے $1 {{PLURAL:$1|دن|دناں}} چ کم کیتا اے۔",
        "activeusers-count": "$1 {{PLURAL:$1|تبدیلی|تبدیلیاں}} پچھلے{{PLURAL:$3|دن|$3 دن}} چ",
        "activeusers-from": "ورتن والے ایس توں شروع ہون والے دسو:",
-       "activeusers-hidebots": "بوٹ چھپاؤ",
-       "activeusers-hidesysops": "مکھۓ لکاؤ",
        "activeusers-noresult": "کوئی ورتن والا نئیں لبیا۔",
        "listgrouprights": "ورتن ٹرلی حق",
        "listgrouprights-summary": "تھلے اک لسٹ اے ورتن ٹولیاں دی ای وکی تے، اپنے رلدے حقاں نال۔ \n\nہربندے دے ح‍ق‍اں [[{{MediaWiki:Listgrouprights-helppage}}|ہور جانکاری]]",
index 16f214a..fbb364b 100644 (file)
        "yourname": "Όνεμαν χρήστε:",
        "yourpassword": "Σημάδι:",
        "yourpasswordagain": "Ξαν' γράψτεν το σημάδι:",
-       "remembermypassword": "Αποθήκεμαν τη σημαδίμ σ' αβούτον τον υπολογιστήν (για μέγιστον $1 {{PLURAL:$1|ημέραν|ημέρας}})",
        "yourdomainname": "Το domain εσούν:",
        "login": "Εμπάτε",
        "nav-login-createaccount": "Εμπάτεν / ποισέστεν λογαρίαν",
        "permissionserrorstext-withaction": "'Κ έχετε την άδειαν για $2, για {{PLURAL:$1|τ'αφκά το λόγον|τ'αφκά τοι λόγους}}:",
        "recreate-moveddeleted-warn": "'''Ωρία: Εφτάτε αξάν μίαν σελίδαν ντ' ενεσβύεν οψεκές.'''\n\nΊσως εν καλλίον να μην εφτάτε τη σελίδαν.\nΤερέστεν για βοήθειαν σ' αρχείον σβησεματίων και ετεροχλαεματίων για την αιτίαν για το σβήσιμον:",
        "moveddeleted-notice": "Αούτο η σελίδαν εβζινέθεν.\nΑφκά ευρίεται έναν γράψιμον ασο αρχείον σβησεματίων και ετεροχλαεματίων τη σελίδας.",
-       "cantcreateaccounttitle": "Το ποίσιμον τη λογαρίας 'κ έντον",
        "viewpagelogs": "Τέρεν αρχεία γι' αβούτεν τη σελίδαν",
        "nohistory": "Αούτο η σελίδαν αλλαγάς 'κ εςς.",
        "currentrev": "Ατωριζνόν μορφήν",
index f4424e0..010c8f6 100644 (file)
        "yourname": "Twajā tērpautajas pabilisnā:",
        "yourpassword": "Twājs kliptaswīrds:",
        "yourpasswordagain": "Āntrinais kliptaswīrdan",
-       "remembermypassword": "Pamēnais majjans enēisnas infōrmaciōnins en šismu kōmputerin (per maksimum of $1 {{PLURAL:$1|deinā|dēinans}})",
        "yourdomainname": "Twajā dōmeni:",
        "externaldberror": "Tikka izwinaīnas autentikāntin dātanbazin blānda, anga ni assei enwarīntan kāi etnaunīnlai twajjan izwinaīnan rekkenan.",
        "login": "Enjaīs",
        "undo-failure": "Ni mazīngi etwārtai wartīntun redigīsenin, kōnfliktas sen persirzdausnas wersiōnins paggan.",
        "undo-norev": "Redigīsenis ni mazzi būtwei etwārtai wartīntan, beggi ni ekzistijja anga pastāi āupausintan.",
        "undo-summary": "Etwārtai wartīnsna stēisan wersiōnin $1 teīktan pra [[Special:Contributions/$2|$2]] ([[User talk:$2|diskusiōni]])",
-       "cantcreateaccounttitle": "Ni mazīngi teīktun rekkenan",
        "cantcreateaccount-text": "Rekkenas teīksenis iz šan IP adressin (\"$1\") pastāi drēuditan pra [[User:$3|$3]].\n\nBrewīnsli dātan pra $3 ast \"$2\"",
        "viewpagelogs": "Wīdais šisse pāusas regīsterins",
        "nohistory": "Ni ast redigīsnas istōrija per šin pāusan.",
        "activeusers": "Aktīwan tērpautajan listi",
        "activeusers-count": "$1 {{PLURAL:$1|redigīsenis|redigīsenei}} en {{PLURAL:$3|panzdauman dēinan|$3 panzdaumans dēinans}}",
        "activeusers-from": "Waidinnais tērpautajans pagaūnintins sen:",
-       "activeusers-hidebots": "Kliptinais bōtans",
-       "activeusers-hidesysops": "Kliptinais perwaldītajans",
        "activeusers-noresult": "Ni aupalā di tērpautajans",
        "listgrouprights": "Tērpautajan gruppin enwarīnsenei",
        "listgrouprights-summary": "Zemmais ast listi stēisan tērpautajan gruppin definītan en šissei wiki sen enwarīnsenins preipeisātan tenēimans.\nIzbandais pāausan sen [[{{MediaWiki:Listgrouprights-helppage}}|papilniminans infōrmaciōnins]] ezze enwarīnsenins.",
index c7c6ac6..c23e1c5 100644 (file)
        "passwordreset-emailtitle": "د {{SITENAME}} د گڼون څرگندنې",
        "passwordreset-emailelement": "کارن-نوم: \n$1\n\nلنډمهاله پټنوم: \n$2",
        "passwordreset-emailsentemail": "د پټنوم بيا پرځای کېدنې لپاره برېښليک درولېږل شو.",
-       "passwordreset-invalideamil": "ناسمه برېښليک پته",
+       "passwordreset-invalidemail": "ناسمه برېښليک پته",
        "changeemail": "برېښليک پته بدلول يا ليرې کول",
        "changeemail-header": "د گڼون برېښليک پته بدلول",
        "changeemail-no-info": "دې مخ ته د لاسرسي لپاره بايد غونډال کې ورننوځۍ.",
        "activeusers-intro": "دا د هغو کارنانو لړليک دی چې په {{PLURAL:$1|تېرې|تېرو}} $1 {{PLURAL:$1|ورځ|ورځو}} کې يې ونډې ترسره کړي.",
        "activeusers-count": "په {{PLURAL:$3|تېرې ورځ|تېرو $3 ورځو}} کې $1 {{PLURAL:$1|سمون|سمونونه}}",
        "activeusers-from": "هغه کارنان کتل چې نومونه يې پېلېږي په:",
-       "activeusers-hidebots": "روباټونه پټول",
-       "activeusers-hidesysops": "پازوالان پټول",
        "activeusers-noresult": "کارن و نه موندل شو.",
        "activeusers-submit": "فعاله کارنان ښکاره کول",
        "listgrouprights": "د کارن ډلو رښتې",
        "feedback-cancel": "ناگارل",
        "feedback-close": "ترسره شو",
        "feedback-external-bug-report-button": "د يوې تخنيکي دندې دوتنه جوړونه",
-       "feedback-error-title": "تېروتنه",
        "feedback-message": "پيغام:",
        "feedback-subject": "سکالو:",
        "feedback-submit": "سپارل",
index 668515e..76a44d5 100644 (file)
                        "Tusca",
                        "Cristofer Alves",
                        "Tark",
-                       "O Andarilho"
+                       "O Andarilho",
+                       "Bruno.S.Alves 270"
                ]
        },
        "tog-underline": "Sublinhar links:",
        "underline-default": "Padrão do navegador/skin",
        "editfont-style": "Estilo da fonte da área de edição:",
        "editfont-default": "Padrão do navegador",
-       "editfont-monospace": "Fonte mono-espaçada",
+       "editfont-monospace": "Fonte monoespaçada",
        "editfont-sansserif": "Fonte sem serifa",
        "editfont-serif": "Fonte serifada",
        "sunday": "domingo",
        "talk": "Discussão",
        "views": "Visualizações",
        "toolbox": "Ferramentas",
+       "tool-link-userrights": "Editar grupos {{GENDER:$1|usuário}}",
        "userpage": "Ver página de usuário",
        "projectpage": "Ver página de projeto",
        "imagepage": "Ver página do arquivo",
        "passwordreset-nocaller": "Um interlocutor deve ser fornecido",
        "passwordreset-nosuchcaller": "O interlocutor não existe: $1",
        "passwordreset-ignored": "A redefinição da senha não foi realizada. Talvez o provedor não tenha sido configurado?",
-       "passwordreset-invalideamil": "Endereço de e-mail inválido",
+       "passwordreset-invalidemail": "Endereço de e-mail inválido",
        "passwordreset-nodata": "Não foram fornecidos nome de usuário nem endereço de e-mail",
        "changeemail": "Alterar ou remover endereço de email",
        "changeemail-header": "Preencha este formulário para alterar seu endereço de e-mail. Se você gostaria de remover a associação de qualquer endereço de e-mail da sua conta, deixe o novo endereço de email em branco quando enviar o formulário.",
        "protectedpages-page": "Página",
        "protectedpages-expiry": "Expira",
        "protectedpages-performer": "Usuário que protegeu",
-       "protectedpages-params": "Parâmetros de proteção.",
+       "protectedpages-params": "Parâmetros de proteção",
        "protectedpages-reason": "Motivo",
        "protectedpages-submit": "Exibir páginas",
        "protectedpages-unknown-timestamp": "Desconhecido",
        "activeusers-intro": "Esta é uma lista de usuários com algum tipo de atividade nos últimos $1 {{PLURAL:$1|dia|dias}}.",
        "activeusers-count": "$1 {{PLURAL:$1|ação|ações}} {{PLURAL:$3|no último dia|nos últimos $3 dias}}",
        "activeusers-from": "Mostrar usuários começando por:",
-       "activeusers-hidebots": "Esconder robôs",
-       "activeusers-hidesysops": "Esconder administradores",
        "activeusers-noresult": "Nenhum usuário encontrado.",
        "activeusers-submit": "Mostrar usuários ativos",
        "listgrouprights": "Privilégios de grupos de usuários",
        "listgrouprights-namespaceprotection-namespace": "Namespace",
        "listgrouprights-namespaceprotection-restrictedto": "Direito(s) permitindo edições do usuário",
        "listgrants": "Atribuições",
+       "listgrants-summary": "Esta é uma lista de atribuições com os respetivos acessos às permissões de usuário. Os usuários podem autorizar aplicações a utilizar suas contas, mas com permissões limitadas baseadas nas atribuições dadas pelos usuários a cada aplicação. No entanto, uma aplicação agindo em nome de um usuário não pode utilizar permissões que o usuário não possui.\nPode haver [[{{MediaWiki:Listgrouprights-helppage}}|informação adicional]] sobre permissões individuais.",
        "listgrants-grant": "Atribuição",
        "listgrants-rights": "Direitos",
        "trackingcategories": "Categorias de rastreamento",
        "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}}|Other pages]] ligam ou redirecionam para a página que você está prestes a excluir.",
+       "deleting-backlinks-warning": "'''Cuidado:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|outras páginas]] ligam ou redirecionam para a página que você está prestes a eliminar.",
        "rollback": "Reverter edições",
        "rollbacklink": "reverter",
        "rollbacklinkcount": "reverter $1 {{PLURAL:$1|edição|edições}}",
        "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",
+       "protect-level-autoconfirmed": "Permitir apenas usuários autoconfirmados",
        "protect-level-sysop": "Permitir apenas administradores",
        "protect-summary-cascade": "em cascata",
        "protect-expiring": "expira em $1 (UTC)",
        "tooltip-t-recentchangeslinked": "Mudanças recentes nas páginas para as quais esta possui links",
        "tooltip-feed-rss": "Feed RSS desta página",
        "tooltip-feed-atom": "Feed Atom desta página",
-       "tooltip-t-contributions": "Ver as contribuições {{GENDER:$1{{BASEPAGENAME}}|deste usuário|desta usuária|deste(a) usuário(a)}}",
+       "tooltip-t-contributions": "Ver as contribuições {{GENDER:$1|deste usuário|desta usuária|deste(a) usuário(a)}}",
        "tooltip-t-emailuser": "Enviar um e-mail a {{GENDER:{{BASEPAGENAME}}|este usuário|esta usuária|este(a) usuário(a)}}",
        "tooltip-t-info": "Mais informações sobre esta página",
        "tooltip-t-upload": "Enviar arquivos",
        "feedback-external-bug-report-button": "Registrar uma tarefa técnica",
        "feedback-dialog-title": "Enviar comentários",
        "feedback-dialog-intro": "Você pode usar o simples formulário abaixo para enviar seus comentários. Os mesmos serão adicionados à página \"$1\", junto com seu nome de usuário.",
-       "feedback-error-title": "Erro",
        "feedback-error1": "Erro: O resultado da API não foi reconhecido",
        "feedback-error2": "Erro: A edição falhou",
        "feedback-error3": "Erro: A API não responde",
index bdb05bf..0873b70 100644 (file)
@@ -90,7 +90,7 @@
        "tog-watchdefault": "Adicionar as páginas e ficheiros que eu editar às minhas páginas vigiadas",
        "tog-watchmoves": "Adicionar as páginas e ficheiros que eu mover às minhas páginas vigiadas",
        "tog-watchdeletion": "Adicionar as páginas e ficheiros que eu eliminar às minhas páginas vigiadas",
-       "tog-watchuploads": "Adicionar novos ficheiros carregados por mim à minha lista de artigos vigiados",
+       "tog-watchuploads": "Adicionar novos ficheiros carregados por mim à minha lista de páginas vigiadas",
        "tog-watchrollback": "Adicionar páginas onde fiz uma reversão às minhas páginas vigiadas",
        "tog-minordefault": "Por omissão, marcar todas as edições como menores",
        "tog-previewontop": "Mostrar a antevisão antes da caixa de edição",
        "category_header": "Páginas na categoria \"$1\"",
        "subcategories": "Subcategorias",
        "category-media-header": "Multimédia na categoria \"$1\"",
-       "category-empty": "''Esta categoria não contém atualmente nenhuma página ou ficheiro multimédia.''",
+       "category-empty": "<em>Esta categoria não contém atualmente nenhuma página ou ficheiro multimédia.</em>",
        "hidden-categories": "{{PLURAL:$1|Categoria oculta|Categorias ocultas}}",
        "hidden-category-category": "Categorias ocultas",
        "category-subcat-count": "{{PLURAL:$2|Esta categoria só contém a seguinte subcategoria.|Esta categoria contém {{PLURAL:$1|a seguinte subcategoria|as seguintes $1 subcategorias}} (de um total de $2).}}",
        "navigation-heading": "Menu de navegação",
        "errorpagetitle": "Erro",
        "returnto": "Voltar para $1.",
-       "tagline": "De {{SITENAME}}",
+       "tagline": "Da wiki {{SITENAME}}",
        "help": "Ajuda",
        "search": "Pesquisa",
        "search-ignored-headings": " #<!-- deixe esta linha exatamente como ela está --> <pre>\n# Títulos de página que serão ignorados pela pesquisa.\n# Mudanças a esta lista terão efeito quando a página com o título referido for indexada.\n# Pode forçar a indexação de uma página realizando uma edição nula nessa página.\n# A sintaxe é a seguinte:\n#  * Tudo desde um símbolo de cardinal (#) até ao fim da linha é um comentário\n#  * Cada linha não vazia é o título exato a ignorar, respeitando o uso de maiúsculas\nReferências\nLinks externos\nVer também\n #</pre> <!-- deixe esta linha exatamente como ela está -->",
        "searchbutton": "Pesquisar",
-       "go": "Ir",
+       "go": "Prosseguir",
        "searcharticle": "Ir",
        "history": "Histórico",
        "history_short": "Histórico",
        "talk": "Discussão",
        "views": "Vistas",
        "toolbox": "Ferramentas",
+       "tool-link-userrights": "Alterar grupos {{GENDER:$1|do utilizador|da utilizadora}}",
+       "tool-link-emailuser": "Enviar correio eletrónico a {{GENDER:$1|este utilizador|esta utilizadora|este(a) utilizador(a)}}",
        "userpage": "Ver página de utilizador",
        "projectpage": "Ver página de projeto",
        "imagepage": "Ver página de ficheiro",
        "pool-errorunknown": "Erro desconhecido",
        "pool-servererror": "O serviço ''pool counter'' não está disponível ($1).",
        "poolcounter-usage-error": "Erro de uso: $1",
-       "aboutsite": "Sobre a {{SITENAME}}",
+       "aboutsite": "Sobre a wiki {{SITENAME}}",
        "aboutpage": "Project:Sobre",
        "copyright": "Conteúdo disponibilizado nos termos da $1, salvo indicação em contrário.",
        "copyrightpage": "{{ns:project}}:Direitos_de_autor",
        "nstab-category": "Categoria",
        "mainpage-nstab": "Página principal",
        "nosuchaction": "Operação não existe",
-       "nosuchactiontext": "A operação especificada pela URL é inválida.\nÉ possível que tenha escrito mal a URL ou seguido uma ligação incorreta.\nIsto pode também indicar um defeito no software da {{SITENAME}}.",
+       "nosuchactiontext": "A operação especificada pelo URL é inválida.\nÉ possível que tenha escrito mal o URL ou seguido uma ligação incorreta.\nIsto pode também indicar um defeito no software da wiki {{SITENAME}}.",
        "nosuchspecialpage": "Esta página especial não existe",
        "nospecialpagetext": "<strong>Solicitou uma página especial inválida.</strong>\n\nEncontra uma lista das páginas especiais válidas em [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Erro",
        "databaseerror-query": "Consulta: $1",
        "databaseerror-function": "Função: $1",
        "databaseerror-error": "Erro: $1",
-       "transaction-duration-limit-exceeded": "Para evitar a criação de lag replicação alta, esta operação foi abortada porque a duração de gravação ($1) excedeu o limite de $2 {{PLURAL:$2|segundo|segundos}}. Se está a mudar muitos itens de uma vez, tente fazer várias operações menores em vez disso.",
+       "transaction-duration-limit-exceeded": "Para evitar grandes atrasos na replicação, esta operação foi cancelada porque a duração de gravação ($1) excedeu o limite de $2 {{PLURAL:$2|segundo|segundos}}. Se está a mudar muitos objetos de uma só vez, tente desmultiplicar a operação em várias de menor dimensão.",
        "laggedslavemode": "'''Aviso:''' A página pode não conter as atualizações mais recentes.",
        "readonly": "Base de dados bloqueada (limitada a leituras)",
        "enterlockreason": "Introduza um motivo para bloquear, incluindo uma estimativa de quando será desbloqueada",
        "readonlytext": "A base de dados está atualmente bloqueada para novas entradas e outras modificações, provavelmente para uma manutenção de rotina, após a qual voltará à sua normalidade.\n\nO administrador que a bloqueou deu a seguinte explicação: $1",
-       "missing-article": "A base de dados não encontrou o texto de uma página que deveria ter encontrado, com o nome \"$1\" $2.\n\nGeralmente, esta situação ocorre ao clicar numa ligação para diferenças desatualizada ou para o histórico de uma página que tenha sido removida.\n\nSe nenhuma destas situações se verifica, pode ter encontrado um defeito no programa.\nAnote a URL e reporte este incidente a um [[Special:ListUsers/sysop|administrador]], por favor.",
+       "missing-article": "A base de dados não encontrou o texto de uma página que deveria ter encontrado, com o nome \"$1\" $2.\n\nGeralmente, esta situação ocorre ao clicar numa ligação para diferenças desatualizada ou para o histórico de uma página que tenha sido removida.\n\nSe nenhuma destas situações se verifica, pode ter encontrado um defeito no programa.\nAnote o URL e reporte este incidente a um [[Special:ListUsers/sysop|administrador]], por favor.",
        "missingarticle-rev": "(revisão#: $1)",
        "missingarticle-diff": "(Dif.: $1, $2)",
        "readonly_lag": "A base de dados foi automaticamente bloqueada enquanto os servidores secundários se sincronizam com o primário",
+       "nonwrite-api-promise-error": "O cabeçalho HTTP 'Promise-Non-Write-API-Action' foi enviado, mas o pedido está a ser feito a um módulo de escrita da API.",
        "internalerror": "Erro interno",
        "internalerror_info": "Erro interno: $1",
        "internalerror-fatal-exception": "Exceção fatal do tipo \"$1\"",
        "delete-hook-aborted": "A eliminação foi cancelada por um \"hook\".\nNão foi dada nenhuma explicação.",
        "no-null-revision": "Não foi possível criar uma nova revisão nula para a página \"$1\"",
        "badtitle": "Título inválido",
-       "badtitletext": "O título de página solicitado era inválido, vazio, ou a ligação interlínguas estava incorreta.\nTalvez contenha um ou mais caracteres que não podem ser usados em títulos.",
+       "badtitletext": "O título de página solicitado era inválido, vazio, ou um link interlínguas ou interwikis incorrecto.\nTalvez contenha um ou mais caracteres que não podem ser usados em títulos.",
        "title-invalid-empty": "O título da página solicitada está vazio ou contém apenas o nome de um domínio.",
        "title-invalid-utf8": "O título da página solicitada contém uma sequência UTF-8 inválida.",
        "title-invalid-interwiki": "O título da página solicitada contém uma ligação interlíngua que não pode ser utilizada em títulos.",
        "title-invalid-magic-tilde": "O título da página solicitada possui uma sequência de tis inválida (<nowiki>~~~</nowiki>).",
        "title-invalid-too-long": "O título da página solicitada é demasiado longo. Não deverá ser maior que $1 {{PLURAL:$1|byte|bytes}} na codificação UTF-8.",
        "title-invalid-leading-colon": "O título da página solicitada contém um erro de pontuação (:) no início.",
-       "perfcached": "Os seguintes dados encontram-se armazenados na ''cache'' e podem não estar atualizados. No máximo {{PLURAL:$1|um resultado é disponível|$1 resultados são disponíveis}} na ''cache''.",
-       "perfcachedts": "Os seguintes dados encontram-se armazenados na ''cache'' e foram atualizados pela última vez a $1. No máximo {{PLURAL:$4|um resultado está disponível|$4 resultados estão disponíveis}} na ''cache''.",
+       "perfcached": "Os seguintes dados encontram-se armazenados na ''cache'' e podem não estar atualizados. {{PLURAL:$1|Está disponível na ''cache'' um máximo de um resultado|Estão disponíveis na ''cache'' um máximo de $1 resultados}}.",
+       "perfcachedts": "Os seguintes dados encontram-se armazenados na ''cache'' e foram atualizados pela última vez a $1. {{PLURAL:$4|Está disponível na ''cache'' um máximo de um resultado|Estão disponíveis na ''cache'' um máximo de $4 resultados}}.",
        "querypage-no-updates": "As atualizações estão presentemente desativadas para esta página.\nPor enquanto, os dados aqui presentes não poderão ser atualizados.",
        "viewsource": "Ver código-fonte",
        "viewsource-title": "Mostrar código-fonte de $1",
        "cannotlogoutnow-title": "Não é possível encerrar a sessão agora",
        "cannotlogoutnow-text": "Não pode encerrar a sessão quando utilizar $1.",
        "welcomeuser": "Bem-vindo, $1!",
-       "welcomecreation-msg": "A sua conta foi criada.\nNão se esqueça de personalizar as suas [[Special:Preferences|preferências]].",
+       "welcomecreation-msg": "A sua conta foi criada.\nNão se esqueça de personalizar as suas [[Special:Preferences|preferências]] na wiki {{SITENAME}}.",
        "yourname": "Nome de utilizador(a):",
        "userlogin-yourname": "Nome de utilizador(a)",
        "userlogin-yourname-ph": "Digite o seu nome de utilizador(a)",
        "cannotloginnow-title": "Não é possível iniciar sessão agora",
        "cannotloginnow-text": "Não pode iniciar a sessão quando utilizar $1.",
        "cannotcreateaccount-title": "Não é possível criar contas",
+       "cannotcreateaccount-text": "A criação direta de contas não está ativada nesta wiki.",
        "yourdomainname": "O seu domínio:",
        "password-change-forbidden": "Não pode alterar palavras-passe nesta wiki.",
        "externaldberror": "Ocorreu um erro externo à base de dados durante a autenticação ou não lhe é permitido atualizar a sua conta externa.",
        "createacct-another-submit": "Criar conta",
        "createacct-continue-submit": "Continuar criação de conta",
        "createacct-another-continue-submit": "Continuar criação de conta",
-       "createacct-benefit-heading": "{{SITENAME}} é feito por pessoas como você.",
+       "createacct-benefit-heading": "A wiki {{SITENAME}} é feita por pessoas como você.",
        "createacct-benefit-body1": "{{PLURAL:$1|edição|edições}}",
        "createacct-benefit-body2": "{{PLURAL:$1|página|páginas}}",
        "createacct-benefit-body3": "{{PLURAL:$1|contribuidor|contribuidores}} recentes",
        "loginerror": "Erro ao iniciar sessão",
        "createacct-error": "Erro na criação da conta",
        "createaccounterror": "Não foi possível criar a conta: $1",
-       "nocookiesnew": "A conta de utilizador foi criada, mas neste momento não tem sessão iniciada.\nA {{SITENAME}} utiliza ''cookies'' para autenticar os utilizadores.\nOs ''cookies'' estão desativados no seu navegador.\nAtive-os e inicie sessão com o seu nome de utilizador e a sua palavra-passe, por favor.",
-       "nocookieslogin": "A {{SITENAME}} utiliza ''cookies'' para autenticar os utilizadores.\nOs ''cookies'' estão desativados no seu navegador.\nAtive-os e tente novamente, por favor.",
+       "nocookiesnew": "A conta de utilizador foi criada, mas neste momento não tem sessão iniciada.\nA wiki {{SITENAME}} utiliza ''cookies'' para autenticar os utilizadores.\nOs ''cookies'' estão desativados no seu navegador.\nAtive-os e inicie sessão com o seu nome de utilizador e a sua palavra-passe, por favor.",
+       "nocookieslogin": "A wiki {{SITENAME}} utiliza ''cookies'' para autenticar os utilizadores.\nOs ''cookies'' estão desativados no seu navegador.\nAtive-os e tente novamente, por favor.",
        "nocookiesfornew": "A conta de utilizador não foi criada, porque não foi possível confirmar a sua origem.\nCertifique-se de que tem os ''cookies'' ativados, recarregue esta página e tente novamente.",
-       "createacct-loginerror": "A conta foi criada com êxito, mas não pôde ser autenticado automaticamente. Por favor, faça o [[Special:UserLogin|início de sessão manualmente]].",
+       "createacct-loginerror": "A conta foi criada, mas não foi possível iniciar a sessão automaticamente. Por favor, [[Special:UserLogin|inície a sessão manualmente]].",
        "noname": "Não especificou um nome de utilizador válido.",
        "loginsuccesstitle": "Autenticação bem sucedida",
-       "loginsuccess": "'''Encontra-se agora ligado à {{SITENAME}} como \"$1\"'''.",
+       "loginsuccess": "<strong>Encontra-se agora ligado à wiki {{SITENAME}} como \"$1\".</strong>",
        "nosuchuser": "Não existe nenhum utilizador com o nome \"$1\".\nOs nomes de utilizador são sensíveis às letras maiúsculas e minúsculas.\nVerifique a ortografia, ou [[Special:CreateAccount|crie uma nova conta]].",
        "nosuchusershort": "Não existe um utilizador com o nome \"$1\". Verifique o nome que introduziu.",
        "nouserspecified": "Precisa de especificar um nome de utilizador.",
        "password-name-match": "A sua palavra-passe tem de ser diferente do seu nome de utilizador.",
        "password-login-forbidden": "Foi proibido o uso deste nome de utilizador e palavra-passe.",
        "mailmypassword": "Reiniciar a palavra-passe",
-       "passwordremindertitle": "Nova palavra-passe temporária na {{SITENAME}}",
-       "passwordremindertext": "Alguém (provavelmente você, a partir do endereço IP $1) solicitou uma palavra-passe nova para a sua conta na {{SITENAME}} ($4).\nFoi criada a palavra-passe temporária \"$3\" para o utilizador \"$2\".\nSe o pedido foi feito por si, entre agora na sua conta e escolha uma palavra-passe nova.\nA palavra-passe temporária expira após {{PLURAL:$5|um dia|$5 dias}}.\n\nCaso outra pessoa tenha feito o pedido, ou se entretanto se recordou da sua palavra-passe e já não deseja alterá-la, ignore esta mensagem e continue a utilizar a palavra-passe antiga.",
+       "passwordremindertitle": "Nova palavra-passe temporária na wiki {{SITENAME}}",
+       "passwordremindertext": "Alguém (provavelmente você, a partir do endereço IP $1) solicitou uma palavra-passe nova para a sua conta na wiki {{SITENAME}} ($4).\nFoi criada a palavra-passe temporária \"$3\" para o utilizador \"$2\".\nSe o pedido foi feito por si, entre agora na sua conta e escolha uma palavra-passe nova.\nA palavra-passe temporária expira após {{PLURAL:$5|um dia|$5 dias}}.\n\nCaso outra pessoa tenha feito o pedido, ou se entretanto se recordou da sua palavra-passe e já não deseja alterá-la, ignore esta mensagem e continue a utilizar a palavra-passe antiga.",
        "noemail": "Não foi registado um endereço de correio eletrónico para o utilizador \"$1\".",
        "noemailcreate": "Tem de fornecer um endereço de correio eletrónico válido.",
        "passwordsent": "Foi enviada uma palavra-passe nova para o endereço de correio eletrónico do utilizador \"$1\".\nVolte a iniciar sessão após recebê-la, por favor.",
        "eauthentsent": "Foi enviada uma mensagem de confirmação para o endereço de correio eletrónico que especificou.\nAntes que seja enviada qualquer outra mensagem para a conta, terá de seguir as instruções na mensagem enviada, de modo a confirmar que a conta lhe pertence.",
        "throttled-mailpassword": "Já foi enviada um email de recuperação de palavra-passe {{PLURAL:$1|na última hora|nas últimas $1 horas}}.\nPara prevenir abusos, só um email de recuperação de palavra-passe pode ser enviado a cada {{PLURAL:$1|hora|$1 horas}}.",
        "mailerror": "Erro ao enviar correio electrónico: $1",
-       "acct_creation_throttle_hit": "Visitantes desta wiki com o seu endereço IP criaram $1 {{PLURAL:$1|conta|contas}} no último dia, o que é o máximo permitido neste período de tempo.\nEm resultado, visitantes com este endereço IP não podem criar mais nenhuma conta neste momento.",
+       "acct_creation_throttle_hit": "Visitantes desta wiki com endereço IP igual ao seu criaram {{PLURAL:$1|uma conta|$1 contas}} nos últimos (ou últimas) $2, o que é o máximo permitido neste período de tempo.\nEm resultado, visitantes com este endereço IP não podem criar mais nenhuma conta de momento.",
        "emailauthenticated": "O seu endereço de correio eletrónico foi confirmado a $2, às $3.",
        "emailnotauthenticated": "O seu endereço de correio eletrónico ainda não foi confirmado.\nNão lhe serão enviadas mensagens por nenhuma das seguintes funcionalidades.",
        "noemailprefs": "Especifique um endereço de correio eletrónico nas suas preferências para ativar estas funcionalidades.",
        "emaildisabled": "Este sítio não consegue enviar mensagens de correio eletrónico.",
        "accountcreated": "Conta criada",
        "accountcreatedtext": "A conta de utilizador para [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) foi criada.",
-       "createaccount-title": "Criação de conta na {{SITENAME}}",
+       "createaccount-title": "Criação de conta na wiki {{SITENAME}}",
        "createaccount-text": "Alguém criou uma conta com o nome $2 para o seu endereço de correio eletrónico, na wiki {{SITENAME}} ($4), com a palavra-passe \"$3\".\nDeve agora iniciar sessão e alterar a sua palavra-passe.\n\nSe a conta foi criada por engano, pode ignorar esta mensagem.",
        "login-throttled": "Realizou demasiadas tentativas de início de sessão com esta conta.\nAguarde $1 antes de tentar novamente, por favor.",
        "login-abort-generic": "O início de sessão falhou - Cancelado",
        "login-migrated-generic": "A sua conta foi migrada e o seu nome de utilizador já não existe nesta wiki.",
-       "loginlanguagelabel": "Idioma: $1",
+       "loginlanguagelabel": "Língua: $1",
        "suspicious-userlogout": "O seu pedido para sair foi negado porque parece ter sido enviado por um navegador danificado ou por um proxy com cache.",
        "createacct-another-realname-tip": "O fornecimento do nome verdadeiro é opcional.\nSe optar por revelá-lo, ele será utilizado para atribuir-lhe crédito pelo seu trabalho.",
        "pt-login": "Entrar",
        "changepassword-success": "A sua palavra-passe foi alterada!",
        "changepassword-throttled": "Realizou demasiadas tentativas de início de sessão com esta conta.\nAguarde $1 antes de tentar novamente, por favor.",
        "botpasswords": "Palavras-passe de robô",
-       "botpasswords-summary": "As <em>palavras-passe de robô</em> permitem o acesso a uma conta de utilizador através da API sem utilizar as principais credenciais de login da conta. Os direitos de um utilizador, ao iniciar sessão com uma palavra-passe de robô, podem estar limitados.\n\nSe não sabe o que o leva a fazer isso, provavelmente não deveria fazê-lo. Ninguém deve solicitar que gere uma destas palavras-passe e a entregue.",
-       "botpasswords-disabled": "As palavras-passe de robô estão desactivadas.",
+       "botpasswords-summary": "As <em>palavras-passe de robô</em> permitem o acesso a uma conta de utilizador através da API, sem utilizar as credenciais principais de autenticação dessa conta. Os direitos de um utilizador, ao iniciar uma sessão com a palavra-passe de robô, podem estar limitados.\n\nSe não sabe para que necessita desta palavra-passe provavelmente não deveria criá-la. Nunca lhe deve ser solicitado que gere e entregue uma destas palavras-passe.",
+       "botpasswords-disabled": "As palavras-passe de robô estão desativadas.",
        "botpasswords-no-central-id": "Para utilizar palavras-passe de robô, deve iniciar sessão com uma conta centralizada.",
        "botpasswords-existing": "Palavras-passe de robô existentes",
        "botpasswords-createnew": "Criar uma nova palavra-passe para robô",
        "botpasswords-label-cancel": "Cancelar",
        "botpasswords-label-delete": "Eliminar",
        "botpasswords-label-resetpassword": "Redefinir palavra-passe",
-       "botpasswords-label-grants": "Permissões aplicáveis:",
+       "botpasswords-label-grants": "Concessões de permissões aplicáveis:",
+       "botpasswords-help-grants": "As concessões de permissões permitem acesso a permissões já detidas pela sua conta de utilizador. Fazer uma concessão aqui não fornece acesso a quaisquer permissões que a usa conta de utilizador não possua. Consulte a [[Special:ListGrants|tabela de concessões]] para mais informação.",
        "botpasswords-label-grants-column": "Concedido",
        "botpasswords-bad-appid": "O nome do robô \"$1\" não é válido.",
        "botpasswords-insert-failed": "Falhou ao adicionar o nome do robô \"$1\". Já foi adicionado?",
        "botpasswords-update-failed": "Falha ao atualizar o nome do robô \"$1\". Será que foi eliminado?",
        "botpasswords-created-title": "Criada palavra-passe para o robô",
        "botpasswords-created-body": "A palavra-passe de robô para o robô \"$1\" do utilizador \"$2\" foi criada.",
-       "botpasswords-updated-title": "A palavra-passe de robô foi actualizada.",
+       "botpasswords-updated-title": "A palavra-passe de robô foi atualizada.",
        "botpasswords-updated-body": "O robô palavra-passe para o nome do robô \"$1\" do utilizador \"$2\" foi atualizado.",
        "botpasswords-deleted-title": "Palavra-passe de robô eliminada",
        "botpasswords-deleted-body": "O robô palavra-passe para o nome do robô \"$1\"do utilizador \"$2\" foi eliminado.",
-       "botpasswords-newpassword": "A nova palavra-passe para iniciar sessão com <strong>$1</strong> é <strong>$2</strong>. Por favor, recorde-se dela para futura referência.</em>",
+       "botpasswords-newpassword": "A nova palavra-passe para iniciar sessão com <strong>$1</strong> é <strong>$2</strong>. <em>Anote-a para referência futura, por favor.</em> <br> (Para robôs antigos cujo nome de acesso tenha de ser igual ao eventual nome de utilizador, também pode usar o nome de utilizador <strong>$3</strong> e a palavra-passe <strong>$4</strong>.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider não está disponível.",
        "botpasswords-restriction-failed": "Restrições de palavra-passe de robô evitam esta autenticação.",
        "botpasswords-invalid-name": "O nome de utilizador especificado não contém o separador de palavra-passe de robô (\"$1\").",
        "passwordreset-capture": "Ver a mensagem resultante?",
        "passwordreset-capture-help": "Se marcar esta caixa, a mensagem (com a palavra-passe temporária) ser-lhe-á mostrada e enviada ao utilizador.",
        "passwordreset-email": "Correio eletrónico:",
-       "passwordreset-emailtitle": "Detalhes da conta na {{SITENAME}}",
-       "passwordreset-emailtext-ip": "Alguém (provavelmente você, a partir do endereço IP $1) pediu a recuperação da palavra-passe no projeto {{SITENAME}} ($4). {{PLURAL:$3|A seguinte conta de utilizador está associada|As seguintes contas de utilizador estão associadas}} a este correio eletrónico:\n\n$2\n\n{{PLURAL:$3|Esta palavra-passe temporária irá|Estas palavras-passes temporárias irão}} expirar dentro de {{PLURAL:$5|um dia|$5 dias}}.\nDeve autenticar-se e escolher uma palavra-passe nova agora. Se outra pessoa fez este pedido, ou se entretanto se recordou da sua palavra-passe original e já não deseja alterá-la, pode ignorar esta mensagem e continuar a usar a palavra-passe antiga.",
-       "passwordreset-emailtext-user": "O utilizador $1 do projeto {{SITENAME}} pediu a recuperação da sua palavra-passe no projeto {{SITENAME}} ($4). {{PLURAL:$3|A seguinte conta de utilizador está associada|As seguintes contas de utilizador estão associadas}} a este endereço de correio eletrónico:\n\n$2\n\n{{PLURAL:$3|Esta palavra-passe temporária irá|Estas palavras-passes temporárias irão}} expirar dentro de {{PLURAL:$5|um dia|$5 dias}}.\nDeve autenticar-se e escolher uma palavra-passe nova agora. Se outra pessoa fez este pedido, ou se entretanto se recordou da sua palavra-passe original e já não deseja alterá-la, pode ignorar esta mensagem e continuar a usar a palavra-passe antiga.",
+       "passwordreset-emailtitle": "Detalhes da conta na wiki {{SITENAME}}",
+       "passwordreset-emailtext-ip": "Alguém (provavelmente você, a partir do endereço IP $1) pediu a recuperação da palavra-passe na wiki {{SITENAME}} ($4). {{PLURAL:$3|A seguinte conta de utilizador está associada|As seguintes contas de utilizador estão associadas}} a este correio eletrónico:\n\n$2\n\n{{PLURAL:$3|Esta palavra-passe temporária irá|Estas palavras-passes temporárias irão}} expirar dentro de {{PLURAL:$5|um dia|$5 dias}}.\nDeve autenticar-se e escolher uma palavra-passe nova agora. Se outra pessoa fez este pedido, ou se entretanto se recordou da sua palavra-passe original e já não deseja alterá-la, pode ignorar esta mensagem e continuar a usar a palavra-passe antiga.",
+       "passwordreset-emailtext-user": "O utilizador $1 da wiki {{SITENAME}} pediu a recuperação da sua palavra-passe ($4). {{PLURAL:$3|A seguinte conta de utilizador está associada|As seguintes contas de utilizador estão associadas}} a este endereço de correio eletrónico:\n\n$2\n\n{{PLURAL:$3|Esta palavra-passe temporária irá|Estas palavras-passes temporárias irão}} expirar dentro de {{PLURAL:$5|um dia|$5 dias}}.\nDeve autenticar-se e escolher uma palavra-passe nova agora. Se outra pessoa fez este pedido, ou se entretanto se recordou da sua palavra-passe original e já não deseja alterá-la, pode ignorar esta mensagem e continuar a usar a palavra-passe antiga.",
        "passwordreset-emailelement": "{{GENDER:$1|Utilizador|Utilizadora}}: \n$1\n\nPalavra-passe temporária: \n$2",
        "passwordreset-emailsentemail": "Se este é o endereço de correio eletrónico associado a esta conta, ser-lhe-á enviada uma palavra-passe de reposição.",
        "passwordreset-emailsentusername": "Se houver um endereço de correio eletrónico associado a esta conta, ser-lhe-á enviada uma mensagem para redefinir a sua palavra-passe.",
-       "passwordreset-emailsent-capture2": "A redefinição da palavra-passe {{PLURAL:$1|do e-mail|dos e-mails}} foi enviada. {{PLURAL:$1|O nome de utilizador e palavra-passe|A lista de nomes de utilizador e palavras-passe}} encontram-se a seguir.",
-       "passwordreset-emailerror-capture2": "O envio do correio {{GENDER:$2|ao utilizador|à utilizadora|a(o) utilizador(a)}} falhou: $1 {{PLURAL:$3|O nome de utilizador e palavra-passe são mostradas abaixo|A lista de nomes de utilizadores e palavras-passe é mostrada abaixo}}.",
+       "passwordreset-emailsent-capture2": "{{PLURAL:$1|A mensagem|As mensagens}} de redefinição da palavra-passe {{PLURAL:$1|foi enviada|foram enviadas}} para o seu correio eletrónico. {{PLURAL:$1|O nome de utilizador e palavra-passe encontram-se|A lista de nomes de utilizador e palavras-passe encontra-se}} a seguir.",
+       "passwordreset-emailerror-capture2": "O envio do correio {{GENDER:$2|ao utilizador|à utilizadora|a(o) utilizador(a)}} falhou: $1 {{PLURAL:$3|O nome de utilizador e palavra-passe são mostrados aqui|A lista de nomes de utilizador e palavras-passe é mostrada aqui}}.",
        "passwordreset-nocaller": "Um interlocutor deve ser fornecido",
        "passwordreset-nosuchcaller": "A pessoa que chama não existe: $1",
-       "passwordreset-ignored": "A reposição de palavra-passe não foi realizada. Talvez não tenha sido configurado o provedor?",
-       "passwordreset-invalideamil": "Correio eletrónico inválido",
+       "passwordreset-ignored": "A reposição de palavra-passe não foi realizada. Talvez o fornecedor não tenha sido configurado?",
+       "passwordreset-invalidemail": "Correio eletrónico inválido",
        "passwordreset-nodata": "Não foram fornecidos nome de utilizador(a) nem endereço de correio eletrónico",
        "changeemail": "Alterar ou remover o endereço de correio eletrónico",
        "changeemail-header": "Complete este formulário para alterar o seu endereço de correio eletrónico. Se quer eliminar a associação de qualquer endereço de correio eletrónico com a sua conta, deixe em branco o novo endereço de correio eletrónico ao submeter o formulário.",
        "changeemail-newemail": "Novo endereço de correio eletrónico:",
        "changeemail-newemail-help": "Este campo deve ser deixado em branco caso pretenda remover o seu endereço de correio eletrónico.\nNão será capaz de redefinir a sua palavra-passe nem receber mensagens eletrónicas desta wiki se efetuar esta operação.",
        "changeemail-none": "(nenhum)",
-       "changeemail-password": "A sua palavra-passe em {{SITENAME}}:",
+       "changeemail-password": "A sua palavra-passe na wiki {{SITENAME}}:",
        "changeemail-submit": "Alterar correio eletrónico",
        "changeemail-throttled": "Realizou demasiadas tentativas de início de sessão.\nAguarde $1 antes de tentar novamente, por favor.",
        "changeemail-nochange": "Por favor insira um novo endereço de e-mail.",
        "explainconflict": "A página foi alterada por alguém desde que começou a editá-la.\nA caixa de texto abaixo mostra o texto existente neste momento.\nAs suas mudanças são mostradas na área ao fundo da página.\nTerá de reintegrar as suas mudanças no texto da caixa abaixo.\n'''Só''' o texto desta caixa será gravado quando clicar \"{{int:savearticle}}\".",
        "yourtext": "O seu texto",
        "storedversion": "Versão gravada",
-       "nonunicodebrowser": "'''Aviso: O seu navegador não é compatível com as especificações Unicode.\nFoi activado um sistema de edição alternativo que lhe permite editar as páginas com segurança: os caracteres não-ASCII aparecerão na caixa de edição no formato de códigos hexadecimais.'''",
+       "nonunicodebrowser": "<strong>Aviso: O seu navegador não é compatível com as especificações Unicode.</strong>\nFoi ativado um sistema de edição alternativo que lhe permite editar as páginas com segurança: os caracteres não-ASCII aparecerão na caixa de edição no formato de códigos hexadecimais.",
        "editingold": "'''Aviso: Está a editar uma revisão desatualizada desta página.'''\nSe gravar, todas as mudanças feitas a partir desta revisão serão perdidas.",
        "yourdiff": "Diferenças",
-       "copyrightwarning": "Note, por favor, que todas as suas contribuições na {{SITENAME}} são consideradas publicadas nos termos da licença $2 (consulte $1 para mais detalhes).\nSe não deseja que o seu texto possa ser inexoravelmente editado e redistribuído, não o envie.\nGarante-nos também que isto é algo escrito por si, ou copiado do domínio público ou de outra fonte de teor livre.<br />\n'''Não envie conteúdos cujos direitos de autor estão protegidos, sem ter a devida permissão!'''",
-       "copyrightwarning2": "Note, por favor, que todas as suas contribuições na {{SITENAME}} podem ser editadas, alteradas ou removidas por outros utilizadores.\nSe não deseja que o seu texto seja inexoravelmente editado, não o envie.<br />\nGarante-nos também que isto é algo escrito por si, ou copiado do domínio público ou de outra fonte de teor livre (consulte $1 para mais detalhes).<br />\n'''Não envie conteúdos cujos direitos de autor estão protegidos, sem ter a devida permissão!'''",
+       "copyrightwarning": "Note, por favor, que todas as suas contribuições na wiki {{SITENAME}} são consideradas publicadas nos termos da licença $2 (consulte $1 para mais detalhes).\nSe não deseja que o seu texto possa ser inexoravelmente editado e redistribuído, não o envie.\nGarante-nos também que isto é algo escrito por si, ou copiado do domínio público ou de outra fonte de teor livre.<br />\n<strong>Não envie conteúdos cujos direitos de autor estão protegidos, sem ter a devida permissão!</strong>",
+       "copyrightwarning2": "Note, por favor, que todas as suas contribuições na wiki {{SITENAME}} podem ser editadas, alteradas ou removidas por outros utilizadores.\nSe não deseja que o seu texto seja inexoravelmente editado, não o envie.<br />\nGarante-nos também que isto é algo escrito por si, ou copiado do domínio público ou de outra fonte de teor livre (consulte $1 para mais detalhes).<br />\n<strong>Não envie conteúdos cujos direitos de autor estão protegidos, sem ter a devida permissão!</strong>",
        "editpage-cannot-use-custom-model": "O modelo de conteúdo desta página não pode ser alterado.",
        "longpageerror": "'''Erro: O texto que submeteu ocupa {{PLURAL:$1|um kilobyte|$1 kilobytes}}, que excede o máximo de {{PLURAL:$2|um kilobyte|$2 kilobytes}}.'''\nA página não pode ser gravada.",
        "readonlywarning": "<strong>Atenção: A base de dados foi bloqueada para manutenção, pelo que não poderá gravar as suas edições neste momento.</strong>\nPode, contudo, copiar e colar o seu texto num ficheiro de texto e guardá-lo para mais tarde.\n\nO administrador do sistema que a bloqueou forneceu a seguinte explicação: $1",
        "template-semiprotected": "(semi-protegida)",
        "hiddencategories": "Esta página pertence a {{PLURAL:$1|uma categoria oculta|$1 categorias ocultas}}:",
        "edittools": "<!-- O texto colocado aqui será mostrado abaixo dos formulários de edição e de envio de ficheiros. -->",
-       "nocreatetext": "A {{SITENAME}} restringe a criação de páginas novas por utilizadores anónimos.\nPode voltar atrás e editar uma página já existente, ou [[Special:UserLogin|inicie sessão ou criar uma conta]].",
+       "nocreatetext": "A wiki {{SITENAME}} restringe a criação de páginas novas por utilizadores anónimos.\nPode voltar atrás e editar uma página já existente, ou [[Special:UserLogin|iniciar uma sessão ou criar uma conta]].",
        "nocreate-loggedin": "Não possui permissão para criar novas páginas.",
        "sectioneditnotsupported-title": "Edição de secções não suportada",
        "sectioneditnotsupported-text": "A edição de secções não é suportada nesta página de edição.",
        "permissionserrorstext": "Não possui permissão para fazer isso, {{PLURAL:$1|pelo seguinte motivo|pelos seguintes motivos}}:",
        "permissionserrorstext-withaction": "Não possui permissão para $2, {{PLURAL:$1|pelo seguinte motivo|pelos seguintes motivos}}:",
        "contentmodelediterror": "Não pode editar esta revisão pois seu modelo de conteúdo é <code>$1</code>, que é diferente do modelo atual da página <code>$2</code>.",
-       "recreate-moveddeleted-warn": "'''Aviso: Está a recriar uma página anteriormente eliminada.'''\n\nVerifique se é apropriado continuar a editar esta página.\nPara sua conveniência, é apresentado de seguida o registo de eliminação e de movimento da página:",
-       "moveddeleted-notice": "Esta página foi eliminada.\nPara referência, é apresentado de seguida o registo de eliminações e de movimento da página.",
+       "recreate-moveddeleted-warn": "<strong>Aviso: Está a recriar uma página anteriormente eliminada.</strong>\n\nVerifique se é apropriado continuar a editar esta página.\nPara sua conveniência, é apresentado abaixo o registo de eliminação e movimentação da página:",
+       "moveddeleted-notice": "Esta página foi eliminada.\nPara sua referência, é apresentado abaixo o registo de eliminação e movimentação da página.",
        "moveddeleted-notice-recent": "Desculpe, esta página foi eliminada recentemente (nas últimas 24 horas).\nA exclusão e registo de movimentação para a página são fornecidos abaixo para referência.",
        "log-fulllog": "Ver registo detalhado",
        "edit-hook-aborted": "A edição foi abortada por um hook.\nNão foi dada nenhuma explicação.",
        "content-json-empty-object": "Objeto vazio",
        "content-json-empty-array": "Matriz vazia",
        "deprecated-self-close-category": "Páginas com etiquetas HTML de autofechamento não válidas",
+       "deprecated-self-close-category-desc": "Esta página contém marcações HTML auto-fechadas, que são inválidas, tais como <code>&lt;b/></code> ou <code>&lt;span/></code>.  O comportamento destas tags será alterado em breve, para ser consistente com a especificação HTML5, pelo que o seu uso na notação wiki foi descontinuado.",
        "duplicate-args-warning": "<strong>Aviso:</strong> [[:$1]] chama [[:$2]] com mais de um valor para o parâmetro \"$3\". Somente o último valor fornecido será utilizado.",
        "duplicate-args-category": "Páginas com argumentos de predefinições duplicados",
-       "duplicate-args-category-desc": "A página contém campos de predefinições que utilizam duplicatas de argumentos, tais como <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> ou <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
+       "duplicate-args-category-desc": "A página contém chamadas de predefinições que passam à predefinição argumentos duplicados, tais como <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> ou <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "'''Aviso:''' Esta página contém demasiadas chamadas de funções exigentes do analisador sintático.\n\nDevia ter menos de $2 {{PLURAL:$2|chamada|chamadas}}. Neste momento tem $1 {{PLURAL:$1|chamada|chamadas}}.",
        "expensive-parserfunction-category": "Páginas com demasiadas chamadas a funções exigentes",
        "post-expand-template-inclusion-warning": "Aviso: O tamanho de inclusão de predefinições é demasiado grande, algumas predefinições não serão incluídas.",
        "logdelete-selected": "{{PLURAL:$1|Evento do registo selecionado|Eventos do registo selecionados}}:",
        "revdelete-text-text": "Revisões eliminadas ainda aparecerão no histórico da página, mas parte do seu conteúdo estará inacessível para o público.",
        "revdelete-text-file": "Versões eliminadas do ficheiro ainda aparecerão no histórico da página, mas parte do seu conteúdo estará inacessível para o público.",
-       "logdelete-text": "Os eventos eliminados ainda aparecerão no histórico da página, mas pare de seu conteúdo será inacessível ao público.",
+       "logdelete-text": "Os eventos eliminados ainda aparecerão no histórico da página, mas parte do seu conteúdo será inacessível ao público.",
        "revdelete-text-others": "Outros administradores serão ainda capazes de aceder ao conteúdo oculto e torná-lo visível novamente, a menos que sejam definidas restrições adicionais.",
        "revdelete-confirm": "Por favor, confirme que pretende executar esta operação, que compreende as suas consequências e que o faz em concordância com as [[{{MediaWiki:Policy-url}}|políticas e recomendações]].",
        "revdelete-suppress-text": "A supressão '''só''' deverá ser usada nos seguintes casos:\n* Informação potencialmente caluniosa, difamatória ou injuriosa\n* Informação pessoal imprópria\n*: ''endereços de domicílio e números de telefone, números de identificação nacional, etc''",
        "revdelete-legend": "Definir restrições de visibilidade",
-       "revdelete-hide-text": "Revisão do texto",
+       "revdelete-hide-text": "Texto da revisão",
        "revdelete-hide-image": "Ocultar conteúdo do ficheiro",
        "revdelete-hide-name": "Ocultar destino e parâmetros",
        "revdelete-hide-comment": "Resumo da edição",
-       "revdelete-hide-user": "Nome de utilizador/endereço de IP",
+       "revdelete-hide-user": "Nome de utilizador/endereço IP",
        "revdelete-hide-restricted": "Ocultar dados dos administradores e de todos os outros",
        "revdelete-radio-same": "(manter)",
        "revdelete-radio-set": "Oculto",
        "mergehistory-fail-bad-timestamp": "Registo data/hora inválido",
        "mergehistory-fail-invalid-source": "Página de origem inválida.",
        "mergehistory-fail-invalid-dest": "Página de destino inválida.",
+       "mergehistory-fail-no-change": "A fusão de histórico não fundiu nenhuma revisão. Verifique os parâmetros de página e tempo, por favor.",
        "mergehistory-fail-permission": "Privilégios insuficientes para fundir os históricos.",
        "mergehistory-fail-self-merge": "As páginas de origem e de destino não podem ser a mesma.",
+       "mergehistory-fail-timestamps-overlap": "As revisões de origem sobrepõem ou são posteriores às revisões de destino.",
        "mergehistory-fail-toobig": "Não é possível fundir o histórico, já que um número de revisão(ões) acima do limite ($1 {{PLURAL:$1|revisão|revisões}}) seriam movidos.",
        "mergehistory-no-source": "A página de origem $1 não existe.",
        "mergehistory-no-destination": "A página de destino $1 não existe.",
        "powersearch-togglenone": "Nenhum",
        "powersearch-remember": "Lembrar seleção para pesquisas futuras",
        "search-external": "Pesquisa externa",
-       "searchdisabled": "Foi impossibilitada a realização de pesquisas na {{SITENAME}}.\nEntretanto, pode realizar pesquisas através do Google.\nNote, no entanto, que a indexação da {{SITENAME}} neste motor de busca pode estar desatualizada.",
+       "searchdisabled": "Foi impossibilitada a realização de pesquisas na wiki {{SITENAME}}.\nEntretanto, pode realizar pesquisas através do Google.\nNote, no entanto, que a indexação da wiki {{SITENAME}} neste motor de busca pode estar desatualizada.",
        "search-error": "Um erro ocorreu enquanto se efectuava a pesquisa: $1",
        "preferences": "Preferências",
        "mypreferences": "Preferências",
        "right-reupload-shared": "Sobrescrever localmente ficheiros no repositório partilhado de imagens",
        "right-upload_by_url": "Carregar um ficheiro de um endereço URL",
        "right-purge": "Limpar a ''cache'' de uma página no servidor sem confirmação",
-       "right-autoconfirmed": "Não ser afetado pelos limites de frequência baseados no número de IP",
+       "right-autoconfirmed": "Não ser afetado pelos limites de frequência de edição baseados em endereços IP",
        "right-bot": "Ser tratado como um processo automatizado",
-       "right-nominornewtalk": "Não despoletar o aviso de mensagens novas ao fazer edições menores a páginas de discussão",
+       "right-nominornewtalk": "Não desencadear o aviso de mensagens novas ao fazer edições menores a páginas de discussão",
        "right-apihighlimits": "Usar limites superiores nas consultas ''(queries)'' via API",
        "right-writeapi": "Usar a API de escrita",
        "right-delete": "Eliminar páginas",
        "right-ipblock-exempt": "Contornar bloqueios de IP, bloqueios automáticos e bloqueios de gamas de IP",
        "right-unblockself": "Desbloquearem-se a si próprios",
        "right-protect": "Mudar níveis de proteção e editar páginas protegidas em cascata",
-       "right-editprotected": "Editar páginas protegidas como \"{{int:protect-level-sysop}}\"",
-       "right-editsemiprotected": "Editar páginas protegidas como \"{{int:protect-level-autoconfirmed}}\"",
+       "right-editprotected": "Editar páginas protegidas com \"{{int:protect-level-sysop}}\"",
+       "right-editsemiprotected": "Editar páginas protegidas com \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Editar o modelo de conteúdo de uma página",
        "right-editinterface": "Editar a interface de utilizador",
        "right-editusercssjs": "Editar os ficheiros CSS e JS de outros utilizadores",
        "right-edituserjs": "Editar os ficheiros JS de outros utilizadores",
        "right-editmyusercss": "Editar os seus próprios ficheiros CSS de utilizador",
        "right-editmyuserjs": "Editar os seus próprios ficheiros JavaScript de utilizador",
-       "right-viewmywatchlist": "Ver a sua lista de vigiados",
+       "right-viewmywatchlist": "Ver a sua lista de páginas vigiadas",
        "right-editmywatchlist": "Editar a sua própria lista de páginas vigiadas. Observe que algumas ações continuaram a adicionar páginas, mesmo sem este direito.",
        "right-viewmyprivateinfo": "Ver os seus próprios dados privados (ex.: endereço de correio eletrónico, nome real)",
        "right-editmyprivateinfo": "Editar os seus próprios dados privados (ex.: endereço de correio eletrónico, nome real)",
        "right-editmyoptions": "Editar as suas próprias preferências",
        "right-rollback": "Reverter rapidamente as edições do último utilizador que editou uma página em particular",
        "right-markbotedits": "Marcar edições revertidas como edições de robô",
-       "right-noratelimit": "Não ser afetado pelos limites de velocidade de operação",
+       "right-noratelimit": "Não ser afetado pelos limites de frequência de edição",
        "right-import": "Importar páginas de outras wikis",
        "right-importupload": "Importar páginas de um ficheiro xml",
        "right-patrol": "Marcar edições de outros utilizadores como patrulhadas",
        "grant-generic": "Conjunto de direitos \"$1\"",
        "grant-group-page-interaction": "Interagir com páginas",
        "grant-group-file-interaction": "Interagir com conteúdo multimédia",
-       "grant-group-watchlist-interaction": "Interagir com a sua lista de vigiados",
+       "grant-group-watchlist-interaction": "Interagir com a sua lista de páginas vigiadas",
        "grant-group-email": "Enviar correio electrónico",
-       "grant-group-high-volume": "Realizar actividades em grande quantidade",
+       "grant-group-high-volume": "Realizar atividades em grande quantidade",
        "grant-group-customization": "Personalização e preferências",
        "grant-group-administration": "Executar acções administrativas",
        "grant-group-private-information": "Aceder aos seus dados privados",
-       "grant-group-other": "Actividade diversa",
+       "grant-group-other": "Atividades diversas",
        "grant-blockusers": "Bloquear e desbloquear utilizadores",
        "grant-createaccount": "Criar contas",
        "grant-createeditmovepage": "Criar, editar e mover páginas",
        "grant-editinterface": "Editar o domínio MediaWiki e o CSS/JavaScript do utilizador",
        "grant-editmycssjs": "Editar o seu CSS/JavaScript personalizado",
        "grant-editmyoptions": "Editar as suas preferências de utilizador",
-       "grant-editmywatchlist": "Editar a sua lista de vigiados",
+       "grant-editmywatchlist": "Editar a sua lista de páginas vigiadas",
        "grant-editpage": "Editar páginas existentes",
        "grant-editprotected": "Editar páginas protegidas",
        "grant-highvolume": "Alta quantidade de edições",
        "grant-oversight": "Ocultar utilizadores e edições suprimidas",
        "grant-patrol": "Patrulhar alterações a páginas",
+       "grant-privateinfo": "Aceder a informação privada",
        "grant-protect": "Proteger e desproteger páginas",
        "grant-rollback": "Reverter alterações a páginas",
        "grant-sendemail": "Enviar correio electrónico a outros utilizadores",
        "grant-uploadfile": "Carregar novos ficheiros",
        "grant-basic": "Direitos básicos",
        "grant-viewdeleted": "Ver páginas e ficheiros eliminados",
-       "grant-viewmywatchlist": "Ver a sua lista de vigiados",
+       "grant-viewmywatchlist": "Ver a sua lista de páginas vigiadas",
+       "grant-viewrestrictedlogs": "Ver entradas de registo restritas",
        "newuserlogpage": "Registo de criação de utilizadores",
        "newuserlogpagetext": "Este é um registo de novas contas de utilizador",
        "rightslog": "Registo de privilégios de utilizadores",
        "action-upload": "enviar este ficheiro",
        "action-reupload": "sobrescrever este ficheiro existente",
        "action-reupload-shared": "sobrepor este ficheiro num repositório partilhado",
-       "action-upload_by_url": "enviar este ficheiro através de uma URL",
+       "action-upload_by_url": "enviar este ficheiro através de um URL",
        "action-writeapi": "utilizar o modo de escrita da API",
        "action-delete": "eliminar esta página",
        "action-deleterevision": "eliminar esta edição",
        "action-managechangetags": "criar e (des)ativar etiquetas",
        "action-applychangetags": "aplicar etiquetas juntamente com as suas alterações",
        "action-changetags": "adicionar e remover etiquetas arbitrárias em revisões e entradas de registo individuais",
+       "action-deletechangetags": "eliminar etiquetas da base de dados",
        "action-purge": "recarregar esta página",
        "nchanges": "$1 {{PLURAL:$1|alteração|alterações}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|desde a última visita}}",
        "enhancedrc-history": "histórico",
        "recentchanges": "Mudanças recentes",
        "recentchanges-legend": "Opções das mudanças recentes",
-       "recentchanges-summary": "Acompanha nesta página as mudanças mais recentes desta wiki.",
+       "recentchanges-summary": "Acompanhe nesta página as mudanças mais recentes da wiki.",
        "recentchanges-noresult": "Nenhuma alteração correspondente a esses critérios foi realizada durante o período selecionado.",
        "recentchanges-feed-description": "Acompanhe neste ''feed'' as mudanças mais recentes da wiki.",
        "recentchanges-label-newpage": "Esta edição criou uma nova página",
        "upload_directory_missing": "O diretório de carregamento de ficheiros ($1) não existe e o servidor de Internet não conseguiu criá-lo.",
        "upload_directory_read_only": "O servidor de Internet não possui permissão de escrita no diretório de carregamento de ficheiros ($1).",
        "uploaderror": "Erro ao carregar",
-       "upload-recreate-warning": "'''Aviso: Um ficheiro com esse nome foi eliminado ou movido.'''\n\nPara sua conveniência, é apresentado de seguida o registo de eliminação e de movimento da página:",
-       "uploadtext": "Utilize o formulário abaixo para fazer o carregamento de novos ficheiros.\nPara ver ou pesquisar ficheiros anteriormente enviados, consulte a [[Special:FileList|lista de ficheiros]].\nOs reenvios de um ficheiro são também registados no [[Special:Log/upload|registo de carregamentos]] e as eliminações no [[Special:Log/delete|registo de eliminações]].\n\nPara utilizar um ficheiro numa página, depois de ter feito o carregamento, insira uma ligação com um dos seguintes formatos:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:ficheiro.jpg]]</nowiki></code>''' para mostrar uma imagem nas suas dimensões originais;\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:ficheiro.png|200px|thumb|left|texto]]</nowiki></code>''' para mostrar uma imagem com a dimensão horizontal de 200 pixeis, dentro de uma caixa, na margem esquerda, contendo 'texto' como descrição (pode usar subconjuntos destas características);\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:ficheiro.ogg]]</nowiki></code>''' para apresentar uma ligação direta para o ficheiro em vez de mostrá-lo, quer este tenha por conteúdo uma imagem ou outros dados.",
+       "upload-recreate-warning": "<strong>Aviso: Um ficheiro com esse nome foi eliminado ou movido.</strong>\n\nPara sua conveniência, é apresentado abaixo o registo de eliminação e movimentação da página:",
+       "uploadtext": "Utilize o formulário abaixo para fazer o carregamento de novos ficheiros.\nPara ver ou pesquisar ficheiros anteriormente enviados, consulte a [[Special:FileList|lista de ficheiros]].\nOs reenvios de um ficheiro são também registados no [[Special:Log/upload|registo de carregamentos]] e as eliminações no [[Special:Log/delete|registo de eliminações]].\n\nPara utilizar um ficheiro numa página, depois de ter feito o carregamento, insira uma ligação com um dos seguintes formatos:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:ficheiro.jpg]]</nowiki></code>''' para mostrar uma imagem nas suas dimensões originais;\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:ficheiro.png|200px|thumb|left|texto]]</nowiki></code>''' para mostrar uma imagem com a dimensão horizontal de 200 píxeis, dentro de uma caixa, na margem esquerda, contendo 'texto' como descrição (pode usar subconjuntos destas características);\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:ficheiro.ogg]]</nowiki></code>''' para apresentar uma ligação direta para o ficheiro em vez de mostrá-lo, quer este tenha por conteúdo uma imagem ou outros dados.",
        "upload-permitted": "{{PLURAL:$2|Tipo|Tipos}} de ficheiro {{PLURAL:$2|permitido|permitidos}}: $1.",
        "upload-preferred": "{{PLURAL:$2|Tipo|Tipos}} de ficheiro {{PLURAL:$2|preferido|preferidos}}: $1.",
        "upload-prohibited": "{{PLURAL:$2|Tipo|Tipos}} de ficheiro {{PLURAL:$2|proibido|proibidos}}: $1.",
        "uploaddisabledtext": "O carregamento de ficheiros está desativado.",
        "php-uploaddisabledtext": "O carregamento de ficheiros está desativado no PHP.\nVerifique a configuração file_uploads, por favor.",
        "uploadscripted": "Este ficheiro contém HTML ou código que pode ser erradamente interpretado por um navegador.",
-       "upload-scripted-pi-callback": "Não se podem carregar arquivos que contenham instruções de processamento de páginas de estilo XML",
+       "upload-scripted-pi-callback": "Não é possível carregar ficheiros que contenham instruções de processamento de páginas de estilo XML.",
        "uploaded-script-svg": "Encontrou um elemento scriptable no ficheiro \"$1\" SVG carregado.",
-       "uploaded-hostile-svg": "Encontrou-se um código CSS não seguro no elemento de estilo do arquivo SVG carregado.",
-       "uploaded-event-handler-on-svg": "Não está permitido configurar atributos controladores de eventos <code>$1=\"$2\"</code> nos arquivos SVG.",
-       "uploaded-image-filter-svg": "Foi encontrado um filtro de imagem com a URL: <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG carregado.",
+       "uploaded-hostile-svg": "Encontrou-se um código CSS não seguro no elemento de estilo do ficheiro SVG carregado.",
+       "uploaded-event-handler-on-svg": "Não á permitido configurar atributos controladores de eventos <code>$1=\"$2\"</code> nos ficheiros SVG.",
+       "uploaded-href-attribute-svg": "Os atributos <code>href</code> em ficheiros SVG só estão autorizados a ligar a endereços http:// ou https://, mas foi encontrado <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "Detetado <code>href</code> para dados inseguros: alvo URI <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG carregado.",
+       "uploaded-animate-svg": "Foi detetado um elemento \"animate\" que pode estar a alterar <code>href</code>, usando o atributo \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG carregado.",
+       "uploaded-setting-event-handler-svg": "A definição de atributos controladores de eventos está bloqueada. Foi detetado <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG carregado.",
+       "uploaded-setting-href-svg": "O uso da tag \"set\" para adicionar o atributo \"href\" ao elemento mãe está bloqueado.",
+       "uploaded-wrong-setting-svg": "O uso da tag \"set\" para adicionar um destino remoto/de dados/<i>script</i> a qualquer atributo está bloqueado. No ficheiro SVG enviado foi encontrado <code>&lt;set to=\"$1\"&gt;</code>.",
+       "uploaded-setting-handler-svg": "A configuração do atributo \"handler\" com destino remoto/de dados/<i>script</i> em ficheiros SVG está bloqueada. Foi detetado <code>$1=\"$2\"</code> no ficheiro SVG carregado.",
+       "uploaded-remote-url-svg": "A configuração de qualquer atributo de estilo com um URL remoto em ficheiros SVG está bloqueada. Foi detetado <code>$1=\"$2\"</code> no ficheiro SVG carregado.",
+       "uploaded-image-filter-svg": "Foi encontrado um filtro de imagem com o URL: <code>&lt;$1 $2=\"$3\"&gt;</code> no ficheiro SVG carregado.",
        "uploadscriptednamespace": "Este ficheiro SVG contém um domínio que não é permitido \"$1\".",
        "uploadinvalidxml": "Erro detectado na análise do XML do ficheiro carregado.",
        "uploadvirus": "O ficheiro contém um vírus! \nDetalhes: $1",
        "upload-file-error-text": "Ocorreu um erro interno ao tentar criar um ficheiro temporário no servidor.\nContacte um [[Special:ListUsers/sysop|administrador]], por favor.",
        "upload-misc-error": "Erro de carregamento desconhecido",
        "upload-misc-error-text": "Ocorreu um erro desconhecido durante o envio.\nVerifique se o endereço (URL) é válido e acessível e tente novamente.\nCaso o problema persista, contacte um [[Special:ListUsers/sysop|administrador]].",
-       "upload-too-many-redirects": "A URL continha demasiados redirecionamentos",
+       "upload-too-many-redirects": "O URL continha demasiados redirecionamentos",
        "upload-http-error": "Ocorreu um erro HTTP: $1",
-       "upload-copy-upload-invalid-domain": "Não é possível realizar carregamentos remotos neste domínio.",
+       "upload-copy-upload-invalid-domain": "Não é possível carregar cópias de ficheiros vindos deste domínio.",
        "upload-foreign-cant-upload": "Esta wiki não está configurada para carregar ficheiros para o repositório externo solicitado.",
+       "upload-foreign-cant-load-config": "Não foi possível inserir a configuração de carregamento de ficheiros no repositório externo.",
+       "upload-dialog-disabled": "O carregamento de ficheiros através deste diálogo está desativado na wiki.",
        "upload-dialog-title": "Carregar ficheiro",
        "upload-dialog-button-cancel": "Cancelar",
+       "upload-dialog-button-back": "Voltar",
        "upload-dialog-button-done": "Feito",
        "upload-dialog-button-save": "Gravar",
        "upload-dialog-button-upload": "Carregar",
        "upload-form-label-infoform-title": "Detalhes",
        "upload-form-label-infoform-name": "Nome",
+       "upload-form-label-infoform-name-tooltip": "Um título descritivo e único para ser usado como nome do ficheiro. Pode usar linguagem normal e espaços. Não inclua a extensão do ficheiro.",
        "upload-form-label-infoform-description": "Descrição",
+       "upload-form-label-infoform-description-tooltip": "Descreva de forma breve todos os elementos de nota sobre o trabalho.\nPara uma fotografia, mencione os principais motivos fotografados, a ocasião, ou o lugar.",
        "upload-form-label-usage-title": "Uso",
        "upload-form-label-usage-filename": "Nome do ficheiro",
        "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-generic-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-generic-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-own-work-message-generic-local": "Confirmo que estou a carregar este ficheiro segundo as condições de serviço e política de licenças da wiki {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-generic-local": "Se não pode carregar este ficheiro de acordo com as normas da wiki {{SITENAME}}, por favor feche esta janela e tente outro método.",
        "upload-form-label-not-own-work-local-generic-local": "Poderá querer experimentar [[Special:Upload|a página padrão de carregamento]].",
        "upload-form-label-own-work-message-generic-foreign": "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-generic-foreign": "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-generic-foreign": "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-not-own-work-local-generic-foreign": "Pode querer tentar utilizar [[Special:Upload|a página de carregamento na wiki {{SITENAME}}]], se este ficheiro puder ser carregado de acordo com as normas da wiki.",
        "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.",
        "uploadstash-errclear": "Não foi possível apagar os ficheiros.",
        "uploadstash-refresh": "Atualizar a lista de ficheiros",
        "uploadstash-thumbnail": "ver miniatura",
+       "uploadstash-exception": "Não foi possível gravar o carregamento na área de ficheiros escondidos ($1): \"$2\".",
        "invalid-chunk-offset": "Deslocamento de fragmento inválido",
        "img-auth-accessdenied": "Acesso negado",
        "img-auth-nopathinfo": "PATH_INFO em falta.\nO seu servidor não está configurado para passar esta informação.\nPode ser baseado em CGI e não consegue suportar img_auth.\nConsulte a documentação em https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-streaming": "A fazer a transmissão de \"$1\".",
        "img-auth-public": "A função do img_auth.php é produzir ficheiros a partir de uma wiki privada.\nEsta wiki está configurada como uma wiki pública.\nPara optimizar a segurança, o img_auth.php está impossibilitado de executar.",
        "img-auth-noread": "O utilizador não tem acesso de leitura ao ficheiro \"$1\".",
-       "http-invalid-url": "URL inválida: $1",
-       "http-invalid-scheme": "URL iniciadas pelo prefixo \"$1\" não são aceites.",
+       "http-invalid-url": "URL inválido: $1",
+       "http-invalid-scheme": "URL iniciados pelo prefixo \"$1\" não são aceites.",
        "http-request-error": "O pedido HTTP falhou devido a um erro desconhecido.",
        "http-read-error": "Erro de leitura HTTP.",
        "http-timed-out": "O pedido HTTP expirou.",
-       "http-curl-error": "Ocorreu um erro ao aceder à URL: $1",
+       "http-curl-error": "Ocorreu um erro ao aceder ao URL: $1",
        "http-bad-status": "Ocorreu um problema durante o pedido HTTP: $1 $2",
-       "upload-curl-error6": "Não foi possível aceder à URL",
-       "upload-curl-error6-text": "Não foi possível aceder à URL.\nVerifique se o endereço está correto e o sítio disponível, por favor.",
+       "upload-curl-error6": "Não foi possível aceder ao URL",
+       "upload-curl-error6-text": "Não foi possível aceder ao URL.\nVerifique se o endereço está correto e o sítio disponível, por favor.",
        "upload-curl-error28": "Tempo limite para o envio do ficheiro excedido",
        "upload-curl-error28-text": "O sítio demorou muito tempo a responder. Verifique que o sítio está disponível, aguarde alguns momentos e tente novamente, por favor. Talvez queira tentar num horário menos congestionado.",
        "license": "Licença:",
        "nolicense": "Nenhuma selecionada",
        "licenses-edit": "Editar opções de licença",
        "license-nopreview": "(Antevisão indisponível)",
-       "upload_source_url": "(um ficheiro de uma URL válida, publicamente acessível)",
+       "upload_source_url": "(um ficheiro de um URL válido, publicamente acessível)",
        "upload_source_file": "(um ficheiro no seu computador)",
        "listfiles-delete": "eliminar",
        "listfiles-summary": "Esta página especial mostra todos os ficheiros carregados.",
        "filerevert-submit": "Reverter",
        "filerevert-success": "'''[[Media:$1|$1]]''' foi revertida para a [$4 versão das $3 de $2].",
        "filerevert-badversion": "Não há uma versão local anterior deste ficheiro no período de tempo especificado.",
+       "filerevert-identical": "A versão atual do ficheiro já é idêntica à selecionada.",
        "filedelete": "Eliminar $1",
        "filedelete-legend": "Eliminar ficheiro",
        "filedelete-intro": "Está prestes a eliminar o ficheiro '''[[Media:$1|$1]]''' e todo o seu histórico.",
        "filedelete-success": "'''$1''' foi eliminado.",
        "filedelete-success-old": "A versão de '''[[Media:$1|$1]]''' tal como $3, $2 foi eliminada.",
        "filedelete-nofile": "'''$1''' não existe.",
-       "filedelete-nofile-old": "Não há nenhuma versão de '''$1''' em arquivo com os parâmetros especificados.",
+       "filedelete-nofile-old": "Não há nenhuma versão de <strong>$1</strong> em arquivo com os atributos especificados.",
        "filedelete-otherreason": "Outro/motivo adicional:",
        "filedelete-reason-otherlist": "Outro motivo",
        "filedelete-reason-dropdown": "*Motivos comuns para eliminação\n** Violação de direitos de autor\n** Ficheiro duplicado",
        "filedelete-edit-reasonlist": "Editar motivos de eliminação",
        "filedelete-maintenance": "Eliminação e restauro de ficheiros foram temporariamente impossibilitadas durante a manutenção.",
        "filedelete-maintenance-title": "Não é possível eliminar o ficheiro",
-       "mimesearch": "Pesquisa MIME",
-       "mimesearch-summary": "Esta página permite a filtragem de ficheiros pelo seu tipo MIME. Entrada: contenttype/subtype ou contenttype/*, ex. <code>image/jpeg</code>.",
+       "mimesearch": "Pesquisa de ficheiros pelo tipo MIME",
+       "mimesearch-summary": "Esta página permite a filtragem de ficheiros pelo seu tipo MIME.\nSintaxe: \"tipo de conteúdo/subtipo\" ou \"tipo de conteúdo/*\". Exemplos, <code>image/jpeg</code>, <code>image/png</code>, <code>application/*</code>.",
        "mimetype": "Tipo MIME:",
        "download": "descarregar",
        "unwatchedpages": "Páginas não vigiadas",
-       "listredirects": "Lista de redirecionamentos",
-       "listduplicatedfiles": "Lista de ficheiros com duplicatas",
-       "listduplicatedfiles-summary": "Esta é uma lista de ficheiros cuja suas versões mais recentes são duplicatas da versão mais recente de outros ficheiros. Somente os ficheiros locais são considerados.",
-       "listduplicatedfiles-entry": "[[:File:$1|$1]] possui [[$3|{{PLURAL:$2|uma duplicata|$2 duplicatas}}]].",
+       "listredirects": "Redirecionamentos",
+       "listduplicatedfiles": "Ficheiros com duplicados",
+       "listduplicatedfiles-summary": "Esta é uma lista de ficheiros cuja versões mais recentes são duplicados da versão mais recente de outros ficheiros. Só os ficheiros locais são considerados.",
+       "listduplicatedfiles-entry": "[[:File:$1|$1]] tem [[$3|{{PLURAL:$2|um duplicado|$2 duplicados}}]].",
        "unusedtemplates": "Predefinições não utilizadas",
        "unusedtemplatestext": "Esta página lista todas as páginas no domínio {{ns:template}} que não são incluídas em nenhuma outra página. Lembre-se de verificar a existência de outras ligações para as predefinições, antes de eliminá-las.",
        "unusedtemplateswlh": "outras ligações",
        "randomincategory-nopages": "Não há páginas na categoria [[:Category:$1|$1]].",
        "randomincategory-category": "Categoria:",
        "randomincategory-legend": "Página aleatória na categoria",
-       "randomincategory-submit": "Ir",
+       "randomincategory-submit": "Continuar",
        "randomredirect": "Redirecionamento aleatório",
        "randomredirect-nopages": "Não há redirecionamentos no domínio \"$1\".",
        "statistics": "Estatísticas",
        "statistics-pages": "Páginas",
        "statistics-pages-desc": "Todas as páginas da wiki, incluindo páginas de discussão, redirecionamentos, etc.",
        "statistics-files": "Ficheiros carregados",
-       "statistics-edits": "Edições de páginas desde que a {{SITENAME}} foi instalada",
+       "statistics-edits": "Edições de páginas desde que a wiki {{SITENAME}} foi instalada",
        "statistics-edits-average": "Média de edições por página",
        "statistics-users": "[[Special:ListUsers|Utilizadores]] registados",
        "statistics-users-active": "Utilizadores ativos",
        "statistics-users-active-desc": "Utilizadores que efectuaram uma operação {{PLURAL:$1|no último dia|nos últimos $1 dias}}",
-       "pageswithprop": "Páginas com uma propriedade",
-       "pageswithprop-legend": "Páginas com uma propriedade",
+       "pageswithprop": "Páginas que usam uma propriedade",
+       "pageswithprop-legend": "Páginas que usam uma propriedade",
        "pageswithprop-text": "Esta página lista páginas que usam uma propriedade em particular.",
        "pageswithprop-prop": "Nome da propriedade:",
        "pageswithprop-submit": "Avançar",
        "fewestrevisions": "Páginas com menos revisões",
        "nbytes": "$1 {{PLURAL:$1|byte|bytes}}",
        "ncategories": "$1 {{PLURAL:$1|categoria|categorias}}",
-       "ninterwikis": "$1 {{PLURAL:$1|interlíngua|interlínguas}}",
+       "ninterwikis": "$1 {{PLURAL:$1|interwiki|interwikis}}",
        "nlinks": "$1 {{PLURAL:$1|ligação|ligações}}",
        "nmembers": "$1 {{PLURAL:$1|membro|membros}}",
        "nmemberschanged": "$1 → $2 {{PLURAL:$2|membro|membros}}",
        "ntransclusions": "usada {{PLURAL:$1|numa página|em $1 páginas}}",
        "specialpage-empty": "Não existem dados para apresentar.",
        "lonelypages": "Páginas órfãs",
-       "lonelypagestext": "As seguintes páginas não são destino de ligação nem são transcluídas a partir de outras páginas na {{SITENAME}}.",
+       "lonelypagestext": "As seguintes páginas não são destino de links nem são transcluídas a partir de outras páginas na wiki {{SITENAME}}.",
        "uncategorizedpages": "Páginas não categorizadas",
        "uncategorizedcategories": "Categorias não categorizadas",
        "uncategorizedimages": "Ficheiros não categorizados",
        "mostlinkedtemplates": "Páginas mais transcluídas",
        "mostcategories": "Páginas com mais categorias",
        "mostimages": "Ficheiros com mais afluentes",
-       "mostinterwikis": "Páginas com mais interlínguas",
+       "mostinterwikis": "Páginas com mais ligações interwikis",
        "mostrevisions": "Páginas com mais revisões",
        "prefixindex": "Todas as páginas iniciadas por",
        "prefixindex-namespace": "Todas as páginas com prefixo (domínio $1)",
        "shortpages": "Páginas curtas",
        "longpages": "Páginas longas",
        "deadendpages": "Páginas sem saída",
-       "deadendpagestext": "As seguintes páginas não contêm ligações para outras páginas em {{SITENAME}}.",
+       "deadendpagestext": "As seguintes páginas não contêm links para outras páginas na wiki {{SITENAME}}.",
        "protectedpages": "Páginas protegidas",
        "protectedpages-indef": "Apenas proteções indefinidas",
        "protectedpages-summary": "Esta página lista páginas existentes que estão protegidas. Para ver os títulos cuja criação está impossibilitada, consulte [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-performer": "Protetor",
        "protectedpages-params": "Parâmetros de proteção",
        "protectedpages-reason": "Motivo",
-       "protectedpages-submit": "Exibir páginas",
+       "protectedpages-submit": "Mostrar páginas",
        "protectedpages-unknown-timestamp": "Desconhecido",
        "protectedpages-unknown-performer": "Utilizador desconhecido",
        "protectedtitles": "Títulos protegidos",
        "protectedtitles-summary": "Esta página lista títulos cuja criação está impossibilitada. Para ver uma lista de páginas protegidas, consulte [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Neste momento, nenhum dos títulos está protegido com estes parâmetros.",
-       "protectedtitles-submit": "Exibir de títulos",
+       "protectedtitles-submit": "Mostrar títulos",
        "listusers": "Utilizadores",
        "listusers-editsonly": "Mostrar apenas utilizadores com edições",
        "listusers-creationsort": "Ordenar por data de criação",
        "ancientpages": "Páginas mais antigas",
        "move": "Mover",
        "movethispage": "Mover esta página",
-       "unusedimagestext": "Os seguintes ficheiros existem mas não são usados na wiki.\nNo entanto, outros sítios na Internet podem ter ligação para um ficheiro através de uma URL direta e, por isso, podem estar listados ficheiros que estão a ser ativamente usados por entidades externas.",
+       "unusedimagestext": "Os seguintes ficheiros existem mas não são usados na wiki.\nNo entanto, outros sítios na Internet podem ter ligação para um ficheiro através de um URL direto e, por isso, podem estar listados ficheiros que estão a ser ativamente usados por entidades externas.",
        "unusedcategoriestext": "As seguintes categorias existem, embora nenhuma página ou categoria faça uso delas.",
        "notargettitle": "Sem alvo",
        "notargettext": "Especifique sobre que página alvo ou utilizador pretende executar esta função.",
        "pager-older-n": "{{PLURAL:$1|1 anterior|$1 anteriores}}",
        "suppress": "Suprimir",
        "querypage-disabled": "Esta página especial está desativada para não prejudicar o desempenho.",
-       "apihelp": "Ajuda API",
+       "apihelp": "Ajuda da API",
        "apihelp-no-such-module": "Módulo \"$1\" não encontrado.",
        "apisandbox": "Testes da API",
+       "apisandbox-jsonly": "Para usar a área de testes da API é necessário o JavaScript.",
        "apisandbox-api-disabled": "A API está desativada neste site.",
-       "apisandbox-intro": "Use esta página para fazer experiências com a <strong>API de serviços da web do MediaWiki</strong>.\nConsulte a [[mw:API:Main page|documentação da API]] para informações sobre o uso da API. Exemplo: [https://www.mediawiki.org/wiki/API#A_simple_example obter o conteúdo da Página Principal]. Selecione uma operação para ver 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 fazer experiências com a <strong>API operacional do MediaWiki</strong>.\nConsulte a [[mw:API:Main page|documentação da API]] para informações sobre o seu uso. Exemplo: [https://www.mediawiki.org/wiki/API#A_simple_example obter o conteúdo da Página Principal]. Selecione uma operação para ver 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-fullscreen": "Expandir painel",
        "apisandbox-fullscreen-tooltip": "Expandir o painel da página de testes para preencher a janela do navegador.",
        "apisandbox-unfullscreen": "Mostrar página",
+       "apisandbox-unfullscreen-tooltip": "Reduza o painel da área de testes, para que as ligações de navegação estejam disponíveis.",
        "apisandbox-submit": "Fazer o pedido",
        "apisandbox-reset": "Limpar",
        "apisandbox-retry": "Tentar novamente",
        "apisandbox-results": "Resultados",
        "apisandbox-sending-request": "A enviar solicitação de API...",
        "apisandbox-loading-results": "A receber resultados da API...",
+       "apisandbox-results-error": "Ocorreu um erro ao carregar a resposta à consulta por API: $1",
        "apisandbox-request-url-label": "URL do pedido:",
        "apisandbox-request-time": "Tempo de processamento: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Corrija o identificador e volte a submete-lo",
        "apisandbox-results-fixtoken-fail": "Não foi possível obter o identificador \"$1\".",
        "apisandbox-alert-page": "Os campos nesta página não são válidos.",
        "apisandbox-alert-field": "O valor deste campo não é válido.",
+       "apisandbox-continue": "Continuar",
+       "apisandbox-continue-clear": "Limpar",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries continuará] o último pedido; {{int:apisandbox-continue-clear}} limpará os parâmetros relativos à continuação.",
+       "apisandbox-param-limit": "Introduza <kbd>max</kbd> para usar o limite máximo.",
        "booksources": "Fontes bibliográficas",
        "booksources-search-legend": "Pesquisar referências bibliográficas",
        "booksources-search": "Pesquisar",
        "booksources-text": "É apresentada abaixo uma lista de ligações para outros sítios na Internet que vendem livros novos e usados e talvez possuam informações adicionais sobre os livros que procura:",
        "booksources-invalid-isbn": "O número ISBN fornecido não parece ser válido; verifique a existência de erros ao copiar da fonte original.",
+       "magiclink-tracking-rfc": "Páginas que usam links mágicos RFC",
+       "magiclink-tracking-rfc-desc": "Esta página usa links mágicos RFC. Consulte a [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] para saber como migrar.",
+       "magiclink-tracking-pmid": "Páginas que usam links mágicos PMID",
+       "magiclink-tracking-pmid-desc": "Esta página usa links mágicos PMID. Consulte a [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] para saber como migrar.",
+       "magiclink-tracking-isbn": "Páginas que usam links mágicos ISBN",
+       "magiclink-tracking-isbn-desc": "Esta página usa links mágicos ISBN. Consulte a [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] para saber como migrar.",
        "specialloguserlabel": "Executante:",
        "speciallogtitlelabel": "Alvo (título ou página ou {{ns:user}}:nome de utilizador):",
        "log": "Registos",
        "allpagessubmit": "Ver",
        "allpagesprefix": "Apresentar páginas iniciadas por:",
        "allpagesbadtitle": "O título de página fornecido era inválido ou tinha um prefixo interlínguas ou interwikis.\nTalvez contenha um ou mais caracteres que não podem ser usados nos títulos.",
-       "allpages-bad-ns": "{{SITENAME}} não possui o domínio \"$1\".",
+       "allpages-bad-ns": "A wiki {{SITENAME}} não possui o espaço nominal \"$1\".",
        "allpages-hide-redirects": "Ocultar redirecionamentos",
        "cachedspecial-viewing-cached-ttl": "Está a ver uma versão desta página guardada na cache há pelo menos $1.",
        "cachedspecial-viewing-cached-ts": "Está a ver uma versão da página guardada na cache, que pode estar desatualizada.",
        "listusers-submit": "Mostrar",
        "listusers-noresult": "Não foram encontrados utilizadores.",
        "listusers-blocked": "({{GENDER:$1|bloqueado|bloqueada|bloqueado(a)}})",
-       "activeusers": "Lista de utilizadores ativos",
+       "activeusers": "Utilizadores ativos",
        "activeusers-intro": "Esta é uma lista dos utilizadores com qualquer tipo de atividade {{PLURAL:$1|no último dia|nos últimos $1 dias}}.",
        "activeusers-count": "$1 {{PLURAL:$1|ação|ações}} {{PLURAL:$3|no último dia|nos últimos $3 dias}}",
        "activeusers-from": "Mostrar utilizadores começados por:",
-       "activeusers-hidebots": "Ocultar robôs",
-       "activeusers-hidesysops": "Ocultar administradores",
+       "activeusers-groups": "Apresentar os utilizadores que pertencem aos grupos:",
        "activeusers-noresult": "Nenhum utilizador encontrado.",
-       "activeusers-submit": "Exibir utilizadores ativos",
+       "activeusers-submit": "Mostrar utilizadores ativos",
        "listgrouprights": "Privilégios dos grupos de utilizadores",
        "listgrouprights-summary": "A seguinte lista contém os grupos de utilizadores definidos nesta wiki, com os respectivos privilégios de acesso.\nEncontram-se disponíveis [[{{MediaWiki:Listgrouprights-helppage}}|informações adicionais]] sobre privilégios individuais.",
        "listgrouprights-key": "Legenda:\n* <span class=\"listgrouprights-granted\">Privilégio concedido</span>\n* <span class=\"listgrouprights-revoked\">Privilégio revogado</span>",
        "listgrouprights-removegroup-self": "Remover a própria conta {{PLURAL:$2|do grupo|dos grupos}}: $1",
        "listgrouprights-addgroup-self-all": "Adicionar a própria conta a todos os grupos",
        "listgrouprights-removegroup-self-all": "Remover a própria conta de todos os grupos",
-       "listgrouprights-namespaceprotection-header": "Restrições do domínio",
+       "listgrouprights-namespaceprotection-header": "Restrições de domínios",
        "listgrouprights-namespaceprotection-namespace": "Domínio",
        "listgrouprights-namespaceprotection-restrictedto": "Direito(s) do utilizador para editar",
-       "listgrants": "Atribuições",
-       "listgrants-summary": "Esta é uma lista de atribuições com os respetivos acessos às permissões de utilizador. Os utilizadores podem autorizar aplicações a utilizar suas contas, mas com permissões limitadas baseadas nas atribuições dadas pelos utilizadores a cada aplicação. No entanto, uma aplicação agindo em nome de um utilizador não pode utilizar permissões que o utilizador não possui.\nPode haver [[{{MediaWiki:Listgrouprights-helppage}}|informação adicional]] sobre permissões individuais.",
-       "listgrants-grant": "Atribuição",
-       "listgrants-rights": "Direitos",
+       "listgrants": "Concessões de permissões a aplicações ligadas",
+       "listgrants-summary": "Esta é uma lista das possíveis concessões de permissões e das respetivas permissões dos utilizadores que são atribuídas por cada concessão. Os utilizadores podem autorizar aplicações a utilizar a sua conta, agindo assim em seu nome mas com as permissões limitadas com base nestas concessões. Uma aplicação que age em nome de um utilizador não pode utilizar permissões que o utilizador não possui.\nPoderá existir [[{{MediaWiki:Listgrouprights-helppage}}|informação adicional]] sobre as permissões individuais.",
+       "listgrants-grant": "Concessão de permissões",
+       "listgrants-rights": "Permissões",
        "trackingcategories": "Categorias de monitorização",
-       "trackingcategories-summary": "Esta página lista as categorias monitoradas que foram geradas automaticamente pelo software MediaWiki. Os seus nomes podem ser alterados ao editar sua mensagem correspondente no domínio {{ns:8}}.",
+       "trackingcategories-summary": "Esta página lista as categorias de monitorização geradas automaticamente pelo software MediaWiki. Os nomes das categorias podem ser alterados modificando as mensagens de sistema relevantes no domínio {{ns:8}}.",
        "trackingcategories-msg": "Categoria monitorada",
        "trackingcategories-name": "Nome da mensagem",
        "trackingcategories-desc": "Critérios de inclusão",
-       "restricted-displaytitle-ignored": "Páginas com títulos de exibição ignorados",
+       "restricted-displaytitle-ignored": "Páginas com títulos de apresentação ignorados",
        "restricted-displaytitle-ignored-desc": "Esta página tem um <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> ignorado porque não é equivalente ao título verdadeiro da página.",
-       "noindex-category-desc": "A página não é indexada por robôs porque contém a palavra mágica <code><nowiki>__NOINDEX__</nowiki></code> e está num domínio onde o estatuto é permitido.",
+       "noindex-category-desc": "A página não é indexada por robôs porque contém a palavra mágica <code><nowiki>__NOINDEX__</nowiki></code> e está num domínio onde esta palavra mágica é permitida.",
        "index-category-desc": "A página contém a palavra mágica <code><nowiki>__INDEX__</nowiki></code> (e está num domínio em que essa marca é permitida) e, portanto, será indexada pelos robôs mesmo quando normalmente não o seria.",
        "post-expand-template-inclusion-category-desc": "O tamanho da página é superior a <code>$wgMaxArticleSize</code>, após a expansão de todas as predefinições, pelo que algumas predefinições não foram expandidas.",
        "post-expand-template-argument-category-desc": "O tamanho da página é superior a <code>$wgMaxArticleSize</code>, após a expansão de um argumento de predefinição (algo em chavetas triplas, como <code>{{{Foo}}}</code>).",
        "emailuser-title-target": "Enviar correio eletrónico a {{GENDER:$1|este utilizador|esta utilizadora|este(a) utilizador(a)}}",
        "emailuser-title-notarget": "Enviar correio eletrónico ao utilizador",
        "emailpagetext": "Pode usar o formulário abaixo para enviar uma mensagem por correio eletrónico para {{GENDER:$1|este utilizador|esta utilizadora}}.\nO endereço de correio que introduziu nas [[Special:Preferences|suas preferências]] irá aparecer no campo do remetente da mensagem \"De:\", para que o destinatário lhe possa responder diretamente.",
-       "defemailsubject": "Correio eletrónico da {{SITENAME}}, {{GENDER:$1|do utilizador|da utilizadora|do(a) utilizador(a)}} \"$1\"",
+       "defemailsubject": "Correio eletrónico {{GENDER:$1|do utilizador|da utilizadora}} \"$1\" da wiki {{SITENAME}}",
        "usermaildisabled": "O correio eletrónico do utilizador foi desativado",
        "usermaildisabledtext": "Não pode enviar correio eletrónico a outros utilizadores desta wiki",
        "noemailtitle": "Sem endereço de correio eletrónico",
        "emailtarget": "Introduza o nome do(a) destinatário(a)",
        "emailusername": "Utilizador(a):",
        "emailusernamesubmit": "Enviar",
-       "email-legend": "Enviar uma mensagem a outro utilizador da {{SITENAME}}",
+       "email-legend": "Enviar uma mensagem a outro utilizador da wiki {{SITENAME}}",
        "emailfrom": "De:",
        "emailto": "Para:",
        "emailsubject": "Assunto:",
        "emailccsubject": "Cópia da sua mensagem para $1: $2",
        "emailsent": "Mensagem enviada",
        "emailsenttext": "A sua mensagem foi enviada.",
-       "emailuserfooter": "Esta mensagem foi {{GENDER:$1|enviada}} por $1 para {{GENDER:$2|$2}} através da opção \"{{int:emailuser}}\" em {{SITENAME}}.",
+       "emailuserfooter": "Esta mensagem foi {{GENDER:$1|enviada}} por $1 para {{GENDER:$2|$2}} através da opção \"{{int:emailuser}}\" da wiki {{SITENAME}}.",
        "usermessage-summary": "Deixar mensagem de sistema.",
        "usermessage-editor": "Editor de mensagens de sistema",
        "watchlist": "Páginas vigiadas",
        "wlshowhideliu": "utilizadores registados",
        "wlshowhideanons": "utilizadores anónimos",
        "wlshowhidepatr": "edições patrulhadas",
-       "wlshowhidemine": "minhas edições",
+       "wlshowhidemine": "edições minhas",
        "wlshowhidecategorization": "categorização de páginas",
        "watchlist-options": "Opções da lista de páginas vigiadas",
        "watching": "A vigiar...",
        "unwatching": "A deixar de vigiar...",
        "watcherrortext": "Ocorreu um erro ao alterar a configuração da sua lista de páginas vigiadas para \"$1\".",
        "enotif_reset": "Marcar todas as páginas como visitadas",
-       "enotif_impersonal_salutation": "Utilizador de {{SITENAME}}",
-       "enotif_subject_deleted": "A página  $1 de {{SITENAME}} foi {{GENDER:$2|eliminada}} por $2",
-       "enotif_subject_created": "A página $1 de {{SITENAME}} foi {{GENDER:$2|criada}} por $2",
-       "enotif_subject_moved": "A página $1 de {{SITENAME}} foi {{GENDER:$2|movida}} por $2",
-       "enotif_subject_restored": "A página $1 de {{SITENAME}} foi {{GENDER:$2|restaurada}} por $2",
-       "enotif_subject_changed": "A página $1 de {{SITENAME}} foi {{GENDER:$2|alterada}} por $2",
-       "enotif_body_intro_deleted": "A página $1 de {{SITENAME}} foi {{GENDER:$2|eliminada}} em $PAGEEDITDATE por $2, ver $3.",
-       "enotif_body_intro_created": "A página $1 em {{SITENAME}} foi {{GENDER:$2| criada}} em $PAGEEDITDATE por $2, ver $3 para a versão atual.",
-       "enotif_body_intro_moved": "A página $1 em {{SITENAME}} foi {{GENDER:$2|movida}} em $PAGEEDITDATE por $2, ver $3 para a versão atual.",
-       "enotif_body_intro_restored": "A página $1 em {{SITENAME}} foi {{GENDER:$2|restaurada}} em $PAGEEDITDATE por $2, ver $3 para a versão atual.",
-       "enotif_body_intro_changed": "A página $1 em {{SITENAME}} foi {{GENDER:$2|alterada}} em $PAGEEDITDATE por $2, ver $3 para a versão atual.",
+       "enotif_impersonal_salutation": "Utilizador da wiki {{SITENAME}}",
+       "enotif_subject_deleted": "A página $1 da wiki {{SITENAME}} foi eliminada {{GENDER:$2|pelo utilizador|pela utilizadora}} $2",
+       "enotif_subject_created": "A página $1 da wiki {{SITENAME}} foi criada {{GENDER:$2|pelo utilizador|pela utilizadora}} $2",
+       "enotif_subject_moved": "A página $1 da wiki {{SITENAME}} foi movida {{GENDER:$2|pelo utilizador|pela utilizadora}} $2",
+       "enotif_subject_restored": "A página $1 da wiki {{SITENAME}} foi restaurada {{GENDER:$2|pelo utilizador|pela utilizadora}} $2",
+       "enotif_subject_changed": "A página $1 da wiki {{SITENAME}} foi alterada {{GENDER:$2|pelo utilizador|pela utilizadora}} $2",
+       "enotif_body_intro_deleted": "A página $1 da wiki {{SITENAME}} foi eliminada a $PAGEEDITDATE {{GENDER:$2|pelo utilizador|pela utilizadora}} $2. Veja $3.",
+       "enotif_body_intro_created": "A página $1 da wiki {{SITENAME}} foi criada a $PAGEEDITDATE {{GENDER:$2|pelo utilizador|pela utilizadora}} $2. Veja a revisão atual em $3.",
+       "enotif_body_intro_moved": "A página $1 da wiki {{SITENAME}} foi movida a $PAGEEDITDATE {{GENDER:$2|pelo utilizador|pela utilizadora}} $2. Veja a revisão atual em $3.",
+       "enotif_body_intro_restored": "A página $1 da wiki {{SITENAME}} foi restaurada a $PAGEEDITDATE {{GENDER:$2|pelo utilizador|pela utilizadora}} $2. Veja a revisão atual em $3.",
+       "enotif_body_intro_changed": "A página $1 da wiki {{SITENAME}} foi alterada a  $PAGEEDITDATE {{GENDER:$2|pelo utilizador|pela utilizadora}} $2. Veja a revisão atual em $3.",
        "enotif_lastvisited": "Consulte $1 para todas as alterações efetuadas desde a sua última visita.",
        "enotif_lastdiff": "Consulte $1 para ver esta alteração.",
        "enotif_anon_editor": "utilizador anónimo $1",
-       "enotif_body": "{{GENDER:$WATCHINGUSERNAME|Caro|Cara|Caro(a)}} $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nResumo da edição: $PAGESUMMARY $PAGEMINOREDIT\n\nContacte o editor:\ncorreio eletrónico: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nAté se autenticar e visitar novamente esta página, não receberá mais notificações das alterações futuras. Também pode reativar as notificações para todas páginas na sua lista de páginas vigiadas.\n\nO seu sistema de notificação amigável da {{SITENAME}}\n\n--\nPara alterar as suas preferências de notificação por correio eletrónico, visite\n{{canonicalurl:{{#special:Preferences}}}}\n\nPara alterar as suas preferências das páginas vigiadas, visite\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nPara retirar a página da lista de páginas vigiadas, visite\n$UNWATCHURL\n\nPara comentários e pedidos de ajuda:\n$HELPPAGE",
+       "enotif_body": "{{GENDER:$WATCHINGUSERNAME|Caro|Cara|Caro(a)}} $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nResumo da edição: $PAGESUMMARY $PAGEMINOREDIT\n\nContacte o editor:\ncorreio eletrónico: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nAté se autenticar e visitar novamente esta página, não receberá mais notificações das alterações futuras. Também pode reativar as notificações para todas páginas na sua lista de páginas vigiadas.\n\nO seu sistema de notificação amigável da wiki {{SITENAME}}\n\n--\nPara alterar as suas preferências de notificação por correio eletrónico, visite\n{{canonicalurl:{{#special:Preferences}}}}\n\nPara alterar as suas preferências das páginas vigiadas, visite\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nPara retirar a página da lista de páginas vigiadas, visite\n$UNWATCHURL\n\nPara comentários e pedidos de ajuda:\n$HELPPAGE",
        "created": "criada",
        "changed": "alterada",
        "deletepage": "Eliminar página",
        "deletereasonotherlist": "Outro motivo",
        "deletereason-dropdown": "* Motivos de eliminação comuns\n** Spam\n** Vandalismo\n** Violação de direitos de autor\n** Pedido do autor\n** Redirecionamento quebrado",
        "delete-edit-reasonlist": "Editar motivos de eliminação",
-       "delete-toobig": "Esta página tem um histórico longo, com mais de $1 {{PLURAL:$1|edição|edições}}.\nA eliminação de páginas como esta foi restringida na {{SITENAME}}, para evitar problemas acidentais.",
-       "delete-warning-toobig": "Esta página tem um histórico de edições longo, com mais de $1 {{PLURAL:$1|edição|edições}}.\nEliminá-la poderá causar problemas na base de dados da {{SITENAME}};\nprossiga com precaução.",
+       "delete-toobig": "Esta página tem um histórico longo, com mais de $1 {{PLURAL:$1|edição|edições}}.\nA eliminação de páginas como esta foi restringida na wiki {{SITENAME}}, para evitar problemas acidentais.",
+       "delete-warning-toobig": "Esta página tem um histórico de edições longo, com mais de $1 {{PLURAL:$1|edição|edições}}.\nEliminá-la poderá causar problemas na base de dados da wiki {{SITENAME}};\nprossiga com precaução.",
        "deleteprotected": "Não é possível eliminar esta página porque foi protegida.",
        "deleting-backlinks-warning": "<strong>Aviso:</strong> Existem [[Special:WhatLinksHere/{{FULLPAGENAME}}|páginas]] que contêm ligações para a página que está prestes a eliminar ou que a transcluem.",
        "rollback": "Reverter edições",
        "rollback-success-notify": "Revertidas as edições de $1;\nMudança para a última revisão de $2. [$3 Mostrar alterações]",
        "sessionfailure-title": "Erro de sessão",
        "sessionfailure": "Foram detectados problemas com a sua sessão;\na operação foi cancelada como medida de proteção contra a interceptação de sessões.\nVolte à página anterior, recarregue-a e tente novamente.",
-       "changecontentmodel": "Editar o modelo de conteúdo de uma página",
+       "changecontentmodel": "Alterar modelo de conteúdo de uma página",
        "changecontentmodel-legend": "Editar modelo de contéudo",
        "changecontentmodel-title-label": "Título da página",
        "changecontentmodel-model-label": "Novo modelo de conteúdo",
        "modifiedarticleprotection": "alterou o nível de proteção para \"[[$1]]\"",
        "unprotectedarticle": "desprotegeu \"[[$1]]\"",
        "movedarticleprotection": "moveu as configurações de proteção de \"[[$2]]\" para \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|Protegeu}} \"[[$1]]\"",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Alterou o nível de proteção}} de \"[[$1]]\"",
+       "unprotectedarticle-comment": "{{GENDER:$2|Removeu a proteção}} de \"[[$1]]\"",
        "protect-title": "Alterar o nível de proteção de \"$1\"",
        "protect-title-notallowed": "Ver o nível de proteção de \"$1\"",
        "prot_1movedto2": "moveu [[$1]] para [[$2]]",
        "undeletehistorynoadmin": "Esta página foi eliminada. O motivo de eliminação é apresentado no sumário abaixo, junto dos detalhes do utilizador que editou esta página antes de eliminar. O texto atual destas edições eliminadas encontra-se agora apenas disponível para administradores.",
        "undelete-revision": "Edição eliminada da página $1 (das $5 de $4), por $3:",
        "undeleterevision-missing": "Edição inválida ou não encontrada.\nPode ter usado uma ligação incorreta ou talvez a revisão tenha sido restaurada ou removida do arquivo.",
+       "undeleterevision-duplicate-revid": "Não foi possível restaurar {{PLURAL:$1|uma revisão|$1 revisões}}, porque {{PLURAL:$1|a sua <code>rev_id</code> já estava a ser usada|as respetivas <code>rev_id</code> já estavam a ser usadas}}.",
        "undelete-nodiff": "Não foram encontradas edições anteriores.",
        "undeletebtn": "Restaurar",
        "undeletelink": "ver/restaurar",
        "namespace_association": "Domínio associado",
        "tooltip-namespace_association": "Marque esta caixa para incluir também o domínio de conteúdo ou de discussão associado à sua seleção",
        "blanknamespace": "(Principal)",
-       "contributions": "Contribuições {{GENDER:$1|do utilizador|da utilizadora|do(a) utilizador(a)}}",
-       "contributions-title": "Contribuições {{GENDER:$1|do utilizador|da utilizadora|do(a) utilizador(a)}} $1",
+       "contributions": "Contribuições {{GENDER:$1|do utilizador|da utilizadora}}",
+       "contributions-title": "Contribuições {{GENDER:$1|do utilizador|da utilizadora}} $1",
        "mycontris": "Contribuições",
        "anoncontribs": "Contribuições",
        "contribsub2": "Para {{GENDER:$3|$1}} ($2)",
        "sp-contributions-blocked-notice": "Este utilizador está bloqueado neste momento.\nPara referência é apresentado abaixo o último registo de bloqueio:",
        "sp-contributions-blocked-notice-anon": "Este endereço IP está bloqueado neste momento.\nPara referência é apresentado abaixo o último registo de bloqueio:",
        "sp-contributions-search": "Pesquisar contribuições",
-       "sp-contributions-username": "Endereço de IP ou utilizador(a):",
+       "sp-contributions-username": "Endereço IP ou nome de utilizador:",
        "sp-contributions-toponly": "Mostrar apenas as edições mais recentes",
        "sp-contributions-newonly": "Mostrar só edições que são criações de páginas",
        "sp-contributions-hideminor": "Ocultar edições menores",
        "whatlinkshere-hideredirs": "$1 redirecionamentos",
        "whatlinkshere-hidetrans": "$1 transclusões",
        "whatlinkshere-hidelinks": "$1 ligações",
-       "whatlinkshere-hideimages": "$1 links para arquivos",
+       "whatlinkshere-hideimages": "$1 ligações para ficheiros",
        "whatlinkshere-filters": "Filtros",
-       "whatlinkshere-submit": "Ir",
-       "autoblockid": "Bloqueio automático nº$1",
+       "whatlinkshere-submit": "Continuar",
+       "autoblockid": "Bloqueio automático nº $1",
        "block": "Bloquear utilizador(a)",
        "unblock": "Desbloquear utilizador",
        "blockip": "Bloquear {{GENDER:$1|utilizador|utilizadora|utilizador(a)}}",
        "blockip-legend": "Bloquear utilizador(a)",
        "blockiptext": "Utilize o formulário abaixo para bloquear o acesso de escrita a um endereço IP específico ou a um nome de utilizador(a).\nIsto só deve ser feito para prevenir vandalismo e de acordo com a [[{{MediaWiki:Policy-url}}|política]]. Indique a seguir um motivo de bloqueio específico (por exemplo, indicando as páginas que foram alvo de vandalismo).\nPode bloquear intervalos de endereços IP com a sintaxe [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]; o maior intervalo permitido é /$1 para IPv4 e /$2 para IPv6.",
-       "ipaddressorusername": "Endereço de IP ou utilizador(a):",
+       "ipaddressorusername": "Endereço IP ou nome de utilizador:",
        "ipbexpiry": "Expiração:",
        "ipbreason": "Motivo:",
        "ipbreason-dropdown": "*Razões comuns para um bloqueio\n** Inserção de informações falsas\n** Remoção de conteúdos de páginas\n** Inserção de \"spam\" para sítios externos\n** Inserção de conteúdo sem sentido/incompreensível nas páginas\n** Comportamento intimidador/inoportuno\n** Uso abusivo de contas múltiplas\n** Nome de utilizador inaceitável",
        "blocklist-userblocks": "Ocultar bloqueios de contas",
        "blocklist-tempblocks": "Ocultar bloqueios temporários",
        "blocklist-addressblocks": "Ocultar bloqueios de IP único",
-       "blocklist-rangeblocks": "Ocultar bloqueios de faixas",
+       "blocklist-rangeblocks": "Ocultar bloqueios de gamas",
        "blocklist-timestamp": "Data e hora",
        "blocklist-target": "Destinatário",
        "blocklist-expiry": "Expira",
        "unblock-hideuser": "Não pode desbloquear o utilizador, porque o nome deste utilizador foi oculto.",
        "ipb_cant_unblock": "Erro: O bloqueio com ID $1 não foi encontrado. Pode já ter sido desbloqueado.",
        "ipb_blocked_as_range": "Erro: O IP $1 não se encontra bloqueado de forma direta e não pode ser desbloqueado deste modo. No entanto, está bloqueado como parte da gama $2, a qual pode ser desbloqueada.",
-       "ip_range_invalid": "Gama de IP inválida.",
+       "ip_range_invalid": "Gama de endereços IP inválida.",
        "ip_range_toolarge": "Não são permitidas gamas de IP maiores do que /$1.",
        "proxyblocker": "Bloqueador de proxies",
        "proxyblockreason": "O seu endereço IP foi bloqueado por ser um ''proxy'' público.\nContacte o seu fornecedor de internet ou o serviço de apoio técnico e informe-os deste grave problema de segurança, por favor.",
-       "sorbsreason": "O seu endereço IP encontra-se listado como ''proxy'' aberto na DNSBL utilizada pela {{SITENAME}}.",
-       "sorbs_create_account_reason": "O seu endereço IP encontra-se listado como ''proxy'' aberto na DNSBL utilizada pela {{SITENAME}}. Não pode criar uma conta",
+       "sorbsreason": "O seu endereço IP encontra-se listado como ''proxy'' aberto na DNSBL utilizada pela wiki {{SITENAME}}.",
+       "sorbs_create_account_reason": "O seu endereço IP encontra-se listado como ''proxy'' aberto na DNSBL utilizada pela wiki {{SITENAME}}. Não pode criar uma conta.",
        "xffblockreason": "Um endereço IP presente no cabeçalho X-Forwarded-For, seja seu ou de um servidor de proxy que estiver a usar, foi bloqueado. A razão do bloqueio original foi: $1",
        "cant-see-hidden-user": "O utilizador que está a tentar bloquear já está bloqueado e oculto.\nComo não tem o privilégio para ocultar utilizadores ''(hideuser)'', não pode ver ou editar o bloqueio deste utilizador.",
        "ipbblocked": "Não pode bloquear ou desbloquear outros, porque está bloqueado",
        "locknoconfirm": "Não marcou a caixa de confirmação.",
        "lockdbsuccesssub": "Base de dados foi bloqueada",
        "unlockdbsuccesssub": "Base de dados foi desbloqueada",
-       "lockdbsuccesstext": "A base de dados da {{SITENAME}} foi bloqueada.<br />\nLembre-se de [[Special:UnlockDB|remover o bloqueio]] após a manutenção.",
+       "lockdbsuccesstext": "A base de dados da wiki {{SITENAME}} foi bloqueada.<br />\nLembre-se de [[Special:UnlockDB|remover o bloqueio]] após a manutenção.",
        "unlockdbsuccesstext": "A base de dados foi desbloqueada.",
        "lockfilenotwritable": "O ficheiro de bloqueio da base de dados não pode ser escrito.\nPara bloquear ou desbloquear a base de dados, este precisa de poder ser escrito pelo servidor de internet.",
        "databaselocked": "A base de dados já está bloqueada.",
        "movepage-page-moved": "A página $1 foi movida para $2.",
        "movepage-page-unmoved": "Não foi possível mover a página $1 para $2.",
        "movepage-max-pages": "O limite de $1 {{PLURAL:$1|página movida|páginas movidas}} foi atingido; não será possível mover mais páginas de forma automática.",
-       "movelogpage": "Registo de movimento",
+       "movelogpage": "Registo de movimentação de páginas",
        "movelogpagetext": "Abaixo encontra-se uma lista de páginas movidas.",
        "movesubpage": "{{PLURAL:$1|Subpágina|Subpáginas}}",
        "movesubpagetext": "Esta página tem $1 {{PLURAL:$1|subpágina mostrada|subpáginas mostradas}} abaixo.",
+       "movesubpagetalktext": "A página de discussão correspondente tem $1 {{PLURAL:$1|subpágina|subpáginas}}, mostradas abaixo.",
        "movenosubpage": "Esta página não tem subpáginas.",
        "movereason": "Motivo:",
        "revertmove": "reverter",
        "tooltip-pt-preferences": "As {{GENDER:|suas}} preferências",
        "tooltip-pt-watchlist": "Lista de mudanças nas páginas que está a vigiar",
        "tooltip-pt-mycontris": "Lista das {{GENDER:|suas}} contribuições",
-       "tooltip-pt-anoncontribs": "Uma lista de edições feitas a partir deste endereço de IP",
+       "tooltip-pt-anoncontribs": "Uma lista de edições feitas a partir deste endereço IP",
        "tooltip-pt-login": "É encorajado que inicie sessão, apesar de não ser obrigatório.",
        "tooltip-pt-logout": "Sair da conta",
        "tooltip-pt-createaccount": "É encorajado a criar uma conta e iniciar sessão; no entanto, não é obrigatório",
        "tooltip-ca-talk": "Discussão sobre o conteúdo da página",
        "tooltip-ca-edit": "Editar esta página",
        "tooltip-ca-addsection": "Iniciar uma nova secção",
-       "tooltip-ca-viewsource": "Esta página está protegida.\nApenas pode visualizar o seu conteúdo",
+       "tooltip-ca-viewsource": "Esta página está protegida.\nSó pode ver o conteúdo.",
        "tooltip-ca-history": "Edições anteriores desta página.",
        "tooltip-ca-protect": "Proteger esta página",
        "tooltip-ca-unprotect": "Alterar a proteção desta página",
        "tooltip-ca-move": "Mover esta página",
        "tooltip-ca-watch": "Adicionar esta página à lista de páginas vigiadas",
        "tooltip-ca-unwatch": "Remover esta página da lista de páginas vigiadas",
-       "tooltip-search": "Pesquisar em {{SITENAME}}",
+       "tooltip-search": "Pesquisar na wiki {{SITENAME}}",
        "tooltip-search-go": "Ir para uma página com este nome exacto, caso exista",
        "tooltip-search-fulltext": "Procurar páginas que contêm este texto",
        "tooltip-p-logo": "Visitar a página principal",
        "tooltip-compareselectedversions": "Ver as diferenças entre as duas versões selecionadas desta página.",
        "tooltip-watch": "Adicionar esta página à lista de páginas vigiadas",
        "tooltip-watchlistedit-normal-submit": "Remover títulos",
-       "tooltip-watchlistedit-raw-submit": "Atualizar a lista de vigiados",
+       "tooltip-watchlistedit-raw-submit": "Atualizar a lista de páginas vigiadas",
        "tooltip-recreate": "Recriar a página apesar de ter sido eliminada",
        "tooltip-upload": "Iniciar o carregamento",
        "tooltip-rollback": "\"{{int:rollbacklink}}\" reverte, com um só clique, as edições do último editor desta página.",
        "print.css": "/* Código CSS colocado aqui afectará as impressões */",
        "noscript.css": "/* Os estilos CSS colocados aqui afetarão os utilizadores que tenham o JavaScript desativado em seus navegadores */",
        "common.js": "/* Código Javascript colocado aqui será carregado para todos os utilizadores em cada carregamento de página */",
-       "anonymous": "{{PLURAL:$1|Utilizador anónimo|Utilizadores anónimos}} da {{SITENAME}}",
-       "siteuser": "$1 da {{SITENAME}}",
-       "anonuser": "utilizador anónimo $1 da {{SITENAME}}",
+       "anonymous": "{{PLURAL:$1|Utilizador anónimo|Utilizadores anónimos}} da wiki {{SITENAME}}",
+       "siteuser": "$1 da wiki {{SITENAME}}",
+       "anonuser": "utilizador anónimo $1 da wiki {{SITENAME}}",
        "lastmodifiedatby": "Esta página foi modificada pela última vez à(s) $2 de $1 por $3.",
        "othercontribs": "Baseado no trabalho de $1.",
        "others": "outros",
-       "siteusers": "{{PLURAL:$2|um utilizador|$2 utilizadores}} da {{SITENAME}} ($1)",
-       "anonusers": "{{PLURAL:$2|utilizador anónimo|utilizadores anónimos}} da {{SITENAME}} ($1)",
+       "siteusers": "{{PLURAL:$2|um utilizador|$2 utilizadores}} da wiki {{SITENAME}} ($1)",
+       "anonusers": "{{PLURAL:$2|utilizador anónimo|utilizadores anónimos}} da wiki {{SITENAME}} ($1)",
        "creditspage": "Créditos da página",
        "nocredits": "Não há informação disponível sobre os créditos desta página.",
        "spamprotectiontitle": "Filtro de proteção contra spam",
        "spamprotectiontext": "A página que deseja gravar foi bloqueada pelo filtro de ''spam''.\nEste bloqueio foi provavelmente causado por uma ligação para um sítio externo que consta da lista negra.",
-       "spamprotectionmatch": "O seguinte texto activou o filtro de spam: $1",
+       "spamprotectionmatch": "O seguinte texto ativou o filtro de <i>spam</i>: $1",
        "spambot_username": "MediaWiki limpeza de spam",
        "spam_reverting": "A reverter para a última revisão que não contém ligação para $1",
        "spam_blanking": "Todas as revisões continham ligações para $1; a esvaziar",
        "pageinfo-header-edits": "Histórico de edições",
        "pageinfo-header-restrictions": "Proteção da página",
        "pageinfo-header-properties": "Propriedades da página",
-       "pageinfo-display-title": "Título exibido",
+       "pageinfo-display-title": "Título apresentado",
        "pageinfo-default-sort": "Chave de classificação padrão",
        "pageinfo-length": "Tamanho da página (em bytes)",
        "pageinfo-article-id": "ID da página",
        "pageinfo-robot-noindex": "Não permitida",
        "pageinfo-watchers": "Número de vigilantes da página",
        "pageinfo-visiting-watchers": "Número de vigilantes que consultaram as edições recentes da página",
-       "pageinfo-few-watchers": "Menos do que $1 {{PLURAL:$1|vigilante|vigilantes}}",
+       "pageinfo-few-watchers": "Menos de $1 {{PLURAL:$1|vigilante|vigilantes}}",
        "pageinfo-few-visiting-watchers": "Pode ou não pode haver editores a vigiar as edições recentes",
        "pageinfo-redirects-name": "Número de redirecionamentos para esta página",
        "pageinfo-subpages-name": "Subpáginas desta página",
        "pageinfo-redirectsto-info": "informação",
        "pageinfo-contentpage": "Contada como página de conteúdo",
        "pageinfo-contentpage-yes": "Sim",
-       "pageinfo-protect-cascading": "A protecção é em cascata a partir daqui",
+       "pageinfo-protect-cascading": "A proteção é em cascata a partir daqui",
        "pageinfo-protect-cascading-yes": "Sim",
        "pageinfo-protect-cascading-from": "As proteções são em cascata a partir de",
        "pageinfo-category-info": "Informações da categoria",
        "pageinfo-category-pages": "Número de páginas",
        "pageinfo-category-subcats": "Número de subcategorias",
        "pageinfo-category-files": "Número de ficheiros",
+       "pageinfo-user-id": "Identificador do utilizador",
        "markaspatrolleddiff": "Marcar como patrulhada",
        "markaspatrolledtext": "Marcar esta página como patrulhada",
        "markaspatrolledtext-file": "Marcar esta versão do ficheiro como patrulhada",
        "patrol-log-header": "Este é um registo de edições patrulhadas.",
        "log-show-hide-patrol": "$1 registo de edições patrulhadas",
        "log-show-hide-tag": "$1 registo de etiquetas",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Marcar a revisão $3 de $2 como patrulhada?",
        "deletedrevision": "Apagou a versão antiga $1",
        "filedeleteerror-short": "Erro ao eliminar ficheiro: $1",
        "filedeleteerror-long": "Foram encontrados erros ao tentar eliminar o ficheiro:\n\n$1",
        "thumbsize": "Tamanho da miniatura:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|página|páginas}}",
        "file-info": "tamanho: $1, tipo MIME: $2",
-       "file-info-size": "$1 × $2 pixels, tamanho: $3, tipo MIME: $4",
-       "file-info-size-pages": "$1 × $2 pixels, tamanho do ficheiro: $3, tipo MIME: $4, $5 {{PLURAL:$5|página|páginas}}",
+       "file-info-size": "$1 × $2 píxeis, tamanho: $3, tipo MIME: $4",
+       "file-info-size-pages": "$1 × $2 píxeis, tamanho do ficheiro: $3, tipo MIME: $4, $5 {{PLURAL:$5|página|páginas}}",
        "file-nohires": "Sem resolução maior disponível.",
-       "svg-long-desc": "ficheiro SVG, de $1 × $2 pixels, tamanho: $3",
-       "svg-long-desc-animated": "ficheiro SVG animado, de $1 × $2 pixels, tamanho: $3",
+       "svg-long-desc": "ficheiro SVG, de $1 × $2 píxeis, tamanho: $3",
+       "svg-long-desc-animated": "ficheiro SVG animado, de $1 × $2 píxeis, tamanho: $3",
        "svg-long-error": "Ficheiro SVG inválido: $1",
        "show-big-image": "Ficheiro original",
        "show-big-image-preview": "Tamanho desta antevisão: $1.",
        "show-big-image-preview-differ": "Tamanho desta antevisão em $3 do ficheiro $2: $1",
        "show-big-image-other": "{{PLURAL:$2|Outra resolução|Outras resoluções}}: $1.",
-       "show-big-image-size": "$1 × $2 pixels",
+       "show-big-image-size": "$1 × $2 píxeis",
        "file-info-gif-looped": "cíclico",
        "file-info-gif-frames": "$1 {{PLURAL:$1|quadro|quadros}}",
        "file-info-png-looped": "ciclo infinito",
        "newimages-showbots": "Mostrar carregamentos feitos por robôs",
        "newimages-hidepatrolled": "Ocultar carregamentos patrulhados",
        "noimages": "Nada para ver.",
+       "gallery-slideshow-toggle": "Alternar miniaturas",
        "ilsubmit": "Pesquisar",
        "bydate": "por data",
        "sp-newimages-showfrom": "Mostrar novos ficheiros a partir das $2 de $1",
        "exif-imagelength": "Altura",
        "exif-bitspersample": "Bits por componente",
        "exif-compression": "Esquema de compressão",
-       "exif-photometricinterpretation": "Composição pixel",
+       "exif-photometricinterpretation": "Composição do píxel",
        "exif-orientation": "Orientação",
        "exif-samplesperpixel": "Número de componentes",
        "exif-planarconfiguration": "Arranjo de dados",
        "exif-orientation-8": "Rodado 90° no sentido horário",
        "exif-planarconfiguration-1": "formato irregular",
        "exif-planarconfiguration-2": "formato plano",
+       "exif-xyresolution-c": "$1 pt/cm",
        "exif-colorspace-65535": "Cor não calibrada",
        "exif-componentsconfiguration-0": "não existe",
        "exif-exposureprogram-0": "Não definido",
        "monthsall": "todos",
        "confirmemail": "Confirmar endereço de correio eletrónico",
        "confirmemail_noemail": "Não tem um endereço de correio eletrónico válido nas suas [[Special:Preferences|preferências de utilizador]].",
-       "confirmemail_text": "{{SITENAME}} requer que valide o seu endereço de correio eletrónico antes de usar as funcionalidades de correio.\nClique o botão abaixo para enviar uma mensagem de confirmação para o seu endereço.\nA mensagem incluirá uma URL que contém um código;\ninsira a URL no seu navegador para confirmar que o seu endereço de correio eletrónico é válido.",
+       "confirmemail_text": "A wiki {{SITENAME}} requer que valide o seu endereço de correio eletrónico antes de usar as funcionalidades de correio.\nClique o botão abaixo para enviar uma mensagem de confirmação para o seu endereço.\nA mensagem incluirá um URL que contém um código;\ninsira o URL no seu navegador para confirmar que o seu endereço de correio eletrónico é válido.",
        "confirmemail_pending": "Um código de confirmação já lhe foi enviado;\ncaso tenha criado a conta recentemente, é recomendado que aguarde alguns minutos até o receber antes de tentar pedir um novo código.",
        "confirmemail_send": "Enviar código de confirmação",
        "confirmemail_sent": "Correio de confirmação enviado.",
        "confirmemail_oncreate": "Foi enviado um código de confirmação para o seu endereço de correio eletrónico.\nEste código não é necessário para se autenticar no sistema, mas será necessário para ativar qualquer funcionalidade baseada no uso de correio na wiki.",
-       "confirmemail_sendfailed": "A {{SITENAME}} não conseguiu enviar a mensagem de confirmação.\nVerifique se o seu endereço de correio eletrónico tem caracteres inválidos.\n\nO sistema de correio devolveu o erro: $1",
+       "confirmemail_sendfailed": "A wiki {{SITENAME}} não conseguiu enviar a mensagem de confirmação.\nVerifique se o seu endereço de correio eletrónico tem caracteres inválidos.\n\nO sistema de correio devolveu o erro: $1",
        "confirmemail_invalid": "Código de confirmação inválido. O código pode ter expirado.",
        "confirmemail_needlogin": "Precisa de $1 para confirmar o seu endereço de correio eletrónico.",
        "confirmemail_success": "O seu endereço de correio eletrónico foi confirmado.\nPode agora [[Special:UserLogin|autenticar-se]] e desfrutar da wiki.",
        "confirmemail_loggedin": "O seu endereço de correio eletrónico foi confirmado.",
-       "confirmemail_subject": "Confirmação de endereço de correio eletrónico da {{SITENAME}}",
-       "confirmemail_body": "Alguém, provavelmente você a partir do endereço IP $1,\nregistou uma conta \"$2\" com este endereço de correio electrónico em {{SITENAME}}.\n\nPara confirmar que esta conta é realmente sua e activar\nas funcionalidades de correio electrónico em {{SITENAME}}, abra a seguinte ligação no seu navegador:\n\n$3\n\nSe a conta *não* é sua, abra a seguinte ligação para cancelar a confirmação do endereço de correio electrónico:\n\n$5\n\nEste código de confirmação expira a $4.",
-       "confirmemail_body_changed": "Alguém, provavelmente você a partir do endereço IP $1,\nalterou o endereço de correio eletrónico da conta \"$2\" para este em {{SITENAME}}.\n\nPara confirmar que esta conta é realmente sua e reativar\nas funcionalidades de correio eletrónico em {{SITENAME}},\nabra o seguinte ligação no seu navegador:\n\n$3\n\nCaso a conta *não* lhe pertença, abra a seguinte ligação\npara cancelar a confirmação do endereço de correio eletrónico:\n\n$5\n\nEste código de confirmação expira a $4.",
-       "confirmemail_body_set": "Alguém, provavelmente você a partir do endereço IP $1,\ndefiniu o seu endereço de correio eletrónico como correio da conta \"$2\" em {{SITENAME}}.\n\nPara confirmar que esta conta é realmente sua e reativar\nas funcionalidades de correio eletrónico em {{SITENAME}},\nabra a seguinte ligação no seu navegador:\n\n$3\n\nCaso a conta *não* lhe pertença, abra a seguinte ligação\npara cancelar a confirmação do endereço de correio eletrónico:\n\n$5\n\nEste código de confirmação expira a $4.",
+       "confirmemail_subject": "Confirmação de endereço de correio eletrónico da wiki {{SITENAME}}",
+       "confirmemail_body": "Alguém, provavelmente você a partir do endereço IP $1,\nregistou uma conta \"$2\" com este endereço de correio eletrónico na wiki {{SITENAME}}.\n\nPara confirmar que esta conta é realmente sua e ativar\nas funcionalidades de correio eletrónico na wiki {{SITENAME}}, abra a seguinte ligação no seu navegador:\n\n$3\n\nSe a conta *não* é sua, abra a seguinte ligação para cancelar a confirmação do endereço de correio eletrónico:\n\n$5\n\nEste código de confirmação expira a $4.",
+       "confirmemail_body_changed": "Alguém, provavelmente você a partir do endereço IP $1,\nalterou o endereço de correio eletrónico da conta \"$2\" para este endereço, na wiki{{SITENAME}}.\n\nPara confirmar que esta conta é realmente sua e reativar\nas funcionalidades de correio eletrónico na wiki {{SITENAME}},\nabra a seguinte ligação no seu navegador:\n\n$3\n\nCaso a conta *não* lhe pertença, abra a seguinte ligação\npara cancelar a confirmação do endereço de correio eletrónico:\n\n$5\n\nEste código de confirmação expira a $4.",
+       "confirmemail_body_set": "Alguém, provavelmente você a partir do endereço IP $1,\ndefiniu o seu endereço de correio eletrónico como correio da conta \"$2\" na wiki {{SITENAME}}.\n\nPara confirmar que esta conta é realmente sua e reativar\nas funcionalidades de correio eletrónico na wiki {{SITENAME}},\nabra a seguinte ligação no seu navegador:\n\n$3\n\nCaso a conta *não* lhe pertença, abra a seguinte ligação\npara cancelar a confirmação do endereço de correio eletrónico:\n\n$5\n\nEste código de confirmação expira a $4.",
        "confirmemail_invalidated": "Confirmação de endereço de correio eletrónico cancelada",
        "invalidateemail": "Cancelar confirmação do correio eletrónico",
-       "notificationemail_subject_changed": "O endereço de correio eletrónico registado em {{SITENAME}} foi alterado",
-       "notificationemail_subject_removed": "O endereço de correio eletrónico registado em {{SITENAME}} foi removido",
-       "notificationemail_body_changed": "Alguém, provavelmente você, a partir do endereço IP $1, alterou o endereço de correio eletrónico da conta \"$2\" para \"$3\" em {{SITENAME}}.\n\nCaso não tenha alterado, contacte imediatamente um administrador do sítio.",
-       "notificationemail_body_removed": "Alguém, provavelmente você, a partir do endereço IP $1, eliminou o endereço de correio eletrónico da conta \"$2\" em {{SITENAME}}.\n\nCaso não tenha alterado, contacte imediatamente um administrador do sítio.",
+       "notificationemail_subject_changed": "O endereço de correio eletrónico registado na wiki {{SITENAME}} foi alterado",
+       "notificationemail_subject_removed": "O endereço de correio eletrónico registado na wiki {{SITENAME}} foi removido",
+       "notificationemail_body_changed": "Alguém, provavelmente você, a partir do endereço IP $1, alterou o endereço de correio eletrónico da conta \"$2\" para \"$3\" na wiki {{SITENAME}}.\n\nCaso não o tenha alterado, contacte imediatamente um administrador do sítio.",
+       "notificationemail_body_removed": "Alguém, provavelmente você, a partir do endereço IP $1, eliminou o endereço de correio eletrónico da conta \"$2\" na wiki {{SITENAME}}.\n\nCaso não o tenha eliminado, contacte imediatamente um administrador do sítio.",
        "scarytranscludedisabled": "[Transclusão interwikis foi impossibilitada]",
        "scarytranscludefailed": "[Não foi possível obter a predefinição a partir de $1]",
        "scarytranscludefailed-httpstatus": "[Não foi possível obter a predefinição a partir de $1: HTTP $2]",
-       "scarytranscludetoolong": "[URL longa demais]",
+       "scarytranscludetoolong": "[O URL é demasiado longo]",
        "deletedwhileediting": "<strong>AVISO:</strong> Esta página foi eliminada depois de ter começado a editá-la!",
-       "confirmrecreate": "Depois de ter começado a editar esta página, {{GENDER:$2|o utilizador|a utilizadora|o(a) utilizador(a)}} [[User:$1|$1]] ([[User talk:$1|discussão]]) eliminou-a pelo seguinte motivo:\n: <em>$2</em>\nPor favor, confirme que quer realmente recriar esta página.",
+       "confirmrecreate": "Depois de ter começado a editar esta página, {{GENDER:$1|o utilizador|a utilizadora|o(a) utilizador(a)}} [[User:$1|$1]] ([[User talk:$1|discussão]]) eliminou-a pelo seguinte motivo:\n: <em>$2</em>\nPor favor, confirme que quer realmente recriar esta página.",
        "confirmrecreate-noreason": "{{GENDER:$1|O utilizador|A utilizadora|O(a) utilizador(a)}} [[User:$1|$1]] ([[User talk:$1|discussão]]) eliminou esta página depois de ter começado a editá-la. Confirme que deseja recriar a página, por favor.",
        "recreate": "Recriar",
        "confirm_purge_button": "OK",
        "imgmultigoto": "Ir para a página $1",
        "img-lang-default": "(língua padrão)",
        "img-lang-info": "Compor esta imagem em $1. $2",
-       "img-lang-go": "Ir",
+       "img-lang-go": "Compor",
        "ascending_abbrev": "asc",
        "descending_abbrev": "desc",
        "table_pager_next": "Página seguinte",
        "table_pager_last": "Última página",
        "table_pager_limit": "Mostrar $1 por página",
        "table_pager_limit_label": "Entradas por página:",
-       "table_pager_limit_submit": "Ir",
+       "table_pager_limit_submit": "Continuar",
        "table_pager_empty": "Sem resultados",
        "autosumm-blank": "Limpou toda a página",
        "autosumm-replace": "Página substituída por \"$1\"",
        "watchlistedit-clear-submit": "Limpar páginas vigiadas (isto é permanente!)",
        "watchlistedit-clear-done": "A sua lista de páginas vigiadas foi limpa.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 página foi removida|$1 páginas foram removidas}}:",
-       "watchlistedit-too-many": "Existem demasiadas páginas para exibir.",
+       "watchlistedit-too-many": "Existem demasiadas páginas para apresentar.",
        "watchlisttools-clear": "Limpar lista de páginas vigiadas",
        "watchlisttools-view": "Ver alterações relevantes",
        "watchlisttools-edit": "Ver e editar a lista de páginas vigiadas",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|discussão]])",
        "timezone-local": "Local",
        "duplicate-defaultsort": "<strong>Aviso:</strong> A chave de ordenação padrão \"$2\" sobrepõe-se à anterior \"$1\".",
-       "duplicate-displaytitle": "<strong>Aviso:</strong> O título em exibição \"$2\" anula o título anteriormente em exibição \"$1\".",
+       "duplicate-displaytitle": "<strong>Aviso:</strong> O título de apresentação \"$2\" anula o título anterior \"$1\".",
        "restricted-displaytitle": "<strong>Aviso</strong>: A apresentação do título \"$1\" foi ignorada porque não é equivalente ao título atual da página.",
        "invalid-indicator-name": "<strong>Erro:</strong> O atributo <code>name</code>, da página de estados, não deve estar em branco.",
        "version": "Versão",
        "version-license-not-found": "Não foi encontrada informação detalhada da licença para esta extensão.",
        "version-credits-title": "Créditos de autoria da extensão $1",
        "version-credits-not-found": "Não foi encontrada informação detalhada dos créditos para esta extensão.",
-       "version-poweredby-credits": "Este é um wiki <strong>[https://www.mediawiki.org/ MediaWiki]</strong>, copyright © 2001-$1 $2.",
+       "version-poweredby-credits": "Esta é uma wiki <strong>[https://www.mediawiki.org/ MediaWiki]</strong>, copyright © 2001-$1 $2.",
        "version-poweredby-others": "outros",
        "version-poweredby-translators": "os tradutores da translatewiki.net",
        "version-credits-summary": "Gostaríamos de reconhecer as seguintes pessoas pela sua contribuição para o [[Special:Version|MediaWiki]].",
        "version-entrypoints": "URL de ponto de entrada",
        "version-entrypoints-header-entrypoint": "Ponto de entrada",
        "version-entrypoints-header-url": "URL",
+       "version-entrypoints-articlepath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgArticlePath Caminho dos artigos]",
+       "version-entrypoints-scriptpath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgScriptPath Caminho dos <i>scripts</i>]",
        "version-libraries": "Bibliotecas instaladas",
        "version-libraries-library": "Biblioteca",
        "version-libraries-version": "Versão",
        "version-libraries-license": "Licença",
        "version-libraries-description": "Descrição",
        "version-libraries-authors": "Autores",
-       "redirect": "Redirecionar por ficheiro, utilizador, página, revisão, ou ID de registo",
-       "redirect-summary": "Esta página especial redireciona para um ficheiro (dado o nome do ficheiro), para uma página (dado um ID de revisão ou página) ou para uma página de utilizador (dado um ID numérico do utilizador), ou para uma entrada do registo (dado o ID do registo). Utilização: [[{{#Special:Redirect}}/file/Example.jpg]], \n[[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], ou [[{{#Special:Redirect}}/logid/186]].",
-       "redirect-submit": "Ir",
+       "redirect": "Redirecionar por nome de ficheiro, ou ID de utilizador, página, revisão ou registo",
+       "redirect-summary": "Esta página especial redireciona para um ficheiro (dado o nome do ficheiro), para uma página (dado o identificador numérico da página ou da revisão), para uma página de utilizador (dado o identificador numérico do utilizador) ou para uma entrada do registo (dado o identificador numérico da entrada no registo). Exemplos de utilização: [[{{#Special:Redirect}}/file/Flag_Bandeiras_lusófonas.JPG]], \n[[{{#Special:Redirect}}/page/12071]], [[{{#Special:Redirect}}/revision/700]], [[{{#Special:Redirect}}/user/1]], ou [[{{#Special:Redirect}}/logid/18868382]].",
+       "redirect-submit": "Continuar",
        "redirect-lookup": "Pesquisa:",
        "redirect-value": "Valor:",
        "redirect-user": "Identificador do utilizador",
-       "redirect-page": "Identificador (ID) da página",
-       "redirect-revision": "Revisão da página",
+       "redirect-page": "Identificador da página",
+       "redirect-revision": "Identificador de revisão da página",
        "redirect-file": "Nome do ficheiro",
-       "redirect-logid": "ID do registo",
+       "redirect-logid": "Identificador da entrada do registo",
        "redirect-not-exists": "Valor não encontrado",
-       "fileduplicatesearch": "Ficheiros duplicados",
-       "fileduplicatesearch-summary": "Procure ficheiros duplicados tendo por base o seu resumo criptográfico.",
-       "fileduplicatesearch-filename": "Ficheiro:",
+       "fileduplicatesearch": "Pesquisa de ficheiros duplicados",
+       "fileduplicatesearch-summary": "Pesquisa de ficheiros duplicados baseada no resumo criptográfico.",
+       "fileduplicatesearch-filename": "Nome do ficheiro:",
        "fileduplicatesearch-submit": "Pesquisar",
-       "fileduplicatesearch-info": "$1 × $2 pixels<br />Tamanho: $3<br />tipo MIME: $4",
-       "fileduplicatesearch-result-1": "O ficheiro \"$1\" não possui cópias idênticas.",
+       "fileduplicatesearch-info": "$1 × $2 píxeis<br />Tamanho: $3<br />tipo MIME: $4",
+       "fileduplicatesearch-result-1": "O ficheiro \"$1\" não tem cópias idênticas.",
        "fileduplicatesearch-result-n": "O ficheiro \"$1\" possui {{PLURAL:$2|uma cópia idêntica|$2 cópias idênticas}}.",
        "fileduplicatesearch-noresults": "Não foi encontrado nenhum ficheiro com o nome \"$1\".",
        "specialpages": "Páginas especiais",
        "specialpages-group-users": "Utilizadores e privilégios",
        "specialpages-group-highuse": "Páginas muito usadas",
        "specialpages-group-pages": "Listas de páginas",
-       "specialpages-group-pagetools": "Ferramentas de páginas",
+       "specialpages-group-pagetools": "Ferramentas de página",
        "specialpages-group-wiki": "Dados e ferramentas",
-       "specialpages-group-redirects": "Redirecionar páginas especiais",
+       "specialpages-group-redirects": "Páginas especiais de redirecionamento",
        "specialpages-group-spam": "Ferramentas anti-spam",
        "specialpages-group-developer": "Ferramentas de desenvolvimento",
        "blankpage": "Página em branco",
        "intentionallyblankpage": "Esta página foi intencionalmente deixada em branco",
-       "external_image_whitelist": " # Deixe esta linha exatamente como ela está<pre>\n# Coloque fragmentos de expressões regulares (apenas a parte entre //) abaixo\n# Estas serão comparadas com as URL das imagens externas (com ligação direta)\n# As que corresponderem serão apresentadas como imagens, caso contrário apenas será apresentado um link para a imagem\n# As linhas que começam com um símbolo de cardinal (#) são tratadas como comentários\n# Esta lista não distingue maiúsculas de minúsculas\n\n# Coloque todos os fragmentos de expressões regulares (regex) acima desta linha. Deixe esta linha exatamente como ela está</pre>",
+       "external_image_whitelist": " # Deixe esta linha exatamente como ela está<pre>\n# Coloque fragmentos de expressões regulares (apenas a parte entre //) abaixo\n# Estas serão comparadas com os URL das imagens externas (com ligação direta)\n# As que corresponderem serão apresentadas como imagens, caso contrário apenas será apresentado um link para a imagem\n# As linhas que começam com um símbolo de cardinal (#) são tratadas como comentários\n# Esta lista não distingue maiúsculas de minúsculas\n\n# Coloque todos os fragmentos de expressões regulares (regex) acima desta linha. Deixe esta linha exatamente como ela está</pre>",
        "tags": "Etiquetas de modificação válidas",
        "tag-filter": "Filtro de [[Special:Tags|etiquetas]]:",
        "tag-filter-submit": "Filtrar",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Etiqueta|Etiquetas}}]]: $2)",
-       "tags-title": "Etiquetas",
+       "tag-mw-contentmodelchange": "alteração do modelo de conteúdo",
+       "tag-mw-contentmodelchange-description": "Edições que [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel alteram o modelo de conteúdo] de uma página",
+       "tags-title": "Etiquetas de modificação válidas",
        "tags-intro": "Esta página lista as etiquetas com que o software poderá marcar uma edição, e o seu significado.",
        "tags-tag": "Nome da etiqueta",
        "tags-display-header": "Aparência nas listas de modificações",
        "tags-deactivate": "desativar",
        "tags-hitcount": "$1 {{PLURAL:$1|modificação|modificações}}",
        "tags-manage-no-permission": "Não possui permissão para gerir alterações de etiquetas.",
-       "tags-manage-blocked": "Não pode gerir alterações de etiquetas enquanto estiver bloqueado.",
+       "tags-manage-blocked": "Não pode gerir etiquetas de modificação enquanto estiver {{GENDER:$1|bloqueado|bloqueada}}.",
        "tags-create-heading": "Criar nova etiqueta",
        "tags-create-explanation": "Por definição, etiquetas recém-criadas estarão disponíveis para utilização por utilizadores e robôs.",
        "tags-create-tag-name": "Nome da etiqueta:",
        "tags-delete-not-found": "A etiqueta \"$1\" não existe.",
        "tags-delete-too-many-uses": "A etiqueta \"$1\" está aplicada em mais que $2 {{PLURAL:$2|edição|edições}}, o que significa que não pode ser eliminada.",
        "tags-delete-warnings-after-delete": "A etiqueta \"$1\" foi eliminada, mas {{PLURAL:$2|o seguinte aviso foi encontrado|os seguintes avisos foram encontrados}}:",
+       "tags-delete-no-permission": "Não tem permissão para eliminar etiquetas de modificação.",
        "tags-activate-title": "Ativar etiqueta",
        "tags-activate-question": "Está prestes a ativar a etiqueta \"$1\".",
        "tags-activate-reason": "Motivo:",
        "tags-deactivate-not-allowed": "Não é possível desativar a etiqueta \"$1\".",
        "tags-deactivate-submit": "Desativar",
        "tags-apply-no-permission": "Não possui privilégios para aplicar alterações a etiquetas em conjunto com as suas modificações.",
+       "tags-apply-blocked": "Não pode aplicar etiquetas de modificação nas suas alterações enquanto estiver {{GENDER:$1|bloqueado|bloqueada}}.",
        "tags-apply-not-allowed-one": "A etiqueta \"$1\" não pode ser aplicada manualmente.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|A seguinte etiqueta não pode ser aplicada|As seguintes etiquetas não podem ser aplicadas}} manualmente: $1",
        "tags-update-no-permission": "Não possui privilégios para adicionar ou remover etiquetas de revisões individuais ou entradas de registo.",
+       "tags-update-blocked": "Não pode adicionar ou remover etiquetas de modificação enquanto estiver {{GENDER:$1|bloqueado|bloqueada}}.",
        "tags-update-add-not-allowed-one": "A etiqueta \"$1\" não pode ser adicionada manualmente.",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|A seguinte etiqueta não pode ser adicionada|As seguintes etiquetas não podem ser adicionadas}} manualmente: $1",
        "tags-update-remove-not-allowed-one": "A remoção da etiqueta \"$1\" não é permitida.",
        "htmlform-cloner-create": "Adicionar mais",
        "htmlform-cloner-delete": "Remover",
        "htmlform-cloner-required": "Pelo menos um valor é necessário.",
+       "htmlform-date-placeholder": "AAAA-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "AAAA-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "O valor especificado não é reconhecido como data. Tente usar o formato AAAA-MM-DD.",
+       "htmlform-time-invalid": "O valor especificado não é reconhecido como hora. Tente usar o formato HH:MM:SS.",
+       "htmlform-datetime-invalid": "O valor especificado não é reconhecido como data e hora. Tente usar o formato AAAA-MM-DD HH:MM:SS.",
+       "htmlform-date-toolow": "O valor especificado é anterior à data mais antiga que é permitida, $1.",
+       "htmlform-date-toohigh": "O valor especificado é posterior à data mais recente que é permitida, $1.",
+       "htmlform-time-toolow": "O valor especificado é anterior à hora mínima permitida, $1.",
+       "htmlform-time-toohigh": "O valor especificado é anterior à hora máxima permitida, $1.",
+       "htmlform-datetime-toolow": "O valor especificado é anterior à data e hora mínima permitida, $1.",
+       "htmlform-datetime-toohigh": "O valor especificado é posterior à data e hora máxima permitida, $1.",
        "htmlform-title-badnamespace": "[[:$1]] não se encontra no domínio \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" não é um título que possa ser atribuído a uma página",
        "htmlform-title-not-exists": "$1 não existe.",
        "logentry-delete-revision-legacy": "$1 {{GENDER:$2|alterou}} a visibilidade de revisões na página $3",
        "logentry-suppress-delete": "$1 {{GENDER:$2|suprimiu}} a página $3",
        "logentry-suppress-event": "$1 {{GENDER:$2|alterou}} secretamente a visibilidade de {{PLURAL:$5|uma entrada|$5 entradas}} em $3: $4",
-       "logentry-suppress-revision": "$1 secretamente alterou a visibilidade de {{PLURAL:$5|uma revisão|$5 revisões}} em $3: $4",
+       "logentry-suppress-revision": "$1 alterou secretamente a visibilidade de {{PLURAL:$5|uma revisão|$5 revisões}} em $3: $4",
        "logentry-suppress-event-legacy": "$1 {{GENDER:$2|alterou}} secretamente a visibilidade de entradas de registo em $3",
        "logentry-suppress-revision-legacy": "$1 {{GENDER:$2|alterou}} secretamente a visibilidade de revisões da página $3",
        "revdelete-content-hid": "conteúdo oculto",
        "logentry-suppress-block": "$1 {{GENDER:$2|bloqueou}} {{GENDER:$4|$3}} com expiração a $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|modificou}} parâmetros de bloqueio de {{GENDER:$4|$3}} com expiração a $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|importou}} $3 através de carregamento de ficheiro",
+       "logentry-import-upload-details": "$1 {{GENDER:$2|importou}} $3 por carregamento de ficheiro($4 {{PLURAL:$4|revisão|revisões}})",
        "logentry-import-interwiki": "$1 {{GENDER:$2|importou}} $3 de outra wiki",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|importou}} $3 de $5 ($4 {{PLURAL:$4|revisão|revisões}})",
        "logentry-merge-merge": "$1 {{GENDER:$2|fundiu}} $3 com $4 (edições até $5)",
        "logentry-move-move": "$1 moveu a página $3 para $4",
        "logentry-move-move-noredirect": "$1 moveu a página $3 para $4 sem deixar um redirecionamento",
        "feedback-external-bug-report-button": "Assinalar erro técnico",
        "feedback-dialog-title": "Enviar opinião",
        "feedback-dialog-intro": "Pode usar o fácil formulário abaixo para enviar os seus comentários. A sua opinião será adicionada à página \"$1\", juntamente com o seu nome de utilizador(a).",
-       "feedback-error-title": "Erro",
        "feedback-error1": "Erro: O resultado da API não foi reconhecido",
        "feedback-error2": "Erro: A edição falhou",
        "feedback-error3": "Erro: A API não responde",
        "feedback-thanks": "Obrigado! O seu comentário foi adicionado à página \"[$2 $1]\".",
        "feedback-thanks-title": "Obrigado!",
        "feedback-useragent": "Agente de utilizador:",
-       "searchsuggest-search": "Pesquisa",
+       "searchsuggest-search": "Pesquisar na wiki {{SITENAME}}",
        "searchsuggest-containing": "contendo...",
-       "api-error-autoblocked": "O seu endereço de IP foi bloqueado automaticamente, pois foi utilizado por um utilizador bloqueado.",
+       "api-error-autoblocked": "O seu endereço IP foi bloqueado automaticamente, pois foi utilizado por um utilizador bloqueado.",
        "api-error-badaccess-groups": "Não tem permissão para enviar ficheiros para esta wiki.",
        "api-error-badtoken": "Erro interno: Chave incorrecta.",
        "api-error-blocked": "Foi bloqueado de editar.",
        "api-error-nomodule": "Erro interno: Não está definido nenhum módulo para o carregamento de ficheiros.",
        "api-error-ok-but-empty": "Erro interno: o servidor não respondeu.",
        "api-error-overwrite": "Não é permitido sobrescrever um ficheiro existente.",
+       "api-error-ratelimited": "Está a tentar carregar mais ficheiros do que esta wiki permite num espaço de tempo curto. Tente de novo dentro de alguns minutos, por favor.",
        "api-error-stashfailed": "Erro interno: O servidor não conseguiu armazenar o ficheiro temporário.",
        "api-error-publishfailed": "Erro interno: Servidor não conseguiu publicar ficheiro temporário.",
        "api-error-stasherror": "Ocorreu um erro no carregamento do ficheiro escondido.",
-       "api-error-stashedfilenotfound": "O ficheiro do stash não foi encontrado ao tentar carregá-lo.",
+       "api-error-stashedfilenotfound": "O ficheiro escondido não foi encontrado ao tentar carregá-lo.",
        "api-error-stashpathinvalid": "O caminho no qual o ficheiro escondido deveria ter sido encontrado era inválido.",
        "api-error-stashfilestorage": "Ocorreu um erro no carregamento do ficheiro escondido.",
-       "api-error-stashzerolength": "O servidor não pôde esconder o ficheiro, porque ele tinha de comprimento zero.",
-       "api-error-stashnotloggedin": "Você deve estar com sessão iniciaca para gravar ficheiros no carregamento do stash.",
-       "api-error-stashwrongowner": "O ficheiro que estava a tentar aceder o stash não pertence a você.",
-       "api-error-stashnosuchfilekey": "O ficheiro de chave que está a tentar aceder no stash não existe.",
+       "api-error-stashzerolength": "Não foi possível o servidor esconder o ficheiro, porque este tinha comprimento zero.",
+       "api-error-stashnotloggedin": "Tem de ter uma sessão iniciada para gravar ficheiros na área de ficheiros escondidos.",
+       "api-error-stashwrongowner": "O ficheiro a que estava a tentar aceder na área de ficheiros escondidos não lhe pertence.",
+       "api-error-stashnosuchfilekey": "O chave do ficheiro a que estava a tentar aceder na área de ficheiros escondidos não existe.",
        "api-error-timeout": "O servidor não respondeu no prazo esperado.",
        "api-error-unclassified": "Ocorreu um erro desconhecido",
        "api-error-unknown-code": "Erro desconhecido: \"$1\"",
        "duration-centuries": "$1 {{PLURAL:$1|século|séculos}}",
        "duration-millennia": "$1 {{PLURAL:$1|milénio|milénios}}",
        "rotate-comment": "Imagem rodada em $1 {{PLURAL:$1|grau|graus}} no sentido dos ponteiros do relógio",
-       "limitreport-title": "Dados de perfis do analisador:",
+       "limitreport-title": "Dados de caracterização do analisador sintático:",
        "limitreport-cputime": "Tempo de utilização da CPU",
        "limitreport-cputime-value": "$1 {{PLURAL:$1|segundo|segundos}}",
        "limitreport-walltime": "Tempo real de utilização",
        "limitreport-templateargumentsize": "Tamanho dos argumentos da predefinição",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-expansiondepth": "Profundidade máxima de expansão",
-       "limitreport-expensivefunctioncount": "Número de funções do analisador custosas",
+       "limitreport-expensivefunctioncount": "Número de funções exigentes do analisador sintático",
        "expandtemplates": "Expandir predefinições",
        "expand_templates_intro": "Esta página especial recebe um texto e expande recursivamente todas as predefinições nele existentes.\nTambém expande funções do analisador sintático ''(parser)'', tais como\n<nowiki>{{</nowiki>#language:...}}, e variáveis, como\n<nowiki>{{</nowiki>CURRENTDAY}}.\nNa verdade, expande tudo o que estiver entre chavetas duplas.",
        "expand_templates_title": "Título de contexto para {{FULLPAGENAME}} etc.:",
        "expand_templates_generate_xml": "Mostrar a árvore de análise sintáctica do XML",
        "expand_templates_generate_rawhtml": "Mostrar o HTML puro",
        "expand_templates_preview": "Antevisão do resultado",
-       "expand_templates_preview_fail_html": "<em>Devido ao fato de {{SITENAME}} possuir código HTML puro ativado e de ter havido perda de dados da sessão, a pré-visualização ficará oculta como precaução contra ataques por JavaScript.</em>\n\n<strong>Se esta é uma legítima tentativa de visualização, por favor tente novamente.</strong>\nCaso continue a não funcionar, tente [[Special:UserLogout|sair]] e voltar a entrar na sua conta, e verifique se o seu navegador permite a utilização de ''cookies'' deste sítio.",
-       "expand_templates_preview_fail_html_anon": "<em>Devido ao fato de {{SITENAME}} possuir código HTML puro ativado e de não ter sessão iniciada, a pré-visualização ficará oculta como precaução contra ataques do JavaScript.</em>\n\n<strong>Se esta é uma legítima tentativa de visualização, por favor [[Especial:UserLogin|inicie sessão]] e tente novamente.</strong>",
+       "expand_templates_preview_fail_html": "<em>Porque a wiki {{SITENAME}} permite código HTML puro e ocorreu uma perda de dados da sessão, a antevisão ficará ocultada como precaução contra ataques por JavaScript.</em>\n\n<strong>Se esta é uma tentativa legítima de visionamento, por favor tente novamente.</strong>\nCaso continue a não funcionar, tente [[Special:UserLogout|sair]] e voltar a entrar na sua conta, e verifique se o seu navegador permite que este site crie ''cookies''.",
+       "expand_templates_preview_fail_html_anon": "<em>Porque a wiki {{SITENAME}} permite código HTML puro e não iniciou uma sessão, a antevisão ficará ocultada como precaução contra ataques por JavaScript.</em>\n\n<strong>Se esta é uma tentativa legítima de visionamento, por favor [[Special:UserLogin|inicie uma sessão]] e tente novamente.</strong>",
        "expand_templates_input_missing": "Necessita de fornecer pelo menos algum texto de entrada.",
        "pagelanguage": "Alterar idioma da página",
        "pagelang-name": "Página",
-       "pagelang-language": "Idioma",
+       "pagelang-language": "Língua",
        "pagelang-use-default": "Usar idioma pré-definido",
        "pagelang-select-lang": "Escolher o idioma",
        "pagelang-submit": "Submeter",
        "log-name-pagelang": "Registo de alteração de idioma",
        "log-description-pagelang": "Este é um registo de alterações aos idiomas das páginas.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|alterou}} o idioma da página $3 de $4 para $5.",
+       "default-skin-not-found": "O tema padrão da sua wiki definido em <code dir=\"ltr\">$wgDefaultSkin</code>, <code>$1</code>, não está disponível.\n\nA instalação parece incluir {{PLURAL:$4|o seguinte tema|os seguintes temas}}. Consulte [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Configuração de Temas] para saber como {{PLURAL:$4|ativá-lo|ativá-los e escolher o tema padrão}}.\n\n$2\n\n; Se acabou de instalar o MediaWiki:\n: Provavelmente instalou-o a partir do git, ou diretamente do código fonte usando outro método. O comportamento é o esperado. Tente instalar temas a partir do [https://www.mediawiki.org/wiki/Category:All_skins diretório de temas da mediawiki.org], assim:\n:* Descarregue o  [https://www.mediawiki.org/wiki/Download tarball de instalação], que contém vários temas e extensões. Pode copiar o diretório <code>skins/</code> nele incluído.\n:* Descarregue tarballs de temas individuais, da [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Use o Git para descarregar temas].\n: Se é programador(a) do MediaWiki, isto não deverá interferir com o seu repositório git.\n\n; Se fez uma atualização do MediaWiki:\n: O MediaWiki 1.24 e versões mais recentes não ativam automaticamente os temas instalados (consulte [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Autodescoberta do Tema]). Pode copiar {{PLURAL:$5|a linha seguinte|as linhas seguintes}} para o ficheiro <code>LocalSettings.php</code> para ativar {{PLURAL:$5|o tema instalado|os temas instalados}}:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Se acabou de modificar o <code>LocalSettings.php</code>:\n: Verifique cuidadosamente se o nome de cada tema está bem soletrado.",
+       "default-skin-not-found-no-skins": "O tema padrão da sua wiki definido em <code dir=\"ltr\">$wgDefaultSkin</code>, <code>$1</code>, não está disponível.\n\nNão tem nenhum tema instalado.\n\n; Se acabou de instalar ou atualizar o MediaWiki:\n: Provavelmente instalou-o a partir do git, ou diretamente do código fonte usando outro método. O comportamento é o esperado. O MediaWiki 1.24 e versões mais recentes não incluem qualquer tema no repositório principal. Tente instalar temas a partir do [https://www.mediawiki.org/wiki/Category:All_skins diretório de temas da mediawiki.org], assim:\n:* Descarregue o  [https://www.mediawiki.org/wiki/Download tarball de instalação], que contém vários temas e extensões. Pode copiar o diretório <code>skins/</code> nele incluído.\n:* Descarregue tarballs de temas individuais, da [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Use o Git para descarregar temas].\n: Se é programador(a) do MediaWiki, isto não deverá interferir com o seu repositório git. Consulte [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Configuração de Temas] para saber como ativar temas e escolher o tema padrão.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (ativado)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>desativado</strong>)",
        "mediastatistics": "Estatísticas multimédia",
-       "mediastatistics-summary": "Estatísticas sobre os tipos de ficheiros carregados. Inclui apenas a versão mais recente do ficheiro. Versões antigas ou eliminadas são excluídas.",
+       "mediastatistics-summary": "Estatísticas sobre os tipos de ficheiro carregados. Inclui apenas a versão mais recente de cada ficheiro. Versões antigas ou eliminadas não estão incluídas.",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 byte|$1 bytes}} ($2; $3%)",
-       "mediastatistics-bytespertype": "Tamanho total de ficheiro para este secção: {{PLURAL:$1|$1 byte|$1 bytes}} ($2; $3%).",
-       "mediastatistics-allbytes": "Tamanho total de ficheiro para todos os ficheiros: {{PLURAL:$1|$1 byte|$1 bytes}} ($2).",
+       "mediastatistics-bytespertype": "Tamanho total dos ficheiros desta secção: {{PLURAL:$1|$1 byte|$1 bytes}} ($2; $3%).",
+       "mediastatistics-allbytes": "Tamanho total de todos os ficheiros: {{PLURAL:$1|$1 byte|$1 bytes}} ($2).",
        "mediastatistics-table-mimetype": "Tipo MIME",
        "mediastatistics-table-extensions": "Extensões possíveis",
        "mediastatistics-table-count": "Número de ficheiros",
        "mediastatistics-table-totalbytes": "Tamanho combinado",
        "mediastatistics-header-unknown": "Desconhecido",
-       "mediastatistics-header-bitmap": "Imagens de mapa de bits",
+       "mediastatistics-header-bitmap": "Imagens em mapa de bits",
        "mediastatistics-header-drawing": "Desenhos (imagens vetoriais)",
        "mediastatistics-header-audio": "Áudio",
        "mediastatistics-header-video": "Vídeo",
        "sessionprovider-generic": "Sessões $1",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sessões baseadas em cookie",
        "sessionprovider-nocookies": "Os cookies podem estar desativados. Certifique-se de que os cookies estão ativados e inicie novamente.",
-       "randomrootpage": "Página raiz aleatória",
+       "randomrootpage": "Página aleatória de raiz",
        "log-action-filter-block": "Tipo de bloqueio:",
        "log-action-filter-contentmodel": "Tipo de alteração de modelo de conteúdo:",
        "log-action-filter-delete": "Tipo de eliminação:",
        "log-action-filter-suppress-revision": "Supressão de revisões",
        "log-action-filter-suppress-delete": "Supressão de página",
        "log-action-filter-suppress-block": "Supressão de utilizadores por bloqueio",
+       "log-action-filter-suppress-reblock": "Supressão de utilizador por rebloqueio",
        "log-action-filter-upload-upload": "Novo carregamento",
        "log-action-filter-upload-overwrite": "Recarregar",
+       "authmanager-authn-not-in-progress": "A autenticação não está em curso ou os dados da sessão foram perdidos. Comece novamente desde o princípio, por favor.",
        "authmanager-authn-no-primary": "As informações de identificação fornecidas não podem ser autenticadas.",
+       "authmanager-authn-no-local-user": "As credenciais fornecidas não estão associadas a nenhum utilizador nesta wiki.",
+       "authmanager-authn-no-local-user-link": "As credenciais fornecidas são válidas mas não estão associadas a nenhum utilizador nesta wiki. Inicie a sessão de outra forma, ou crie um novo utilizador, e terá a opção de ligar as credenciais anteriores a essa conta.",
        "authmanager-authn-autocreate-failed": "A criação automática de uma conta local falhou: $1",
+       "authmanager-change-not-supported": "As credenciais fornecidas não podem ser alteradas porque ninguém as utiliza.",
        "authmanager-create-disabled": "A criação de contas está desativada.",
        "authmanager-create-from-login": "Para criar a sua conta, por favor, preencha os campos abaixo.",
+       "authmanager-create-not-in-progress": "A criação da conta não está em curso ou os dados da sessão foram perdidos. Comece novamente desde o princípio, por favor.",
+       "authmanager-create-no-primary": "Não foi possível criar uma conta com as credenciais fornecidas.",
+       "authmanager-link-no-primary": "Não foi possível ligar a conta usando as credenciais fornecidas.",
+       "authmanager-link-not-in-progress": "A ligação da conta não está em curso ou os dados da sessão foram perdidos. Comece novamente desde o princípio, por favor.",
        "authmanager-authplugin-setpass-failed-title": "A alteração de palavra-passe falhou",
        "authmanager-authplugin-setpass-failed-message": "O plugin de autenticação negou a alteração de palavra-passe.",
        "authmanager-authplugin-create-fail": "O plugin de autenticação negou a criação de conta.",
        "authmanager-autocreate-noperm": "A criação automática de contas não é permitida.",
        "authmanager-autocreate-exception": "A criação automática de contas foi temporariamente desativada devido a erros prévios.",
        "authmanager-userdoesnotexist": "A conta de utilizador(a) \"$1\" não está registada.",
+       "authmanager-userlogin-remembermypassword-help": "Se a palavra-passe deve ser recordada por um período superior à duração da sessão.",
        "authmanager-username-help": "Nome de utilizador(a) para autenticação.",
        "authmanager-password-help": "Palavra-passe para autenticação.",
        "authmanager-domain-help": "Domínio para a autenticação externa.",
        "authmanager-provider-password-domain": "Autenticação baseada em palavra-passe e domínio",
        "authmanager-provider-temporarypassword": "Palavra-passe temporária",
        "authprovider-confirmlink-message": "Com base nas tuas últimas tentativas para iniciar sessão, as seguintes contas podem ser ligadas à tua conta wiki. Vinculá-las permite que inicie sessão através das mesmas. Selecione quais pretende vincular.",
-       "authprovider-confirmlink-success-line": "$1: Ligado com êxito.",
+       "authprovider-confirmlink-request-label": "Contas que devem ser ligadas",
+       "authprovider-confirmlink-success-line": "$1: Ligação realizada.",
+       "authprovider-confirmlink-failed": "A ligação das contas não foi totalmente realizada: $1",
+       "authprovider-confirmlink-ok-help": "Continuar depois de mostrar as mensagens de erro na ligação.",
        "authprovider-resetpass-skip-label": "Ignorar",
        "authprovider-resetpass-skip-help": "Ignorar redefinição de palavra-passe",
+       "authform-nosession-login": "A autenticação ocorreu, mas o seu navegador não se \"recorda\" de ter iniciado uma sessão.\n\n$1",
+       "authform-nosession-signup": "A conta foi criada, mas o seu navegador não se \"recorda\" de ter iniciado uma sessão.\n\n$1",
        "authform-newtoken": "Chave em falta. $1",
        "authform-notoken": "Chave em falta",
        "authform-wrongtoken": "Chave errada",
        "specialpage-securitylevel-not-allowed-title": "Não permitido",
-       "specialpage-securitylevel-not-allowed": "Desculpe, não tem permissão para utilizar esta página porque a sua identidade não pôde ser verificada.",
+       "specialpage-securitylevel-not-allowed": "Desculpe, não tem permissão para utilizar esta página porque não foi possível verificar a sua identidade.",
        "authpage-cannot-login": "Não é possível iniciar sessão.",
        "authpage-cannot-login-continue": "Não é possível continuar a iniciar sessão. A sua sessão pode ter expirado.",
        "authpage-cannot-create": "Não é possível iniciar a criação da conta.",
        "linkaccounts-success-text": "A conta foi associada.",
        "linkaccounts-submit": "Associar contas",
        "unlinkaccounts": "Desassociar contas",
-       "unlinkaccounts-success": "A conta foi desassociada."
+       "unlinkaccounts-success": "A conta foi desassociada.",
+       "authenticationdatachange-ignored": "A alteração dos dados de autenticação não foi realizada. Talvez o fornecedor não tenha sido configurado?",
+       "userjsispublic": "Nota: As subpáginas de Javascript não devem conter dados confidenciais porque podem ser vistas por outros utilizadores.",
+       "usercssispublic": "Nota: As subpáginas de CSS não devem conter dados confidenciais porque podem ser vistas por outros utilizadores.",
+       "restrictionsfield-badip": "Endereço IP (ou gama de endereços IP) inválido: $1",
+       "restrictionsfield-label": "Gamas de endereços IP permitidas:",
+       "restrictionsfield-help": "Um endereço IP ou uma gama CIDR por linha. Para ativar todos,\nuse<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Erro: $1",
+       "edit-error-long": "Erros:\n\n$1"
 }
index e2b8292..07b55f9 100644 (file)
        "navigation": "This is shown as a section header in the sidebar of most skins.\n\n{{Identical|Navigation}}",
        "and": "The translation for \"and\" appears in the [[Special:Version]] page, between the last two items of a list. If a comma is needed, add it at the beginning without a gap between it and the \"&\". &amp;#32; is a blank space, one character long. Please leave it as it is.\n\nThis can also appear in the credits page if the credits feature is enabled,for example [{{canonicalurl:Support|action=credits}} the credits of the support page]. (To view any credits page type <nowiki>&action=credits</nowiki> at the end of any URL in the address bar.)\n{{Identical|And}}",
        "qbfind": "Alternative for \"search\" as used in Cologne Blue skin.\n{{Identical|Find}}",
-       "qbbrowse": "Heading in sidebar menu in CologneBlue skin as seen in http://i.imgur.com/I08Y3jW.png\n{{Identical|Browse}}",
+       "qbbrowse": "Heading in sidebar menu in CologneBlue skin as seen in [[File:CologneBlue sidebar qqx.png]]\n{{Identical|Browse}}",
        "qbedit": "Heading in sidebar menu in CologneBlue skin as seen in http://i.imgur.com/I08Y3jW.png\n{{Identical|Edit}}",
        "qbpageoptions": "Heading in sidebar menu in CologneBlue skin as seen in http://i.imgur.com/I08Y3jW.png\n{{Identical|This page}}",
        "qbmyoptions": "Heading in the Cologne Blue skin user menu containing links to user (talk) page, preferences, watchlist, etc.\n{{Identical|My pages}}",
        "botpasswords-label-delete": "Button label for the button to delete a bot password.\n{{Identical|Delete}}",
        "botpasswords-label-resetpassword": "Label for the checkbox to reset the actual password for the current bot password.",
        "botpasswords-label-grants": "Label for the checkmatrix for selecting grants allowed when the bot password is used.\n\ngrant: Vidu http://komputeko.net/index_en.php?vorto=grant sed \"konced/i\" egale funkcius.",
-       "botpasswords-help-grants": "Help text for the grant selection checkmatrix.",
+       "botpasswords-help-grants": "Help text for the grant selection checkmatrix.\n\nIdentical:\n* {{msg-mw|Mwoauth-consumer-grantshelp}}",
        "botpasswords-label-grants-column": "Label for the checkbox column on the checkmatrix for selecting grants allowed when the bot password is used.",
        "botpasswords-bad-appid": "Used as an error message when an invalid \"bot name\" is supplied on [[Special:BotPasswords]]. Parameters:\n* $1 - The rejected bot name.",
        "botpasswords-insert-failed": "Error message when saving a new bot password failed. It's likely that the failure was because the user resubmitted the form after a previous successful save. Parameters:\n* $1 - Bot name",
        "passwordreset-emailsentusername": "Used in [[Special:PasswordReset]].\n\nSee also:\n* {{msg-mw|Passwordreset-emailsent-capture}}\n* {{msg-mw|Passwordreset-emailerror-capture}}",
        "passwordreset-emailsent-capture2": "Used in [[Special:PasswordReset]].\n\nParameters:\n* $1 - number of accounts notified\n\nSee also:\n* {{msg-mw|Passwordreset-emailsentemail}}\n* {{msg-mw|Passwordreset-emailsentusername}}\n* {{msg-mw|Passwordreset-emailerror-capture}}",
        "passwordreset-emailerror-capture2": "Error message displayed in [[Special:PasswordReset]] when sending an email fails. Parameters:\n* $1 - error message\n* $2 - username, used for GENDER\n* $3 - number of accounts notified\n\nSee also:\n* {{msg-mw|Passwordreset-emailsentemail}}\n* {{msg-mw|Passwordreset-emailsentusername}}\n* {{msg-mw|Passwordreset-emailsent-capture}}\n* {{msg-mw|Passwordreset-emailerror-capture}}",
-       "passwordreset-nocaller": "Shown when a password reset was requested but the caller was not provided. This is an internal error.",
+       "passwordreset-nocaller": "Shown when a password reset was requested but the process failed due to an internal error related to missing details about the origin (caller) of the password reset request.",
        "passwordreset-nosuchcaller": "Shown when a password reset was requested but the username of the caller could not be resolved to a user. This is an internal error.\n\nParameters:\n* $1 - username of the caller",
        "passwordreset-ignored": "Shown when password reset was unsuccessful due to configuration problems.",
-       "passwordreset-invalideamil": "Returned when the email address is syntatically invalid.",
+       "passwordreset-invalidemail": "Returned when the email address is syntatically invalid.",
        "passwordreset-nodata": "Returned when no data was provided.",
        "changeemail": "Title of [[Special:ChangeEmail|special page]]. This page also allows removing the user's email address.",
        "changeemail-summary": "{{ignored}}",
        "editpage-invalidcontentmodel-text": "Error message shown when using an unrecognized content model on EditPage. $1 is the user's invalid input",
        "editpage-notsupportedcontentformat-title": "Title of error page shown when using an incompatible format on EditPage.\n\nUsed as title for the following error message:\n* {{msg-mw|Editpage-notsupportedcontentformat-text}}.",
        "editpage-notsupportedcontentformat-text": "Error message shown when using an incompatible format on EditPage.\n\nThe title for this error is {{msg-mw|Editpage-notsupportedcontentformat-title}}.\n\nParameters:\n* $1 - the format id\n* $2 - the content model name",
-       "content-model-wikitext": "Name for the wikitext content model, used when decribing what type of content a page contains.\n\nThis message is substituted in:\n*{{msg-mw|Bad-target-model}}\n*{{msg-mw|Content-not-allowed-here}}",
+       "content-model-wikitext": "Name for the wikitext content model, used when decribing what type of content a page contains.\n\nThis message is substituted in:\n*{{msg-mw|Bad-target-model}}\n*{{msg-mw|Content-not-allowed-here}}\n{{Identical|Wikitext}}",
        "content-model-text": "Name for the plain text content model, used when decribing what type of content a page contains. Plaintext means that the content of the page will be rendered as is like:\n\n<nowiki>This is [[plain text]]. <a href=\"https://www.mediawiki.org/\">Really!</a></nowiki>\n\nThis message is substituted in:\n*{{msg-mw|Bad-target-model}}\n*{{msg-mw|Content-not-allowed-here}}\n\n{{Identical|Plain text}}",
        "content-model-javascript": "Name for the JavaScript content model, used when decribing what type of content a page contains.\n\nThis message is substituted in:\n*{{msg-mw|Bad-target-model}}\n*{{msg-mw|Content-not-allowed-here}}",
-       "content-model-css": "Name for the CSS content model, used when decribing what type of content a page contains.\n\nThis message is substituted in:\n*{{msg-mw|Bad-target-model}}\n*{{msg-mw|Content-not-allowed-here}}",
+       "content-model-css": "Name for the CSS content model, used when decribing what type of content a page contains.\n\nThis message is substituted in:\n*{{msg-mw|Bad-target-model}}\n*{{msg-mw|Content-not-allowed-here}}\n{{Identical|CSS}}",
        "content-model-json": "Name for the JSON content model, used when decribing what type of content a page contains.\n\nThis message is substituted in:\n*{{msg-mw|Bad-target-model}}\n*{{msg-mw|Content-not-allowed-here}}",
        "content-json-empty-object": "Used to represent an object with no properties on a JSON content model page.",
        "content-json-empty-array": "Used to represent an array with no values on a JSON content model page.",
        "group-bot": "{{doc-group|bot}}\n{{Identical|Bot}}",
        "group-sysop": "{{doc-group|sysop}}\n{{Identical|Administrator}}",
        "group-bureaucrat": "{{doc-group|bureaucrat}}",
-       "group-suppress": "{{doc-group|suppress}}\nThis is an optional (disabled by default) user group, meant for the [[mw:RevisionDelete|RevisionDelete]] feature, to change the visibility of revisions through [[Special:RevisionDelete]].\n\n{{Identical|Suppress}}",
+       "group-suppress": "{{doc-group|suppress}}\nThis is an optional (disabled by default) user group, meant for the suppression feature in [[mw:Flow|Flow]]. It is not to be confused with the Oversighters group, which also has access to the [[mw:RevisionDelete|RevisionDelete]] feature, to change the visibility of revisions through [[Special:RevisionDelete]].\n\n{{Identical|Suppress}}",
        "group-all": "The name of the user group that contains all users, including anonymous users\n\n{{Identical|All}}",
        "group-user-member": "{{doc-group|user|member}}\n{{Identical|User}}",
        "group-autoconfirmed-member": "{{doc-group|autoconfirmed|member}}",
        "right-ipblock-exempt": "{{doc-right|ipblock-exempt}}\nThis user automatically bypasses IP blocks, auto-blocks and range blocks - so I presume - but I am uncertain",
        "right-unblockself": "{{doc-right|unblockself}}",
        "right-protect": "{{doc-right|protect}}",
-       "right-editprotected": "{{doc-right|editprotected}}\nRefers to {{msg-mw|Protect-level-sysop}}.\n\nSee also:\n* {{msg-mw|Right-editsemiprotected}}",
-       "right-editsemiprotected": "{{doc-right|editsemiprotected}}\nRefers to {{msg-mw|Protect-level-autoconfirmed}}.\n\nSee also:\n* {{msg-mw|Right-editprotected}}",
+       "right-editprotected": "{{doc-right|editprotected}}\nRefers to {{msg-mw|Protect-level-sysop}}.\n\nSee also:\n* {{msg-mw|Right-editeditorprotected}}\n* {{msg-mw|Right-editextendedsemiprotected}}\n* {{msg-mw|Right-editprotected}}\n* {{msg-mw|Right-editsemiprotected}}",
+       "right-editsemiprotected": "{{doc-right|editsemiprotected}}\nRefers to {{msg-mw|Protect-level-autoconfirmed}}.\n\nSee also:\n* {{msg-mw|Right-editeditorprotected}}\n* {{msg-mw|Right-editextendedsemiprotected}}\n* {{msg-mw|Right-editprotected}}\n* {{msg-mw|Right-editsemiprotected}}",
        "right-editcontentmodel": "{{doc-right|editcontentmodel}}",
        "right-editinterface": "{{doc-right|editinterface}}",
        "right-editusercssjs": "{{doc-right|editusercssjs}}",
        "right-changetags": "{{doc-right|changetags}}",
        "right-deletechangetags": "{{doc-right|deletechangetags}}",
        "grant-generic": "Used if the grant name is not defined. Parameters:\n* $1 - grant name\n\nDefined grants (grant name refers: blockusers, createeditmovepage, ...):\n* {{msg-mw|grant-checkuser}}\n* {{msg-mw|grant-blockusers}}\n* {{msg-mw|grant-createaccount}}\n* {{msg-mw|grant-createeditmovepage}}\n* {{msg-mw|grant-delete}}\n* {{msg-mw|grant-editinterface}}\n* {{msg-mw|grant-editmycssjs}}\n* {{msg-mw|grant-editmyoptions}}\n* {{msg-mw|grant-editmywatchlist}}\n* {{msg-mw|grant-editpage}}\n* {{msg-mw|grant-editprotected}}\n* {{msg-mw|grant-highvolume}}\n* {{msg-mw|grant-oversight}}\n* {{msg-mw|grant-patrol}}\n* {{msg-mw|grant-privateinfo}}\n* {{msg-mw|grant-protect}}\n* {{msg-mw|grant-rollback}}\n* {{msg-mw|grant-sendemail}}\n* {{msg-mw|grant-uploadeditmovefile}}\n* {{msg-mw|grant-uploadfile}}\n* {{msg-mw|grant-basic}}\n* {{msg-mw|grant-viewdeleted}}\n* {{msg-mw|grant-viewmywatchlist}}",
-       "grant-group-page-interaction": "{{Related|grant-group}}",
-       "grant-group-file-interaction": "{{Related|grant-group}}",
-       "grant-group-watchlist-interaction": "{{Related|grant-group}}",
+       "grant-group-page-interaction": "{{Related|Grant-group}}",
+       "grant-group-file-interaction": "{{Related|Grant-group}}",
+       "grant-group-watchlist-interaction": "{{Related|Grant-group}}",
        "grant-group-email": "{{Related|Grant-group}}\n{{Identical|E-mail}}",
        "grant-group-high-volume": "{{Related|Grant-group}}",
        "grant-group-customization": "{{Related|Grant-group}}",
        "grant-patrol": "Name for grant \"patrol\".\n{{Related|Grant}}",
        "grant-privateinfo": "Name for grant \"privateinfo\".\n{{Related|Grant}}",
        "grant-protect": "Name for grant \"protect\".\n{{Related|Grant}}",
-       "grant-rollback": "Name for grant \"rollback\".\n{{Related|Grant}}",
+       "grant-rollback": "Name for grant \"rollback\".\n{{Related|Grant}}\n{{Identical|Rollback}}",
        "grant-sendemail": "Name for grant \"sendemail\".\n{{Related|Grant}}",
        "grant-uploadeditmovefile": "Name for grant \"uploadeditmovefile\".\n{{Related|Grant}}",
        "grant-uploadfile": "Name for grant \"uploadfile\".\n{{Related|Grant}}\n{{Identical|Upload new file}}",
        "grant-basic": "Name for grant \"basic\".\n{{Related|Grant}}",
        "grant-viewdeleted": "Name for grant \"viewdeleted\".\n{{Related|Grant}}",
        "grant-viewmywatchlist": "Name for grant \"viewmywatchlist\".\n{{Related|Grant}}\n{{Identical|View your watchlist}}",
+       "grant-viewrestrictedlogs": "Name for grant \"viewrestrictedlogs\".\n{{Related|Grant}}",
        "newuserlogpage": "{{doc-logpage}}\n\nPart of the \"Newuserlog\" extension. It is both the title of [[Special:Log/newusers]] and the link you can see in [[Special:RecentChanges]].",
        "newuserlogpagetext": "Part of the \"Newuserlog\" extension. It is the description you can see on [[Special:Log/newusers]].",
        "rightslog": "{{doc-logpage}}\n\nIn [[Special:Log]]",
        "action-suppressionlog": "{{Doc-action|suppressionlog}}",
        "action-block": "{{Doc-action|block}}",
        "action-protect": "{{Doc-action|protect}}",
-       "action-rollback": "{{Doc-action|rollback}}",
+       "action-rollback": "{{Doc-action|rollback}}\n{{Identical|Rollback}}",
        "action-import": "{{Doc-action|import}}",
        "action-importupload": "{{Doc-action|importupload}}",
        "action-patrol": "{{Doc-action|patrol}}",
        "filedelete-edit-reasonlist": "Shown beneath the file deletion form on the right side. It is a link to [[MediaWiki:Filedelete-reason-dropdown]].\n\n{{Identical|Edit delete reasons}}",
        "filedelete-maintenance": "Content of the error page when $wgUploadMaintenance is set to true.",
        "filedelete-maintenance-title": "Title of the error page when $wgUploadMaintenance is set to true.",
-       "mimesearch": "Title of [[Special:MIMESearch]]. Also used as legend of the form.\n\nSee also:\n* {{msg-mw|Mimetype|label for input box}}\n* {{msg-mw|Ilsubmit|Submit button text}}",
-       "mimesearch-summary": "Text for [[Special:MIMESearch]]",
-       "mimetype": "Used as label for input box in the MIMESearch form on [[Special:MIMESearch]].\n\nSee also:\n* {{msg-mw|Mimesearch|page title}}\n* {{msg-mw|Ilsubmit|Submit button text}}\n{{Identical|MIME type}}",
+       "mimesearch": "Used as page title for [[Special:MIMESearch]], legend of input form and link text in [[Special:SpecialPages]].\n\nStrings on the page:\n* {{msg-mw|Mimesearch|page title, legend of input form, link in special pages}}\n* {{msg-mw|Mimesearch-summary|page summary}}\n* {{msg-mw|Mimetype|label for input box}}\n* {{msg-mw|Ilsubmit|search button}}\n\nCheck [[mw:Manual:MIME_type_detection]] for MIME types.",
+       "mimesearch-summary": "Page summary for [[Special:MIMESearch]]\n\nStrings on the page:\n* {{msg-mw|Mimesearch|page title, legend of input form, link in special pages}}\n* {{msg-mw|Mimesearch-summary|page summary}}\n* {{msg-mw|Mimetype|label for input box}}\n* {{msg-mw|Ilsubmit|search button}}\n\nCheck [[mw:Manual:MIME_type_detection]] for MIME types.",
+       "mimetype": "Label for input box in [[Special:MIMESearch]].\n\nStrings on the page:\n* {{msg-mw|Mimesearch|page title, legend of input form, link in special pages}}\n* {{msg-mw|Mimesearch-summary|page summary}}\n* {{msg-mw|Mimetype|label for input box}}\n* {{msg-mw|Ilsubmit|search button}}\n\nCheck [[mw:Manual:MIME_type_detection]] for MIME types.\n\n{{Identical|MIME type}}",
        "download": "Direct download link in each line returned by [[Special:MIMESearch]]. Points to the actual file, rather than the image description page.\n{{Identical|Download}}",
        "unwatchedpages": "{{doc-special|UnwatchedPages}}",
        "unwatchedpages-summary": "{{doc-specialpagesummary|unwatchedpages}}",
        "apisandbox-results-fixtoken-fail": "Displayed as an error message from JavaScript when a CSRF token could not be fetched.\n\nParameters:\n* $1 - Token type",
        "apisandbox-alert-page": "Tooltip for the alert icon on a module's page tab when the page contains fields with issues.",
        "apisandbox-alert-field": "Tooltip for the alert icon on a field when the field has issues.",
+       "apisandbox-continue": "Button text for sending another request using query continuation.\n{{Identical|Continue}}",
+       "apisandbox-continue-clear": "Button text for clearing query continuation parameters.\n{{Identical|Clear}}",
+       "apisandbox-continue-help": "Help text for the continue and clear buttons.",
+       "apisandbox-param-limit": "Additional documentation text for 'limit'-type parameters.",
        "booksources": "{{doc-special|BookSources}}\n\n'''This message shouldn't be changed unless it has serious mistakes.'''\n\nIt's used as the page name of the configuration page of [[Special:BookSources]]. Changing it breaks existing sites using the default version of this message.\n\nSee also:\n* {{msg-mw|Booksources|title}}\n* {{msg-mw|Booksources-text|text}}",
        "booksources-summary": "{{doc-specialpagesummary|booksources}}",
        "booksources-search-legend": "Box heading on [[Special:BookSources|book sources]] special page. The box is for searching for places where a particular book can be bought or viewed.",
        "booksources-search": "Search button in [[Special:BookSources]]\n\n{{Identical|Search}}",
        "booksources-text": "Used in [[Special:BookSources/1]].\n\nThis message is followed by a list of links to other sites.\n\nSee also:\n* {{msg-mw|Booksources|title}}\n* {{msg-mw|Booksources-text|text}}",
        "booksources-invalid-isbn": "This message is displayed after an invalid ISBN is entered on [[Special:Booksources]].",
+       "magiclink-tracking-rfc": "Name of the [[mw:Special:MyLanguage/Help:Tracking categories|tracking category]] where pages that use RFC magic links will be added.",
+       "magiclink-tracking-rfc-desc": "Description of the tracking category {{mw-msg|magiclink-tracking-rfc}}",
+       "magiclink-tracking-pmid": "Name of the [[mw:Special:MyLanguage/Help:Tracking categories|tracking category]] where pages that use PMID magic links will be added.",
+       "magiclink-tracking-pmid-desc": "Description of the tracking category {{mw-msg|magiclink-tracking-pmid}}",
+       "magiclink-tracking-isbn": "Name of the [[mw:Special:MyLanguage/Help:Tracking categories|tracking category]] where pages that use ISBN magic links will be added.",
+       "magiclink-tracking-isbn-desc": "Description of the tracking category {{mw-msg|magiclink-tracking-isbn}}",
        "rfcurl": "{{notranslate}}\nParameters:\n* $1 - RFC number\nSee also:\n* {{msg-mw|Pubmedurl}}",
        "pubmedurl": "{{notranslate}}\nParameters:\n* $1 - Pubmed number\nSee also:\n* {{msg-mw|Rfcurl}}",
        "specialloguserlabel": "Used in [[Special:Log]] as a label for an input field with which the log can be filtered for entries describing actions ''performed'' by the specified user.  \"Carried out\" and \"done\" are possible alternatives for \"performed\".",
        "activeusers-summary": "{{doc-specialpagesummary|activeusers}}",
        "activeusers-intro": "Used as introduction in [[Special:ActiveUsers]]. Parameters:\n* $1 - number of days (<code>$wgActiveUserDays</code>)",
        "activeusers-count": "Used in [[Special:ActiveUsers]] to show the active user's recent action count in brackets ([]).\n* $1 is the number of recent actions\n* $2 is the user's name for use with GENDER (optional)\n* $3 is the maximum number of days of the RecentChangesList",
-       "activeusers-from": "Used as label for checkbox in the form on [[Special:ActiveUsers]].\n\nidentical with {{msg-mw|listusersfrom}}\n\nSee also:\n* {{msg-mw|activeusers|legend for the form}}\n* {{msg-mw|activeusers-hidebots|label for checkbox}}\n* {{msg-mw|activeusers-hidesysops|label for checkbox}}",
-       "activeusers-hidebots": "Used as label for checkbox in the form on [[Special:ActiveUsers]].\n\nSee also:\n* {{msg-mw|activeusers|legend for the form}}\n* {{msg-mw|activeusers-from|label for input box}}\n* {{msg-mw|activeusers-hidesysops|label for checkbox}}",
-       "activeusers-hidesysops": "Used as label for checkbox in the form on [[Special:ActiveUsers]].\n\nSee also:\n* {{msg-mw|activeusers|legend for the form}}\n* {{msg-mw|activeusers-from|label for input box}}\n* {{msg-mw|activeusers-hidebots|label for checkbox}}",
+       "activeusers-from": "Used as label for checkbox in the form on [[Special:ActiveUsers]].\n\nidentical with {{msg-mw|listusersfrom}}\n\nSee also:\n* {{msg-mw|activeusers|legend for the form}}",
+       "activeusers-groups": "Used as label on [[Special:ActiveUsers]].",
        "activeusers-noresult": "identical with {{msg-mw|listusers-noresult}}",
        "activeusers-submit": "Used as label for button in the form on [[Special:ActiveUsers]]",
        "listgrouprights": "The name of the special page [[Special:ListGroupRights]].",
        "modifiedarticleprotection": "This is a ''logentry'' message only used on IRC.\nText describing an action. $1 is a page title.",
        "unprotectedarticle": "This is a ''logentry'' message only used on IRC.\nUsed as action. Parameters:\n* $1 - target page title",
        "movedarticleprotection": "This is a ''logentry'' message only used on IRC. It appears in the log if a protected page is renamed.\n\nExample:\n<code>00:51, 16 September 2010 Siebrand +(Talk • contribs • block) moved protection settings from \"User:Siebrand/prot-move\" to \"User:Siebrand/prot-moved\" ‎ (User:Siebrand/prot-move moved to User:Siebrand/prot-moved: prot_move test.)</code>\n\nParameters:\n* $1 - target page title\n* $2 - source page title",
+       "protectedarticle-comment": "Used as part of the edit summary placed in the page history when a page is protected.\n\nParameters:\n* $1 - page title\n* $2 - user who carried out the action (should only be used in the <code>GENDER</code> magic word)",
+       "modifiedarticleprotection-comment": "Used as part of the edit summary placed in the page history when a page's protection settings are modified.\n\nParameters:\n* $1 - page title\n* $2 - user who carried out the action (should only be used in the <code>GENDER</code> magic word)",
+       "unprotectedarticle-comment": "Used as part of the edit summary placed in the page history when a page is unprotected.\n\nParameters:\n* $1 - page title\n* $2 - user who carried out the action (should only be used in the <code>GENDER</code> magic word)",
        "protect-title": "Title for the protection form. $1 is the title of the page to be (un)protected.",
        "protect-title-notallowed": "Same as {{msg-mw|Protect-title}}, but when the user does not have the right to change protection levels.\n\nParameters:\n* $1 - page title",
        "prot_1movedto2": "Message description: [[mw:Manual:Interface/1movedto2]]\n\nParameters:\n* $1 - source page title\n* $2 - target page title",
        "movepage-max-pages": "PROBABLY (A GUESS): when moving a page, you can select an option of moving its subpages, but there is a maximum that can be moved automatically.\n\nParameters:\n* $1 - maximum moved pages, defined in the variable [[mw:Special:MyLanguage/Manual:$wgMaximumMovedPages|$wgMaximumMovedPages]]",
        "movelogpage": "{{doc-logpage}}\n\nTitle of [[Special:Log/move]]. Used as heading on that page, and in the dropdown menu on log pages.",
        "movelogpagetext": "Text on the special page 'Move log'.",
-       "movesubpage": "This is a section header on [[Special:MovePage]], below is a list of subpages.\n\nParameters:\n* $1 - number of subpages\nSee also:\n* {{msg-mw|movenosubpage|without subpage}}\n* {{msg-mw|movesubpagetext|with subpages}}",
-       "movesubpagetext": "Used in [[Special:MovePage]]. Parameters:\n* $1 - number of subpages\nSee also:\n* {{msg-mw|movesubpage|section header}}\n* {{msg-mw|movenosubpage|without subpage}}",
-       "movenosubpage": "See also:\n* {{msg-mw|movesubpage|section header}}\n* {{msg-mw|movenosubpage|without subpage}}\n* {{msg-mw|movesubpagetext|with subpages}}",
+       "movesubpage": "This is a section header on [[Special:MovePage]], below is a list of subpages.\n\nParameters:\n* $1 - number of subpages\nSee also:\n* {{msg-mw|movenosubpage|without subpage}}\n* {{msg-mw|movesubpagetext|with subpages}}\n* {{msg-mw|movesubpagetalktext|with talk subpages}}",
+       "movesubpagetext": "Used in [[Special:MovePage]]. Parameters:\n* $1 - number of subpages\nSee also:\n* {{msg-mw|movesubpage|section header}}\n* {{msg-mw|movenosubpage|without subpage}}\n* {{msg-mw|movesubpagetalktext|with talk subpages}}",
+       "movesubpagetalktext": "Used in [[Special:MovePage]] when corresponding talk page has subpages. Parameters:\n* $1 - number of subpages\nSee also:\n* {{msg-mw|movesubpage|section header}}\n* {{msg-mw|movenosubpage|without subpage}}",
+       "movenosubpage": "See also:\n* {{msg-mw|movesubpage|section header}}\n* {{msg-mw|movenosubpage|without subpage}}\n* {{msg-mw|movesubpagetext|with subpages}}\n* {{msg-mw|movesubpagetalktext|with talk subpages}}",
        "movereason": "Used in [[Special:MovePage]]. The text for the inputbox to give a reason for the page move.\n\nSee also:\n* {{msg-mw|Move-page-legend|legend for the form}}\n* {{msg-mw|newtitle|label for new title}}\n* {{msg-mw|Movetalk|label for checkbox}}\n* {{msg-mw|Move-leave-redirect|label for checkbox}}\n* {{msg-mw|Fix-double-redirects|label for checkbox}}\n* {{msg-mw|Move-subpages|label for checkbox}}\n* {{msg-mw|Move-talk-subpages|label for checkbox}}\n* {{msg-mw|Move-watch|label for checkbox}}\n{{Identical|Reason}}",
        "move-redirect-text": "{{ignored}}The text that's added to a redirected page when that redirect is created.",
        "category-move-redirect-override": "{{ignored}}The text that's added to a redirected category page when that redirect is created.",
        "pageinfo-category-pages": "See also:\n* {{msg-mw|Pageinfo-category-subcats}}\n* {{msg-mw|Pageinfo-category-files}}\n{{Identical|Number of pages}}",
        "pageinfo-category-subcats": "See also:\n* {{msg-mw|Pageinfo-category-pages}}\n* {{msg-mw|Pageinfo-category-files}}",
        "pageinfo-category-files": "See also:\n* {{msg-mw|Pageinfo-category-pages}}\n* {{msg-mw|Pageinfo-category-subcats}}",
+       "pageinfo-user-id": "The numeric ID for a user",
        "markaspatrolleddiff": "{{doc-actionlink}}\nSee also:\n* {{msg-mw|Markaspatrolledtext}}\n{{Identical|Mark as patrolled}}",
        "markaspatrolledlink": "{{notranslate}}\nParameters:\n* $1 - link which has text {{msg-mw|Markaspatrolledtext}}",
        "markaspatrolledtext": "{{doc-actionlink}}\nSee also:\n* {{msg-mw|Markaspatrolleddiff}}",
        "patrol-log-header": "Text that appears above the log entries on the [[Special:log|patrol log]].",
        "log-show-hide-patrol": "Used in [[Special:Log]]. Parameters:\n* $1 - link text; one of {{msg-mw|Show}} or {{msg-mw|Hide}}\n{{Related|Log-show-hide}}",
        "log-show-hide-tag": "Used in [[Special:Log]]. Parameters:\n* $1 - link text; one of {{msg-mw|Show}} or {{msg-mw|Hide}}\n{{Related|Log-show-hide}}",
+       "confirm-markpatrolled-button": "Used as Submit button text.\n{{Identical|OK}}",
+       "confirm-markpatrolled-top": "Confirmation message on interstitial form.\n\nParameters:\n* $1 - Target page title\n* $2 - Link to target page with page title as label\n* $3 - Link to recent change diff with revision ID as label",
        "deletedrevision": "Used as log comment. Parameters:\n* $1 - archive name of old image",
        "filedeleteerror-short": "Used as error message. Parameters:\n* $1 – There are two uses: 1) filename or 2) more specific error message like {{msg-mw|Backend-fail-internal}}.\nSee also:\n* {{msg-mw|Filedeleteerror-long}}",
        "filedeleteerror-long": "Used as error message. Parameters:\n* $1 - ...\nSee also:\n* {{msg-mw|Filedeleteerror-short}}",
        "newimages-showbots": "Used as label for a checkbox. When checked, [[Special:NewImages]] will also display uploads by users in the bots group.",
        "newimages-hidepatrolled": "Used as label for a checkbox. When checked, [[Special:NewImages]] will not display patrolled uploads.\n\nCf. {{msg-mw|tog-hidepatrolled}} and {{msg-mw|apihelp-feedrecentchanges-param-hidepatrolled}}.",
        "noimages": "This is shown on the special page [[Special:NewImages]], when there aren't any recently uploaded files.",
-       "ilsubmit": "Used as label for input box in the MIMESearch form on [[Special:MIMESearch]].\n\nSee also:\n* {{msg-mw|Mimesearch|page title}}\n* {{msg-mw|Mimetype|label for input box}}\n{{Identical|Search}}",
+       "gallery-slideshow-toggle": "Tooltip for the icon that toggles thumbnails on a slideshow  gallery.",
+       "ilsubmit": "Search button in [[Special:MIMESearch]].\n\nStrings on the page:\n* {{msg-mw|Mimesearch|page title, legend of input form, link in special pages}}\n* {{msg-mw|Mimesearch-summary|page summary}}\n* {{msg-mw|Mimetype|label for input box}}\n* {{msg-mw|Ilsubmit|search button}}\n\nCheck [[mw:Manual:MIME_type_detection]] for MIME types.\n\n{{Identical|Search}}",
        "bydate": "{{Identical|Date}}",
        "sp-newimages-showfrom": "This is a link on [[Special:NewImages]] which takes you to a gallery of the newest files.\n* $1 is a date (example: ''19 March 2008'')\n* $2 is a time (example: ''12:15'')",
        "video-dims": "{{optional}}\nParameters:\n* $1 - ...\n* $2 - width\n* $3 - height",
        "tags-deactivate": "Used on [[Special:Tags]]. Verb. Used as display text on a link to deactivate a tag.\n{{Identical|Delete}}",
        "tags-hitcount": "Shown in the \"{{msg-mw|Tags-hitcount-header}}\" column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].\n\nParameters:\n* $1 - the number of changes marked with the tag",
        "tags-manage-no-permission": "Error message on [[Special:Tags]]",
-       "tags-manage-blocked": "Error message on [[Special:Tags]]",
+       "tags-manage-blocked": "Error message on [[Special:Tags]]\n\nParameters:\n* $1 - user name for gender",
        "tags-create-heading": "The title of a fieldset, beneath which lies a form used to create a tag. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
        "tags-create-explanation": "The first paragraph of an explanation to tell users what they are about to do.",
        "tags-create-tag-name": "Form field label for the name of the tag to be created.",
        "tags-deactivate-not-allowed": "Error message on [[Special:Tags]]",
        "tags-deactivate-submit": "The label of the form \"submit\" button when the user is about to deactivate a tag.\n{{Identical|Deactivate}}",
        "tags-apply-no-permission": "Error message seen via the API when a user lacks the permission to apply change tags.",
-       "tags-apply-blocked": "Error message seen via the API when a user is blocked and attempted to apply change tags.",
+       "tags-apply-blocked": "Error message seen via the API when a user is blocked and attempted to apply change tags.\n\nParameters:\n* $1 - user name for gender",
        "tags-apply-not-allowed-one": "Error message seen via the API when a user tries to apply a single tag that is not properly defined. This message is only ever used in the case of 1 tag.\n\nParameters:\n* $1 - tag name",
        "tags-apply-not-allowed-multi": "Error message seen via the API when a user tries to apply more than one tag that is not properly defined.\n\nParameters:\n* $1 - comma-separated list of tag names\n* $2 - number of tags",
        "tags-update-no-permission": "Error message seen via the API when a user lacks the permission to add or remove change tags after the fact.",
-       "tags-update-blocked": "Error message seen via the API when a user is blocked and attempted to add or remove change tags after the fact.",
+       "tags-update-blocked": "Error message seen via the API when a user is blocked and attempted to add or remove change tags after the fact.\n\nParameters:\n* $1 - user name for gender",
        "tags-update-add-not-allowed-one": "Error message seen via the API when a user tries to add a single tag that is not properly defined. This message is only ever used in the case of 1 tag.\n\nParameters:\n* $1 - tag name",
        "tags-update-add-not-allowed-multi": "Error message seen via the API when a user tries to add more than one tag that is not properly defined.\n\nParameters:\n* $1 - comma-separated list of tag names\n* $2 - number of tags",
        "tags-update-remove-not-allowed-one": "Error message seen via the API when a user tries to remove a single tag that is not properly defined. This message is only ever used in the case of 1 tag.\n\nParameters:\n* $1 - tag name",
        "htmlform-date-toohigh": "Used as error message in HTML forms. Parameters:\n* $1 - maximum date\nSee also:\n* {{msg-mw|Htmlform-invalid-input}}\n* {{msg-mw|Htmlform-required}}\n* {{msg-mw|Apifeatureusage-htmlform-date-invalid}}\n* {{msg-mw|Apifeatureusage-htmlform-date-toolow}}",
        "htmlform-time-toolow": "Used as error message in HTML forms. Parameters:\n* $1 - minimum date\nSee also:\n* {{msg-mw|Htmlform-invalid-input}}\n* {{msg-mw|Htmlform-required}}\n* {{msg-mw|Apifeatureusage-htmlform-time-invalid}}\n* {{msg-mw|Apifeatureusage-htmlform-time-toohigh}}",
        "htmlform-time-toohigh": "Used as error message in HTML forms. Parameters:\n* $1 - maximum date\nSee also:\n* {{msg-mw|Htmlform-invalid-input}}\n* {{msg-mw|Htmlform-required}}\n* {{msg-mw|Apifeatureusage-htmlform-time-invalid}}\n* {{msg-mw|Apifeatureusage-htmlform-time-toolow}}",
-       "htmlform-datetime-toolow": "Used as error message in HTML forms. Parameters:\n* $1 - minimum date\nSee also:\n* {{msg-mw|Htmlform-invalid-input}}\n* {{msg-mw|Htmlform-required}}\n* {{msg-mw|Apifeatureusage-htmlform-datetime-invalid}}\n* {{msg-mw|Apifeatureusage-htmlform-datetime-toohigh}}",
-       "htmlform-datetime-toohigh": "Used as error message in HTML forms. Parameters:\n* $1 - maximum date\nSee also:\n* {{msg-mw|Htmlform-invalid-input}}\n* {{msg-mw|Htmlform-required}}\n* {{msg-mw|Apifeatureusage-htmlform-datetime-invalid}}\n* {{msg-mw|Apifeatureusage-htmlform-datetime-toolow}}",
+       "htmlform-datetime-toolow": "Used as error message in HTML forms. Parameters:\n* $1 - minimum date\nSee also:\n* {{msg-mw|Htmlform-invalid-input}}\n* {{msg-mw|Htmlform-required}}",
+       "htmlform-datetime-toohigh": "Used as error message in HTML forms. Parameters:\n* $1 - maximum date\nSee also:\n* {{msg-mw|Htmlform-invalid-input}}\n* {{msg-mw|Htmlform-required}}",
        "htmlform-title-badnamespace": "Error message shown if the page title provided by the user is not in the required namespace. $1 is the page, $2 is the numerical namespace index.",
        "htmlform-title-not-creatable": "Error message shown if the page title provided by the user is not creatable (a special page). $1 is the page title.",
        "htmlform-title-not-exists": "Error message shown if the page title provided by the user does not exist. $1 is the page title.",
        "feedback-external-bug-report-button": "A button for submitting an external technical bug report.",
        "feedback-dialog-title": "Title of the feedback dialog",
        "feedback-dialog-intro": "An introduction at the top of the feedback dialog. $1 - Feedback page link",
-       "feedback-error-title": "{{Identical|Error}}",
        "feedback-error1": "Error message, appears when an unknown error occurs submitting feedback",
        "feedback-error2": "Error message, appears when we could not add feedback",
        "feedback-error3": "Error message, appears when we lose our connection to the wiki",
        "feedback-thanks": "Thanks message, appears if feedback was successful. Parameters:\n* $1 - \"Feedback\"\n* $2 - Feedback page URL",
        "feedback-thanks-title": "The title of the thank you dialog at the end of the submission process.\n{{Identical|Thank you}}",
        "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-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{{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-was-deleted": "API error message that can be used for client side localisation of API errors.",
        "duration-seconds": "Used as duration. Parameters:\n* $1 - number of seconds\n{{Related|Duration}}\n{{Identical|Second}}",
        "duration-minutes": "Used as duration. Parameters:\n* $1 - number of minutes\n{{Related|Duration}}\n{{Identical|Minute}}",
-       "duration-hours": "Used as duration. Parameters:\n* $1 - number of hours\n{{Related|Duration}}",
-       "duration-days": "Used as duration. Parameters:\n* $1 - number of days\n{{Related|Duration}}",
-       "duration-weeks": "Used as duration. Parameters:\n* $1 - number of weeks\n{{Related|Duration}}",
-       "duration-years": "Used as duration. Parameters:\n* $1 - number of years\n{{Related|Duration}}",
+       "duration-hours": "Used as duration. Parameters:\n* $1 - number of hours\n{{Related|Duration}}\n{{Identical|Hour}}",
+       "duration-days": "Used as duration. Parameters:\n* $1 - number of days\n{{Related|Duration}}\n{{Identical|Day}}",
+       "duration-weeks": "Used as duration. Parameters:\n* $1 - number of weeks\n{{Related|Duration}}\n{{Identical|Week}}",
+       "duration-years": "Used as duration. Parameters:\n* $1 - number of years\n{{Related|Duration}}\n{{Identical|Year}}",
        "duration-decades": "Used as duration. Parameters:\n* $1 - number of decades\n{{Related|Duration}}",
        "duration-centuries": "Used as duration. Parameters:\n* $1 - number of centuries\n{{Related|Duration}}",
        "duration-millennia": "Used as duration. Parameters:\n* $1 - number of millennia\n{{Related|Duration}}",
        "usercssispublic": "A reminder to users that CSS subpages are not preferences but normal pages, and thus can be viewed by other users and the general public. This message is shown to a user whenever they are editing a subpage in their own user-space that ends in .css. See also {{msg-mw|userjsispublic}}",
        "restrictionsfield-badip": "An error message shown when one entered an invalid IP address or range in a restrictions field (such as Special:BotPassword). $1 is the IP address.",
        "restrictionsfield-label": "Field label shown for restriction fields (e.g. on Special:BotPassword).",
-       "restrictionsfield-help": "Placeholder text displayed in restriction fields (e.g. on Special:BotPassword)."
+       "restrictionsfield-help": "Placeholder text displayed in restriction fields (e.g. on Special:BotPassword).",
+       "edit-error-short": "Error message. Parameters:\n* $1 - the error details\nSee also:\n* {{msg-mw|edit-error-long}}\n{{Identical|Error}}",
+       "edit-error-long": "Error message. Parameters:\n* $1 - the error details\nSee also:\n* {{msg-mw|edit-error-short}}\n{{Identical|Error}}"
 }
index bb89a09..86abce6 100644 (file)
        "notextmatches": "Manam ima p'anqakunap qillqankunapipas tarisqachu",
        "prevn": "{{PLURAL:$1|$1}} ñawpaq",
        "nextn": "{{PLURAL:$1|$1}} qatiq",
+       "prev-page": "ñawpaqnin p'anqa",
+       "next-page": "qatiqnin p'anqa",
        "prevn-title": "Ñawpaq $1 {{PLURAL:$1|taripasqa|taripasqakuna}}",
        "nextn-title": "Qatiq $1 {{PLURAL:$1|taripasqa|taripasqakuna}}",
        "shown-title": "Huk p'anqapi $1 {{PLURAL:$1|taripasqata|taripasqakunata}} rikuchiy",
        "activeusers-intro": "Kay qatiqpiqa ruraqkunatam rikunki, qhipaq $1 {{PLURAL:$1|p'unchawpi|p'unchawkunapi}} kay wikipi imatapas ruraq.",
        "activeusers-count": "$1 {{PLURAL:$1|llamk'apusqa|llamk'apusqakuna}} ñaqha {{PLURAL:$3|p'unchawpi|$3 p'unchawkunapi}}",
        "activeusers-from": "Ruraqkunata rikuchiy, kaywan qallarispa:",
-       "activeusers-hidebots": "Rurana antachakunata pakay",
-       "activeusers-hidesysops": "Kamachiqkunata pakay",
        "activeusers-noresult": "Ruraqkunataqa manam tarinichu.",
        "listgrouprights": "Ruraq huñup hayñinkuna",
        "listgrouprights-summary": "Kay qatiq sutisuyupiqa kay wikipi sut'ichasqa ruraq huñukunatam, kikinpa chayamuna hayñinkunatawan rikunki.\nChay kikinkunap hayñinkunamanta astawan ñawirinaykipaqqa [[{{MediaWiki:Listgrouprights-helppage}}|kaypi qhaway]].",
        "htmlform-chosen-placeholder": "Akllanata akllay",
        "htmlform-cloner-create": "Astawan yapay",
        "htmlform-cloner-delete": "Qichuy",
-       "sqlite-has-fts": "$1 hunt'a qillqa maskana yanapawan",
-       "sqlite-no-fts": "$1 mana hunt'a qillqa maskana yanapawan",
        "logentry-delete-delete": "{{GENDER:$2|}}$1 sutiyuq ruraqqa $3 nisqa p'anqatam qullun",
        "logentry-delete-restore": "{{GENDER:$2|}}$1 sutiyuq ruraqqa $3 nisqa p'anqatam qullusqamanta paqarichin",
        "logentry-delete-event": "{{GENDER:$2|}}$1 sutiyuq ruraqqa {{PLURAL:$5|huk hallch'ay|$5 hallch'ay}} ruraypa rikunalla kayninta wakinchan $3 p'anqapi: $4",
index 6de7ea2..e1c2830 100644 (file)
        "yourname": "Rurak shuti:",
        "yourpassword": "Yaykunkapak rimay:",
        "yourpasswordagain": "Yaykunapak rimayta kutin killkapay:",
-       "remembermypassword": "Kay Internet-wampunapi {{PLURAL:$1|shuk punchata|$1 punchakunata}} ñuka rurak shutiwan yaykushkami katichiwapay.",
        "login": "Yaykuna",
        "nav-login-createaccount": "Yaykuna",
        "userlogin": "Yaykuna",
index 52111d3..6e54be3 100644 (file)
        "activeusers-intro": "Quai è ina glista dals utilisaders che han gì activitads {{PLURAL:$1|l'ultim di|en ils ultims $1 dis}}.",
        "activeusers-count": "$1 {{PLURAL:$1|acziun|acziuns}} {{PLURAL:$3|l'ultim di|ils ultims $3 dis}}",
        "activeusers-from": "Mussar utilisaders davent da:",
-       "activeusers-hidebots": "Zuppentar bots",
-       "activeusers-hidesysops": "Zuppentar administraturs",
        "activeusers-noresult": "Chattà nagins utilisaders.",
        "listgrouprights": "Dretgs da las gruppas d'utilisaders",
        "listgrouprights-summary": "Sutvart vegn mussada ina glista da las gruppas d'utilisaders sin questa wiki cun ils dretgs d'access associads.\nInfurmaziuns supplementaras davart ils singuls dretgs chattas [[{{MediaWiki:Listgrouprights-helppage}}|sin questa pagina]].",
index c2c42c2..0d4a8b2 100644 (file)
        "passwordreset-emailelement": "Nume de utilizator: \n$1\n\nParolă temporară: \n$2",
        "passwordreset-emailsentemail": "Dacă această adresă de e-mail este asociată contului dumneavoastră, atunci se va trimite un e-mail de resetare a parolei.",
        "passwordreset-emailsentusername": "Dacă există o adresă de e-mail asociată acestui nume de utilizator, atunci se va trimite un e-mail de resetare a parolei.",
-       "passwordreset-invalideamil": "Adresă de e-mail nevalidă",
+       "passwordreset-invalidemail": "Adresă de e-mail nevalidă",
        "passwordreset-nodata": "Nu au fost furnizate un nume de utilizator sau o adresă de e-mail",
        "changeemail": "Modificare sau înlăturare adresă de e-mail",
        "changeemail-header": "Completați acest formular pentru a vă schimba adresa de e-mail. Dacă doriți să înlăturați orice asociere a unei adrese de e-mail cu contul dumneavoastră, lăsați necompletat câmpul pentru introducerea unei noi adrese de e-mail atunci când trimiteți formularul.",
        "expensive-parserfunction-warning": "Atenție: Această pagină conține prea multe apelări costisitoare ale funcțiilor parser.\n\nAr trebui să existe mai puțin de $2 {{PLURAL:$2|apelare|apelări}}, acolo există {{PLURAL:$1|$1 apelare|$1 apelări}}.",
        "expensive-parserfunction-category": "Pagini cu prea multe apelări costisitoare de funcții parser",
        "post-expand-template-inclusion-warning": "Atenție: Formatele incluse sunt prea mari.\nUnele formate nu vor fi incluse.",
-       "post-expand-template-inclusion-category": "Paginile în care este inclus formatul are o dimensiune prea mare",
+       "post-expand-template-inclusion-category": "Pagini în care formatele incluse au o dimensiune prea mare",
        "post-expand-template-argument-warning": "Atenție: Această pagină conține cel puțin un argument al unui format care are o mărime prea mare atunci când este expandat.\nAcsete argumente au fost omise.",
        "post-expand-template-argument-category": "Pagini care conțin formate cu argumente omise",
        "parser-template-loop-warning": "Buclă de formate detectată: [[$1]]",
        "activeusers-intro": "Aceasta este o listă cu utilizatorii care au avut orice fel de activitate în {{PLURAL:$1|ultima zi|ultimele $1 zile}}.",
        "activeusers-count": "{{PLURAL:$1|o acțiune|$1 acțiuni|$1 de acțiuni}} în {{PLURAL:$3|ultima zi|ultimele $3 zile|ultimele $3 de zile}}",
        "activeusers-from": "Afișează utilizatori începând cu:",
-       "activeusers-hidebots": "Ascunde roboții",
-       "activeusers-hidesysops": "Ascunde administratorii",
        "activeusers-noresult": "Niciun utilizator găsit.",
        "activeusers-submit": "Afișează utilizatorii activi",
        "listgrouprights": "Permisiuni grupuri de utilizatori",
        "sp-contributions-username": "Adresă IP sau nume de utilizator:",
        "sp-contributions-toponly": "Afișează numai versiunile recente",
        "sp-contributions-newonly": "Afișează numai modificările care au dus la crearea de pagini",
+       "sp-contributions-hideminor": "Ascunde modificările minore",
        "sp-contributions-submit": "Căutare",
        "whatlinkshere": "Ce trimite aici",
        "whatlinkshere-title": "Pagini care conțin legături spre „$1”",
        "recreate": "Recreează",
        "confirm_purge_button": "OK",
        "confirm-purge-top": "Doriți să reîncărcați pagina?",
-       "confirm-purge-bottom": "Actualizaea unei pagini șterge cache-ul și forțează cea mai recentă variantă să apară.",
+       "confirm-purge-bottom": "Actualizarea unei pagini șterge cache-ul și forțează cea mai recentă variantă să apară.",
        "confirm-watch-button": "OK",
        "confirm-watch-top": "Adăugați această pagină la lista de pagini urmărite?",
        "confirm-unwatch-button": "OK",
        "autosumm-replace": "Pagină înlocuită cu „$1”",
        "autoredircomment": "Redirecționat înspre [[$1]]",
        "autosumm-new": "Pagină nouă: $1",
-       "autosumm-newblank": "A creat o pagină goală",
+       "autosumm-newblank": "Creat o pagină goală",
        "size-bytes": "{{PLURAL:$1|un octet|$1 octeți|$1 de octeți}}",
        "size-pixel": "$1 {{PLURAL:$1|pixel|pixeli|de pixeli}}",
        "lag-warn-normal": "Modificările mai noi de $1 {{PLURAL:$1|secondă|seconde}} pot să nu apară în listă.",
        "feedback-external-bug-report-button": "Semnalare problemă tehnică",
        "feedback-dialog-title": "Trimitere păreri",
        "feedback-dialog-intro": "Puteți folosi formularul simplificat de mai jos pentru a vă trimite părerile. Comentariul dumneavoastră va fi adăugat în pagina „$1”, alături de numele dumneavoastră de utilizator.",
-       "feedback-error-title": "Eroare",
        "feedback-error1": "Eroare: Rezultat necunoscut de la API",
        "feedback-error2": "Eroare: editarea nu a reușit",
        "feedback-error3": "Eroare: Niciun răspuns de la API",
index a9db650..deeece5 100644 (file)
@@ -15,6 +15,7 @@
        "tog-hideminor": "Scunne le cangiaminde stuédeche jndr'à le cangiaminde recende",
        "tog-hidepatrolled": "Scunne le cangiaminde condrollate jndr'à le cangiaminde recende",
        "tog-newpageshidepatrolled": "Scunne le pàggene tenute sotte condrolle da l'elenghe de le pàggene nuève",
+       "tog-hidecategorization": "Scunne le categorije d'a vôsce",
        "tog-extendwatchlist": "Spanne l'elenghe de le pàggene condrollate pe fa vedè tutte le cangiaminde fatte, none sulamende l'urteme",
        "tog-usenewrc": "Cangiaminde d'u gruppe pe pàgene jndr'à le urteme cangiaminde e elenghe de le pàggene condrollate",
        "tog-numberheadings": "Testate auto-numerate",
@@ -25,6 +26,7 @@
        "tog-watchdefault": "Mitte le pàggene ca je agghie cangiate jndr'à le pàggene condrollate",
        "tog-watchmoves": "Mitte le pàggene ca je agghie spustate jndr'à le pàggene condrollate",
        "tog-watchdeletion": "Mitte le pàggene ca je agghie scangellate jndr'à le pàggene condrollate",
+       "tog-watchuploads": "Aggiunge file nuéve a l'elenghe de le pàggene condrollate",
        "tog-watchrollback": "Aggiunge le pàggene addò agghie fatte 'n'annullamende jndr'à l'elenghe de le pàggene condrollate",
        "tog-minordefault": "Pe convenzione signe tutte le cangiaminde cumme stuédeche",
        "tog-previewontop": "Fa vedè l'andeprime apprime d'a caselle de le cangiaminde",
@@ -34,7 +36,7 @@
        "tog-enotifminoredits": "Manneme 'na mail quanne onne state fatte cangiaminde stuèdeche sus a le pàggene",
        "tog-enotifrevealaddr": "Fa vedè l'indirizze e-mail jndr'à le e-mail de notifiche",
        "tog-shownumberswatching": "Fa vedè 'u numere de le utinde ca uardene",
-       "tog-oldsig": "Firme esistende:",
+       "tog-oldsig": "'A firma toje:",
        "tog-fancysig": "Firma grezze cumme a 'nu teste de Uicchi (senza collegamende automatiche)",
        "tog-uselivepreview": "Ause l'andeprime da 'u vive",
        "tog-forceeditsummary": "Ciércame conferme quanne stoche a 'nzerische 'nu riepighe vianghe",
@@ -42,6 +44,7 @@
        "tog-watchlisthidebots": "Scunne le cangiaminde de le bot da l'elenghe de le pàggene condrollate",
        "tog-watchlisthideminor": "Scunne le cangiaminde stuèdeche da l'elenghe de le pàggene condrollate",
        "tog-watchlisthideliu": "Scunne le cangiaminde de l'utinde canusciute da l'elenghe de le pàggene condrollate",
+       "tog-watchlistreloadautomatically": "Recareche automaticamende l'eleghe de le pàggene condrollate quanne cange 'nu filtre (richieste Javascript)",
        "tog-watchlisthideanons": "Scunne le cangiaminde de l'utinde scanusciute da l'elenghe de le pàggene condrollate",
        "tog-watchlisthidepatrolled": "Scunne le cangiaminde condrollate jndr'à l'elenghe de le pàggene condrollate",
        "tog-ccmeonemails": "Manneme 'na copie de le mail ca je manne a l'ôtre utinde",
        "october-date": "Ottommre $1",
        "november-date": "Novemmre $1",
        "december-date": "Decemmre $1",
+       "period-am": "AM",
+       "period-pm": "PM",
        "pagecategories": "{{PLURAL:$1|Categorije|Categorije}}",
        "category_header": "Pàggene jndr'à categorie \"$1\"",
        "subcategories": "Sotte Categorije",
        "morenotlisted": "Ste elenghe non g'è comblete.",
        "mypage": "'A pàgena meje",
        "mytalk": "'Ngazzaminde mie",
-       "anontalk": "'Ngazzaminde pe quiste IP",
+       "anontalk": "'Ngazzaminde",
        "navigation": "Naveghesce",
        "and": "&#32;e",
        "qbfind": "Cirche",
        "laggedslavemode": "Attenzione: 'A pàgene no ge tène cangiaminde recente.",
        "readonly": "Archivie blocchete",
        "enterlockreason": "Mitte 'na raggione p'u blocche, 'ncludenne 'na stime de quanne 'u blocche avène luate.",
-       "readonlytext": "'U database jndr'à stu mumende jè blocchete pe nueve 'nzereminde e otre cangiaminde, pò essere 'nu blocche pe 'na manutenziona de ''routine'', apprisse 'a quale torne tutte a poste.\n\nLe amministrature ca onne mise 'u blocche onne date sta motivazione: $1",
+       "readonlytext": "'U database jndr'à stu mumende ète bloccate pe 'nzereminde nuéve e otre cangiaminde, pò essere 'nu blocche pe 'na manutenziona de ''routine'', apprisse 'a quale torne tutte a poste.\n\nLe amministrature ca onne mise 'u blocche onne date sta mutivazione: $1",
        "missing-article": "'U database non ge iacchije 'u teste de 'na pàgene ca avesse acchià, nnomenete \"$1\" $2.\n\nStu fatte pò succedere quanne le collegaminde 'mbrà le differenze o le cunde non ge sonde aggiornete sus a 'na pàgene ca ha state scangellete.\n\nCe quiste non g'è 'u case, tu pò essere ca è 'cchiate 'nu bochere jndr'à 'u software.\nPe piacere manne 'na comunicazzione a 'n'[[Special:ListUsers/sysop|amministratore]], mettène jndr'à note pure l'URL.",
        "missingarticle-rev": "(versione#: $1)",
        "missingarticle-diff": "(Diff: $1, $2)",
        "yourpasswordagain": "Scrive 'a passuord notra vote:",
        "createacct-yourpasswordagain": "Conferme 'a passuord",
        "createacct-yourpasswordagain-ph": "Mitte arrete 'a passuord",
-       "remembermypassword": "Arrencuerdete 'u nome mije sus a stu combiuter (pe 'nu massime de $1 {{PLURAL:$1|sciurne|sciurne}})",
        "userlogin-remembermypassword": "Arrecuèrdeme",
        "userlogin-signwithsecure": "Ause 'na connessione secure",
+       "cannotlogin-title": "Non ge puè trasé",
        "yourdomainname": "'U nome d'u dominie tue:",
        "password-change-forbidden": "Non ge puè cangià le passuord sus a sta uicchi.",
        "externaldberror": "Vide bbuene, o stè 'n'errore de autendicazione a 'u database oppure tu non ge puè aggiorna 'u cunde tue esterne.",
        "newarticle": "(Nuève)",
        "newarticletext": "Tu ste segue 'nu collegamende a pàgene ca angore non g'esiste.\nPe ccrejà 'a pàgene, accuminze a scrivere jndr'à 'u scatole de sotte (vide 'a [$1 pàggene d'ajute] pe avè cchiù 'mbormaziune).\nCe tu te iacche aqquà e manghe tu 'u se purcè, allore cazze 'u buttone '''back''' d'u brauser.",
        "anontalkpagetext": "----''Queste jè 'na pàgene de 'ngazzaminde pe 'n'utende anonime, ca non ge vò ccu ccreje angore 'nu cunde utende, o de ce non g'u use.\nNuje auseme 'n'indirizze IP (ca jè numereche) pe identificarle.\nE' normale ca essende 'n'indirizze IP pò essere ausete pure da otre utinde ca 'u pigghiene.\nCe tu non ge si 'n'utende anonime e pinze ca le commende ca so revolte a te sonde studecarije, pe piacere [[Special:CreateAccount|ccreje 'nu cunde utende]] o [[Special:UserLogin|tràse]] pe no fà confusione jndr'à 'u future cu otre utinde anoneme.''",
-       "noarticletext": "Non ge stè scritte ninde jndr'à sta pàgene.\nTu puè [[Special:Search/{{PAGENAME}}|cercà pe quiste titele]] jndr'à otre pàggene, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}] oppure [{{fullurl:{{FULLPAGENAME}}|action=edit}} cange sta pàgene]</span>.",
+       "noarticletext": "Non ge stè scritte ninde jndr'à sta pàgene.\nTu puè [[Special:Search/{{PAGENAME}}|cercà pe quiste titole]] jndr'à otre pàggene, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} cirche l'archivije sue] o [{{fullurl:{{FULLPAGENAME}}|action=edit}} ccreje sta pàgene]</span>.",
        "noarticletext-nopermission": "Pe mò non ge stè teste jndr'à sta pàgene.\nTu puè [[Special:Search/{{PAGENAME}}|cercà pe stu titole]] jndr'à otre pàggene,\no <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} cirche jndr'à l'archivije cullegate]</span>, ma non ge tìne le permesse pe ccrejà sta pàgene.",
        "missing-revision": "'A revisione #$1 d'a pàgene chiamate \"{{FULLPAGENAME}}\" non g'esiste.\n\nQuiste succede normalmende purcé 'u cunde jè collegate a 'na pàgene ca ha state scangellate.\nLe dettaglie le puè acchià jndr'à l'[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} archivije de le scangellaziune].",
        "userpage-userdoesnotexist": "'U cunde utende \"<nowiki>$1</nowiki>\" non g'è reggistrete.\nPe piacere, condrolle ce tu vuè cu ccreje/cange sta pàgene.",
        "searchprofile-advanced-tooltip": "Cirche jndr'à le namespace personalizzete",
        "search-result-size": "$1 ({{PLURAL:$2|1 parole|$2 parole}})",
        "search-result-category-size": "{{PLURAL:$1|1 membre|$1 membre}} ({{PLURAL:$2|1 sottecategorije|$2 sottecategorije}}, {{PLURAL:$3|1 file|$3 file}})",
-       "search-redirect": "(Redirette $1)",
+       "search-redirect": "(Redirette da $1)",
        "search-section": "(sezione $1)",
        "search-category": "(categorije $1)",
        "search-file-match": "(combronde 'u condenute d'u file)",
        "activeusers-intro": "Queste jè 'n'elenghe de utinde ca avene fatte certe tipe de attività fine a l'urteme $1 {{PLURAL:$1|sciurne|sciurne}}.",
        "activeusers-count": "$1 {{PLURAL:$1|cangiamende|cangiaminde}} jndr'à l'urteme {{PLURAL:$3|sciurne}}",
        "activeusers-from": "Fà vedè l'utinde partenne da:",
-       "activeusers-hidebots": "Scunne le bot",
-       "activeusers-hidesysops": "Scunne le amministrature",
        "activeusers-noresult": "Nisciune utende acchiate.",
        "listgrouprights": "Deritte de le gruppe utinde",
        "listgrouprights-summary": "'A liste ca ste vide ète 'na liste de le gruppe utinde ccreiate sus a sta Uicchi, cu le lore deritte d'accesse associate.\nPonne stà [[{{MediaWiki:Listgrouprights-helppage}}|'mbormaziune de cchiù]] sus a le deritte individuale.",
        "contributions": "Condrebbute de l'{{GENDER:$1|utende}}",
        "contributions-title": "Condrebbute de l'utende pe $1",
        "mycontris": "Condrebbute mie",
+       "anoncontribs": "Condrebbute",
        "contribsub2": "Pe {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "'U cunde utende \"$1\" non g'è reggistrate.",
        "nocontribs": "Nisciune cangiamende ha state acchiate cu ste criterie.",
        "javascripttest": "Test de JavaScript",
        "javascripttest-pagetext-unknownaction": "Aziona scanusciute \"$1\"",
        "javascripttest-qunit-intro": "Vide 'a [$1 documendazione d'u test] sus a mediawiki.org.",
-       "tooltip-pt-userpage": "'A pàgene utende meje",
+       "tooltip-pt-userpage": "'A pàgene {{GENDER:|utende}} meje",
        "tooltip-pt-anonuserpage": "'A pàgene utende pe l'IP ca tu ste cange cumme",
-       "tooltip-pt-mytalk": "'Ngazzaminde mie",
+       "tooltip-pt-mytalk": "'Ngazzaminde {{GENDER:|mie}}",
        "tooltip-pt-anontalk": "'Ngazzamende sus a le cangiaminde da stu indirizze IP",
-       "tooltip-pt-preferences": "Me piece accussì",
+       "tooltip-pt-preferences": "{{GENDER:|Me piace}} accussì",
        "tooltip-pt-watchlist": "'A liste de le pàggene ca ste condrolle pe le camgiaminde",
-       "tooltip-pt-mycontris": "Liste de le condrebbute mie",
+       "tooltip-pt-mycontris": "Liste de le condrebbute {{GENDER:|mie}}",
        "tooltip-pt-login": "Tu si 'ncoraggiete a cullegarte, jidde non g'è 'n'obblighe.",
        "tooltip-pt-logout": "Isse",
        "tooltip-pt-createaccount": "Te ste 'ngoragge pe ccrejà 'nu cunde e trasè; comungue, non g'è obbligatorie",
        "tooltip-t-recentchangeslinked": "Cangiaminde recende jndr'à le pàggene appundete da sta pàgene",
        "tooltip-feed-rss": "RSS feed pe sta pàgene",
        "tooltip-feed-atom": "Atom feed pe sta pàgene",
-       "tooltip-t-contributions": "Vide 'a liste de le condrebbute de quiste utende",
+       "tooltip-t-contributions": "Vide l'elenghe de le condrebbute de {{GENDER:$1|stu utende}}",
        "tooltip-t-emailuser": "Manne n'e-mail a stu utende",
        "tooltip-t-info": "Cchiù 'mbormaziune sus a sta pàgene",
        "tooltip-t-upload": "Careche le file",
        "htmlform-title-not-exists": "$1 non g'esiste.",
        "htmlform-user-not-exists": "<strong>$1</strong> non g'esiste.",
        "htmlform-user-not-valid": "<strong>$1</strong> non g'è 'nu nome utende valide.",
-       "sqlite-has-fts": "$1 cu 'u supporte d'a ricerche full-text",
-       "sqlite-no-fts": "$1 senze 'u supporte d'a ricerche full-text",
        "logentry-delete-delete": "$1 pàgena {{GENDER:$2|scangellate}} $3",
        "logentry-delete-restore": "$1 pàgena {{GENDER:$2|repristinate}} $3",
        "logentry-delete-event": "$1 {{GENDER:$2|cangiate}} 'a vesibbilità {{PLURAL:$5|de l'archivije de le fatte|$5 de l'archivije de le fatte}} sus 'a $3: $4",
        "feedback-external-bug-report-button": "Memorizze 'nu combite tecniche",
        "feedback-dialog-title": "Conferme 'a segnalazione",
        "feedback-dialog-intro": "Tu puè ausà 'u module facile facile aqquà sotte pe confermà 'a segnalaziona toje. 'U commende tune avène aggiunde sus 'a pàgene \"$1\", affianghe a 'u nome utende tune.",
-       "feedback-error-title": "Errore",
        "feedback-error1": "Errore: resultate inaspettate da l'API",
        "feedback-error2": "Errore: Cangiamende fallite",
        "feedback-error3": "Errore: Nisciuna resposte da l'API",
        "feedback-thanks": "Grazie! 'A segnalaziona toje ha state mannate a 'a pàgene \"[$2 $1]\".",
        "feedback-thanks-title": "Grazie 'mbà!",
        "feedback-useragent": "Utende agente:",
-       "searchsuggest-search": "Cirche",
+       "searchsuggest-search": "Cirche {{SITENAME}}",
        "searchsuggest-containing": "tène...",
        "api-error-badaccess-groups": "Tu non ge puè carecà file sus a sta Uicchi.",
        "api-error-badtoken": "Errore inderne: Gettone errate.",
index 6dd8846..01b0767 100644 (file)
@@ -94,7 +94,9 @@
                        "Jdforrester",
                        "Jack who built the house",
                        "Cat1987",
-                       "SergeyButkov"
+                       "SergeyButkov",
+                       "Irus",
+                       "Kareyac"
                ]
        },
        "tog-underline": "Подчёркивание ссылок:",
        "virus-badscanner": "Ошибка настройки. Неизвестный сканер вирусов: ''$1''",
        "virus-scanfailed": "ошибка сканирования (код $1)",
        "virus-unknownscanner": "неизвестный антивирус:",
-       "logouttext": "'''Вы завершили сеанс работы.'''\n\nНекоторые страницы могут продолжать отображаться в том виде, как будто вы всё ещё представлены системе. Для борьбы с этим явлением обновите кэш браузера.",
+       "logouttext": "<strong>Вы завершили сеанс работы.</strong>\n\nНекоторые страницы могут продолжать отображаться в том виде, как будто вы всё ещё представлены системе. Для борьбы с этим явлением обновите кэш браузера.",
        "cannotlogoutnow-title": "Невозможно выйти прямо сейчас",
        "cannotlogoutnow-text": "Нельзя выйти во время использования $1.",
        "welcomeuser": "Добро пожаловать, $1!",
        "passwordreset-nocaller": "Должен быть предоставлен источник вызова",
        "passwordreset-nosuchcaller": "Источник вызова не существует: $1",
        "passwordreset-ignored": "Сброс пароля не был обработан. Может быть, не был настроен ни один провайдер?",
-       "passwordreset-invalideamil": "Недопустимый адрес электронной почты",
+       "passwordreset-invalidemail": "Недопустимый адрес электронной почты",
        "passwordreset-nodata": "Ни имя участника, ни адрес электронной почты не были предоставлены",
        "changeemail": "Изменить или удалить адрес электронной почты",
        "changeemail-header": "Заполните эту форму, чтобы изменить свой адрес электронной почты. Если вы хотите отвязать свой адрес электронной почты от учётной записи, то при заполнении формы оставьте пустым поле нового адреса электронной почты.",
        "minoredit": "Малое изменение",
        "watchthis": "Следить за этой страницей",
        "savearticle": "Записать страницу",
-       "savechanges": "СоÑ\85Ñ\80аниÑ\82Ñ\8c Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ\8f",
+       "savechanges": "Ð\97апиÑ\81аÑ\82Ñ\8c Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83",
        "publishpage": "Создать страницу",
        "publishchanges": "Записать страницу",
        "preview": "Предпросмотр",
        "content-model-css": "CSS",
        "content-json-empty-object": "Пустой объект",
        "content-json-empty-array": "Пустой массив",
-       "deprecated-self-close-category": "Страницы, использующие недопустимые самозакрывающеся HTML-теги",
+       "deprecated-self-close-category": "СÑ\82Ñ\80аниÑ\86Ñ\8b, Ð¸Ñ\81полÑ\8cзÑ\83Ñ\8eÑ\89ие Ð½ÐµÐ´Ð¾Ð¿Ñ\83Ñ\81Ñ\82имÑ\8bе Ñ\81амозакÑ\80Ñ\8bваÑ\8eÑ\89иеÑ\81Ñ\8f HTML-Ñ\82еги",
        "deprecated-self-close-category-desc": "Страница содержит недопустимые самозакрывающиеся HTML-теги, такие как <code>&lt;b/></code> или <code>&lt;span/></code>. В скором времени их действие изменится, чтобы соответствовать спецификации HTML5, так что использование этих устаревших тегов в вики-тексте нежелательно.",
        "duplicate-args-warning": "<strong>Внимание:</strong> [[:$1]] вызывает [[:$2]] с более чем одним значением параметра «$3». Будет использовано только последнее указанное значение.",
        "duplicate-args-category": "Страницы, использующие повторяющиеся аргументы в вызовах шаблонов",
        "undo-failure": "Правка не может быть отменена из-за несовместимости промежуточных изменений.",
        "undo-norev": "Правка не может быть отменена, так как её не существует или она была удалена.",
        "undo-nochange": "Правка, похоже, уже была отменена.",
-       "undo-summary": "Отмена правки $1, сделанной {{GENDER:$2|участником|участницей}} [[Special:Contribs/$2|$2]] ([[User talk:$2|обс.]])",
+       "undo-summary": "Отмена правки $1, сделанной [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]])",
        "undo-summary-username-hidden": "Отмена правки $1, сделанной участником, чьё имя скрыто",
        "cantcreateaccount-text": "Создание учётных записей с этого IP-адреса ('''$1''') было заблокировано {{GENDER:$3|участником|участницей|}} [[User:$3|$3]].\n\n$3 {{GENDER:$3|указал|указала}} следующую причину: ''$2''.",
        "cantcreateaccount-range-text": "{{GENDER:$3|Участник|Участница}} [[User:$3|$3]] {{GENDER:$3|установил|установила}} запрет на создание учётных записей из диапазона IP-адресов <strong>$1</strong>, включающего ваш IP-адрес (<strong>$4</strong>). \n\nБыла указана следующая причина: $2.",
        "grant-basic": "Основные права",
        "grant-viewdeleted": "Просмотр удалённых файлов и страниц",
        "grant-viewmywatchlist": "Просмотр вашего списка наблюдения",
+       "grant-viewrestrictedlogs": "Смотреть записи журнала с ограниченным доступом",
        "newuserlogpage": "Журнал регистрации участников",
        "newuserlogpagetext": "Список недавно зарегистрировавшихся участников",
        "rightslog": "Журнал прав участника",
        "upload-dialog-disabled": "На этом вики-сайте отключена возможность загрузки файлов с помощью этого диалогового окна.",
        "upload-dialog-title": "Загрузить файл",
        "upload-dialog-button-cancel": "Отменить",
+       "upload-dialog-button-back": "Назад",
        "upload-dialog-button-done": "Готово",
        "upload-dialog-button-save": "Сохранить",
        "upload-dialog-button-upload": "Загрузить",
        "apisandbox-results-fixtoken-fail": "Не удалось вызвать токен «$1».",
        "apisandbox-alert-page": "Поля на этой странице некорректны.",
        "apisandbox-alert-field": "Значение этого поля является недопустимым.",
+       "apisandbox-continue": "Продолжить",
+       "apisandbox-continue-clear": "Очистить",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries продолжит] последний запрос; {{int:apisandbox-continue-clear}} очистит связанные с продолжением параметры.",
+       "apisandbox-param-limit": "Введите <kbd>максимальное</kbd> использование максимального предела.",
        "booksources": "Источники книг",
        "booksources-search-legend": "Поиск информации о книге",
        "booksources-isbn": "ISBN:",
        "booksources-search": "Найти",
        "booksources-text": "На этой странице приведён список ссылок на сайты, где вы, возможно, найдёте дополнительную информацию о книге. Это интернет-магазины и системы поиска в библиотечных каталогах.",
        "booksources-invalid-isbn": "Указанный номер ISBN, судя по всему, содержит ошибку. Пожалуйста, проверьте, что при переносе номера из первоисточника не возникло искажений.",
+       "magiclink-tracking-rfc": "Страницы, использующие волшебные ссылки RFC",
+       "magiclink-tracking-rfc-desc": "Эта страница использует волшебные ссылки RFC. См. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] о том, как осуществить перенос.",
+       "magiclink-tracking-pmid": "Страницы, использующие волшебные ссылки PMID",
+       "magiclink-tracking-pmid-desc": "Эта страница использует волшебные ссылки PMID. См. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] о том, как осуществить перенос.",
+       "magiclink-tracking-isbn": "Страницы, использующие волшебные ссылки ISBN",
+       "magiclink-tracking-isbn-desc": "Эта страница использует волшебные ссылки ISBN. См. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] о том, как осуществить перенос.",
        "specialloguserlabel": "Исполнитель:",
        "speciallogtitlelabel": "Цель (название или {{ns:user}}:имя участника):",
        "log": "Журналы",
        "activeusers-intro": "Это список участников, совершавших какие-либо действия за {{PLURAL:$1|последний $1 день|последние $1 дня|последние $1 дней|1=последний день}}.",
        "activeusers-count": "$1 {{PLURAL:$1|правка|правки|правок}} за {{PLURAL:$3|$3 последний день|последние $3 дня|последние $3 дней|1=последний день}}",
        "activeusers-from": "Показать участников, начиная с:",
-       "activeusers-hidebots": "Скрыть ботов",
-       "activeusers-hidesysops": "Скрыть администраторов",
+       "activeusers-groups": "Отображать пользователей, принадлежащих к группам:",
        "activeusers-noresult": "Не найдено участников.",
        "activeusers-submit": "Показать активных участников",
        "listgrouprights": "Права групп участников",
        "alreadyrolled": "Невозможно откатить последние изменения страницы «[[:$1]]», совершённые [[User:$2|$2]] ([[User talk:$2|обсуждение]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]),\nпоскольку кто-то другой уже успел откатить эти правки или отредактировать страницу.\n\nПоследние изменения {{GENDER:$3|внёс|внесла}} [[User:$3|$3]] ([[User talk:$3|обсуждение]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Было дано описание изменения: <em>$1</em>.",
        "revertpage": "Откат правок [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]]) к версии [[User:$1|$1]]",
-       "revertpage-nouser": "Ð\9fÑ\80авки (имÑ\8f Ñ\83Ñ\87аÑ\81Ñ\82ника Ñ\81кÑ\80Ñ\8bÑ\82о) Ð¾Ñ\82каÑ\87енÑ\8b к версии {{GENDER:$1|[[User:$1|$1]]}}",
+       "revertpage-nouser": "Ð\9eÑ\82каÑ\82 Ð¿Ñ\80авок (имÑ\8f Ñ\83Ñ\87аÑ\81Ñ\82ника Ñ\81кÑ\80Ñ\8bÑ\82о) к версии {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Откачены правки $1; возврат к версии $2.",
        "rollback-success-notify": "Откачены правки $1; возврат к последней версии $2. [$3 Показать изменения]",
        "sessionfailure-title": "Ошибка сеанса",
        "modifiedarticleprotection": "изменён уровень защиты страницы «[[$1]]»",
        "unprotectedarticle": "снята защита с «[[$1]]»",
        "movedarticleprotection": "перенёс настройки защиты с «[[$2]]» на «[[$1]]»",
+       "protectedarticle-comment": "Защитил{{GENDER:$2||а}} «[[$1]]»",
+       "modifiedarticleprotection-comment": "Изменил{{GENDER:$2||а}} уровень защиты «[[$1]]»",
+       "unprotectedarticle-comment": "Убрал {{GENDER:$2||а}} защиту с «[[$1]]»",
        "protect-title": "Установка уровня защиты для «$1»",
        "protect-title-notallowed": "Просмотр уровня защиты «$1»",
        "prot_1movedto2": "[[$1]] переименована в [[$2]]",
        "movelogpagetext": "Ниже представлен список переименованных страниц.",
        "movesubpage": "{{PLURAL:$1|1=Подстраница|Подстраницы}}",
        "movesubpagetext": "У этой страницы $1 {{PLURAL:$1|подстраница|подстраницы|подстраниц}}.",
+       "movesubpagetalktext": "У соответствующей страницы обсуждения есть $1 {{PLURAL:$1|подстраница, показанная |подстраниц, показанных|подстраницы, показанные}} ниже.",
        "movenosubpage": "У этой страницы нет подстраниц.",
        "movereason": "Причина:",
        "revertmove": "возврат",
        "pageinfo-category-pages": "Количество страниц",
        "pageinfo-category-subcats": "Количество подкатегорий",
        "pageinfo-category-files": "Количество файлов",
+       "pageinfo-user-id": "Идентификатор участника",
        "markaspatrolleddiff": "Отметить как проверенную",
        "markaspatrolledtext": "Отметить эту статью как проверенную",
        "markaspatrolledtext-file": "Пометить эту версию файла как отпатрулированную",
        "patrol-log-header": "Это журнал патрулированных версий.",
        "log-show-hide-patrol": "$1 журнал патрулирования",
        "log-show-hide-tag": "$1 журнал меток",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Пометить версию $3 страницы $2 как отпатрулированную?",
        "deletedrevision": "Удалена старая версия $1",
        "filedeleteerror-short": "Ошибка удаления файла: $1",
        "filedeleteerror-long": "Во время удаления файла возникли ошибки:\n\n$1",
        "newimages-showbots": "Показать загрузки ботов",
        "newimages-hidepatrolled": "Скрыть отпатрулированные загрузки",
        "noimages": "Изображения отсутствуют.",
+       "gallery-slideshow-toggle": "Переключить миниатюры",
        "ilsubmit": "Найти",
        "bydate": "по дате",
        "sp-newimages-showfrom": "Показать новые файлы, начиная с $2, $1",
        "tags-deactivate-not-allowed": "Невозможно отключить метку «$1».",
        "tags-deactivate-submit": "Отключить",
        "tags-apply-no-permission": "У вас нет права применять метки изменения к своими изменениям.",
-       "tags-apply-blocked": "Вы не можете применять метки правок к своим правкам, пока вы заблокированы.",
+       "tags-apply-blocked": "Вы не можете применять метки правок к своим правкам, пока {{GENDER:$1|вы}} заблокированы.",
        "tags-apply-not-allowed-one": "Метка «$1» не может быть применена вручную.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|Следующая метка не может быть применена|Следующие метки не могут быть применены}} вручную: $1",
        "tags-update-no-permission": "У вас нет права на добавление или изменение меток изменения из отдельных версий или записей журналов.",
-       "tags-update-blocked": "Вы не можете добавлять или удалять метки правок, пока вы заблокированы.",
+       "tags-update-blocked": "Вы не можете добавлять или удалять метки правок, пока {{GENDER:$1|вы}} заблокированы.",
        "tags-update-add-not-allowed-one": "Тег \"$1\" не может быть добавлен вручную.",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|Следующий тег|Следующие теги}} нельзя добавлять вручную: $1",
        "tags-update-remove-not-allowed-one": "Метка «$1» не может быть удалена.",
        "htmlform-cloner-create": "Добавить ещё",
        "htmlform-cloner-delete": "Удалить",
        "htmlform-cloner-required": "Требуется по крайней мере одно значение.",
+       "htmlform-date-placeholder": "ГГГГ-ММ-ДД",
+       "htmlform-time-placeholder": "ЧЧ:ММ:СС",
+       "htmlform-datetime-placeholder": "ГГГГ-ММ-ДД ЧЧ:ММ:СС",
+       "htmlform-date-invalid": "Указанное вами значение не похоже на дату. Попробуйте использовать формат ГГГГ-ММ-ДД.",
+       "htmlform-time-invalid": "Указанное вами значение не похоже на время. Попробуйте использовать формат ЧЧ-ММ-СС.",
+       "htmlform-datetime-invalid": "Указанное вами значение не похоже на дату и время. Попробуйте использовать формат ГГГГ-ММ-ДД ЧЧ-ММ-СС.",
+       "htmlform-date-toolow": "Указанное вами значение меньше самой ранней разрешённой даты — $1.",
+       "htmlform-date-toohigh": "Указанное вами значение больше самой поздней разрешённой даты — $1.",
+       "htmlform-time-toolow": "Указанное вами значение меньше самого раннего разрешённого времени — $1.",
+       "htmlform-time-toohigh": "Указанное вами значение больше самого позднего разрешённого времени — $1.",
+       "htmlform-datetime-toolow": "Указанное вами значение меньше самым ранних разрешённых даты и времени — $1.",
+       "htmlform-datetime-toohigh": "Указанное вами значение больше самых поздних разрешённых даты и времени — $1.",
        "htmlform-title-badnamespace": "[[:$1]] находится не в пространстве имён «{{ns:$2}}».",
        "htmlform-title-not-creatable": "«$1» — заголовок страницы, которая не может быть создана",
        "htmlform-title-not-exists": "$1 не существует.",
        "feedback-external-bug-report-button": "Отправить техническое задание",
        "feedback-dialog-title": "Отправить отзыв",
        "feedback-dialog-intro": "Вы можете воспользоваться простой формой ниже, чтобы оставить свой отзыв. Комментарий с вашим именем участника будет добавлен на страницу «$1».",
-       "feedback-error-title": "Ошибка",
        "feedback-error1": "Ошибка. Неизвестный результат из API",
        "feedback-error2": "Ошибка. Сбой редактирования",
        "feedback-error3": "Ошибка. Нет ответа от API",
        "feedback-thanks": "Спасибо! Ваш отзыв размещён на странице «[$2 $1]».",
        "feedback-thanks-title": "Спасибо!",
        "feedback-useragent": "Браузер:",
-       "searchsuggest-search": "Ð\9fоиÑ\81к",
+       "searchsuggest-search": "Ð\98Ñ\81каÑ\82Ñ\8c Ð² {{grammar:prepositional|{{SITENAME}}}}",
        "searchsuggest-containing": "содержащие…",
        "api-error-autoblocked": "Ваш IP-адрес был автоматически заблокирован, потому что он был использован заблокированным участником.",
        "api-error-badaccess-groups": "Вам не разрешено загружать файлы в эту вики.",
        "usercssispublic": "Обратите внимание: подстраницы CSS не должны содержать конфиденциальные сведения, поскольку они доступны для просмотра другим участникам.",
        "restrictionsfield-badip": "Недопустимый IP-адрес или диапазон адресов: $1",
        "restrictionsfield-label": "Разрешённые диапазоны IP-адресов:",
-       "restrictionsfield-help": "По одному IP-адресу или CIDR-диапазону в строке. Чтобы разрешить всё, используйте <br /><code>0.0.0.0/0</code><br /><code>::/0</code>"
+       "restrictionsfield-help": "По одному IP-адресу или CIDR-диапазону в строке. Чтобы разрешить всё, используйте <br /><code>0.0.0.0/0</code><br /><code>::/0</code>",
+       "edit-error-short": "Ошибка: $1",
+       "edit-error-long": "Ошибки: $1"
 }
index 1259b35..dbc7b57 100644 (file)
        "yourpasswordagain": "Повторяйте гесло:",
        "createacct-yourpasswordagain": "Потвердьте гесло",
        "createacct-yourpasswordagain-ph": "Уведьте гесло знову",
-       "remembermypassword": "Запамнятати моє приголошіня на тім компютерї (максімално $1 {{PLURAL:$1|день|днів}})",
        "userlogin-remembermypassword": "Приголосити ня на довго",
        "userlogin-signwithsecure": "Хосновати забеспечене споїня",
        "yourdomainname": "Ваша домена:",
        "passwordreset-emailtext-user": "{{gender:$1|Хоснователь|Хоснователька|Хоснователь}} $1 {{grammar:2sg|{{SITENAME}}}} {{gender:$1|попросив|попросила|попросив}} о наставлїня нового гесла до вашого\nконта на {{grammar:6sg|{{SITENAME}}}} ($4). З тов адресов {{PLURAL:$3|є повязане наступне конто|суть повязаны наступны конта}}:\n\n$2\n\n{{PLURAL:$3|Тото дочасне гесло кінчить|Тоты дочасны гесла кінчать}} {{PLURAL:$5|о єден день|о $5 днї|о $5 днїв}}.\nТеперь бы сьте ся мали приголосити і зволити собі нове гесло. Кідь тоту пожадавку \nпослав дахто другый або сьте собі на своє старе гесло спомянули і не хочете го\nзмінити, можете тото повідомлїня іґноровати і надале хосновати старе гесло.",
        "passwordreset-emailelement": "Імя хоснователя: \n$1\n\nДочасне гесло: \n$2",
        "passwordreset-emailsentemail": "Імейл з геслом быв посланый.",
-       "passwordreset-emailsent-capture": "Быв выґенерованый імейл з геслом, што є вказаный ниже.",
-       "passwordreset-emailerror-capture": "Быв выґенерованый імейл з геслом, котрый є указаный ниже, але ся го не вдало загнати {{GENDER:$2|хоснователёви|хосновательцї}}: $1",
        "changeemail": "Зміна імейловой адресы",
        "changeemail-header": "Зміна імейловой адресу ку конту",
        "changeemail-no-info": "Ку тій сторінцї мають прямый приступ лем приголошены хоснователї.",
        "undo-norev": "Тото едітованя не можете вернути назад, бо не екзістує або было змазане.",
        "undo-summary": "Зрушена верзія $1 од хоснователя [[Special:Contributions/$2|$2]] ([[User talk:$2|діскузія]])",
        "undo-summary-username-hidden": "Зрушыти ревізію $1 скрытого хоснователя",
-       "cantcreateaccounttitle": "Не є можне вытворити конто",
        "cantcreateaccount-text": "Створёваня новых конт з той IP адресы ('''$1''') было заблоковане хоснователём [[User:$3|$3]].\n\n$3 зазначів тоту причіну: ''$2''",
        "viewpagelogs": "Вказати лоґы про тоту сторінку",
        "nohistory": "Про тоту статю не екзістує історія едітовань.",
        "activeusers-intro": "Тото є список хоснователїв, котры были даяк актівны за {{plural:$1|остатнїй день|остатных $1 днїв}}.",
        "activeusers-count": "$1 {{PLURAL:$1|дїя|дїї|дїй}} через {{PLURAL:$3|остатнёго дня|остатнїх  $3 днїв}}",
        "activeusers-from": "Вказати хоснователїв, што ся зачінають на:",
-       "activeusers-hidebots": "Сховати ботів",
-       "activeusers-hidesysops": "Сховати адміністраторів",
        "activeusers-noresult": "Ненайдженый жаден хоснователь.",
        "listgrouprights": "Права ґруп хоснователїв",
        "listgrouprights-summary": "Тото є список ґруп хоснователїв дефінованых на тій вікіi і&nbsp;їх приступовых прав.\n\n[[{{MediaWiki:Listgrouprights-helppage}}|Детайлны інформації о&nbsp;єднотливых правах]]",
        "htmlform-no": "Нє",
        "htmlform-yes": "Гей",
        "htmlform-chosen-placeholder": "Звольте параметер",
-       "sqlite-has-fts": "$1 з підпоров повнотекстового гляданя",
-       "sqlite-no-fts": "$1 без підпоры повнотекстового гляданя",
        "logentry-delete-delete": "$1 {{GENDER:$2|змазав|змазала}} сторінку $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|обновив|обновила}} сторінку $3",
        "logentry-delete-event": "$1 {{GENDER:$2|змінив|змінила}}  відимость {{PLURAL:$5|протоколового запису|$5 протоколовых записів}} к сторінцї $3: $4",
        "special-characters-group-lao": "Лаоськы",
        "special-characters-group-khmer": "Кгмерськы",
        "mw-widgets-dateinput-placeholder-day": "РРРР-ММ-ДД",
-       "mw-widgets-dateinput-placeholder-month": "РРРР-ММ",
-       "api-error-blacklisted": "Звольте іншу, пописну назву."
+       "mw-widgets-dateinput-placeholder-month": "РРРР-ММ"
 }
index 9591937..d96819c 100644 (file)
        "activeusers-intro": "एषा तु गतेषु $1 {{PLURAL:$1|दिनेषु}} कृतकार्याणां योजकाना आवली ।",
        "activeusers-count": "$1 {{PLURAL:$1|कार्यं|कार्याणि}} गतेषु $3 {{PLURAL:$3|दिनेषु}} कृतानि  ।",
        "activeusers-from": "एतस्मात् आरभमाणान् योजकान् दर्शयतु ।",
-       "activeusers-hidebots": "स्वयं चालकान् गोपयतु ।",
-       "activeusers-hidesysops": "प्रशासकान् गोपयतु ।",
        "activeusers-noresult": "सदस्यः न प्राप्तः ।",
        "listgrouprights": "योजकसमूहाधिकाराः ।",
        "listgrouprights-summary": "अधोदत्ता विकिपरिभाषितस्य सङ्गताभिगम्यताधिकारैः सहिता योजकसमूहस्य आवली । [[{{MediaWiki:Listgrouprights-helppage}}|additional information]]",
        "feedback-external-bug-report-button": "यान्त्रककार्यम् अङ्क्यताम्",
        "feedback-dialog-title": "स्वप्रतिक्रियां लिखतु",
        "feedback-dialog-intro": "स्वप्रतिक्रियां लेखितुं निम्नं सरलपत्रम् उपयोक्तुं शक्नोति   ।\nभवतः/भवत्याः योजकनामोल्लेखन सह $1 इत्यस्मिन् पृष्ठे भवतः/भवत्याः प्रतिक्रियां योजयिष्यामः ।",
-       "feedback-error-title": "दोषः",
        "feedback-error1": "API इत्यस्मात् दोषः : अज्ञातः परिणामः ।",
        "feedback-error2": "दोषः : सम्पादनं निष्फलं जातम्",
        "feedback-error3": "दोषः : ए पि ऐ तः प्रतिस्पन्दः न प्राप्तः",
index 598e10d..2f0fbc9 100644 (file)
@@ -34,6 +34,7 @@
        "tog-watchdefault": "Уларыппыт сирэйдэрбин уонна билэлэрбин кэтээн көрүү тиһигэр киллэрэн ис",
        "tog-watchmoves": "Аатын уларыппыт сирэйдэрбин уонна билэлэрбин кэтээн көрүү тиһигэр киллэрэн ис",
        "tog-watchdeletion": "Соппут сирэйдэрбин уонна билэлэрбин кэтээн көрүү тиһигэр киллэрэн ис",
+       "tog-watchuploads": "Хачайдаан киллэрбит билэлэрбин кэтииргэ",
        "tog-watchrollback": "Төннөрбүт сирэйдэрбин кэтэбилим тиһигэр киллэрэн ис",
        "tog-minordefault": "Уларытыылары атын этиллибэтэҕинэ кыра уларытыы курдук бэлиэтээ",
        "tog-previewontop": "Хайдах буоларын уларытар түннүк үрдүнэн (иннигэр) көрдөр",
        "newwindow": "(атын түннүккэ арыллар)",
        "cancel": "Салҕаама",
        "moredotdotdot": "Өссө...",
-       "morenotlisted": "Ð\91Ñ\83 Ñ\82иһик Ñ\82олоÑ\80Ñ\83Ñ\82а Ñ\81Ñ\83оÑ\85.",
+       "morenotlisted": "Ð\91Ñ\83 Ñ\82иһилик Ñ\82олоÑ\80Ñ\83Ñ\82а Ñ\81Ñ\83оÑ\85 Ð±Ñ\83олÑ\83он Ñ\81өп.",
        "mypage": "Сирэй",
        "mytalk": "Кэпсэтэр сирим",
        "anontalk": "Ырытыы",
        "tagline": "{{SITENAME}} диэн сиртэн ылыллыбыт",
        "help": "Көмө",
        "search": "Көрдөөһүн",
+       "search-ignored-headings": " #<!-- бу устуруоканы уларытыма --> <pre>\n# Көрдүүр тиһиктэр көрбөтөҕө буолуохтаах ааттара.\n# Уларыйыы көрдүүр тиһик (поисковик) сирэйи болҕомтоҕо ылбытын кэннэ олоххо киирэр.\n# Болҕомтоҕо ылыыны түргэтэтэр туһугар кураанах (ньуул) уларытыы оҥоруохха сөп.\n# Синтэксииһэ маннык көстөр:\n#   * Маннык бэлиэттэн саҕаланар устуруока «#» ырытыы быһыытынан ааҕыллар.\n#   * Кураанаҕа суох устуруока барыта — көрүллүбэт аат чопчу көрүҥэ, эрэгиистирин эҥин учуоттаан туран.\nБыһаарыылар\nСигэлэр\nЭбии көр\n #</pre> <!-- бу устуруоканы уларытыма -->",
        "searchbutton": "Бул",
        "go": "Бар",
        "searcharticle": "Көрдөр",
        "talk": "Ырытыы",
        "views": "Көрүү",
        "toolbox": "Сэп-сэбиргэл",
+       "tool-link-userrights": "{{GENDER:$1|Кыттааччы}} бөлөҕүн уларыт",
+       "tool-link-emailuser": "{{GENDER:$1|Кыттааччыга}} сурук суруйуу",
        "userpage": "Кыттааччы туһунан сирэй",
        "projectpage": "Бырайыак сирэйэ",
        "imagepage": "Билэ сирэйин көрүү",
        "versionrequiredtext": "Бу сирэйи туттарга MediaWiki $1 -с барыла наада. [[Special:Version|Барыллар тустарынан сирэйи]] көр.",
        "ok": "Сөп",
        "retrievedfrom": "Төрдө — «$1»",
-       "youhavenewmessages": "$1 ($2) кэллэ.",
+       "youhavenewmessages": "$1 ($2) {{PLURAL:$3|кэллэ}}.",
        "youhavenewmessagesfromusers": "Маны $1 {{PLURAL:$3|соҕотох кыттааччыттан|$3 кыттааччыттан}} туппуккун ($2).",
        "youhavenewmessagesmanyusers": "Маны $1 элбэх кыттааччыттан туппуккун ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|саҥа этии|999=саҥа этии}}",
        "createacct-yourpasswordagain-ph": "Киирии тылгын хатылаа",
        "userlogin-remembermypassword": "Тиһиликтэн тахсыма",
        "userlogin-signwithsecure": "Бигэ холбонуу",
+       "cannotlogin-title": "Киирэр сатаммат",
+       "cannotlogin-text": "Тиһиккэ киирэр табыллыбат.",
        "cannotloginnow-title": "Сип-билигин киирэр кыах суох",
        "cannotloginnow-text": "Маны $1 туһанар кэмҥэ киирэр кыах суох.",
+       "cannotcreateaccount-title": "Бэлиэтэнэр табыллыбат",
+       "cannotcreateaccount-text": "Быһа бэлиэтэнии бу биикигэ сатаммат эбит.",
        "yourdomainname": "Эн дөмүөнүҥ:",
        "password-change-forbidden": "Бу биикигэ киирии тылы уоарытар табыллыбат.",
        "externaldberror": "Тас киирии билиитин олоҕун сыыһата буолла, эбэтэр тас киирии билииҥ олоҕун саҥардар кыаҕыҥ суох.",
        "login": "Киир",
+       "login-security": "Ким буоларгын бигэргэт",
        "nav-login-createaccount": "Киир / бэлиэтэн",
        "userlogin": "Киир / бэлиэтэн",
        "userloginnocreate": "Киир",
        "searchprofile-advanced-tooltip": "Этиллибит аат далларыгар көрдөөһүн",
        "search-result-size": "$1 ({{PLURAL:$2|1 тыл|$2 тыл}})",
        "search-result-category-size": "{{PLURAL:$1|$1 элэмиэн|$1 элэмиэннэр}} ({{PLURAL:$2|$2 субкатегория|$2 субкатегориялар}}, {{PLURAL:$3|$3 билэ|$3 билэлэр}})",
-       "search-redirect": "(утаарыы $1)",
+       "search-redirect": "(мантан $1 утаарылынна)",
        "search-section": "($1 сиэксийэ)",
        "search-category": "(категория $1)",
        "search-file-match": "(билэ иһинээҕитин кытта сөп түбэһэр)",
        "activeusers-intro": "Бу кэлиҥҥи $1 {{PLURAL:$1|күҥҥэ|күннэргэ}} тугу эмэ гыммыт кыттааччылар тиһиктэрэ.",
        "activeusers-count": "Кэнники $3 күҥҥэ саҥа $1 көннөрүү киирбит",
        "activeusers-from": "Мантан саҕалаан кыттааччылары көрүү:",
-       "activeusers-hidebots": "Руобаттары көрдөрүмэ",
-       "activeusers-hidesysops": "Дьаһабыллары көрдөрүмэ",
        "activeusers-noresult": "Кыттааччылар көстүбэтилэр.",
        "activeusers-submit": "Көхтөөх кыттааччылары көрдөр",
        "listgrouprights": "Кыттааччылар бөлөхтөрүн бырааптара",
        "feedback-external-bug-report-button": "Тех. садаанньаны ыытыы",
        "feedback-dialog-title": "Санааҕын ыыт",
        "feedback-dialog-intro": "Санааҕын этэргэ аллара баар судургу форманы туһаныаххын сөп. Оччоҕо Эн аатыҥ уонна этииҥ «$1» сирэйгэ эбиллиэ.",
-       "feedback-error-title": "Алҕас",
        "feedback-error1": "Алҕас: API биллибэт түмүгэ",
        "feedback-error2": "Алҕас: Көннөрүү сатаммата",
        "feedback-error3": "Алҕас: API хоруйдаабата",
        "feedback-thanks": "Махтал! Эн санааҥ бу сирэйгэ \"[$2 $1]\" сурулунна.",
        "feedback-thanks-title": "Махтал!",
        "feedback-useragent": "Браузерым:",
-       "searchsuggest-search": "Көрдөөһүн",
+       "searchsuggest-search": "{{SITENAME}} иһигэр көрдөөһүн",
        "searchsuggest-containing": "тыл баар ыстатыйалара...",
        "api-error-badaccess-groups": "Эн бу биикигэ билэ киллэрэриҥ хааччахтаммыт.",
        "api-error-badtoken": "Ис алҕас: Омсолоох токен.",
index 7b57f55..f711abd 100644 (file)
        "yourpasswordagain": "Arhõ oku namber olme",
        "createacct-yourpasswordagain": "Uku nambar sãyãḱme",
        "createacct-yourpasswordagain-ph": "Uku nambar arhõ emme",
-       "remembermypassword": "Mitṭen khon bạṛti khata reaḱ cạbi disạ dohoḱma (Jạsti $1 {{PLURAL:$1 din reaḱ din reaḱ}} lạgit)",
        "userlogin-remembermypassword": "Bolo thirege dohokạńme",
        "yourdomainname": "Amaḱ ḍomen:",
        "externaldberror": "Hoe daṛeyaḱa jahan bahre reaḱ jacaeaḱ ḍaṭabes vul hoeakana se amaḱ bahre reaḱ ekaunṭ do nahaḱ halot aguire ạidạri bạnuḱa.",
        "passwordreset-emailtitle": "{{SITENAME}} sayeṭre beoharićaḱ purạo thutiko",
        "passwordreset-emailelement": "Beoharićaḱ ńutum: \n$1\n\nMit́ ghạṛi lạgit uku nambar: \n$2",
        "passwordreset-emailsentemail": "Mitṭen disạ ruaṛ e-mail do kulena.",
-       "passwordreset-emailsent-capture": "Mit́ṭen disạ ruaṛaḱ e-mail dokulena, oka do latarre ńeloḱ kana.",
-       "passwordreset-emailerror-capture": "Disạ ruạṛ oco lạgit́te mit́ṭen e-mail tear hoelena, oka do latarre udugoḱkana, menkhan $1 beoharić ṭhen  ṭhen baṅ kul hoe akana.",
        "changeemail": "E-mail ṭhikạna do bodolme",
        "changeemail-header": "Ekaunṭ e-mail ṭhikạna do bodolme",
        "changeemail-no-info": "Noa sakam sojhete laṛcaṛ lạgit́te am do bhitri boloḱ hoyoḱtama.",
        "post-expand-template-inclusion-category": "Sakamko oka borḍre noa tahẽna ona doe paromkeda",
        "post-expand-template-argument-warning": "'''Sontoroḱmẽ:''' Noa sakamre komse kom mitṭen forma joṛao menaḱa ạḍi lạṭute pasnao akana.\nOnate noa ạrgumenṭkodo bạgi giḍi hoena.",
        "post-expand-template-argument-category": "Bagi forma ạrgumenṭ sapdoho sakam",
-       "cantcreateaccounttitle": "Ekaunṭ do baṅ tearlena",
        "viewpagelogs": "Noa sakam reaḱ cạbi udukme",
        "nohistory": "Noa sakam re do jahan sompadon reaḱ jạṛ bạnuḱa.",
        "currentrev": "Mucạt nãwã aroe",
index 6dc082e..2bdc449 100644 (file)
        "yourpasswordagain": "Repite sa password:",
        "createacct-yourpasswordagain": "Cunfirma sa password",
        "createacct-yourpasswordagain-ph": "Inserta sa password torra",
-       "remembermypassword": "Ammenta sa password in custu navigadore (pro unu màssimu de $1 {{PLURAL:$1|die|dies}})",
        "userlogin-remembermypassword": "Mantènnemi cullegadu",
        "userlogin-signwithsecure": "Imprea una cunnessione segura",
        "yourdomainname": "Ispetzìfica su domìniu",
        "content-model-css": "CSS",
        "post-expand-template-inclusion-category": "Pàginas in is cale sa dimensione templates inclùdidos propassat su lìmite cunsentidu",
        "post-expand-template-argument-category": "Pàginas cuntenentes templates cun argumentos fartados",
-       "cantcreateaccounttitle": "Non si podet creare unu contu",
        "viewpagelogs": "Càstia is registros de custa pàgina",
        "nohistory": "Non b'est sa stòria de is acontzos pro custa pàgina.",
        "currentrev": "Revisione currente",
        "linksearch-line": "$1 est ligadu in sa pàgina $2",
        "listusers-submit": "Ammustra",
        "listusers-blocked": "(blocadu)",
-       "activeusers-hidebots": "Cua bots",
-       "activeusers-hidesysops": "Cua amministradores",
        "listgrouprights-group": "Grupu",
        "listgrouprights-rights": "Deretos",
        "listgrouprights-members": "(lista de is cumponentes)",
index 3f5890a..807dbfc 100644 (file)
        "tog-watchlisthidebots": "Ammuccia li canciamenti dî bot ntâ lista taliata",
        "tog-watchlisthideminor": "Ammuccia li canciamenti nichi ntâ lista taliata",
        "tog-watchlisthideliu": "Ammuccia li canciamenti di l'utilizzatura riggistrati ntâ lista taliata",
+       "tog-watchlistreloadautomatically": "Ricarica automaticamenti l'elencu di l'ussirvati spiciali ogni vota ca si cancia nu filtru (addumanna JavaScript)",
        "tog-watchlisthideanons": "Ammuccia li canciamenti di l'utilizzatura anònimi ntâ lista taliata",
        "tog-watchlisthidepatrolled": "Ammuccia li canciamenti virificati ntâ lista taliata",
+       "tog-watchlisthidecategorization": "Ammuccia la catigurizzazioni dî pàggini",
        "tog-ccmeonemails": "Mànnami na copia dî missaggi spiduti a l'àutri utenti",
        "tog-diffonly": "Nun ammustrari lu cuntinutu dî pàggini sutta dî cunfrunti tra virsioni",
        "tog-showhiddencats": "Ammustra li catigurìi ammucciati",
        "tog-norollbackdiff": "Nun ammustrari lu cunfruntu tra virsioni doppu aviri fattu nu canciu n'arreri",
        "tog-useeditwarning": "Avvèrtimi quannu mi nni vaiu di na pàggina cu canciamenti nun sarvati",
-       "tog-prefershttps": "Adòpira sempri na cunnissioni sicura quannu trasisti",
+       "tog-prefershttps": "Adòpirati sempri na cunnissioni sicura quannu trasiti",
        "underline-always": "Sempri",
        "underline-never": "Mai",
        "underline-default": "Mpustazzioni pridifinuta dâ peddi o dû browser",
        "october-date": "$1 di uttùviru",
        "november-date": "$1 di nuvèmmiru",
        "december-date": "$1 di dicèmmiru",
+       "period-am": "di matina",
        "pagecategories": "{{PLURAL:$1|Catigurìa|Catigurìi}}",
        "category_header": "Pàggini ntâ catigurìa \"$1\"",
        "subcategories": "Suttacatigurìi",
        "newwindow": "(grapi na finestra nova)",
        "cancel": "Annulla",
        "moredotdotdot": "Àutru...",
-       "morenotlisted": "Sta lista è ncumpreta",
+       "morenotlisted": "Sta lista putissi siri ncumpreta",
        "mypage": "Pàggina",
        "mytalk": "La mè pàggina di discussioni",
-       "anontalk": "Discussioni di stu nnirizzu IP",
+       "anontalk": "Discussioni",
        "navigation": "Navigazzioni",
        "and": "&#32;e",
        "qbfind": "Attrova",
        "yourpasswordagain": "Scrivi la password n'àutra vota",
        "createacct-yourpasswordagain": "Cunfirma la password",
        "createacct-yourpasswordagain-ph": "Nzirisci la password attorna",
-       "remembermypassword": "Arricorda la password supra stu computer (pi ô massimu $1 {{PLURAL:$1|jornu|jorna}})",
        "userlogin-remembermypassword": "Mantènimi culligatu",
        "userlogin-signwithsecure": "Adòpira na cunnissioni sicura",
        "yourdomainname": "Lu tò duminiu:",
        "passwordreset-emailtext-user": "L'utenti $1 supra a {{SITENAME}} fici n'addumannata pi l'azziramentu dâ tò password pi {{SITENAME}} ($4). {{PLURAL:$3|Lu cuntu utenti siguenti è assuciatu|Li cunti utenti siguenti sù assuciati}} cu stu nnirizzu di posta elittrònica:\n\n$2\n\n{{PLURAL:$3|Sta password timpurània|Sti password timpurànii}} scàdinu tra {{PLURAL:$5|un jornu|$5 jorna}}.\nOra tu avissi a tràsiri e scègghiri na password nova. Si fu quarchidun'àutru a fari st'addumannata e nun tu, o si t'arricurdasti la tò password origginali e nun la voi canciari cchiù, poi gnurari stu missaggiu e cuntinuari a adupirari la tò password vecchia.",
        "passwordreset-emailelement": "Nomu utenti: \n$1\n\nPassword timpurània: \n$2",
        "passwordreset-emailsentemail": "Nu missaggiu di posta elittrònica d'azziramentu dâ password fu mannatu.",
-       "passwordreset-emailsent-capture": "Nu missaggiu di posta elittrònica d'azziramentu dâ password fu mannatu, cû cuntinutu chi si pò taliari ccassutta.",
-       "passwordreset-emailerror-capture": "Nu missaggiu di posta elittrònica d'azziramentu dâ password fu cumpilatu, cû cuntinutu chi si pò taliari ccassutta, pirò la sò spidizzioni a l'utenti {{GENDER:$2|user}} nun arriniscìu: $1",
        "changeemail": "Canciu dû nnirizzu di posta elittrònica",
        "changeemail-header": "Jinchi stu mòdulu pi canciari lu tò nnirizzu di posta elittrònica. Hai a nziriri la tò password pi cunfirmari stu canciamentu.",
        "changeemail-no-info": "Hai a aviri trasutu p'aviri accessu direttu a sta pàggina.",
        "undo-nochange": "Pari chi lu canciamentu già fu annullatu.",
        "undo-summary": "Annullatu lu canciamentu $1 di [[Special:Contributions/$2|$2]] ([[User talk:$2|discussioni]])",
        "undo-summary-username-hidden": "Annullata la virsioni $1 fatta di n'utenti ammucciatu",
-       "cantcreateaccounttitle": "Mpussìbbili criari un cuntu",
        "cantcreateaccount-text": "La criazzioni di cunti a pàrtiri di stu nnirizzu IP (<strong>$1</strong>), fu bluccata di [[User:$3|$3]].\n\nLa spigazzioni data di $3 è <em>$2</em>",
        "cantcreateaccount-range-text": "La criazzioni di cunti a pàrtiri dî nnirizzi IP ntô ntervallu <strong>$1</strong>, chi cumprenni lu tò nnirizzu IP (<strong>$4</strong>), fu bluccata di [[User:$3|$3]].\n\nLa spigazzioni data di $3 è <em>$2</em>",
        "viewpagelogs": "Talìa li riggistri di sta pàggina",
        "activeusers-intro": "Chista è na lista di l'utenti chi fìciru na quarchi attività {{PLURAL:$1|nta l'ùrtimu jornu|nta l'ùrtimi $1 jorna}}.",
        "activeusers-count": "$1 {{PLURAL:$1|azzioni}} nta {{PLURAL:$3|l'ùrtimu jornu|l'ùrtimi $3 jorna}}",
        "activeusers-from": "Ammustra l'utenti a pàrtiri di:",
-       "activeusers-hidebots": "Ammuccia li bot",
-       "activeusers-hidesysops": "Ammuccia l'amministratura",
        "activeusers-noresult": "Nuddu utenti attruvatu.",
        "listgrouprights": "Dritti di gruppa d'utenti",
        "listgrouprights-summary": "Ccà sutta sunnu elincati li gruppa d'utenti difinuti nta sta wiki, cu li sò dritti d'accessu.\nCi ponnu èssiri [[{{MediaWiki:Listgrouprights-helppage}}|àutri nfurmazzioni]] a prupòsitu d'ognidunu drittu.",
        "htmlform-title-not-exists": "$1 nun esisti.",
        "htmlform-user-not-exists": "<strong>$1</strong> nun esisti.",
        "htmlform-user-not-valid": "<strong>$1</strong> nun è vàlidu comu nomu utenti.",
-       "sqlite-has-fts": "$1 cu capacità d'arricerca a tuttu testu",
-       "sqlite-no-fts": "$1 senza capacità d'arricerca a tuttu testu",
        "logentry-delete-delete": "$1 {{GENDER:$2|cancillau}} la pàggina $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|ripristinau}} la pàggina $3",
        "logentry-delete-event": "$1 {{GENDER:$2|canciau}} la visibbilità di {{PLURAL:$5|n'eventu dû riggistru|$5 eventi dû riggistru}} di $3: $4",
        "feedback-external-bug-report-button": "Signala nu prubblema tècnicu",
        "feedback-dialog-title": "Lassa nu cummentu",
        "feedback-dialog-intro": "Poi adupirari stu mòdulu facili ccassutta pi lassari lu tò cummentu. Stu cummentu è agghiunciutu â pàggina «$1», nzèmmula ô tò nomu utenti.",
-       "feedback-error-title": "Erruri",
        "feedback-error1": "Erruri: Risurtatu di l'API nun arricanusciutu",
        "feedback-error2": "Erruri: Lu canciamentu nun arriniscìu",
        "feedback-error3": "Erruri: Nudda arrispunnuta di l'API",
index 152a08a..a94b562 100644 (file)
        "yourpasswordagain": "Retype passwaird:",
        "createacct-yourpasswordagain": "Confirm passwaird.",
        "createacct-yourpasswordagain-ph": "Enter passwaird again.",
-       "remembermypassword": "Mynd ma login oan this brouser (fer $1 {{PLURAL:$1|day|days}} at the maist)",
        "userlogin-remembermypassword": "Keep me loggit in",
        "userlogin-signwithsecure": "Uise secure connection",
        "cannotloginnow-title": "Canna log in nou",
        "activeusers-intro": "This is ae leet o uisers that had some kynd o acteevitie wiin the last $1 {{PLURAL:$1|day|days}}.",
        "activeusers-count": "$1 {{PLURAL:$1|action|actions}} in the laist {{PLURAL:$3|day|$3 days}}",
        "activeusers-from": "Displey uisers stairtin at:",
-       "activeusers-hidebots": "Skauk bots",
-       "activeusers-hidesysops": "Skauk admeenistraters",
        "activeusers-noresult": "Naw uisers foond.",
        "listgrouprights": "Uiser groop richts",
        "listgrouprights-summary": "The follaein is ae leet o uiser groops defined oan this wiki, wi thair associatit access richts.\nThaur micht be [[{{MediaWiki:Listgrouprights-helppage}}|addeetional information]] aneat indiveedual richts.",
        "htmlform-cloner-create": "Eik mair",
        "htmlform-cloner-delete": "Remuiv",
        "htmlform-cloner-required": "At least the ae value is needit.",
-       "sqlite-has-fts": "$1 wi ful-tex rake support",
-       "sqlite-no-fts": "$1 wioot ful-tex rake support",
        "logentry-delete-delete": "$1 {{GENDER:$2|delytit}} page $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|restored}} page $3",
        "logentry-delete-event": "$1 {{GENDER:$2|chynged}} veesibeelitie o {{PLURAL:$5|ae log event|$5 log events}} oan $3: $4",
index 15d45cf..3787b3b 100644 (file)
        "tog-showtoolbar": "سنوار اوزار ڏيکاريو",
        "tog-editondblclick": "ٻٽي ڪلڪ تي صفحا سنواريو",
        "tog-watchcreations": "منهنجا سرجيل صفحا ۽ منهنجا چاڙهيل فائيل منهنجي زيرِ نظر فهرست تي رکو",
-       "tog-watchdefault": "منهنجا ترميميل صفحا ۽ فائيل  منهنجي زير نظر فهرست تي رکو",
-       "tog-watchmoves": "جيڪي صفحا ۽ فائيل آءُٗ چوريان، سي منهنجي زير نظر فهرست ۾ شامل ڪريو.",
-       "tog-watchdeletion": "آءُٗ جيڪي صفحا ۽ فائيل  ڊاهيان، سي منهنجي زير نظر فهرست تي رکو",
-       "tog-watchrollback": "انهن صفحن کي منهنجي زير نظر فهرست تي رکو، جن ۾ تبديلين کي مون واپس ورايو آهي.",
+       "tog-watchdefault": "منهنجا ترميميل صفحا ۽ فائيل  منهنجي نظرھيٺ فھرست ۾ رکو",
+       "tog-watchmoves": "جيڪي صفحا ۽ فائيل آءُٗ چوريان، سي منهنجي نظرھيٺ فھرست ۾ شامل ڪريو.",
+       "tog-watchdeletion": "آءُٗ جيڪي صفحا ۽ فائيل  ڊاهيان، سي منهنجي نظرھيٺ فھرست تي رکو",
+       "tog-watchuploads": "منهنجا نوان چاڙهيل فائيلس ٽيٽ فهرست ۾ شامل ڪريو",
+       "tog-watchrollback": "انهن صفحن کي منهنجي نظرھيٺ فھرست تي رکو، جن ۾ تبديلين کي مون واپس ورايو آهي.",
        "tog-minordefault": "سمورين تبديلين کي بنان چئي معمولي ترميم تصور ڪريو",
-       "tog-previewontop": "ترÙ\85Ù\8aÙ\85Ù\8a Ø¨Ø§ÚªØ³ مٿان پيش نگاهہ ڏيکاريو",
+       "tog-previewontop": "ترÙ\85Ù\8aÙ\85Ù\8a Ø¯Ù»Ù\8aØ¡Ù\8e مٿان پيش نگاهہ ڏيکاريو",
        "tog-previewonfirst": "پهرين ترميم تي پيش نگاهہ ڏيکاريو",
-       "tog-enotifwatchlistpages": "Ù\85Ù\88Ù\86Ú©Ù\8a Ø§Ù\8aÙ\85Ù\8aÙ\84 ÚªØ±Ù\8aÙ\88 Ø¬Ú\8fÙ\87Ù\86 Ù\85Ù\86Ù\87Ù\86جÙ\8a Ø²Ù\8aر Ù\86ظر Ù\81Ù\87رست ÚªØ§ ØµÙ\81Ø­Ù\88 Ù\8aا Ù\81ائÙ\8aÙ\84 ØªØ¨Ø¯Ù\8aÙ\84 ÚªÙ\8aÙ\88 Ù\88Ú\83Ù\8a",
+       "tog-enotifwatchlistpages": "Ù\85Ù\86Ù\87Ù\86جÙ\8a Ù½Ù\8aÙ½ Ù\81ھرست Ø§Ù\86در Ø´Ø§Ù\85Ù\84 ÚªÙ\86Ù\87Ù\86 ØµÙ\81Ø­Ù\8a Ù\8aا Ù\81ائÙ\8aÙ\84 Û¾ ØªØ¨Ø¯Ù\8aÙ\84 Ù¾Ù\8aØ´ Ø§Ú\86Ù\8a Ù\85Ù\88Ù\86 Ú©Ù\8a Ø¨Ø±Ù\82 Ù½Ù¾Ø§Ù\84 Ø§Ù\85اڻÙ\8aÙ\88",
        "tog-enotifusertalkpages": "منهنجي مباحثي صفحي ۾ تبديليءَ جي صورت ۾ مون کي برق ٽپال اماڻيو",
        "tog-enotifminoredits": "صفحن ۾ معمولي ترميمن جي صورت ۾ بہ مون کي برق ٽپال ڪريو",
        "tog-enotifrevealaddr": "پڌراين ۾ منهنجو برق ٽپال پتو ظاهر ڪريو.",
        "tog-shownumberswatching": "ڏسندڙ يوزرس جو انگ ڏيکاريو",
-       "tog-oldsig": "موجوده دستخط",
+       "tog-oldsig": "توھان جو موجوده دستخط:",
+       "tog-fancysig": "صحيح کي وڪيٽيڪسٽ سمجھو (ڪنھن خوڪار ڳنڍڻي کانسواءِ)",
        "tog-uselivepreview": "سڌي سنئين پيش نگاھہ استعمال ڪريو",
        "tog-watchlisthideown": "زير نظر فهرست مان منهنجون ڪيل ترميمون لڪايو",
        "tog-watchlisthidebots": "ٽيٽ فهرست تان بوٽ جون ترميمون لڪايو",
        "tog-watchlisthideminor": "ٽيٽ فهرست تان معمولي ترميمون لڪايو",
        "tog-watchlisthideliu": "لاگ اِن ٿيل يوزرس جون ڪيل ترميمون زيرنظر فهرست ۾ نہ ڏيکاريو",
        "tog-watchlisthideanons": "ٽيٽ فهرست تان اڻڄاتل يوزر جون ترميمون لڪايو",
+       "tog-watchlisthidepatrolled": "ٽيٽ فھرست مان گشت ڪيل ترميمون لڪايو",
        "tog-watchlisthidecategorization": "صفحن جا زمرا لڪايو",
        "tog-ccmeonemails": "ٻين يوزرس ڏانهن منهنجي موڪليل برق ٽپال جو پرت مون کي اماڻيو",
        "tog-diffonly": "تفاوت هيٺان صفحي جو مواد نہ ڏيکاريو",
        "tog-showhiddencats": "لڪل زمرا ڏيکاريو",
+       "tog-norollbackdiff": "واپس ورائڻ کان پوءِ تفاوت نہ ڏيکاريو",
        "tog-useeditwarning": "مونکي خبردار ڪريو جڏهن مان هڪ ترميم وارو صفحو بغير تبديلين سانڍڻ جي ڇڏيان",
-       "tog-prefershttps": "هميشه محفوظ ڪنيڪشن استعمال ڪريو جڏهن لاگ اِن ٿيل هجو",
+       "tog-prefershttps": "هميشہ محفوظ ڪنيڪشن استعمال ڪريو جڏهن داخل ٿيل هجو",
        "underline-always": "هميشہ",
        "underline-never": "ڪڏهن بہ نہ",
+       "underline-default": "پيش طَي چَم يا جھانگُو",
        "editfont-style": "ايراضي جو فونٽ اسٽائيل سنواريو:",
-       "editfont-serif": "سيرِف اِنڊو",
+       "editfont-default": "پيش طَي جھانگُو",
+       "editfont-monospace": "يڪ وٺيل اِنڊو",
+       "editfont-sansserif": "بي سريف اِنڊو",
+       "editfont-serif": "باسريف اِنڊو",
        "sunday": "آچر",
        "monday": "سومر",
        "tuesday": "اڱارو",
@@ -66,7 +74,7 @@
        "february": "فيبروري",
        "march": "مارچ",
        "april": "اپريل",
-       "may_long": "مَئي",
+       "may_long": "مَي",
        "june": "جُونِ",
        "july": "جُولاءِ",
        "august": "آگسٽ",
@@ -80,7 +88,7 @@
        "april-gen": "اپريل",
        "may-gen": "مَئي",
        "june-gen": "جُونِ",
-       "july-gen": "جÙ\8fÙ\88Ù\84اءÙ\90",
+       "july-gen": "جولاءِ",
        "august-gen": "آگسٽ",
        "september-gen": "سيپٽمبر",
        "october-gen": "آڪٽوبر",
@@ -90,7 +98,7 @@
        "feb": "فيبروري",
        "mar": "مارچ",
        "apr": "اپريل",
-       "may": "مَئي",
+       "may": "مَي",
        "jun": "جُونِ",
        "jul": "جُولاءِ",
        "aug": "آگسٽ",
        "august-date": "آگسٽ $1",
        "september-date": "سيپٽمبر $1",
        "october-date": "آڪٽوبر $1",
-       "november-date": "Ù\86Ù\8eÙ\88Ù\90مبر $1",
+       "november-date": "Ù\86Ù\88مبر $1",
        "december-date": "ڊسمبر $1",
        "period-am": "صبح جو",
        "period-pm": "منجھند کان بعد",
        "category-article-count-limited": "هيٺِون {{PLURAL:$1|صفحو آهي|$1 صفحا آهن}} تازي زمري ۾.",
        "category-file-count": "{{PLURAL:$2|هن زمري ۾ صرف هيٺيون فائيل آهي.|هيٺيون يا هيٺيان {{PLURAL:$1|فائيل آهي|$1 فائيل آهن}} هن زمري ۾، سمورن $2 مان.}}",
        "category-file-count-limited": "هيٺيون يا هيٺيان {{PLURAL:$1|فائيل آهي|$1 فائيل آهن}} هن تازي زمري ۾.",
-       "listingcontinuesabbrev": "جاري..",
+       "listingcontinuesabbrev": "جاري.",
        "index-category": "ڏسڻيل صفحا",
        "noindex-category": "غيرڏسڻيل صفحا",
        "broken-file-category": "فائيل جي ٽٽل ڳنڍڻن وارا صفحا",
        "newwindow": "(نئين دريءَ ۾ کلندو)",
        "cancel": "رد",
        "moredotdotdot": "اڃا...",
-       "morenotlisted": "فهرست مڪمل ڪانهي.",
+       "morenotlisted": "ھي فھرست نامڪمل بہ ٿي سگھي ٿي.",
        "mypage": "منهنجو صفحو",
-       "mytalk": "ڳالهہ ٻول",
-       "anontalk": "ڳالھ ٻولھ",
+       "mytalk": "بحث",
+       "anontalk": "بحث",
        "navigation": "رهنمائي",
        "and": "&#32؛۽",
        "qbfind": "ڳوليو",
        "qbpageoptions": "هيءُ صفحو",
        "qbmyoptions": "منهنجا صفحا",
        "faq": "ڪپس",
-       "faqpage": "Project:ڪپوس",
-       "actions": "فعل",
-       "namespaces": "نانءُ پولار:",
+       "faqpage": "Project:ڪپس",
+       "actions": "ڪارگذاريون",
+       "namespaces": "نانءُپولارَ",
        "variants": "بَدَلَ",
        "navigation-heading": "رهنما مينيو",
        "errorpagetitle": "چُڪَ",
        "search": "ڳولا",
        "searchbutton": "ڳوليو",
        "go": "کوليو",
-       "searcharticle": "کوليو",
+       "searcharticle": "وڃو",
        "history": "صفحي جي سوانح",
        "history_short": "سوانح",
        "printableversion": "ڇپائتو پرت",
        "permalink": "مسقتل ڳنڍڻو",
        "print": "ڇاپيو",
-       "view": "نگاهہ",
+       "view": "ڏسو",
        "view-foreign": "$1 تي ڏسو",
        "edit": "سنواريو",
        "edit-local": "مقامي تشريح کي ترميميو",
        "talk": "بحث",
        "views": "ڏيٺون",
        "toolbox": "اوزارَ",
+       "tool-link-userrights": "{{GENDER:$1|يوزر}} گروھ تبديل ڪريو",
+       "tool-link-emailuser": "ھن {{GENDER:$1|يوزر}} ڏانھن برقٽپال موڪليو",
        "userpage": "يوزر صفحو ڏسو",
        "projectpage": "رٿائي صفحو ڏسو",
        "imagepage": "ذريعاتي صفحو ڏسو",
        "otherlanguages": "ٻين ٻولين ۾",
        "redirectedfrom": "($1 کان چوريل)",
        "redirectpagesub": "چوريل صفحو",
-       "redirectto": "ڏانهن چوريو",
+       "redirectto": "ڏانھن چوريو:",
        "lastmodifiedat": "هيءُ صفحو آخري دفعو $2، $1ع تي سنواريو ويو هو.",
        "viewcount": "هيءُ صفحو {{PLURAL:$1|دفعو|$1 دفعا}} ڏسجي چڪو آهي.",
        "protectedpage": "تحفظيل صفحو",
-       "jumpto": "ڏانهن ٽپ ڏيو",
+       "jumpto": "ڏانھن ٽپ ڏيو:",
        "jumptonavigation": "رهنمائي",
        "jumptosearch": "ڳولا",
+       "view-pool-error": "معذرت سان سرور هاڻي تمام گھڻو سُڪ آهي.\nتمام گھڻا يوزر ھن صفحي کي ڏسڻ جي ڪوشش ڪري رھيا آھن.\nمهرباني ڪري ٿورو ترسو انکان اڳ جو توھان ھن صفحي تائين رسڻ لاءِ ٻيھر ڪوشش ڪريو.\n\n$1",
        "generic-pool-error": "معذرت سان سرور هاڻي تمام گھڻو سُڪ آهي.\nتمام گھڻا يوزر هتي موجود آهن.\nمهرباني ڪري ٿورو ترسي پوءِ ڪوشش ڪريو.",
        "pool-errorunknown": "اڻ ڄاتل چُڪَ",
        "poolcounter-usage-error": "استعمال جي خرابي: $1",
        "aboutsite": "{{SITENAME}} بابت",
        "aboutpage": "Project:بابت",
        "copyright": "ڪجھہ ٻيو ڄاڻايل نہ هجڻ جي صورت ۾ سمورو مواد $1 تحت ميسر ڪجي ٿو.",
-       "copyrightpage": "{{ns:project}}:Ø­Ù\82 Û½ Ù\88اسطا",
+       "copyrightpage": "{{ns:project}}:تاÙ\84Ù\8aÙ\81 Ø¬Ø§ Ø­Ù\82",
        "currentevents": "ھاڻوڪا واقعا",
-       "currentevents-url": "Project: اعداد",
+       "currentevents-url": "Project:ھاڻوڪا واقعا",
        "disclaimers": "غيرجوابداريناما",
        "disclaimerpage": "Project:عام غيرجوابدارينامو",
        "edithelp": "مدد براءِ ترميم",
        "helppage-top-gethelp": "مدد",
-       "mainpage": "مُک صفحو",
-       "mainpage-description": "مُک صفحو",
+       "mainpage": "مک صفحو",
+       "mainpage-description": "مک صفحو",
        "policy-url": "Project:پاليسي",
        "portal": "نياتي باب",
        "portal-url": "Project:نياتي باب",
        "retrievedfrom": "\"$1\" تان ورتل",
        "youhavenewmessages": "توهان لاءِ $1 ($2) آهن.",
        "youhavenewmessagesmanyusers": "توهان لاءِ ڪيترن ئي يُوزرس ($2) طرفان $1 آيل آهن.",
+       "newmessageslinkplural": "{{PLURAL:$1|ھڪ نئون پيغام|999=نوان پيغام}}",
+       "newmessagesdifflinkplural": "آخري {{PLURAL:$1|تبديلي|999=تبديليون}}",
        "youhavenewmessagesmulti": "$1 تي توهان لاءِ نوان نياپا آهن",
        "editsection": "سنواريو",
        "editold": "سنواريو",
        "editlink": "سنواريو",
        "viewsourcelink": "ڪوڊ ڏسو",
        "editsectionhint": "سنواريو سيڪشن: $1",
-       "toc": "فهرست",
+       "toc": "فھرست",
        "showtoc": "ڏيکاريو",
        "hidetoc": "لڪايو",
        "collapsible-collapse": "بند ڪريو",
        "site-atom-feed": "$1 اڻو روان رسد",
        "page-rss-feed": "\"$1\" RSS برق مواد",
        "page-atom-feed": "\"$1\" اڻو روان رسد",
-       "red-link-title": "$1 (صفحو وجود نہ ٿو رکي)",
+       "red-link-title": "$1 (صفحو وجود نٿو رکي)",
        "sort-descending": "لهندڙ ترتيب ڏيو",
        "sort-ascending": "چڙهندڙ ترتيب ڏيو",
        "nstab-main": "صفحو",
        "databaseerror-query": "استفسار: $1",
        "databaseerror-function": "ڪاڄ: $1",
        "databaseerror-error": "چُڪَ: $1",
+       "laggedslavemode": "<strong>چتاءُ:</strong> صفحي ۾ ھاڻوڪيون تبديليون نه ھجڻ جو امڪان آھي.",
        "readonly": "اعدادخانو بنديل",
        "missingarticle-rev": "(ڀيرو#: $1)",
        "missingarticle-diff": "(تفاوت: $1، $2)",
        "mypreferencesprotected": "توهان جي پنهنجون ترجيحات سنوارڻ جي اجات حاصل ڪانهي.",
        "ns-specialprotected": "خاص صفحا سنواري نٿا سگھجن.",
        "titleprotected": "[[User:$1|$1]] اهڙي عنوان سان صفحو سرجڻ تي روڪ لڳائي ڇڏي آهي. سبب <em>$2</em> ڄاڻايو ويو آهي.",
-       "exception-nologin": "لا اِن ٿيل ناهيو",
+       "exception-nologin": "داخل ٿيل نہ آهيو",
        "virus-unknownscanner": "اڻ ڄاتل نِس وائرس:",
-       "cannotlogoutnow-title": "ھاڻÙ\8a Ù\84اگ Ø¢Ø¦Ù\88Ù½ Ù\86Ù¿Ù\88 ڪري سگھجي",
-       "cannotlogoutnow-text": "$1 Ø§Ø³ØªØ¹Ù\85اÙ\84 ÚªØ±Ú» Ø¯Ù\88راÙ\86 Ù\84اگ Ø¢Ø¦Ù\88Ù½ ڪرڻ ممڪن نہ آھي.",
+       "cannotlogoutnow-title": "ھاڻÙ\8a Ù»Ø§Ú¾Ø± Ù\86Ù¿Ù\88 Ù\86ڪري سگھجي",
+       "cannotlogoutnow-text": "$1 Ø§Ø³ØªØ¹Ù\85اÙ\84 ÚªØ±Ú» Ø¯Ù\88راÙ\86 Ù»Ø§Ú¾Ø± Ù\86ڪرڻ ممڪن نہ آھي.",
        "welcomeuser": "ڀلي ڪري آيا، $1!",
        "yourname": "يُوزرنانءُ:",
        "userlogin-yourname": "يوزرنانءُ",
        "userlogin-yourname-ph": "پنهنجو يوزرنانءُ ڄاڻايو",
        "createacct-another-username-ph": "يُوزرنانءُ ڄاڻايو",
-       "yourpassword": "ڳجھو لفظ:",
-       "userlogin-yourpassword": "ڳجھو لفظ",
-       "userlogin-yourpassword-ph": "پنهنجو ڳجھو لفظ ڄاڻايو",
-       "createacct-yourpassword-ph": "ڳجھو لفظ ڄاڻايو",
+       "yourpassword": "ڳجھولفظ:",
+       "userlogin-yourpassword": "ڳجھولفظ",
+       "userlogin-yourpassword-ph": "پنهنجو ڳجھولفظ ڄاڻايو",
+       "createacct-yourpassword-ph": "ڳجھولفظ ڄاڻايو",
        "yourpasswordagain": "يُوزرنان ٻيهر ٽائيپ ڪريو:",
        "createacct-yourpasswordagain": "ڳجھي لفظ جي خاطري ڪريو",
-       "createacct-yourpasswordagain-ph": "ٻيهر ڳجھو لفظ داخل ڪريو",
-       "remembermypassword": "هن برائوزر تي منهنجي لاگ ان کي (وڌ ۾ وڌ $1 {{PLURAL:$1|ڏينهن}} لاءِ) ياد رکو",
-       "userlogin-remembermypassword": "مون کي لاگ اِن رکو",
+       "createacct-yourpasswordagain-ph": "ٻيھر ڳجھولفظ داخل ڪريو",
+       "userlogin-remembermypassword": "مون کي داخل ٿيل رکو",
        "userlogin-signwithsecure": "محفوظ ڳانڍاپو استعمال ڪريو",
-       "cannotloginnow-title": "ھاڻي لاگ ان نٿو ڪري سگھجي",
-       "cannotloginnow-text": "$1 استعمال ڪرڻ دوران لاگ ان ڪرڻ ممڪن نہ آھي.",
+       "cannotlogin-title": "داخل نٿو ٿي سگھجي",
+       "cannotlogin-text": "داخل ٿيڻ ممڪن نه آھي",
+       "cannotloginnow-title": "ھاڻي داخل نٿو ٿي سگھجي",
+       "cannotloginnow-text": "$1 استعمال ڪرڻ دوران داخل ٿيڻ ممڪن نہ آھي.",
+       "cannotcreateaccount-title": "کاتا کولي نہ ٿو سگھي",
        "yourdomainname": "توهان جو ميدان:",
-       "password-change-forbidden": "هن وڪِي تي توهان ڳجھو لفظ بدلائي نہ ٿا سگھو.",
-       "login": "لاگ اِن",
-       "nav-login-createaccount": "لاگ اِن ٿيو / کاتو کوليو",
-       "userlogin": "لاگ اِن ٿيو / کاتو کوليو",
-       "userloginnocreate": "لاگ اِن",
-       "logout": "لاگ آئوٽ",
-       "userlogout": "لاگ آئوٽ",
-       "notloggedin": "لاگ اِن ٿيل ناهيو",
+       "password-change-forbidden": "هن وڪِي تي توهان ڳجھالفظ بدلائي نٿا سگھو.",
+       "login": "داخل ٿيو",
+       "login-security": "پنھنجي سڃاڻپ جي خاطري ڪريو",
+       "nav-login-createaccount": "داخل ٿيو / کاتو کوليو",
+       "userlogin": "داخل ٿيو / کاتو کوليو",
+       "userloginnocreate": "داخل ٿيو",
+       "logout": "ٻاھر نڪرو",
+       "userlogout": "ٻاھر نڪرو",
+       "notloggedin": "داخل ٿيل نہ آهيو",
        "userlogin-noaccount": "کاتو نہ ٿا رکو؟",
        "userlogin-joinproject": "{{SITENAME}} ۾ شامل ٿيو",
        "nologin": " کاتو نہ ٿا رکو؟ '''$1'''.",
        "nologinlink": "نئون کاتو کوليو",
        "createaccount": "کاتو کوليو",
        "gotaccount": "ڇا اڳي ئي کاتو رکو ٿا؟ '''$1'''.",
-       "gotaccountlink": "لاگ اِن",
-       "userlogin-resetlink": "پنهنجي لاگ اِن جا تفصيل وساري ويٺا؟",
-       "userlogin-resetpassword-link": "ڳجھو لفظ وساري ويٺا آهيو؟",
-       "userlogin-helplink2": "لاگ اِن ٿيڻ ۾ مدد",
+       "gotaccountlink": "داخل ٿيو",
+       "userlogin-resetlink": "پنهنجي داخل ٿيڻ جا تفصيل وساري ويٺا؟",
+       "userlogin-resetpassword-link": "ڳجھولفظ وساري ويٺا آهيو؟",
+       "userlogin-helplink2": "داخل ٿيڻ ۾ مدد",
+       "userlogin-reauth": "اھو پڪ ڪرڻ لاءِ ته توھان {{GENDER:$1|$1}} آھيو توھان کي ٻيھر داخل ٿيڻو پوندو.",
        "userlogin-createanother": "ٻيو کاتو کوليو",
        "createacct-emailrequired": "برق ٽپال پتو",
        "createacct-emailoptional": "برق ٽپال پتو (مرضيءَ موجب)",
        "createacct-reason-ph": "توهان ٻيو کاتو ڇو کولي رهيا آهيو",
        "createacct-submit": "پنهنجو کاتو کوليو",
        "createacct-another-submit": "کاتو کوليو",
+       "createacct-continue-submit": "کاتو کولڻ جاري رکو",
+       "createacct-another-continue-submit": "کاتو کولڻ جاري رکو",
        "createacct-benefit-heading": "{{SITENAME}} توهان جهڙن سڄڻن ٺاهيو آهي.",
        "createacct-benefit-body1": "{{PLURAL:$1|ترميم|ترميمون}}",
        "createacct-benefit-body2": "{{PLURAL:$1|صفحو|صفحا}}",
-       "createacct-benefit-body3": "حاليه {{PLURAL:$1|ڀاڱيدار}}",
-       "badretype": "توهان جو ڄاڻايل ڳجھو لفظ درست نہ آهي.",
+       "createacct-benefit-body3": "ھاڻوڪا {{PLURAL:$1|ڀاڱيدار}}",
+       "badretype": "توهان جو ڄاڻايل ڳجھولفظ درست نہ آهي.",
        "usernameinprogress": "ان يُوزرنانءُ لاءِ کاتو اڳ ۾ ئي تياريءَ هيٺ آهي. مهرباني ڪري انتظار فرمايو.",
        "userexists": "ڄاڻايل يوزرنانءُ اڳ ۾ ئي استعمال هيٺ آهي. مهرباني ڪري ڪو ٻيو يُوزرنانءُ چونڊيو.",
-       "loginerror": "لاگ اِن چُڪَ",
+       "loginerror": "داخل ٿيڻ ۾ چُڪَ",
        "createacct-error": "کاٿو کولڻ ۾ چُڪَ",
        "createaccounterror": "کاتو کُلي نہ سگھيو: $1",
-       "nocookiesnew": "يُوزر کاتو کلي چڪو، پر توهان لاگ اِن نہ ٿيا آهيو. يُوزرس کي لاگ اِن ڪرڻ لاءِ {{SITENAME}} ڪوڪيز استعمال ڪندي آهي. توهان ڪوڪيز کي ناڪاره بڻائي رکيو آهي. لاگ اِن ٿيڻ لاءِ ڪوڪيز کي ڪارائتو بڻايو.",
+       "nocookiesnew": "يُوزر کاتو کلي چڪو، پر توهان داخل نہ ٿيا آهيو. يُوزرس کي داخل ڪرڻ لاءِ {{SITENAME}} ڪوڪيز استعمال ڪندي آهي. توهان ڪوڪيز کي ناڪاره بڻائي رکيو آهي. داخل ٿيڻ لاءِ ڪوڪيز کي ڪارائتو بڻايو.",
        "nocookieslogin": "يُوزرس کي لاگ اِن ڪرڻ لاءِ {{SITENAME}} ڪوڪيز استعمال ڪندي آهي. توهان ڪوڪيز کي ناڪاره بڻائي رکيو آهي. لاگ اِن ٿيڻ لاءِ ڪوڪيز کي ڪارائتو بڻايو.",
        "noname": "توهان جو ڄاڻايل يُوزرنانءُ ناقابل ڪار آهي.",
-       "loginsuccesstitle": "لاگ اِن ٿيل",
-       "loginsuccess": "'''هاڻي توهان {{SITENAME}} تي بطور \"$1\" لاگ اِن ٿيل آهيو.'''",
+       "loginsuccesstitle": "داخل ٿيل",
+       "loginsuccess": "'''هاڻي توهان {{SITENAME}} تي بطور \"$1\" داخل ٿيل آهيو.'''",
        "nosuchuser": "\"$1\" نالي سان ڪو بہ يوزر نہ آهي.\nننڍن وڏن اکرن ۾ امتياز ڪرڻ لازمي آهي. \nهِجي چڪاسيو، يا [[Special:CreateAccount|نئون کاتو تخليق ڪريو]]",
        "nosuchusershort": "\"$1\" نالي ڪو بہ يُوزر ناهي.\nهِجي جي پڪ ڪندا.",
        "nouserspecified": "توهان کي ڪو يوزرنانءُ ڄاڻائڻو پوندو.",
-       "login-userblocked": "هيءُ يُوزر بندشيل آهي. لاگ اِن جي اجازت نہ ٿي ڏجي.",
-       "wrongpassword": "ڏنل ڳجھو لفظ غير درست آهي. مهرباني ڪري ٻيهر ڪوشش ڪندا.",
-       "wrongpasswordempty": "ڏنل ڳجھو لفظ خالي هو. مهرباني ڪري وري ڪوشش ڪندا.",
-       "passwordtooshort": "ڳجھÙ\8a لفظ گھٽ ۾ گھٽ  {{PLURAL:$1|1 اکر|$1 اکرَن}} تي ٻڌل هوڻ گھرجي.",
-       "passwordtoolong": "ڳجھو لفظ {{PLURAL:$1|1 اکر|$1 اکرن}} کان وڏو نہ ٿو ٿي سگھي.",
-       "password-name-match": "توهان جو ڳجھو لفظ توهان جي يوزرنانءُ کان مختلف هجڻ گھرجي.",
-       "mailmypassword": "ڳجھو لفظ  نئين سِر مقرر ڪريو",
-       "passwordremindertitle": "{{SITENAME}} لاءِ نئون عارضي ڳجھو لفظ",
+       "login-userblocked": "هيءُ يُوزر بندشيل آهي. داخل ٿيڻ جي اجازت نٿي ڏجي.",
+       "wrongpassword": "ڏنل ڳجھولفظ غير درست آهي. مھرباني ڪري ٻيھر ڪوشش ڪندا.",
+       "wrongpasswordempty": "ڏنل ڳجھولفظ خالي هو.\nمهرباني ڪري وري ڪوشش ڪندا.",
+       "passwordtooshort": "ڳجھÙ\88لفظ گھٽ ۾ گھٽ  {{PLURAL:$1|1 اکر|$1 اکرَن}} تي ٻڌل هوڻ گھرجي.",
+       "passwordtoolong": "ڳجھولفظ {{PLURAL:$1|1 اکر|$1 اکرن}} کان وڏو نٿو ٿي سگھي.",
+       "password-name-match": "توهان جو ڳجھولفظ توهان جي يوزرنانءُ کان مختلف هجڻ گھرجي.",
+       "mailmypassword": "ڳجھولفظ ٻيھر مقرر ڪريو",
+       "passwordremindertitle": "{{SITENAME}} لاءِ نئون عارضي ڳجھولفظ",
        "passwordremindertext": "ڪنهن (شايد توهان آءِ پي پتي $1 تان) اسان کي {{SITENAME}} ($4) لاءِ نئون ڳجھو لفظ اماڻڻ جي گھُرَ ڪئي.\"$2\" يوزر لاءِ هڪ ڳجھُ لفظ تخليق ڪيو ويو آهي \"$3\" تي ترتيب ڏنو ويو هو. جيڪڏهن اهو توهان جي ارادو هيو، ته هاڻي توهان کي هينئر ئي لاگ اِن ٿي پنهنجو ڳجھو لفظ تبديل ڪرڻ گھرجي.\nتوهان جو عارضي ڳجھو لفظ {{PLURAL:$5|هڪ ڏينهُن|$5 ڏينهَن}} ۾ ختم ٿيندو.\n\nجيڪڏهن اها گھُرَ اوهان نه ڪئي هئي، يا هاڻي اوهان کي پنهنجو ڳجھو لفظ ياد اچي ويو آهي ۽ توهان ان کي تبديل ڪرڻ نه ٿا چاهيو، ته توهان هن نياپي کي نظر انداز ڪندي پنهنجو پراڻو ڳجھو لفظ ئي استعمال ڪري سگھو ٿا.",
        "noemail": "يُوزر \"$1\" جي ڪو بہ برق ٽپال پتو درج ٿيل ناهي.",
        "noemailcreate": "توهان کي قابل ڪار برق ٽپال پتو مهيا ڪرڻو پوندو.",
        "accountcreated": "کاتو کلي چڪو",
        "accountcreatedtext": "يوزر کاتو [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) جي لاءِ تخليق ٿي چڪو آهي.",
        "createaccount-title": "{{SITENAME}} تي کاتو کولڻ",
-       "login-throttled": "توهان تازو ئي لاگ اِن ٿيڻ جون هيڪانديون گھڻيون ڪوششون ڪيون آهن. مهرباني ڪري $1 لاءِ ترسي پوءِ وري ڪوشش ڪريو.",
-       "login-abort-generic": "توهان جو لاگ اِن ناڪام ويو.",
+       "login-throttled": "توهان تازو ئي داخل ٿيڻ جون هيڪانديون گھڻيون ڪوششون ڪيون آهن. مهرباني ڪري $1 لاءِ ترسي پوءِ وري ڪوشش ڪريو.",
+       "login-abort-generic": "توهان جو داخل ٿيڻ ناڪام ويو - بند ڪيل",
        "login-migrated-generic": "توهان جو کاتو لڏي چڪو آهي، ۽ هن وڪيءَ تي توهان جو يُوزنانءُ هاڻي وجود نہ ٿو رکي.",
        "loginlanguagelabel": "ٻولي: $1",
        "createacct-another-realname-tip": "اصل نالو ڄاڻائڻ اختياري آهي. جيڪڏهن توهان اصل نالو ڄاڻايو ٿا، تہ اهو توهان کي توهان جي ڪم جي مڃتا ڏيڻ لاءِ ڪم آندو ويندو.",
-       "pt-login": "لاگ ان ٿيو",
-       "pt-login-button": "لاگ اِن",
+       "pt-login": "داخل ٿيو",
+       "pt-login-button": "داخل ٿيو",
+       "pt-login-continue-button": "داخل ٿيڻ جاري رکو",
        "pt-createaccount": "کاتو کوليو",
-       "pt-userlogout": "Ù\84اگ Ø¢Ø¦Ù\88Ù½",
+       "pt-userlogout": "ٻاھر Ù\86ڪرÙ\88",
        "php-mail-error-unknown": "پي ايڇ پي جي  ڪاڄ اندر اڻڄاتل چُڪَ.",
        "user-mail-no-addy": "برق ٽپال پتو ڄاڻائڻ کان سواءِ برق ٽپال اماڻڻ جي ڪوشش ڪئي وئي.",
-       "changepassword": "ڳجھو لفظ تبديل ڪريو",
-       "resetpass_announce": "لاگ اِن جو عمل پورو ڪرڻ لاءِ، توهان کي نئون ڳجھو لفظ اختيار مقرر ڪرڻو پوندو.",
-       "resetpass_header": "کاتي جو ڳجھو لفظ بدلايو",
-       "oldpassword": "اڳوڻو ڳجھو لفظ:",
-       "newpassword": "نئون ڳجھو لفظ:",
-       "retypenew": "نئون ڳجھو لفظ ٻيهر ٽائيپ ڪندا:",
-       "resetpass_submit": "ڳجھو لفظ طَي ڪريو ۽ لاگ اِن ٿيو",
+       "changepassword": "ڳجھولفظ تبديل ڪريو",
+       "resetpass_announce": "داخل ٿيڻ جو عمل پورو ڪرڻ لاءِ، توهان کي نئون ڳجھولفظ اختيار مقرر ڪرڻو پوندو.",
+       "resetpass_header": "کاتي جو ڳجھولفظ بدلايو",
+       "oldpassword": "اڳوڻو ڳجھولفظ:",
+       "newpassword": "نئون ڳجھولفظ:",
+       "retypenew": "نئون ڳجھولفظ ٻيهر ٽائيپ ڪندا:",
+       "resetpass_submit": "ڳجھولفظ طَي ڪريو ۽ داخل ٿيو",
        "changepassword-success": "توهان جو ڳجھولفظ بدلايو ويو آھي!",
-       "changepassword-throttled": "توهان تازو ئي لاگ اِن ٿيڻ جون هيڪانديون گھڻيون ڪوششون ڪيون آهن. مهرباني ڪري $1 لاءِ ترسي پوءِ وري ڪوشش ڪريو.",
+       "changepassword-throttled": "توهان تازو ئي داخل ٿيڻ جون هيڪانديون گھڻيون ڪوششون ڪيون آهن. مهرباني ڪري $1 لاءِ ترسي پوءِ وري ڪوشش ڪريو.",
        "botpasswords-label-create": "سرجيو",
        "botpasswords-label-update": "تجديد",
        "botpasswords-label-cancel": "رد",
        "botpasswords-label-delete": "ڊاهيو",
-       "botpasswords-label-resetpassword": "ڳجھو لفظ  نئين سِر مقرر ڪريو",
-       "resetpass_forbidden": "ڳجھو لفظ بدلائي نہ ٿو سگھجي.",
-       "resetpass-no-info": "هيءُ صفحو پڙهڻ لاءِ لاگ اِن ٿيڻ ضروري آهي.",
-       "resetpass-submit-loggedin": "ڳجھو لفظ بدلايو",
+       "botpasswords-label-resetpassword": "ڳجھولفظ ٻيھر مقرر ڪريو",
+       "botpasswords-label-grants-column": "منظور",
+       "resetpass_forbidden": "ڳجھالفظ بدلائي نٿا سگھجن",
+       "resetpass_forbidden-reason": "ڳجھالفظ بدلائي نٿا سگھجن:$1",
+       "resetpass-no-info": "هيءُ صفحو پڙهڻ لاءِ داخل ٿيڻ ضروري آهي.",
+       "resetpass-submit-loggedin": "ڳجھولفظ بدلايو",
        "resetpass-submit-cancel": "رد",
        "resetpass-wrong-oldpass": "ناقابل ڪار هاڻوڪو يا عارضي ڳجھولفظ. \nتوهان پنهنجو ڳجھو لفظ اڳ ۾ ئي بدلائي چڪا آهيو يا نئين ڳجھي لفظ لاءِ درخواست ڏئي چڪا آهيو.",
        "resetpass-recycled": "مهرباني ڪري پنهنجي هاڻوڪي ڳجھي لفظ کان ڪو مختلف ڳجھو لفظ چونڊيو.",
        "resetpass-temp-emailed": "توهان برق ٽپال ذريعي اماڻيل عارضي ڳجھي لفظ سان لاگ اِن ٿيا آهيو. لاگ اِن کي مڪمل ڪرڻ لاءِ توهان کي هتي نئون ڳجھو لفظ طَي ڪرڻو ئي پوندو:",
-       "resetpass-temp-password": "عارضي ڳجھو لفظ:",
-       "resetpass-expired": "توهان جو ڳجھو لفظ مدي خارج ٿي چڪو آهي. نئون ڳجھو لفظ مقرر ڪريو ۽ لاگ اِن ٿيو.",
+       "resetpass-temp-password": "عارضي ڳجھولفظ:",
+       "resetpass-expired": "توهان جو ڳجھولفظ مدي خارج ٿي چڪو آهي. نئون ڳجھولفظ مقرر ڪريو ۽ داخل ٿيو.",
        "resetpass-expired-soft": "توهان جو ڳجھو لفظ مدي خارج ٿي چڪو آهي. مهرباني ڪري نئون ڳجھو لفظ چونڊيو، يا ساڳيو ڪم ڪنهن ٻي وقت ڪرڻ لاءِ \"{{int:authprovider-resetpass-skip-label}}\" تي ڪلڪ ڪريو.",
-       "resetpass-validity-soft": "توهان جو ڳجھو لفظ ناقابل ڪار آهي: $1\nمهرباني ڪري نئون ڳجھو لفظ چونڊيو، يا ساڳيو ڪم ڪنهن ٻي وقت ڪرڻ لاءِ \"{{int:authprovider-resetpass-skip-label}}\" تي ڪلڪ ڪريو.",
-       "passwordreset": "ڳجھو لفظ مَٽايو",
-       "passwordreset-text-one": "برق ٽپال ذريعي عارضي ڳجھو لفظ حاصل ڪرڻ لاءِ هيءُ فارم پُر ڪريو.",
-       "passwordreset-disabled": "هن وڪيءَ تي ڳجھو لفظ نئين سِر مقرر ڪرڻ وارو چارو غير فعال بڻايو ويو آهي.",
+       "resetpass-validity-soft": "توهان جو ڳجھولفظ ناقابل ڪار آهي: $1\nمهرباني ڪري نئون ڳجھولفظ چونڊيو، يا ساڳيو ڪم ڪنهن ٻي وقت ڪرڻ لاءِ \"{{int:authprovider-resetpass-skip-label}}\" تي ڪلڪ ڪريو.",
+       "passwordreset": "ڳجھولفظ مَٽايو",
+       "passwordreset-text-one": "برق ٽپال ذريعي عارضي ڳجھولفظ حاصل ڪرڻ لاءِ هيءُ فارم پُر ڪريو.",
+       "passwordreset-disabled": "هن وڪيءَ تي ڳجھولفظ ٻيھر مقرر ڪرڻ وارو چارو غير فعال بڻايو ويو آهي.",
        "passwordreset-emaildisabled": "هن وڪيءَ تي برق‌ٽپال واريون خصوصيتون غير فعال بڻايون ويون آهن.",
        "passwordreset-username": "يُوزرنانءُ:",
        "passwordreset-domain": "ميدان:",
        "passwordreset-email": "برق ٽپال پتو:",
        "passwordreset-emailtitle": "{{SITENAME}} واري کاتي جا تفصيل",
        "passwordreset-emailelement": "يُوزر نانءُ: \n$1\n\nعارضي ڳجھو لفظ:\n$2",
+       "passwordreset-invalidemail": "ناقابل ڪار برق ٽپال پتو",
        "changeemail": "برق ٽپال پتو مِٽايو يا بدلايو",
-       "changeemail-passwordrequired": "توهانکي هن تبديلي جي تصديق ڪرڻ جي لاءِ پنهنجو ڳجھو لفظ داخل ڪرڻ جي ضرورت پوندي.",
        "changeemail-oldemail": "هاڻوڪو برق ٽپال پتو:",
        "changeemail-newemail": "نئون برق ٽپال پتو:",
        "changeemail-none": "(ڪو بہ نہ)",
        "resettokens-tokens": "ٽوڪنس:",
        "resettokens-token-label": "$1 (حاليہ قدر: $2)",
        "resettokens-resetbutton": "چونڊيل ٽوڪن ٻيهر ترتيب ڪريو",
-       "bold_sample": "گهري تحرير",
-       "bold_tip": "گهري لکت",
+       "bold_sample": "گھري لکت",
+       "bold_tip": "گھري لکت",
        "italic_sample": "ترڇي لکت",
        "italic_tip": "ترڇي لکت",
        "link_sample": "ڳنڍڻي جو عنوان",
        "link_tip": "داخلي ڳنڍڻو",
        "extlink_sample": "http://www.example.com ڳنڍڻي جو عنوان",
        "extlink_tip": "خارجي ڳنڍڻو (اڳياڙي http://  نہ وساريندا)",
-       "headline_sample": "سرخي",
+       "headline_sample": "سرخي جي لکت",
        "headline_tip": "سطح 2 جي سرخي",
        "nowiki_tip": "وڪي فارميٽڱ کي نظرانداز ڪريو",
        "image_tip": "جَڙيل فائيل",
        "minoredit": "هيءَ هڪ معمولي ترميم آهي",
        "watchthis": "هيءُ صفحو سانڍيو",
        "savearticle": "صفحو سانڍيو",
-       "preview": "پيش نگاهہ",
-       "showpreview": "پيش نگاهہ",
+       "savechanges": "تبديليون سانڍيو",
+       "publishpage": "صفحو ڇاپيو",
+       "publishchanges": "تبديليون ڇاپيو",
+       "preview": "پيش نگاھ",
+       "showpreview": "پيش نگاھ",
        "showdiff": "تبديليون ڏيکاريو",
-       "anoneditwarning": "<strong>خبردار:</strong> توهان لاگ اِن ٿيل نہ آهيو. جيڪڏهن توهان ڪي ترميمون ڪيون تہ هن صفحي جي سوانح ۾ توهان جو آءِ پي پتو درج ڪيو ويندو. جي توهان <strong>[$1 لاگ اِن]</strong> ٿيو ٿا <strong>[$2 کاتو کوليو] </strong> ٿا، تہ توهان جو ترميمون توهان جي يوزرنانءُ سن منسوب ڪيون وينديون، جنهن جا ٻيا بہ فائدا ٿي سگھن ٿا.",
-       "anonpreviewwarning": "توهان لاگ اِن ٿيل نہ آهيو. جيڪڏهن توهان صفحي ۾ تبديليون سانڍيون تہ اهڙين تبديلين ساڻ توهان جو آءِ پي پتو درج ڪيو ويندو.",
+       "anoneditwarning": "<strong>خبردار:</strong> توهان داخل ٿيل نہ آهيو. جيڪڏهن توهان ڪي ترميمون ڪيون تہ هن صفحي جي سوانح ۾ توهان جو آءِ پي پتو درج ڪيو ويندو. جي توهان <strong>[$1 داخل]</strong> ٿيو ٿا < يا strong>[$2 کاتو کوليو] </strong> ٿا، تہ توهان جو ترميمون توهان جي يوزرنانءُ سان منسوب ڪيون وينديون، جنهن جا ٻيا بہ فائدا ٿي سگھن ٿا.",
+       "anonpreviewwarning": "توهان داخل ٿيل نہ آهيو. جيڪڏهن توهان صفحي ۾ تبديليون سانڍيون تہ اهڙين تبديلين ساڻ توهان جو آءِپي پتو درج ڪيو ويندو.",
        "missingcommenttext": "براءِ مهرباني هيٺ پنهنجا تاثرات درج ڪندا.",
-       "summary-preview": "تت تي پيش نگاهہ:",
-       "subject-preview": "موضوع پيش نگاهہ:",
+       "summary-preview": "تت تي پيش نگاھ:",
+       "subject-preview": "موضوع پيش نگاھ:",
        "blockedtitle": "يُوزر بندشيل آهي.",
        "blockedtext": "'''توهان جي يوزرنانءُ يا آءِ پي کي بندشيو ويو آهي.'''\n\nبندش $1 هنئي. جڏهن تہ ڄاڻايل سبب ''$2'' آهي.\n\n\n* بندش جو آغاز: $8\n* بندش جو انجام: $6\n* بندش جو هدف: $7\n\nاهڙي روڪ تي بحث ڪرڻ لاءِ توهان $1 يا ڪنهن ٻي [[{{MediaWiki:Grouppage-sysop}}|منتظم]] سان رابطو ڪري سگھو ٿا. جيڪڏهن توهان جو درست [[Special:ترجيحات|کاتو ترجيحات]] ۾ درست برق ٽپال پتو درج ٿيل نہ آهي تہ توهان 'هن يوزر کي برق ٽپال ڪريو' وارو فيچر نہ ٿا \nYou cannot use the 'e-mail this user' feature unless a valid e-mail address is specified in your [[Special:Preferences|account preferences]] and you have not been blocked from using it.\nاستعمال ڪري سگھو. توهان جو هاڻوڪو آءِ پي پتو $3 آهي، ۽ بندش سڃاڻپ $5 آهي. مهرباني ڪري ڪنهن بہ پڇا ڳاڇا يا لهوچڙ لاءِ انهن مان ڪنهن هڪ يا ٻنهي جو حوالو ڏيندا.",
        "blockednoreason": "سبب اڻڄاڻايل",
        "whitelistedittext": "صفحا سنوارڻ لاءِ مهرباني ڪري $1.",
        "confirmedittext": "صفحا سنوارڻ کان اڳ توهان کي پنهنجي ايميل پتي جي تصديق ڪرڻي پوندي. مهرباني ڪري [[Special:Preferences|use preferences]] ذريعي پنهنجو ايميل پتو ڄاڻايو ۽ تصديقيو.",
        "nosuchsectiontitle": "سيڪشن نٿو لهي سگهي",
-       "loginreqtitle": "لاگ اِن گھربل آهي",
-       "loginreqlink": "لاگ اِن",
+       "loginreqtitle": "داخل ٿيڻ گھربل آهي",
+       "loginreqlink": "داخل ٿيو",
        "loginreqpagetext": "ٻيا صفحا ڏسڻ لاءِ مهرباني ڪري $1",
-       "accmailtitle": "ڳجھو لفظ اماڻجي چڪو.",
+       "accmailtitle": "ڳجھولفظ اماڻجي چڪو",
        "newarticle": "(نئون)",
-       "newarticletext": "توهان اهڙي صفحي جو ڳنڍڻو وٺي هتي پهتا آهيو، جيڪو اڃا وجود نہ ٿو رکي. اهڙو صفحو جوڙڻ لاءِ هيٺين باڪس ۾ ٽائيپ ڪرڻ شروع ڪريو (وڌيڪ ڄاڻڻ لاءِ [$1 امدادي صفحو] ڏسندا). جي توهان هتي غلطيءَ ۾ اچي ويا آهيو تہ رڳو پنهنجي جهانگُوءَ جو '''back''' بٽڻ ڪلڪ ڪندا.",
+       "newarticletext": "توهان اهڙي صفحي جو ڳنڍڻو وٺي هتي پهتا آهيو، جيڪو اڃا وجود نٿو رکي.\nاهڙو صفحو جوڙڻ لاءِ، هيٺين باڪس ۾ ٽائيپ ڪرڻ شروع ڪريو (وڌيڪ ڄاڻڻ لاءِ [$1 امدادي صفحو] ڏسندا).\nجي توهان هتي غلطيءَ ۾ اچي ويا آهيو، تہ رڳو پنهنجي جهانگُوءَ جو <strong>back</strong> تي ٽڙڪ ڪريو.",
        "noarticletext": "في‌الوقت هن صفحي اندر ڪو بہ ٽيڪسٽ نہ آهي.\nتوهان ٻين صفحن ۾ [[Special:Search/{{PAGENAME}}|search ساڳي عنوان جي ڳولا]] ڪري سگھو ٿا،  \n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} لاڳاپيل لاگس ۾ ڳوليو]،\nor [{{fullurl:{{FULLPAGENAME}}|action=edit}} هيءُ صفحو ترميميو]</span>.",
        "userpage-userdoesnotexist-view": "يُوزر کاتو $1 درج ٿيل نہ آهي.",
        "blocked-notice-logextract": "هيءَ يُوزر في‌الحال بندشيل آهي. تازو بندش لاگ حوالي طور پيش ڪجي ٿو:",
        "updated": "(تجديديل)",
        "note": "<strong>نوٽ:</strong>",
-       "previewnote": "<strong>'''هيءَ محظ پيش نگاهہ آهي.</strong> ترميمون اڃا سانڍجوين ناهن!'''",
+       "previewnote": "<strong>هيءَ فقط پيش نگاھ آهي.</strong>\nتوھان جون ترميمون اڃان نہ سانڍيون ويون آھن!",
        "continue-editing": "ترميم گاھ ڏانهن وڃو",
-       "editing": "زير ترميم $1",
+       "editing": "$1 سنواريندي",
        "creating": "$1 سرجيندي",
        "editingsection": "زير ترميم $1 (سيڪشن)",
        "editingcomment": "ترميم هيٺ $1 (نئون سيڪشن)",
        "protectedpagewarning": "<strong>چتاءُ: هيءَ صفحو اهڙيءَ ريت تحفظيو ويو آهي جو فقط منتظمين ئي ان کي سنواري سگھن ٿا. </strong>\nتازه ترين لاگ حوالي طور پيش ڪجي ٿو:",
        "semiprotectedpagewarning": "<strong>نوٽ: هيءَ صفحو اهڙيءَ ريت تحفظيو ويو آهي جو فقط کاتيدار يُوزرس ئي ان کي سنواري سگھن ٿا. </strong>\nتازه ترين لاگ حوالي طور پيش ڪجي ٿو:",
        "templatesused": "هن صفحي تي استعمال ٿيندڙ {{PLURAL:$1|سانچو|سانچا}}:",
-       "templatesusedpreview": "هن پيش نگاهہ ۾ استعمال ٿيل {{PLURAL:$1|سانچو|سانچا}}:",
+       "templatesusedpreview": "هن پيش نگاھ ۾ استعمال ٿيل {{PLURAL:$1|سانچو|سانچا}}:",
        "templatesusedsection": "هن سيڪشن ۾ استعمال ٿيل {{PLURAL:$1|سانچو|سانچا}}:",
        "template-protected": "(تحفظيل)",
-       "template-semiprotected": "(نيم تحفظيل)",
+       "template-semiprotected": "(نيم-تحفظيل)",
        "hiddencategories": "هيءُ صفحو  {{PLURAL:$1|1 لڪل زمري|$1 لڪل زمرن}}: جو رڪن آهي:",
        "nocreatetext": "{{SITENAME}} نوان صفحا سرجڻ جي روڪَ ڪئي آهي.\nتوهان اڳي ئي موجود صفحن کي سنواري سگھو ٿا، يا [[Special:UserLogin|لاگ اِن ٿي يا نئون کاتو کولي سگھو ٿا]].",
        "nocreate-loggedin": "توهان کي نوان صفحا سرجڻ جي اجازت حاصل ڪانهي.",
        "content-json-empty-array": "خالي اري",
        "duplicate-args-warning": "چتاءُ: [[:$2]] کي [[:$1]] ڪال ڪري رهيو آهي، جنهن منجھہ ’$3‘ نيم‌پيما لاءِ هڪ کان وڌيڪ قدر ڄاڻايل آهن. فقط آخري ڄاڻايل قدر استعمال ڪيو ويندو.",
        "parser-template-loop-warning": "سانچو چڪر لڌو ويو: [[$1]]",
-       "cantcreateaccounttitle": "کاتو کولي نہ ٿو سگھجي",
        "cantcreateaccount-text": "هن آءِ پي پتي تان کاتي جي تخليق تي يُوز (<strong>$1</strong>)  [[User:$3|$3]] روڪ لڳائي آهي.\n\n$3 جو ڄاڻايل سبب آهي <em>$2</em> آهي.",
        "cantcreateaccount-range-text": "آءِپي پتن جي حد <strong>$1</strong> ۾ [[User:$3|$3]] کاتو کولڻ تي روڪ لڳائي وئي آهي،$4 جنهن ۾ توهان جو آءِپي پتو بہ (<strong>$4</strong>)،  پڻ شامل آهي. \n\n$3 ان روڪَ جو سبب \"$2\" ڄاڻايو آهي.",
        "viewpagelogs": "هن صفحي جا لاگس ڏسو",
        "history-show-deleted": "رڳو ڊاٺل",
        "histfirst": "اوائلي ترين",
        "histlast": "تازه ترين",
-       "historysize": "({{PLURAL:$1|1 ٻاٽڻ|$1 ٻاٽڻيون}})",
+       "historysize": "({{PLURAL:$1|1 بائيٽ|$1 بائيٽس}})",
        "historyempty": "(خالي)",
        "history-feed-title": "ترميمي سوانح",
        "history-feed-description": "وڪي جي هن صفحي جي ترميمي سوانح",
        "history-feed-item-nocomment": "$2 تي $1",
+       "rev-deleted-comment": "(ترميمي خلاصو ھٽايل)",
        "rev-deleted-user": "(يُوزرنانءُ ڊاٺو ويو)",
        "rev-deleted-event": "(لاگ تفصيل هٽايا ويا)",
        "rev-deleted-user-contribs": "[يُوزرنانءُ يا آءِ پِي پتو مِٽايو ويو - ڀاڱيدارين مان ترميمون لڪايون ويون]",
+       "rev-suppressed-no-diff": "توهان اهو تفاوت ڏسي نہ ٿا سگھو، ڇاڪاڻ تہ ڪا هڪ ترميم <strong> ڊهي چڪي </strong> آهي.",
        "rev-delundel": "نمائش تبديل ڪريو",
        "rev-showdeleted": "ڏيکاريو",
        "revisiondelete": "مسوادا ڊاهيو/اڻ‌ڊاهيو",
        "searchprofile-everything-tooltip": "سموري مواد ۾ ڳوليو",
        "searchprofile-advanced-tooltip": "مرضيءَ جي نانءُپولارن ۾ ڳوليو",
        "search-result-size": "$1 ({{PLURAL:$2|لفظُ|$2 لفظَ}})",
-       "search-redirect": "($1 کي چوريو)",
+       "search-redirect": "($1 کان چوريو)",
        "search-section": "(سيڪشن $1)",
        "search-category": "(ذمرو $1)",
-       "search-suggest": "ڇا توهان جو مطلب $1 آهي؟",
+       "search-suggest": "ڇا توهان جو مطلب ھيو: $1",
        "search-interwiki-caption": "برادر رٿائون",
        "search-interwiki-default": "$1 مان نتيجا",
        "search-interwiki-more": "(وڌيڪ)",
        "preferences": "ترجيحات",
        "mypreferences": "ترجيحات",
        "prefs-edits": "ترميمن جو تعداد:",
-       "prefsnologintext2": "پنهنجون ترجيحات بدلائڻ لاءِ لاگ اِن ٿيو.",
+       "prefsnologintext2": "پنهنجون ترجيحات بدلائڻ لاءِ داخل ٿيو.",
        "prefs-skin": "چَمَ",
        "skin-preview": "پيش نگاهہ",
        "datedefault": "بلا ترجيحا",
        "prefs-user-pages": "يُوزر صفحو",
        "prefs-personal": "يُوزر جو خدوخال",
        "prefs-rc": "تازيون تبديليون",
-       "prefs-watchlist": "Ù½Ù\8aÙ½ Ù\81Ù\87رست",
-       "prefs-editwatchlist": "Ù½Ù\8aÙ½ Ù\81Ù\87رست کي سنواريو",
-       "prefs-editwatchlist-label": "Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù½Ù\8aÙ½ Ù\81Ù\87رست ۾ درج ٿيل شين کي سنواريو:",
-       "prefs-editwatchlist-edit": "پنهنجي ٽيٽ فهرست ۾ موجود عنوان ڏسو ۽ مٽايو",
-       "prefs-editwatchlist-raw": "ÚªÚ\86Ù\8a Ù½Ù\8aÙ½ Ù\81Ù\87رست سنواريو",
-       "prefs-editwatchlist-clear": "Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù½Ù\8aÙ½ Ù\81Ù\87رست ڊاهيو",
-       "prefs-watchlist-days": "Ù½Ù\8aÙ½ Ù\81Ù\87رست Û¾ Ú\8fÙ\8aکارڻ Ù\84اءÙ\90 Ú\8fÙ\8aÙ\86Ù\87Ù\86 :",
+       "prefs-watchlist": "Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست",
+       "prefs-editwatchlist": "Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست کي سنواريو",
+       "prefs-editwatchlist-label": "Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست ۾ درج ٿيل شين کي سنواريو:",
+       "prefs-editwatchlist-edit": "پنھنجي نظرھيٺ فھرست ۾ موجود عنوان ڏسو ۽ مٽايو",
+       "prefs-editwatchlist-raw": "ÚªÚ\86Ù\8a Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست سنواريو",
+       "prefs-editwatchlist-clear": "Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست ڊاهيو",
+       "prefs-watchlist-days": "Ù\86ظرھÙ\8aÙº Ù\81ھرست Û¾ Ú\8fÙ\8aکارڻ Ù\84اءÙ\90 Ú\8fÙ\8aÙ\86Ù\87Ù\86:",
        "prefs-watchlist-days-max": "وڌ ۾ وڌ $1 {{PLURAL:$1|ڏينهن}}",
        "prefs-watchlist-edits-max": "وڌ ۾ وڌ تعداد: 1000",
-       "prefs-watchlist-token": "Ù½Ù\8aÙ½ Ù\84سٽ جو ٽوڪن:",
+       "prefs-watchlist-token": "Ù\86ظرھÙ\8aÙº Ù\81ھرست جو ٽوڪن:",
        "prefs-misc": "متفرق",
-       "prefs-resetpass": "ڳجھو لفظ بدلايو",
+       "prefs-resetpass": "ڳجھولفظ بدلايو",
        "prefs-changeemail": "برق ٽپال پتو مِٽايو يا بدلايو",
        "prefs-setemail": "ڪو برق ٽپال پتو ڄاڻايو",
        "prefs-email": "برق ٽپال چارا",
        "prefs-dateformat": "تاريخ جو طرز",
        "prefs-advancedediting": "عمومي چارا",
        "prefs-editor": "ايڊيٽر",
-       "prefs-preview": "پيش نگاهہ",
+       "prefs-preview": "پيش نگاھ",
        "prefs-advancedrc": "متقدم چارا",
        "prefs-advancedrendering": "متقدم چارا",
        "prefs-advancedsearchoptions": "متقدم چارا",
        "prefs-displaywatchlist": "نماڪار چارا",
        "prefs-tokenwatchlist": "ٽوڪن",
        "prefs-diffs": "تفاوت",
-       "prefs-help-prefershttps": "هيءَ ترجيح توهان جي ايندڙ لاگ اِن تي عمل ۾ ايندي.",
+       "prefs-help-prefershttps": "هيءَ ترجيح توهان جي ايند داخل ٿيڻ تي عمل ۾ ايندي.",
        "userrights": "يُوزر حقن جو بندوبست",
        "userrights-lookup-user": "يوزر گروپَ سنڀاليو",
        "userrights-user-editname": "يُوزرنانءُ ڄاڻايو:",
        "group-bureaucrat": "ڪامورا",
        "group-all": "(سڀ)",
        "group-user-member": "{{GENDER:$1|يُوزر}}",
+       "group-bot-member": "{{GENDER:$1|بوٽ}}",
        "group-sysop-member": "{{GENDER:$1|منتظم}}",
+       "group-bureaucrat-member": "{{GENDER:$1|ڪامورو}}",
+       "group-suppress-member": "{{GENDER:$1|دٻائيندڙ}}",
        "grouppage-user": "{{ns:project}}:يُوزرس",
+       "grouppage-autoconfirmed": "{{ns:project}}:خودڪارنموني پڪ ڪيل رڪن",
+       "grouppage-bot": "{{ns:project}}:بوٽس",
        "grouppage-sysop": "{{ns:project}}:منتظمين",
        "grouppage-bureaucrat": "{{ns:project}}:ڪامورا",
+       "grouppage-suppress": "{{ns:project}}:دٻايو",
        "right-read": "صفحا پڙهو",
        "right-edit": "صفحا سنواريو",
        "right-createpage": "صفحا سنواريو (جيڪي مباحثي صفحا نہ آهن)",
        "right-upload": "فائيل چاڙهيو",
        "right-reupload": "موجوده فائيلن مٿان",
        "right-upload_by_url": "ڪنهن يُوآرايل تان فائيل چاڙهيو",
-       "right-writeapi": "اي پر آءِ لکڻ جو استعمال",
+       "right-writeapi": "ايپيآءِ لکڻ جو استعمال",
        "right-delete": "صفحا ڊاهيو",
        "right-bigdelete": "ڊگھيون سوانح رکندڙ صفحا ڊاهيو",
        "right-browsearchive": "ڊاٺل صفحا ڳوليو",
        "right-undelete": "ڪو صفحو اڻڊاهيو",
        "right-unblockself": "ڪنهن تان بندش ختم ڪريو",
        "right-editinterface": "يُوزر باهمرُو کي سنواريو",
-       "right-viewmywatchlist": "Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù½Ù\8aÙ½ Ù\84سٽ ڏسو",
+       "right-viewmywatchlist": "Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù\86ظرھÙ\8aÙº Ù\81ھرست ڏسو",
        "right-editmyoptions": "پنهنجون ترجيحات سنواريو",
        "right-import": "ٻين وڪيز کان صفحا درآمديو",
        "right-importupload": "ڪو فائيل چاڙهي صفحا درآمديو",
        "right-override-export-depth": "5ئين اونهائيءَ تائين ڳنڍيل صفحن سميت صفحا برآمديو",
        "right-sendemail": "ٻين يوزرس ڏانهن ايميل موڪليو",
        "right-passwordreset": "ڳجھو لفظ مقرري برق ٽپالون ڏسو",
-       "right-managechangetags": "اعدادخاني ۾ [[Special:Tags|ٽيگس]] سرجيو ۽ ڊاهيو.",
+       "right-managechangetags": "[[Special:Tags|ٽيگس]] سرجيو ۽ ڊاهيو.",
        "grant-group-email": "برق ٽپال اماڻيو",
        "grant-blockusers": "يُوزرس کي بندشيو ۽ اڻبندشيو",
        "grant-createaccount": "نئون کاتو کوليو",
-       "grant-editmywatchlist": "پنهنجي ٽيٽ فهرست سنواريو",
+       "grant-editmywatchlist": "پنھنجي نظرھيٺ فھرست سنواريو",
        "grant-editprotected": "تحفظيل صفحا سنواريو",
        "grant-rollback": "صفحن ۾ ڪيل تبديليون واپس ورايو",
        "grant-sendemail": "ٻين يوزرس ڏانهن ايميل موڪليو",
        "grant-uploadfile": "نئون فائيل چاڙهيو",
        "grant-basic": "بنيادي حقَ",
        "grant-viewdeleted": "ڊَٺَلَ فائيلَ ۽ صفحا ڏسو",
-       "grant-viewmywatchlist": "Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù½Ù\8aÙ½ Ù\81Ù\87رست ڏسو",
+       "grant-viewmywatchlist": "Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست ڏسو",
        "newuserlogpage": "يوزر کاتن جو لاگ",
        "rightslog": "يُوزر حق لاگ",
        "action-read": "هي صفحو پڙهو",
        "action-rollback": "ڪنهن مخصوص صفحي تي آخري ترميم ڪندڙ يُوزر جي سمورين ترميمن کي ترت واپس ورايو",
        "action-import": "ٻي ڪنهن وڪي کان صفحا درآمد ڪريو",
        "action-importupload": "ڪو فائيل چاڙهي صفحا درآمديو",
-       "action-unwatchedpages": "اڻ ٽيٽيل صفحن جي فهرست ڏسو",
+       "action-unwatchedpages": "اڻ ڏٺل صفحن جي فھرست ڏسو",
        "action-mergehistory": "هن صفحي جي سوانح ضم ڪريو",
        "action-userrights": "سڀ يوزر حق ترميم ڪريو",
        "action-userrights-interwiki": "ٻين وڪيز جي يوزرس جا حق ترميم ڪريو",
        "action-siteadmin": "اعدادخاني کي بند ڪريو يا کوليو",
        "action-sendemail": "برق ٽپال اماڻيو",
-       "action-editmywatchlist": "پنهنجي ٽيٽ فهرست سنواريو",
-       "action-viewmywatchlist": "Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù½Ù\8aÙ½ Ù\81Ù\87رست ڏسو",
+       "action-editmywatchlist": "پنھنجي نظرھيٺ فھرست سنواريو",
+       "action-viewmywatchlist": "Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست ڏسو",
        "action-viewmyprivateinfo": "پنهنجي ذاتي معلومات ڏسو",
        "action-editmyprivateinfo": "پنهنجي ذاتي معلومات سنواريو",
        "nchanges": "$1 {{PLURAL:$1|تبديلي|تبديليون}}",
        "enhancedrc-history": "سوانح",
        "recentchanges": "تازيون تبديليون",
-       "recentchanges-legend": "تازين تبديلين جو آپشن",
+       "recentchanges-legend": "تازين تبديلين جا چارا",
        "recentchanges-summary": "هن صفحي تي وڪيءَ ۾ ڪيل تازيون ترين ترميمون ڏيکاريو.",
        "recentchanges-feed-description": "ۡهن روان رسد ۾ آيل تازيون تبديليون لهو",
-       "recentchanges-label-newpage": "هن ترميم سان نئون صفحو جڙيو.",
-       "recentchanges-label-minor": "هيءُ هڪ معمولي ترميم آهي.",
+       "recentchanges-label-newpage": "هن ترميم سان نئون صفحو جڙيو",
+       "recentchanges-label-minor": "هيء هڪ معمولي ترميم آهي",
        "recentchanges-label-bot": "هيءُ ترميم بوٽ عمل ۾ آندي.",
-       "recentchanges-label-plusminus": "هن صفحي جي ماپ ۾ هيترين ٻاٺڻين جو ڦير آيو آهي",
-       "recentchanges-legend-heading": "<strong>\"ڪنجي.</strong>",
+       "recentchanges-label-unpatrolled": "ھن ترميم جو اڃان گشت نہ ڪيو ويو آھي",
+       "recentchanges-label-plusminus": "هن صفحي جي ماپ ۾ هيترين بائيٽس جو ڦير آيو آهي",
+       "recentchanges-legend-heading": "<strong>ڪنجي:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (پڻ ڏسو [[Special:NewPages|نون صفحن جي فهرست]])",
        "recentchanges-submit": "ڏيکاريو",
        "rcnotefrom": "هيٺ {{PLURAL:$5|تبديلي آهي|تبديليون آهن}} کان <strong>$3, $4</strong> (تائين <strong>$1</strong> ) ڏيکاريل آهن.",
-       "rclistfrom": "$3 $2 کان شروع ٿيندڙ نيون تبديليون",
+       "rclistfrom": "$2، $3 کان شروع ٿيندڙ نيون تبديليون ڏيکاريو",
        "rcshowhideminor": "$1 معمولي ترميمون",
-       "rcshowhideminor-show": "نمايو",
+       "rcshowhideminor-show": "ڏيکاريو",
        "rcshowhideminor-hide": "لڪايو",
        "rcshowhidebots": "$1 بوٽس",
-       "rcshowhidebots-show": "نمايو",
+       "rcshowhidebots-show": "ڏيکاريو",
        "rcshowhidebots-hide": "لڪايو",
        "rcshowhideliu": "$1 کاتيدار يوزرس",
        "rcshowhideliu-show": "ڏيکاريو",
        "rcshowhideliu-hide": "لڪايو",
        "rcshowhideanons": "$1 نامعلوم يُوزرس",
-       "rcshowhideanons-show": "نمايو",
+       "rcshowhideanons-show": "ڏيکاريو",
        "rcshowhideanons-hide": "لڪايو",
        "rcshowhidepatr": "$1 تاڻيل ترميمون",
        "rcshowhidepatr-show": "ڏيکاريو",
        "rcshowhidepatr-hide": "لڪايو",
-       "rcshowhidemine": "منهنجون ترميمون $1",
-       "rcshowhidemine-show": "نمايو",
+       "rcshowhidemine": "منھنجون ترميمون $1",
+       "rcshowhidemine-show": "ڏيکاريو",
        "rcshowhidemine-hide": "لڪايو",
        "rcshowhidecategorization": "$1 صفحاتي زمراڪاري",
        "rcshowhidecategorization-show": "ڏيکاريو",
        "recentchangeslinked-feed": "لاڳاپيل تبديليون",
        "recentchangeslinked-toolbox": "لاڳاپيل تبديليون",
        "recentchangeslinked-title": "\"$1\" سان لاڳاپيل تبديليون",
-       "recentchangeslinked-page": "صفحي جو عنوان",
+       "recentchangeslinked-page": "صفحي جو نالو:",
        "recentchangeslinked-to": "رڳو ڄاڻايل صفحي سان ڳانڍيل صفحن ۾ ٿيل تبديليون نمايو",
        "upload": "فائيل چاڙهيو",
        "uploadbtn": "فائيل چاڙهيو",
-       "uploadnologin": "لاگ اِن ٿيل نہ آهيو",
+       "uploadnologin": "داخل ٿيل ناھيو",
        "uploadnologintext": "فائيل چاڙهڻ لاءِ $1.",
-       "uploaderror": "چاڙهہ چُڪَ",
-       "uploadlogpage": "چاڙهہ لاگ",
+       "uploaderror": "چاڙھ چُڪَ",
+       "uploadlogpage": "چاڙھ لاگ",
        "filename": "فائيل نانءُ",
        "filedesc": "خلاصو",
        "fileuploadsummary": "خلاصو:",
        "upload-http-error": "ايڇ ٽي ٽي پي جي چُڪَ ٿي آهي: $1",
        "upload-dialog-title": "فائيل چاڙهيو",
        "upload-dialog-button-cancel": "رد",
+       "upload-dialog-button-back": "واپس",
        "upload-dialog-button-done": "ٿي ويو",
        "upload-dialog-button-save": "سانڍيو",
        "upload-dialog-button-upload": "چاڙهيو",
        "filedelete-maintenance-title": "فائيل ڊهي نہ سگھيو",
        "mimesearch": "مائيم ڳولا",
        "download": "اتاريو",
-       "unwatchedpages": "اڻ ٽيٽيل صفحا",
+       "unwatchedpages": "اڻ ڏٺل صفحا",
        "listredirects": "چورڻن جي فهرست",
        "unusedtemplates": "اڻ استعماليل سانچا",
        "unusedtemplateswlh": "ٻيا ڳنڍڻا",
        "withoutinterwiki": "ڪنهن بہ ٻي ٻوليءَ سان نہ ڳنڍيل صفحا",
        "withoutinterwiki-summary": "هيٺيان صفحا ڪنهن بہ ٻي ٻوليءَ ۾ ساڳي صفحي سان ڳنڍيل نہ آهن.",
        "withoutinterwiki-legend": "اڳياڙي",
-       "withoutinterwiki-submit": "نمايو",
+       "withoutinterwiki-submit": "ڏيکاريو",
        "fewestrevisions": "گھٽانگھٽ ترميميل صفحا",
-       "nbytes": "$1 {{PLURAL:$1|ٻاٽڻ|ٻاٽڻيون}}",
+       "nbytes": "$1 {{PLURAL:$1|بائيٽ|بائيٽس}}",
        "ncategories": "$1 {{PLURAL:$1|زمرو|زمرا}}",
        "ninterwikis": "$1 {{PLURAL:$1|بين‌الوڪي}}",
        "nlinks": "$1 {{PLURAL:$1|ڳنڍڻو|ڳنڍڻا}}",
        "apisandbox-dynamic-parameters-add-label": "نيمپيما شامل ڪريو",
        "apisandbox-dynamic-parameters-add-placeholder": "نيمپيما نانءُ",
        "apisandbox-results": "نتيجا",
+       "apisandbox-continue": "جاري رکو",
        "booksources": "ڪتابي وسيلا",
        "booksources-search-legend": "ڪتابي ذريعن جي ڳولا ڪريو",
        "booksources-search": "ڳوليو",
        "prevpage": "پويون صفحو ($1)",
        "allpagesfrom": "ھتان شروع ٿيندڙ صفحا نمايو",
        "allpagesto": "ان تي ختم ٿيندڙ صفحا نُمايو:",
-       "allarticles": "سمورا مضمون",
+       "allarticles": "سڀ صفحا",
        "allinnamespace": "سمورا صفحا ($1 نانءُپولار)",
        "allpagessubmit": "ھلو",
        "allpagesprefix": "صفحا نمايو بمع اڳياڙي:",
        "sp-deletedcontributions-contribs": "ڀاڱيداريون",
        "linksearch-ns": "نانءُپولار",
        "linksearch-ok": "ڳوليو",
-       "listusers-submit": "نمايو",
+       "listusers-submit": "ڏيکاريو",
        "listusers-noresult": "ڪو بہ يُوزر نہ لڌو",
        "listusers-blocked": "(بندشيل)",
        "activeusers": "سرگرم يُوزرس جي فهرست",
-       "activeusers-hidebots": "بوٽس لڪايو",
-       "activeusers-hidesysops": "منتظمن کي لڪايو",
        "activeusers-noresult": "ڪي بہ يُوزرس نہ لڌا.",
        "activeusers-submit": "سرگرم يُوزرس ڏيکاريو",
        "listgrouprights": "يوزر گروپ جا حق",
        "trackingcategories-nodesc": "ڪا به تشريح موجود نه آهي.",
        "trackingcategories-disabled": "زمرو ناقابلِ ڪار بڻايل آهي.",
        "emailuser": "هن يوزر کي برق ٽپال اماڻيو",
+       "emailuser-title-target": "ھن {{GENDER:$1|يوزر}} ڏانھن برقٽپال موڪليو",
        "emailuser-title-notarget": "يُوزر ڏانهن برق ٽپال اماڻيو",
        "usermaildisabled": "يوزر ايميل ناقابلِ ڪار بڻيل",
        "usermaildisabledtext": "توهان هن وڪي تي ٻين يوزرس ڏانهن ايميل نٿا موڪلي سگھو",
        "emailccme": "نياپي جو پرت مون کي برق ٽپال ڪريو.",
        "emailsent": "برق ٽپال اماڻجي چڪي",
        "emailsenttext": "توهان جو برق ٽپال نياپو اماڻجي چڪو آهي.",
-       "watchlist": "Ù½Ù\8aÙ½ Ù\81Ù\87رست",
-       "mywatchlist": "Ù½Ù\8aÙ½ Ù\81Ù\87رست",
-       "addwatch": "Ù½Ù\8aÙ½ Ù\81Ù\87رست ۾ شامل ڪريو",
-       "addedwatchtext": "صÙ\81Ø­Ù\88\"[[:$1]]\" Ø§Ù\86 Ø¬Ù\8a Ø¨Ø­Ø« Ù\88ارÙ\88 ØµÙ\81Ø­Ù\88 Ø§Ù\88Ù\87اÙ\86 Ø¬Ù\8a [[Special:Watchlist|Ù½Ù\8aÙ½ Ù\81Ù\87رست]] ۾ شامل ڪيو ويو آهي.",
-       "removewatch": "Ù½Ù\8aÙ½ Ù\81Ù\87رست Ù\85اÙ\86 Ø®Ø§Ø±Ø¬ ÚªØ±يو",
-       "removedwatchtext": "صÙ\81Ø­Ù\88 Ø¨Ø¹Ù\86Ù\88اÙ\86 \"[[:$1]]\" ØªÙ\88Ù\87اÙ\86 Ø¬Ù\8a [[Special:Watchlist|Ù½Ù\8aÙ½ Ù\81Ù\87رست]] مان هٽي چڪو آهي.",
-       "removedwatchtext-short": "\"صÙ\81Ø­Ù\88 Ø¨Ø¹Ù\86Ù\88اÙ\86 \"$1\" ØªÙ\88Ù\87اÙ\86 Ø¬Ù\8a Ù½Ù\8aÙ½ Ù\81Ù\87رست مان هٽي چڪو آهي.\"",
-       "watch": "Ù½Ù\8aÙ½Ù\8aو",
-       "watchthispage": "Ù\87Ù\8aØ¡Ù\8f ØµÙ\81Ø­Ù\88 Ù½Ù\8aÙ½Ù\8aو",
-       "unwatch": "اڻ ٽيٽيو",
-       "unwatchthispage": "Ù½Ù\8aÙ½ڻ ڇڏيو",
+       "watchlist": "Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست",
+       "mywatchlist": "Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست",
+       "addwatch": "Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست ۾ شامل ڪريو",
+       "addedwatchtext": "صÙ\81Ø­Ù\88\"[[:$1]]\" Ø§Ù\86 Ø¬Ù\8a Ø¨Ø­Ø« Ù\88ارÙ\88 ØµÙ\81Ø­Ù\88 Ø§Ù\88Ù\87اÙ\86 Ø¬Ù\8a [[Special:Watchlist|Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست]] ۾ شامل ڪيو ويو آهي.",
+       "removewatch": "Ù\86ظرھÙ\8aÙº Ù\81ھرست Ù\85اÙ\86 Ú¾Ù½Ø§يو",
+       "removedwatchtext": "صÙ\81Ø­Ù\88 Ø¨Ø¹Ù\86Ù\88اÙ\86 \"[[:$1]]\" ØªÙ\88Ù\87اÙ\86 Ø¬Ù\8a [[Special:Watchlist|Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست]] مان هٽي چڪو آهي.",
+       "removedwatchtext-short": "\"صÙ\81Ø­Ù\88 Ø¨Ø¹Ù\86Ù\88اÙ\86 \"$1\" ØªÙ\88Ù\87اÙ\86 Ø¬Ù\8a Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست مان هٽي چڪو آهي.\"",
+       "watch": "Ù\86ظرھÙ\8aÙº Ø±Ú©و",
+       "watchthispage": "Ù\87Ù\8aØ¡Ù\8f ØµÙ\81Ø­Ù\88 Ù\86ظرھÙ\8aÙº Ø±Ú©و",
+       "unwatch": "نظرھيٺ نہ رکو",
+       "unwatchthispage": "Ù\86ظرھÙ\8aÙº Ø±Ú©ڻ ڇڏيو",
        "notanarticle": "غير موادي صفحو",
        "watchlist-details": "{{PLURAL:$1|$1 صفحو|$1 صفحا}} توهان جي ٽيٽ فهرست، ڳالھ ٻولھ جا صفحا الڳ شمار نٿا ٿين.",
        "wlshowlast": "گذريل $1 ڪلاڪ $2 ڏينهن ڏيکاريو",
        "wlshowhideliu": "کاتيدار يُوزرس",
        "wlshowhideanons": "گمنام يُوزرس",
        "wlshowhidemine": "منهنجون ترميمون",
-       "watchlist-options": "زيرِ نظر فهرست جا چارا",
-       "watching": "Ù½Ù\8aÙ½Ù\8aندي...",
-       "unwatching": "اڻ ٽيٽيندي...",
+       "watchlist-options": "نظرھيٺ فھرست جا چارا",
+       "watching": "Ù\86ظرھÙ\8aÙº Ø±Ú©ندي...",
+       "unwatching": "نظرھيٺان ڪڍندي...",
        "enotif_reset": "سڀ گھميل صفحن تي نشان لڳايو",
        "enotif_impersonal_salutation": "{{SITENAME}} يُوزر",
        "enotif_lastdiff": "هي تبديلي ڏسڻ لاءِ $1 ڏسو",
        "protect-expiry-options": "1 ڪلاڪ:1 hour,1 ڏينهن:1 day,1 هفتو:1 week,2 هفتو:2 weeks,1 مهينا:1 month,3 مهينا:3 months,6 مهينا:6 months,1 سال:1 year,اڻ کٽ:infinite",
        "restriction-type": "اجازتنامو:",
        "restriction-level": "روڪ سطح:",
-       "pagesize": "(ٻاٽڻيون)",
+       "pagesize": "(بائيٽس)",
        "restriction-edit": "سنواريو",
        "restriction-move": "چوريو",
        "restriction-create": "سرجيو",
        "contribsub2": "{{GENDER:$3|$1}} ($2) لاءِ",
        "contributions-userdoesnotexist": "يُوزر کاتو \"$1\" درج ٿيل نہ آهي.",
        "uctop": "(هاڻوڪو)",
-       "month": "Ù\85Ù\87Ù\8aÙ\86Ù\88 (۽ اڳوڻيون):",
-       "year": "سال (۽ اڳوڻيون):",
+       "month": "Ù\85Ù\87Ù\8aÙ\86Ù\8a Ú©Ø§Ù\86 (۽ اڳوڻيون):",
+       "year": "سال کان (۽ اڳوڻيون):",
        "sp-contributions-newbies": "صرف نون کاتن جون ڀاڱيداريون ڏيکاريو",
        "sp-contributions-newbies-sub": "نون کاتن لاءِ",
        "sp-contributions-newbies-title": "نون کاتن جي لاءِ يوزر جون ڀاڱيداريون",
-       "sp-contributions-blocklog": "بÙ\86سش لاگ",
-       "sp-contributions-deleted": "يُوزر جون ڊاٺل ڀاڱيداريون",
+       "sp-contributions-blocklog": "بÙ\86دش لاگ",
+       "sp-contributions-deleted": "ڊاٿل {{GENDER:$1|يوزر}} ڀاڱيداريون",
        "sp-contributions-uploads": "چاڙھَ",
        "sp-contributions-logs": "لاگس",
-       "sp-contributions-talk": "ڳالھہ",
+       "sp-contributions-talk": "ڳالھ",
        "sp-contributions-userrights": "يُوزر حقن جي سنڀال",
        "sp-contributions-search": "ڀاڱيدارين لاءِ ڳولا ڪريو",
        "sp-contributions-username": "آءِپي پتو يا يوزرنانءُ:",
        "whatlinkshere": "هتان ڇا ڳنڍيل آهي",
        "whatlinkshere-title": "$1 سان ڳنڍيل صفحا",
        "whatlinkshere-page": "صفحو:",
-       "linkshere": "هيٺيان صفحا '''[[:$1]]''' سان ڳنڍيل آهن:",
+       "linkshere": "هيٺيان صفحا <strong>[[:$1]]</strong> سان ڳنڍيل آهن:",
        "nolinkshere": "'''[[:$1]]''' سان ڪو بہ صفحو ڳنڍيل ناهي.",
        "isredirect": "چورڻو صفحو",
        "istemplate": "شموليت",
        "unlockbtn": "اعدادخاني کي کوليو",
        "move-page": "$1 چوريو",
        "move-page-legend": "صفحو چوريو",
-       "movepagetext": "هيٺيون فارم استعمال ڪندي ڪنهن صفحي کي نئون عنوان ڏئي سگھجي ٿو، جنهن سان سمورو صفحو نئين عنوان ڏانهن هليو ويندو. \nاڳوڻو عنوان نئين عنوان ڏانهن چورڻو بنجي ويندو. \nتوهان  چورڻن کي سنواري سگھو ٿا جيڪي اصل عنوان ڏانهن خودبخود اشارو ڪن ٿا.\nIf you choose not to, be sure to check for [[Special:DoubleRedirects|double]] or [[Special:BrokenRedirects|broken redirects]].\nان ڳالهه جي پڪ ڪرڻ ذميواري توهان تي آهي ته ڳنڍڻا اتي ئي وٺي وڃن ٿا جتي انهن کي وٺي وڃڻ گھرجي.\n\nياد رکندا ته جيڪڏهن نئين عنوان سان اڳي ئي ڪو مضمون موجود آهي ته پوءِ صفحو '''نه''' چوريو ويندو، سوا ان جي ته موجوده صفحو محظ خالي آهي يا ڪا به سوانح نه رکندڙ ڪو چورڻو آهي.\n\n<strong>خبردار!</strong>\nاها هڪ مقبول صفحي لاءِ ڪا غير متوقه ۽ انتهائي اڻوڻندڙ تبديلي ثابت ٿي سگھي ٿي؛ براءِ مهرباني اڳتي وڌڻ کان اڳ پڪ ڪندا ته توهان اها تبديلي آڻڻ جي نتيجن کان چڱيءَ ريت واقف آهيو.",
+       "movepagetext": "هيٺيون فارم استعمال ڪندي ڪنهن صفحي کي نئون عنوان ڏئي سگھجي ٿو، جنهن سان سمورو صفحو نئين عنوان ڏانهن هليو ويندو. \nاڳوڻو عنوان نئين عنوان ڏانهن چورڻو بنجي ويندو. \nتوهان  چورڻن کي سنواري سگھو ٿا جيڪي اصل عنوان ڏانهن خودبخود اشارو ڪن ٿا.\nIf you choose not to, be sure to check for [[Special:DoubleRedirects|double]] or [[Special:BrokenRedirects|broken redirects]].\nان ڳالهه جي پڪ ڪرڻ ذميواري توهان تي آهي ته ڳنڍڻا اتي ئي وٺي وڃن ٿا جتي انهن کي وٺي وڃڻ گھرجي.\n\nياد رکندا ته جيڪڏهن نئين عنوان سان اڳي ئي ڪو مضمون موجود آهي ته پوءِ صفحو '''نه''' چوريو ويندو، سوا ان جي ته موجوده صفحو محظ خالي آهي يا ڪا به سوانح نه رکندڙ ڪو چورڻو آهي.\n\n<strong>نوٽ!</strong>\nاها هڪ مقبول صفحي لاءِ ڪا غير متوقه ۽ انتهائي اڻوڻندڙ تبديلي ثابت ٿي سگھي ٿي؛ براءِ مهرباني اڳتي وڌڻ کان اڳ پڪ ڪندا ته توهان اها تبديلي آڻڻ جي نتيجن کان چڱيءَ ريت واقف آهيو.",
        "movepagetalktext": "جيڪڏهن توهان هن خاني کي نشان لڳائيندئو، واسطيدار مباحثي صفحو پاڻ ئي چوريو ويندو ماسواءِ اتي ڪو اڳ ئي ڪو غيرخالي مباحثي صفحو موجود هجي.\n\nان صورت ۾، جيڪڏهن توهان چاهيو ته صفحي کي پاڻ چوري يا ضم ڪري سگھو ٿا.",
        "movenotallowed": "توهان کي صفحا چورڻ جي اجازت حاصل ڪانهي.",
        "movenotallowedfile": "توهان کي فائيلس چورڻ جي اجازت حاصل ڪانهي.",
        "tooltip-pt-userpage": "{{GENDER:|توھانجو يوزر}} صفحو",
        "tooltip-pt-mytalk": "{{GENDER:|توھانجو}} يوزر صفحو",
        "tooltip-pt-preferences": "{{GENDER:|توھانجون}} ترجيحات",
-       "tooltip-pt-watchlist": "توهان جي ٽيٽ فهرست ۾ شامل صفحا",
+       "tooltip-pt-watchlist": "توھان جي تبديلين جي نظرھيٺ صفحن جي فھرست",
        "tooltip-pt-mycontris": "{{GENDER:|توھانجي}} ڀاڱيدارين جي فھرست",
-       "tooltip-pt-login": "توهان کي همٿائجي ٿو تہ توهان لاگ اِن ٿيو، بهرحال اهو لازمي نہ آهي.",
-       "tooltip-pt-logout": "Ù\84اگ Ø¢Ø¦Ù\88Ù½",
-       "tooltip-pt-createaccount": "کاتو کولڻ ۽ لاگ اِن ٿيڻ تي توهان کي همٿايو ويندو؛  جيتوڻيڪ، اهو ضروري نہ آهي",
+       "tooltip-pt-login": "توھان کي ھمٿائجي ٿو تہ توهان داخل ٿيو؛ بھرحال، اھو لازمي ناھي",
+       "tooltip-pt-logout": "ٻاھر Ù\86ڪرÙ\88",
+       "tooltip-pt-createaccount": "کاتو کولڻ ۽ داخل ٿيڻ تي توھان کي ھمٿايو وڃي ٿو؛  جيتوڻيڪ، اهو ضروري ناھي",
        "tooltip-ca-talk": "موادي صفحي تي بحث",
        "tooltip-ca-edit": "هيءُ صفحو سنواريو",
        "tooltip-ca-addsection": "نئون سيڪشن شروع ڪريو",
-       "tooltip-ca-viewsource": "هيءُ صفحو تحفظيل آهي. توهان ان جو ڪوڊ ڏسي سگھو ٿا.",
+       "tooltip-ca-viewsource": "هيءُ صفحو تحفظيل آهي.\nتوهان ان جو ذريعو ڏسي سگھو ٿا",
        "tooltip-ca-history": "هن صفحي جا اڳوڻا ڀيرا",
        "tooltip-ca-protect": "هيءُ صفحو تحفظيو",
        "tooltip-ca-delete": "هيءُ صفحو ڊاهيو",
        "tooltip-ca-move": "هيءُ صفحو چوريو",
-       "tooltip-ca-watch": "Ù\87Ù\8aØ¡Ù\8f ØµÙ\81Ø­Ù\88 Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù½Ù\8aÙ½ Ù\81Ù\87رست ۾ شامل ڪريو",
-       "tooltip-ca-unwatch": "Ù\87Ù\8aØ¡Ù\8f ØµÙ\81Ø­Ù\88 Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù½Ù\8aÙ½ Ù\81Ù\87رست تان هٽايو",
+       "tooltip-ca-watch": "Ù\87Ù\8aØ¡Ù\8f ØµÙ\81Ø­Ù\88 Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست ۾ شامل ڪريو",
+       "tooltip-ca-unwatch": "Ù\87Ù\8aØ¡Ù\8f ØµÙ\81Ø­Ù\88 Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست تان هٽايو",
        "tooltip-search": "{{SITENAME}} ۾ ڳوليو",
        "tooltip-search-go": "تز ان ئي نالي سان ڪو صفحو موجود آهي تہ کوليو",
        "tooltip-search-fulltext": "هن متن لاءِ صفحا ڳوليو",
        "tooltip-p-logo": "مک صفحو گھمو",
        "tooltip-n-mainpage": "مک صفحو گھمو",
        "tooltip-n-mainpage-description": "مک صفحو گھمو",
-       "tooltip-n-portal": "هن رٿا بابت، توهان ڇا ٿا ڪري سگھو، ڪهڙي شَي ڪٿي ملندي",
-       "tooltip-n-currentevents": "تازن واقعن تي تفصيلي ڄاڻ لهو",
-       "tooltip-n-recentchanges": "هن وڪيءَ ۾ تازين تبديلين جي فهرست.",
-       "tooltip-n-randompage": "بلاترتيب ڪو بہ صفحو اتاريو",
-       "tooltip-n-help": "ڳولي لهڻ جي جاءِ",
-       "tooltip-t-whatlinkshere": "هتان ڳنڍيل سمورا وڪي صفحا",
+       "tooltip-n-portal": "ھن رٿا بابت، توھان ڇا ٿا ڪري سگھو، شيون ڪٿي ڳولھجن",
+       "tooltip-n-currentevents": "تازن واقعن تي تفصيلي ڄاڻ لھو",
+       "tooltip-n-recentchanges": "ھن وڪيءَ ۾ تازين تبديلين جي فھرست",
+       "tooltip-n-randompage": "ڪو بلاترتيب صفحو اتاريو",
+       "tooltip-n-help": "ڳولي لھڻ جي جاءِ",
+       "tooltip-t-whatlinkshere": "ھتان ڳنڍيل سمورن وڪي صفحن جي فھرست",
        "tooltip-t-recentchangeslinked": "ويجھڙائيءَ ۾ صفحن ۾ ٿيل تبديليون هن صفحي سان ڳنڍيل آهن",
        "tooltip-feed-atom": "هن صفحي لاءِ ايٽم فيڊ",
        "tooltip-t-contributions": "{{GENDER:$1|ھن يوزر}} جي ڀاڱيدارين جي فھرست",
        "tooltip-t-permalink": "صفحي جي ان نظرثاليءَ ڏانهن مستقل ڳنڍڻو",
        "tooltip-ca-nstab-main": "مواد جي صفحي کي ڏسو",
        "tooltip-ca-nstab-user": "هن جو يُوزر صفحو ڏسو",
-       "tooltip-ca-nstab-special": "هيءُ خاص صفحو آهي، ان ۾ ترميم ڪري نہ ٿي سگھجي.",
+       "tooltip-ca-nstab-special": "هيءُ خاص صفحو آهي، ان ۾ ترميم ڪري نٿي سگھجي",
        "tooltip-ca-nstab-project": "رٿائي صفحو ڏسو",
        "tooltip-ca-nstab-image": "هن فائيل جو صفحو ڏسو",
        "tooltip-ca-nstab-template": "سانچو ڏسو",
        "tooltip-ca-nstab-help": "امدادي صفحو ڏسو",
        "tooltip-ca-nstab-category": "هن زمري جو صفحو ڏسو",
        "tooltip-minoredit": "ان کي هڪ معمولي ترميم ڄاڻايو",
-       "tooltip-save": "پنهنجون ڪيل تبديليون سانڍيو",
-       "tooltip-preview": "سانڍڻ کان اڳ براءِ مهرباني پنهنجي تبديلين تي پيش نگاهه وجھندا!",
-       "tooltip-diff": "Ù¾Ù\86Ù\87Ù\86جÙ\88Ù\86 ÚªÙ\8aÙ\84 ØªØ¨Ø¯Ù\8aÙ\84Ù\8aÙ\88Ù\86 Ú\8fسÙ\88.",
+       "tooltip-save": "پنهنجون تبديليون سانڍيو",
+       "tooltip-preview": "پنھنجي تبديلين تي نگاھ وجھو. براءِ مھرباني اھو سانڍڻ کان اڳ ڪندا.",
+       "tooltip-diff": "Ù\84کت Û¾ ÚªÙ\8aÙ\84 Ù¾Ù\86Ù\87Ù\86جÙ\88Ù\86 ØªØ¨Ø¯Ù\8aÙ\84Ù\8aÙ\88Ù\86 Ú\8fسÙ\88",
        "tooltip-compareselectedversions": "هن صفحي جن ٻن چونڊيل پرتن درميان تفاوت ڏسو.",
-       "tooltip-watch": "Ù\87Ù\8aØ¡Ù\8f ØµÙ\81Ø­Ù\88 Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù½Ù\8aÙ½ Ù\81Ù\87رست ۾ شامل ڪريو",
+       "tooltip-watch": "Ù\87Ù\8aØ¡Ù\8f ØµÙ\81Ø­Ù\88 Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست ۾ شامل ڪريو",
        "tooltip-rollback": "\"واپس پرايو\" هن صفحي ۾ پوئين ڀاڱيدار جي ڪيل ترميم (ترميمن) کي هڪ ڪلڪ سان اڻڪري ٿو.",
        "tooltip-summary": "ننڍو خلاصو ڏيو",
        "anonymous": "گمنام {{PLURAL:$1|يوزر|يوزرس}} جو {{SITENAME}}",
        "file-nohires": "اڃا سنهو تحلل ميسر ناهي.",
        "svg-long-desc": "ايس وي جي فائيل، اٽڪل $1 × $2 عڪسلون، فائيل سائيز: $3",
        "show-big-image": "اصلوڪو فائيل",
-       "show-big-image-preview": "هن پيش نگاهہ جي ماپ: $1",
+       "show-big-image-preview": "هن پيش نگاھ جي ماپ: $1",
        "show-big-image-other": "ٻيا {{PLURAL:$2|تحلل}}:$1",
        "show-big-image-size": "$1*$2 پڪزلس",
        "newimages": "نون فائيلن جي گيلري",
        "confirmemail_subject": "{{SITENAME}} برق ٽپال پتي جي تصديق",
        "recreate": "ورسرجيو",
        "confirm-watch-button": "ٺيڪ",
-       "confirm-watch-top": "Ù\87Ù\8aØ¡Ù\8f ØµÙ\81Ø­Ù\88 Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù½Ù\8aÙ½ Ù\81Ù\87رست ۾ شامل ڪندا؟",
+       "confirm-watch-top": "Ù\87Ù\8aØ¡Ù\8f ØµÙ\81Ø­Ù\88 Ù¾Ù\86Ù\87Ù\86جÙ\8a Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست ۾ شامل ڪندا؟",
        "confirm-unwatch-button": "ٺيڪ",
        "confirm-unwatch-top": "هيءُ صفحو پنهنجي ٽيٽ فهرست مان هٽائيندا؟",
        "quotation-marks": "\"$1\"",
        "table_pager_limit_label": "وَٿُون في صفحو:",
        "table_pager_limit_submit": "ھلو",
        "table_pager_empty": "ڪو بہ نتيجو نہ مليو",
-       "watchlistedit-normal-title": "Ù½Ù\8aÙ½ Ù\81Ù\87رست کي سنواريو",
+       "watchlistedit-normal-title": "Ù\86ظرھÙ\8aÙº Ù\81Ú¾رست کي سنواريو",
        "watchlistedit-raw-titles": "عنوانَ:",
        "watchlistedit-clear-titles": "عنوانَ:",
        "watchlisttools-view": "لاڳاپيل تبديليون ڏسو",
        "watchlisttools-edit": "ٽيٽ فهرست ڏسو ۽ سنواريو",
        "watchlisttools-raw": "ڪچي ٽيٽ فهرست سنواريو",
-       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|ڳالهہ]])",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|ڳالھ]])",
        "version": "ڀيرو",
        "version-extensions": "تنصيب شده توسيعات",
        "version-skins": "تنصيب شده چَمڙيون",
        "feedback-back": "پوئتي",
        "feedback-cancel": "رد",
        "feedback-close": "ٿي ويو",
-       "feedback-error-title": "چُڪَ",
        "feedback-message": "نياپو:",
        "feedback-subject": "موضوع:",
        "feedback-submit": "جمع ڪرايو",
        "feedback-thanks-title": "توهان جي مهرباني!",
-       "searchsuggest-search": "ڳوليو",
+       "searchsuggest-search": "ڳوليو {{SITENAME}}",
        "api-error-filename-tooshort": "فائيل‌نانءَُ هيڪاندو ننڍو آهي.",
        "api-error-unclassified": "ڪا اڻجاتل چُڪَ واقع ٿي.",
        "api-error-unknown-code": "اڻڄاتل چُڪَ: \"$1\".",
index bfd5492..faafcb4 100644 (file)
        "yourname": "Innòmu utenti",
        "yourpassword": "Paràura d'órdhini",
        "yourpasswordagain": "Ripeti la paràura d'órdhini",
-       "remembermypassword": "Ammenta la me' paràura d'órdhini in chisthu nabiggadori (par un màssimu di $1 {{PLURAL:$1|dì|dì}})",
        "yourdomainname": "Ippizzificà lu dumìniu",
        "externaldberror": "S'è verifiggaddu un errori cu lu server di autentificazioni esthernu, oppuru nò si diponi di l'autorizazioni nezzessàri pa aggiornà la propria registhrazioni estherna.",
        "login": "Intra",
        "undo-success": "Chistha mudìfigga pò assé annulladda. Verifiggà lu sighenti cuntrasthu prisintaddu pa s'azzirthà chi lu cuntinuddu curripundi a cantu disizaddu e dunca saivvà li mudìfigghi pa cumprità la procedura di annullamentu.",
        "undo-failure": "Impussìbiri annullà la mudìfigga a càusa d'un cuntrasthu cun mudìfigghi intermédi.",
        "undo-summary": "Annulladda la mudìfigga $1 di [[Special:Contributions/$2|$2]] ([[User talk:$2|Dischussioni]])",
-       "cantcreateaccounttitle": "Impussìbiri registhrà un utenti",
        "cantcreateaccount-text": "Criazioni di registhrazioni da chistu indirizzu IP ('''$1''') è isthadda broccadda da [[User:$3|$3]].\n\nLa rasgioni frunidda da $3 è ''$2''",
        "viewpagelogs": "Visuarizza li rigisthri reratibi a chistha pàgina.",
        "nohistory": "Cronologia di li versioni di chistha pàgina nò riperìbiri.",
index 5d38477..86d1f66 100644 (file)
        "userlogin-yourpassword-ph": "تێپەڕوشەگەت بنۊس",
        "createacct-yourpassword-ph": "تێپەڕوشەێگ بنۊس",
        "yourpasswordagain": "دیسان تێپەڕوشەگە بنۊسەو:",
-       "remembermypassword": "تێپەروشەگەم لەسەر ئەی کامپیوترە پاشدەس بکە (ئەو پەڕی $1 {{PLURAL:$1|ڕووژ}}ە)",
        "login": "بچووە ناو",
        "nav-login-createaccount": "بچووە ناو / ھەژمار درس بکە",
        "userlogin": "بچووە ناو / ھەژمار درس بکە",
index 79eccff..0b2b10c 100644 (file)
        "yourname": "Geavaheaddjidovddaldat",
        "yourpassword": "Suollemassátni:",
        "yourpasswordagain": "Čále suollemassáni ođđasit:",
-       "remembermypassword": "Muite mu (for a maximum of $1 {{PLURAL:$1|day|days}})",
        "yourdomainname": "Fierbmenamma",
        "login": "Čálligoađe sisa",
        "nav-login-createaccount": "Daga ođđa geavaheaddjidovddaldaga dahje čálligoađe sisa",
        "template-protected": "(suodjáluvvon)",
        "template-semiprotected": "(suodjáluvvon anonyma ja ođđa geavaheddjiin)",
        "edittools": "<!-- Teaksta mii lea dás, čájehuvvo rievdadanskovi vuolábealde. -->",
-       "cantcreateaccounttitle": "Dovddaldaga ráhkadeapmi ii lihkosmuvvan",
        "viewpagelogs": "Čájet dán siiddu loggaid",
        "nohistory": "Dán siiddus ii leat rievdadanhistorjá.",
        "currentrev": "Dálá veršuvdna",
        "activeusers-intro": "Dát lea listu geavaheddjiin, mat leat bargan juoidá maŋimus $1 {{PLURAL:$1|beaivvi|beaivvi}} siste.",
        "activeusers-count": "$1 {{PLURAL:$1|rievdadus|rievdadusa}} maŋimus $3 beaivvi siste",
        "activeusers-from": "Čájet geavaheddjiid dán rájes:",
-       "activeusers-hidebots": "Čiega bohtaid",
-       "activeusers-hidesysops": "Čiega administráhtoriid",
        "listgrouprights-members": "(listu miellahtuin)",
        "mailnologin": "Sáddejeaddji čujuhus váilo",
        "mailnologintext": "Don fertet leat [[Special:UserLogin|čálligoahtán sisa]] ja du [[Special:Preferences|ásahusain]] ferte leat gelbbolaš ja <strong>sihkarastojuvvon</strong> e-poastačujuhus, ovdalgo sáhtat sáddet e-poasta eará geavaheddjiide.",
index f031e4e..62ecd78 100644 (file)
        "yourname": "Caitom ID:",
        "yourpassword": "Quimx canj:",
        "yourpasswordagain": "Vanquimx canj:",
-       "remembermypassword": "Qualtiinii he quimx canj jan ordinator iti (for a maximum of $1 {{PLURAL:$1|day|days}})",
        "yourdomainname": "Hedomino:",
        "externaldberror": "Pos-römjde authenticacionde database extername jöx me necoccebj permiccionde updatan mecaitom externom.",
        "login": "Caápo",
        "undo-success": "Ticpatlöx zo pos-coccebj iixponintöx. Controlar comparicion zo !-cmaade verifiatom jan coccebj yazuáxiim ö xuniim quiíx zo !-cmaade fini iixponintöx ticpatlöx zo.",
        "undo-failure": "Ticpatlöx zo necoccebj ticpatlöxde ticpatlöxám iti-am conflictom.",
        "undo-summary": "Iixponintöx revicion $1 'de [[Special:Contributions/$2|$2]] ([[User talk:$2|Czaxö]])",
-       "cantcreateaccounttitle": "Nexuatláminop",
        "cantcreateaccount-text": "Creacionde caitomde jan adressade IP ('''$1''') coccebj blockom [[User:$3|$3]] mii.\n\nRae' zo xuniim $3 mii coccebj ''$2''",
        "viewpagelogs": "Cohuatlöx logámde jan páhina",
        "nohistory": "Jan páhina necoccebj históriade ticpatlöx.",
index caddb8a..c3817d5 100644 (file)
        "yourpasswordagain": "Šennikufal hantum taaga:",
        "createacct-yourpasswordagain": "Šennikufal tabatandi",
        "createacct-yourpasswordagain-ph": "Šennikufal dam taaga",
-       "remembermypassword": "Hong'ay huruyan tammaasa ceecikaa woo ga (a ma ši bisa {PLURAL:$1|jirbi|jirbi}}) $1",
        "userlogin-remembermypassword": "Ay goywaatoo ma gaabandi ka feera",
        "userlogin-signwithsecure": "Ciya nda saajaw",
        "yourdomainname": "Ni zunbu dogoo:",
        "passwordreset-emailtext-user": "Goykaw $1 {{SITENAME}} wiri ka war sennikufaloo yeeti {{SITENAME}} se\n($4). Goykaa woo {{PLURAL:$3|kontoo ga|kontey ga}} marga nda nda bataga aderesoo woo:\n\n$2\n\n {{PLURAL:$3|Šiiyan šennikufaloo woo|Šiiyan šennikufaley wey}} ga buu {{PLURAL:$5|jirbi foo|jirbi $5}} ra.\nWar ga hima ka huru  nda šennikufal taaga suuba sohõ. Nda boro waani ka ceeci\n ka woo tee wala war ga honga wara šennikufal žeenaa nda war ši boona koyne\n k'a barma, war ga hin ka šaawaroo woo muray nda gaabandi ka goy nda war\n šennikufal žeenaa.",
        "passwordreset-emailelement": "Goykaw maa: \n$1\n\nŠiiyan šennikufal: \n$2",
        "passwordreset-emailsentemail": "Šennikufal yeetiyan bataga n' ka sanbandi war se.",
-       "passwordreset-emailsent-capture": "Šennikulal yeetiyan bataga n' ka sanbandi war se, kaŋ ga cebandi ne ganda.",
-       "passwordreset-emailerror-capture": "Šennikufal yeetiyan bataga n' ka teendi, kaŋ ga cebandi ne ganda, amm'a mana hin ka sanbandi {{GENDER:$2|goykaw}} do: $1",
        "changeemail": "Bataga aderesu barmay",
        "changeemail-header": "Takaddaa woo toonandi ka war bataga aderesoo barmay. War ka hima ka war šennikufaloo dam ka barmayyanoo tabatandi.",
        "changeemail-no-info": "War ga hima ka huru ka hin duu moɲoo woo.",
        "undo-nochange": "A ga hima kaŋ barmaa n' ka taafeeri ka ben.",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|deede]]) na $1 fillaa taafeeri",
        "undo-summary-username-hidden": "Goykaw tugante na $1 fillaa taafeeri",
-       "cantcreateaccounttitle": "Ši hin ha kontu tee",
        "cantcreateaccount-text": "[User:$3|$3]] ganji kontu ma tee IP aderesu (<strong>$1</strong>) ga.\n\nDaliloo kaŋ $3 n'a noo ti <em>$2</em>",
        "cantcreateaccount-range-text": "[[User:$3|$3]] ganji kaŋ kontu ma tee IP aderesey kaŋyaŋ goo <strong>$1</strong> laamaa ra ga, sanda war IP aderesoo (<strong>$4</strong>).\n\nDaliloo kaŋ $3 n'a noo ti <em>$2</em>",
        "viewpagelogs": "Hantum taarikey guna moɲoo woo se",
        "activeusers-intro": "Wey ti goykey kaŋ cindi goymee tana ra {{PLURAL:$1|jirbi}} $1 kaŋ kokor ra.",
        "activeusers-count": "{{PLURAL:$1|teera}} $1 {{PLURAL:$3|jirbi|$3}} kaŋ kokor ra.",
        "activeusers-from": "Goykey cebe kaŋ ga šintin ne:",
-       "activeusers-hidebots": "Maršin berekey tugu",
-       "activeusers-hidesysops": "Juwalkey tugu",
        "activeusers-noresult": "Goykaw kul mana duwandi.",
        "listgrouprights": "Goykaw kuray alhakey",
        "listgrouprights-summary": "The following is a list of user groups defined on this wiki, with their associated access rights.\nA ga hin ka tee [[{{MediaWiki:Listgrouprights-helppage}}|alhabar tontoni]] ga bara boro alhakey ga.",
        "htmlform-cloner-create": "Tonton koyne",
        "htmlform-cloner-delete": "Kaa",
        "htmlform-cloner-required": "Nd'ajaase hinna foo ga waažibandi.",
-       "sqlite-has-fts": "$1 nda hantum-timmante ceeci gaakašinay",
-       "sqlite-no-fts": "$1 bila nda hantum-timmante  ceeci gaakašinay",
        "logentry-delete-delete": "$1  {{GENDER:$2|na}} moo $3 tuusu",
        "logentry-delete-restore": "$1 {{GENDER:$2|na}} moo yeeti $3",
        "logentry-delete-event": "$1 {{GENDER:$2|na}} diira sahã barmay {{PLURAL:$5|taariki teera $5}} se $3 ga: $4",
index 273c8a6..8b905f2 100644 (file)
@@ -23,6 +23,7 @@
        "tog-watchdefault": "Pridietė poslapius, katrūs keito, keravuojamu sārošap",
        "tog-watchmoves": "Pridietė poslapius, katrūs parvadėno, keravuojamu sārošap",
        "tog-watchdeletion": "Pridietė poslapius, katrūs ėštrėno, keravuojamu sārošap",
+       "tog-watchuploads": "I keravuojamu sāraša pridietė mona ožkrautus abruozdielius",
        "tog-watchrollback": "Pridietė poslapius, katrūs keitėmus grōžėno atgal, keravuojamu sārošap",
        "tog-minordefault": "Kāp prėgol pažīmietė pakeitėmus mažās",
        "tog-previewontop": "Ruodītė parvaiza vėrš taisīmu lauka",
@@ -40,6 +41,7 @@
        "tog-watchlisthidebots": "Kavuotė robotu pakeitėmos keravuojamu sārošė",
        "tog-watchlisthideminor": "Kavuotė mažus pakeitėmus keravuojamu sārošė",
        "tog-watchlisthideliu": "Kavuotė prėsėjongosiu nauduotuoju keitėmus keravuojamu sārošė",
+       "tog-watchlistreloadautomatically": "Parkrautė keravuojamu poslapiu sāraša kap tik kuoštovis būn pakeists (rēk JavaScript)",
        "tog-watchlisthideanons": "Kavuotė anonimėniu nauduotuoju keitėmus keravuojamu sārošė",
        "tog-watchlisthidepatrolled": "Kavuotė sodabuotus pakeitėmus keravuojamu sārošė",
        "tog-watchlisthidecategorization": "Kavuotė poslapiu kateguorėzacėjė",
@@ -48,7 +50,7 @@
        "tog-showhiddencats": "Ruodītė pakavuotas kateguorėjės",
        "tog-norollbackdiff": "Nekrēptė diemesė i skėrtoma atlėkus atmetėma",
        "tog-useeditwarning": "Monėi dout žėnuot, kāp ėšēno ėš poslapė anon naėšsauguojis",
-       "tog-prefershttps": "Vėsūmet nauduotė saugu rīši kāp būno prėsijongė̄s",
+       "tog-prefershttps": "Vėsūmet nauduotė saugu rīši kap būno prisijongė̄s",
        "underline-always": "Vėsūmet",
        "underline-never": "Nikūmet",
        "underline-default": "Vagol naršīklės nustatīmus",
        "actions": "Vēksmā",
        "namespaces": "Vardū srėtis",
        "variants": "Atmainā",
-       "navigation-heading": "Naršīma pasėrinkėmā",
+       "navigation-heading": "Naršīma pasirinkėmā",
        "errorpagetitle": "Klaida",
        "returnto": "Grīžtė i $1.",
        "tagline": "Straipsnis ėš {{SITENAME}}.",
        "edit-local": "Taisītė vėitėni aprašīma",
        "create": "Padėrbtė",
        "create-local": "Prėkergtė vėitėni aprašīma",
-       "editthispage": "Taisītė ton poslapė",
+       "editthispage": "Taisītė ton poslapi",
        "create-this-page": "Dėrbtė ton poslapi",
        "delete": "Trintė",
-       "deletethispage": "Trintė ton poslapė",
+       "deletethispage": "Trintė ton poslapi",
        "undeletethispage": "Ton poslapi padėrbtė apent",
        "undelete_short": "Dėrbtė apent $1 {{PLURAL:$1:pakeitėma|pakeitėmus|pakeitėmu}}",
        "viewdeleted_short": "Veizietė $1 {{PLURAL:$1|ėštrinta keitėma|ėštrintus keitėmus|ėštrintū keitėmu}}",
        "talk": "Aptarėms",
        "views": "Parveizė̄jėmā",
        "toolbox": "Rakondā",
+       "tool-link-userrights": "Mainītė {{GENDER:$1|nauduotuoja|nauduotuojės}} gropės",
+       "tool-link-emailuser": "Rašītė gromata {{GENDER:$1|tamou nauduotuojou}}",
        "userpage": "Ruodītė nauduotuojė poslapi",
        "projectpage": "Ruodītė pruojekta poslapi",
        "imagepage": "Veizietė abruozdielė poslapi",
        "jumptonavigation": "naršīms",
        "jumptosearch": "paėiška",
        "view-pool-error": "Atsėprašuom, bat serverē daba īr parkrautė.\nNuognē pardaug nauduotoju skait ton poslapi.\nPrašuom palaukat ė mieginkat i ton poslapi patekt apent.\n\n$1",
+       "generic-pool-error": "Atsėprašuom, ale serverē daba īr parkrautė.\nNuognē pardaug nauduotoju skaita ton poslapi.\nPrašuom palaukat ė mieginkat i ton poslapi patekt apent.\n\n$1",
        "pool-errorunknown": "Nežėnuoma klaida",
        "poolcounter-usage-error": "Naudojėma soklīdėms: $1",
        "aboutsite": "Aple {{SITENAME}}",
        "laggedslavemode": "Atėduos: Poslapie gal' nesmatītė vielībiausiu pakeitėmu.",
        "readonly": "Doumenū bazė ožrakėnta",
        "enterlockreason": "Iveskėt ožrakėnėma prižasti, tēpuogi kumet daugmaž bus atrokėnta",
-       "readonlytext": "Doumenū bazė daba īr ožrakėnta naujėm irašam a kėtėm keitėmam,\nmažo doumenū bazės techninē pruofilaktėkā,\npuo tuo vėsks griš i sava viežes.\nOžrakėnusiuojo admėnėstratuoriaus pateikts rakėnima paaiškėnims: $1",
+       "readonlytext": "Doumenū bazė daba īr ožrakinta naujėm irašam a kėtėm keitėmam,\nmažo doumenū bazės techninē pruofilaktėkā,\npu tuo viskos grīš i sava viežės.\nOžrakėnosė admėnėstratuorė douts rakėnėma paaiškėnėms: $1",
        "missing-article": "Doumenū bazė nerada poslapė teksta, katra ana torietu rastė, pavadėnta „$1“ $2.\n\nPaprastā tas būn dielē pasenosės skėrtoma vuo istuorėjės nūruodas i poslapi, katros bova ėštrėnts.\n\nJēgo tas nie šėts varėjants, Tamsta mažo raduot klaida pruogramėnė ironguo.\nPrašuom aple šėtā paskelbtė [[Special:ListUsers/sysop|adminėstratoriō]], nepamėršdamė nuruodītė nūruoda.",
        "missingarticle-rev": "(atmains nr. $1)",
        "missingarticle-diff": "(Skėrt.: $1, $2)",
        "yourpasswordagain": "Pakartuoket slaptažuodė:",
        "createacct-yourpasswordagain": "Čīstā tuokis slaptažuodis?",
        "createacct-yourpasswordagain-ph": "Apent ožrašīkat slaptažuodi",
-       "remembermypassword": "Atmintė prisėjongėma infuormacėjė šėtom kuompioteri (daugiausē $1 {{PLURAL:$1|dėina|dėinė|dėinas}})",
        "userlogin-remembermypassword": "Ka liktō prisėjongis",
        "userlogin-signwithsecure": "Apsauguots rīšīs",
+       "cannotlogin-title": "Nēn prisijongtė",
+       "cannotlogin-text": "Nie galam prisijongtė.",
        "cannotloginnow-title": "Nēn prėsijongtė",
        "yourdomainname": "Tamstas domens:",
        "password-change-forbidden": "Negalat tuo wiki keistė slaptažuodiu.",
        "nav-login-createaccount": "Prėsėjongtė / padėrbtė paskīra",
        "userlogin": "Prėsėjongtė / padėrbtė paskīra",
        "userloginnocreate": "Prėsėjongtė",
-       "logout": "Atsėjongtė",
-       "userlogout": "Atsėjongtė",
+       "logout": "Atsijongtė",
+       "userlogout": "Atsijongtė",
        "notloggedin": "Neprėsėjongis",
        "userlogin-noaccount": "Netorat paskīruos?",
        "userlogin-joinproject": "Jonkėtėis prī {{SITENAME}}",
        "userlogin-resetpassword-link": "Ožmiršat sava slaptažuodi?",
        "userlogin-helplink2": "Prėsėjongėma pagelba",
        "userlogin-loggedin": "Tamsta jau īr prėsijongė̄s kāp {{GENDER:$1|$1}}.\nJēb nuorat prisėjongtė kāp kėts žmuogos, nauduokat skvarma apatiuo.",
+       "userlogin-reauth": "Tamsta torat prisijongtė apent, ka būtom aiško, ka esat {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Padėrbtė kėta paskīra",
        "createacct-emailrequired": "El. pašta adresos",
        "createacct-emailoptional": "El. paštos (nie būtėns)",
        "createacct-reason-ph": "Kūdie dėrbat kėta nauduotojė poslapi",
        "createacct-submit": "Padėrbkat savėi paskīra",
        "createacct-another-submit": "Padėrbtė paskīra",
+       "createacct-continue-submit": "Tuoliaus dėrbtė nauduotuoja paskīra",
+       "createacct-another-continue-submit": "Tuoliaus dėrbtė nauduotuoja paskīra",
        "createacct-benefit-heading": "{{SITENAME}} īr sokorta prietėliu, tuokiu, kāp Tamsta.",
        "createacct-benefit-body1": "{{PLURAL:$1|pataisīms|pataisīmā|pataisīmu}}",
        "createacct-benefit-body2": "{{PLURAL:$1|poslapis|poslapē|poslapiu}}",
        "createaccounterror": "Nė̄šiejė padėrbtė paskīruos: $1",
        "nocookiesnew": "Nauduotuojė paskīra bova sokurta, bat Tamsta nēsot prėsėjongis. {{SITENAME}} nauduo pakavukus (''cookies''), ka prėkergtom nauduotuojus. Tamsta esot ėšjongis anūs. Prašuom ijongtė pakavukus, tumet prisėjonkat so sava naujo nauduotuojė vardo ė slaptažuodio.",
        "nocookieslogin": "{{SITENAME}} nauduo pakavukus (''cookies''), ka prėkergtom nauduotuojus. Tamsta esat ėšjongis anūs. Prašuom ijongtė pakavukus ė pamiegītė apent.",
+       "noname": "Naožrašėt tinkama nauduotuoja varda!",
        "loginsuccesstitle": "Prisijongiet gerā",
        "loginsuccess": "'''Dabā Tamsta esat prėsėjongis prī {{SITENAME}} kāp „$1“.'''",
        "nosuchuser": "Nier anėjuokė nauduotuojė, katrou vards būtom „$1“ (dėdliuosės rādės svarbo ī).\nPatikrinkėt rašība aba [[Special:CreateAccount|padėrbkėt naujė paskīra]].",
        "eauthentsent": "Patvėrtėnėma gruomata bova nusiōsta i paskėrta el. pašta adresa.\nPrīš ėšsiontiant kėta gruomata i Tamstas diežote, Tamsta torėt vīkdītė nuruodīmus gruomatuo, kū patvėrtėntomiet, kū diežotė tėkrā īr Tamstas.",
        "throttled-mailpassword": "Slaptažuodžė priminims jau bova ėšsiōsts, par paskotėnės {{PLURAL:$1|adīna|$1 adīnas}}. Nuorint apsėsauguotė nū pėktnaudēvėma, slaptažuodė priminėms gal būt ėšsiōsts tėk kas {{PLURAL:$1|adīna|$1 adīnas}}.",
        "mailerror": "Bieda siontiont gromata: $1",
-       "acct_creation_throttle_hit": "Ton pruojekta lankītuojē, katrėi nauduo Tamstas IP adresa, padėrba {{PLURAL:$1|$1 paskīra|$1 paskīras|$1 paskīrū}} par paskotėnta dėina, a tas īr dėdliausis leidams skaitlios par ta čiesa.\nTudie šėton čieso lankītuojē, katrėi nauduo ta IP adresa, daugiau paskīrū dėrbt negal.",
+       "acct_creation_throttle_hit": "Ton pruojekta lankītuojē, katrėi nauduo Tamstas IP adresa, padėrba {{PLURAL:$1|$1 paskīra|$1 paskīras|$1 paskīrū}} par paskotėnta $2, a tas īr dėdliausis leidams skaitlios par ta čiesa.\nTudie šėton čieso lankītuojē, katrėi nauduo tou IP adresa, daugiau paskīrū dėrbtė nagal.",
        "emailauthenticated": "Tamstas el. pašta adresos bova ožtvirtėnts $2 d. $3.",
        "emailnotauthenticated": "Tamstas el. pašta adresos da nier patvėrtėnts. Anėjuokės gruomatas\nnebus siontamas ni vėinam žemiau ėšvardėntam puoslaugiō.",
        "noemailprefs": "Nuruodėkīt el. pašta adresa, kū vėiktu šėtos funkcėjės.",
        "pt-login-button": "Prėsėjongtė",
        "pt-login-continue-button": "Tuoliau prisijongėnietė",
        "pt-createaccount": "Pasėdėrbtė paskīra",
-       "pt-userlogout": "Atsėjongtė",
+       "pt-userlogout": "Atsijongtė",
        "changepassword": "Pakeistė slaptažuodė",
        "resetpass_announce": "Ka ožbengtomiet jongtėis, torėt sokortė naujė slaptažuodi.",
        "resetpass_header": "Keistė paskīruos slaptažuodi",
        "resetpass_submit": "Nostatītė slaptažuodi ė prėsėjongtė",
        "changepassword-success": "Tamstas slaptažuodis pamainīts gerā!",
        "changepassword-throttled": "Baisē daug čiesu mieginot prisėjongtė.\nDaba palaukėt $1 prīš mieginant vie.",
+       "resetpass-no-info": "Ka ētomiet tėisē ont tou poslapė, Tamstā rēk prisijongtė.",
        "resetpass-submit-loggedin": "Keistė slaptažuodi",
        "resetpass-submit-cancel": "Pabengtė",
+       "resetpass-wrong-oldpass": "Bluogs laikėns aba esams slaptažuodis.\nTamsta, rasietās, anou pamainėt aba ožprašiet naujė laikėna slaptažuodi.",
+       "resetpass-recycled": "Pamainīkat sava slaptažuodi i kėtuoki, nego daba ī.",
+       "resetpass-temp-emailed": "Tamsta prisijongėt so laikėno kuodo, ėš al. gruomatas.\nKa ožbengtomėt prisijongėma, Tamstā rēk ožrašītė nauja slaptažuodi.",
        "resetpass-temp-password": "Laikėns slaptažuodis:",
        "resetpass-expired": "Tamstas slaptažuodis bengė vēktė. Padirbkėt nauja slaptažuodi, ka prisijongtomiet.",
        "passwordreset": "Apent padėrbtė slaptažuodi",
        "passwordreset-username": "Nauduotuojė vards:",
        "passwordreset-domain": "Domens:",
        "passwordreset-email": "El. pašta adresos:",
+       "passwordreset-emailtitle": "{{SITENAME}} paskīruos aprašīms",
        "passwordreset-emailtext-ip": "Kažėkas (mosietās Tamsta, ėš IP adresa $1) ožprašė pamainītė slaptažuodi tinklapie {{SITENAME}} ($4). Tou nauduotuojė {{PLURAL:$3|poslapis|poslapio|poslapē|poslapiu}}\nsorištė so tou al. pašta adreso ī:\n\n$2\n\n{{PLURAL:$3|Tas čiesėškos slaptažuodis|čiesėški slaptažuodē}} bengs vēktė pu {{PLURAL:$5|dėinuos|$5 dėinū}}.\nTamsta prisijonkėt ė pamainīkėt sava slaptažuodi. Jēb kas tā kėts padirba tou prašīma, aba jēb atminiet sava sena slaptažuodi, ta galėt nakrēptė atėdies i tou gromata ė jongtėis so sava seno slaptažuodio.",
+       "passwordreset-emailtext-user": "Nauduotuos $1 ėš {{SITENAME}} ožprašė, ka būtom atgrōžints Tamstas {{SITENAME}} slaptažuodis ($4). Ton nauduotuoja {{PLURAL:$3|paskīra|paskīras}} prigol prī ton al. pašta adresa:\n\n$2\n\n{{PLURAL:$3|Tas laikėns slaptažuodis|Tėi laikėni slaptažuodē}} bengs vēktė ož {{PLURAL:$5|vėinuos dėinuos|$5 dėinū}}.\n\nTamsta galat prisijongtė ė pasirinktė nauja slaptažuodi. Jēb kon tās kėts ožprašė šėton, aba jēb atmėniet sava slaptažuodi ė nabnuorat anou mainītė, ta galat nakrēptė diemesė i šėton gruomata ė pu senuobie nauduotė sava slaptažuodi.",
        "passwordreset-emailelement": "Nauduotuos:\n$1\n\nČiesėšks slaptažuodis:\n$2",
+       "passwordreset-invalidemail": "Bluogs alektruonėnė pašta adresos",
        "changeemail": "Keistė aba trintė el. pašta adresa",
+       "changeemail-no-info": "Ka ētomiet tėisē ont tou poslapė, Tamstā rēk prisijongtė.",
        "changeemail-oldemail": "Vielībs el. pašta adresosː",
        "changeemail-newemail": "Naus el. pašta adresosː",
        "changeemail-none": "(nie)",
        "changeemail-password": "Tamstas {{SITENAME}} slaptažuodis:",
        "changeemail-submit": "Keistė el. pašta",
        "changeemail-throttled": "Tamsta nuognē daug sīkiu miegėnat prėsėjongtė.\nPalaukat $1 prīš miegėnont apent.",
+       "changeemail-nochange": "Irašīkat kėtuoki nauja al. pašta adresa.",
        "bold_sample": "Pastuorints raštos",
        "bold_tip": "Pastuorints raštos",
        "italic_sample": "Pasviris raštos",
        "summary": "Keitėma paāškėnėms:",
        "subject": "Tema/ontraštė:",
        "minoredit": "Mažos pakeitėms",
-       "watchthis": "Keravuotė ton poslapė",
+       "watchthis": "Keravuotė ton poslapi",
        "savearticle": "Ėšsauguotė poslapi",
+       "savechanges": "Ėšsauguotė pakeitėmus",
        "publishpage": "Padėrbtė ton poslapi",
        "publishchanges": "Ožrašītė poslapė pamainīmus",
        "preview": "Parveiza",
        "missingsummary": "'''Priminėms:''' Tamsta nenuruodiet pakeitėma kuomentara. Jēgo viel paspausėt ''Ėšsauguotė'', Tamstas pakeitėms bus ėšsauguots ba anuo.",
        "selfredirect": "<strong>Atėdės:</strong> Tamsta dėrbat poslapė nosokėma savėsp.\nParašīkat tėkslē, kor ons poslapis tor soktė.\nJēgo apent mīgsat \"{{int:savearticle}}\", ta ons poslapis vės vėin bos padėrbts.",
        "missingcommenttext": "Duokat pāiškėnėma apatiuo.",
+       "missingcommentheader": "'''Primėnėms:''' Tamsta nadaviet pakeitėma paaiškėnėma. Jēgo apent paspausat \"{{int:savearticle}}\", Tamstas pakeitėms būs ėšsauguots ba anuo.",
        "summary-preview": "Pāiškėnėma parvaiza:",
        "subject-preview": "Skėrsnelė/ontraštės parvaiza:",
+       "previewerrortext": "Miegėnant parveizietė pakeitėmus nūtėka klaida.",
        "blockedtitle": "Nauduotuos īr ožgints",
        "blockedtext": "'''Tamstas nauduotuojė vards aba IP adresos ožgints īr.'''\n\nOžgīnė nauduotuos $1.\nDingstės ''$2''.\n\n* Ožgīnėms prasėdė̄jė: $8\n* Ožgīnėms pasėbengs: $6\n* Kas tor būtė ožgints: $7\n\nTamsta galat parašītė $1 aba kėtėim\n[[{{MediaWiki:Grouppage-sysop}}|admėnėstratuorėm]], jēgo mīslėjat, ka Tamstā ožgīnė ba grieka.\nTamsta negalat „rašītė gromata ton nauduotuojō“, jēgo nasat davis tėkra sava el. pašta adresa sava [[Special:Preferences|paskīruos nustatīmūs]] ė nasat ožgints nu anuos nauduojėma.\nTamstas dabartėnis IP adresos īr $3, vuo ožgīnėma ID īr #$5. Prašuom nuruodītė ton, kumet prašīsėt atgėnoms.",
        "autoblockedtext": "Tamstas IP adresos bova liuosā ožgints, tudie, ka ana nauduojė kėts nauduotuos, katra ožgīnė $1.\nDouta dingstės īr tuokė:\n\n:''$2''\n\n* Ožgīnėms prasėdė̄jė: $8\n* Ožgīnėms pasėbengs: $6\n* Kas tor būtė ožgints: $7\n\nTamsta galėt sosėsėiktė so $1 aba kėtu [[{{MediaWiki:Grouppage-sysop}}|adminėstratuoriom]], kū aprokoutomėt biedas diel bluokavėma.\n\nTamsta galat parašītė $1 aba kėtėim\n[[{{MediaWiki:Grouppage-sysop}}|admėnėstratuorėm]], jēgo mīslėjat, ka Tamstā ožgīnė ba grieka.\nTamsta negalat „rašītė gromata ton nauduotuojō“, jēgo nasat davis tėkra sava el. pašta adresa sava [[Special:Preferences|paskīruos nustatīmūs]] ė nasat ožgints nu anuos nauduojėma.\nTamstas dabartėnis IP adresos īr $3, vuo ožgīnėma ID īr #$5. Prašuom nuruodītė ton, kumet prašīsėt atgėnoms.",
        "blockednoreason": "dingstėis nie douta",
        "whitelistedittext": "Tamstā rēk $1, ka dėrbtomiet poslapius.",
        "nosuchsectiontitle": "Nier tuokė skėrsnė",
+       "nosuchsectiontext": "Tamsta miegėnuot keistė skėrsni, katruo daba jau nabie.\nRasietās, kas tā par ton čiesa anou ėštrīnė aba parvadėna.",
        "loginreqtitle": "Rēk prėsėjongtė",
        "loginreqlink": "prėsėjongtė",
        "loginreqpagetext": "Rēk $1, paveiziejėmō kėtū poslapiu.",
        "userpage-userdoesnotexist-view": "Nie nauduotuojė vardo „$1“",
        "blocked-notice-logextract": "Nauduotuos ožgints īr.\nApatiuo paruodīta kas ė kāpː",
        "clearyourcache": "'''Diemesė:''' ėšsauguojus Tamstā gal prireiktė ėšvalītė Tamstas naršīklės rėnktovė, kū paveizėtomėt pakeitėmus. '''Mozilla / Safari / Konqueror:''' laikīdami ''Shift'' pasėrinkėt ''Atsiōstė ėš nauja'', a paspauskėt ''Ctrl-Shift-R'' (sėstemuo Apple Mac ''Cmd-Shift-R''); '''IE:''' laikīdamė ''Ctrl'' paspauskėt ''Atnaujėntė'', o paspauskėt ''Ctrl-F5''; '''Konqueror:''' paprastiausē paspauskėt ''Perkrautė'' mīgtoka, o paspauskėt ''F5''; '''Opera''' nauduotuojam gal prireiktė pėlnā ėšvalītė anū rėnktovė ''Rakondā→Nustatīmā''.",
-       "usercssyoucanpreview": "'''Patarėms:''' Nauduokit „Ruodītė parvaiza“ mīgtoka, kū ėšmiegintomiet sava naujaji CSS priš ėšsaugont.",
-       "userjsyoucanpreview": "'''Patarėms:''' Nauduokit „Ruodītė parvaiza“ mīgtoka, kū ėšmiegintomiet sava naujaji JS priš ėšsaugont.",
+       "usercssyoucanpreview": "'''Patarėms:''' Nauduokat „{{int:showpreview}}“ mīgtoka, kū ėšmiegintomiet sava naujaji CSS prīš anou ėšsaugont.",
+       "userjsyoucanpreview": "'''Patarėms:''' Nauduokat „{{int:showpreview}}“ mīgtoka, kū ėšmiegintomiet sava naujaji JS prīš anou ėšsaugont.",
        "usercsspreview": "'''Napamirškėt, kū Tamsta tėk parveizėt sava nauduotoja CSS, ans da nabova ėšsauguots!'''",
        "userjspreview": "'''Nepamirškėt, kū Tamsta tėk testoujat/parvaizėt sava nauduotoja ''JavaScript'', ans da nabova ėšsauguots!'''",
        "userinvalidcssjstitle": "'''Diemesė:''' Nė juokės ėšruodos „$1“. Napamirškėt, kū sava .css ėr .js poslapē nauduo pavadėnėma mažuosiomės raidiemis, pvz., Nauduotuos:Foo/vector.css, o ne Nauduotuos:Foo/Vector.css.",
        "updated": "(Atnaujėnta)",
        "note": "'''Žėniuo:'''",
-       "previewnote": "'''Nepamėrškėt, kū tas tėktās pervaiza, pakeitėmā da nier ėšsauguotė!'''",
-       "continue-editing": "Dėrbtė tuoliau",
+       "previewnote": "'''Napamirškat, kū tas tėktās tier parvaiza, pakeitėmā da nier ėšsauguoti!'''",
+       "continue-editing": "Dėrbtė tūliaus",
        "previewconflict": "Šėta parvaiza paruod teksta ėš vėršotinėjė teksta redagavėma lauka tēp, kāp ans bus ruodoms, jei pasirinksėt anū ėšsauguotė.",
-       "session_fail_preview": "'''Atsiprašuom! Mes nagalėm vīkdītė Tamstas keitėma diel sesėjės doumenū praradima.\nPrašuom pamiegintė vielēk. Jei šėtā napaded, pamieginkėt atsėjongtė ėr prėsėjongtė atgal.'''",
-       "session_fail_preview_html": "'''Atsėprašuom! Mes nagalėm apdoroutė Tamstas keitėma diel sesėjės doumenū praradėma.'''\n''Kadaogi šėtom pruojekte grīnasės HTML īr ijongts, parveiza īr pasliepta kāp atsargoma prėimonė priš JavaScript atakas.''\n'''Jei tā teisiets keitėma bandīms, prašuom pamiegint viel. Jei šėtā napaded, pamieginkėt atsėjongtė ėr prėsėjongtė atgal.'''",
+       "session_fail_preview": "'''Atsiprašuom! Mes nagalam ožrašītė Tamstas keitėma diel sesėjės doumenū praradima.\nPrašuom pamiegintė vielek. Jeb tas namacīj, pamieginkat atsijongtė ė prisijongtė apent.'''",
+       "session_fail_preview_html": "'''Atsiprašuom! Mes nagalam apdirbtė Tamstas keitėma diel sesėjės doumenū praradėma.'''\n''Ka tamė pruojektė grīnasis HTML īr ijongts, parveiza īr pakavuota kap atsargoms prīš JavaScript poulėmus.''\n'''Je tā teisiets keitėma miegėnėms, prašuom pamiegintė apent. Je tas namacīj, pamieginkėt atsijongtė ė prisijongtė apent.'''",
        "editing": "Taisuoms straipsnis - $1",
        "creating": "Dėrbama $1",
        "editingsection": "Keitams $1 (skėrsnelis)",
        "editingold": "'''Atėdės: Tamsta keitat ne vielībiausi poslapė atmaina.\nJēgo ėšsauguosat sava pakeitėmus, īkondin darītė pakeitėmā prapols.'''",
        "yourdiff": "Skėrtomā",
        "copyrightwarning": "Žėnuokat, ka vėsks, kas patenk i {{SITENAME}}, īr laikuoma pavėišėnto vagol $2 (platiau - $1). Jēgo nenuorat, ka Tamstas duovis būtom ba gailesė keitams ė skleidams, nerašīkat čė.<br />\nTamsta tēpuogi pasėžadat, ka tas īr Tamstas patėis rašīts torėnīs aba parrašīts nug vėišū aba panašiū liousū vėitu.\n'''NEDIEKAT AUTUORĖNIEM TEISIEM APSERGIETU DARBŪ BA LEIDĖMA!'''",
-       "copyrightwarning2": "Žėnuokat, ka vėsks, kas patenk i {{SITENAME}}, gal būtė keitama ė trėnama. Jēgo nenuorat, ka Tamstas duovis būtom ba gailesė keitams ė skleidams, nerašīkat čė.<br />\nTamsta tēpuogi pasėžadat, ka tas īr Tamstas patėis rašīts torėnīs aba parrašīts nug vėišū aba panašiū liousū vėitu.\n'''NEDIEKAT AUTUORĖNIEM TEISIEM APSERGIETU DARBŪ BA LEIDĖMA!'''",
+       "copyrightwarning2": "Žėnuokat, ka vėskos, kas pakliūn i {{SITENAME}}, gal būtė keitama ė trėnama. Jēgo nenuorat, ka Tamstas duovis būtom ba gailesė keitams ė skleidams, nerašīkat čė.<br />\nTamsta tepuogė pasižadat, ka tas īr Tamstas patėis rašīts torėnīs aba parrašīts nug vėišū aba panašiū liousū vėitu.\n'''NEDIEKAT AUTUORĖNIEM TEISIEM APSERGIETU DARBŪ BA LEIDĖMA!'''",
        "readonlywarning": "'''DIEMESĖ: Doumenū bazė bova ožrakėnta teknėnē pruofilaktėkā,\ntudie negaliesėt ėšsauguotė sava pakeitėmu daba. Tamsta galėt nosėkopėjoutė teksta i tekstėni faila\nė paskum ikeltė ana čė.'''",
        "protectedpagewarning": "'''DIEMESĖ: Šėts poslapis īr ožrakints ėr anū redagoutė gal tėk admėnėstratuorė teises torėntīs prietelē.'''",
        "semiprotectedpagewarning": "'''Pastebiejėms:''' Šėts poslapis bova ožrakėnts ėr anuo gal redagoutė tėk regėstroutė nauduotojā.",
        "postedit-confirmation-saved": "Tamstas padėrbts pakeitėms ėšsauguots īr.",
        "edit-already-exists": "Nie galam padėrbtė poslapė. Ons jau īr.",
        "defaultmessagetext": "Tekstos kāp prėklaus",
+       "content-model-wikitext": "viki tekstos",
+       "content-model-text": "paprasts tekstos",
+       "content-model-javascript": "JavaScript",
+       "content-json-empty-object": "Dīks dākts",
        "post-expand-template-inclusion-warning": "Perspiejėms: Šabluonu īterpėma dėdoms īr par dėdelis.\nKāp katrėi šabluonā nebus ītrauktė.",
        "post-expand-template-inclusion-category": "Poslapē, kur šabluonu īterpėma dėdoms viršėjams",
        "post-expand-template-argument-warning": "Perspiejėms: Tas poslapis tor nuors vėina šabluona argomenta, katros tor per dėdli ėšplietėma dėdoma.\nTė argomentā bova praleistė.",
        "history-feed-title": "Versėju istuorėjė",
        "history-feed-item-nocomment": "$1 $2",
        "history-feed-empty": "Prašuoms poslapis nēgzėstuo.\nAns galiejė būtė ėštrėnts ėš pruojekta, aba parvardėnts.\nPamiegīkėt [[Special:Search|ėiškoutė pruojektė]] sosėjosiu naujū poslapiu.",
+       "rev-deleted-comment": "(keitėma aprašīms ėštrints)",
+       "rev-deleted-user": "(nauduotuoja vards ėštrints)",
        "rev-delundel": "ruodītė/kavuotė",
        "rev-showdeleted": "ruodītė",
        "revisiondelete": "Trintė/atkortė versėjės",
+       "revdelete-show-file-confirm": "A ėš tėkrā nuorat parveizietė ėštrinta abruozdielė „<nowiki>$1</nowiki>“ $2 $3 atmaina?",
        "revdelete-show-file-submit": "Tēp",
+       "revdelete-selected-text": "[[:$2]] {{PLURAL:$1|pasirinkts atmains|pasirinkti atmainā}}:",
        "logdelete-selected": "{{PLURAL:$2|Pasėrinkts|Pasėrinktė|Pasėrinktė}} $1 istuorėjės {{PLURAL:$2|atėtėkims|atsėtėkimā|atsėtėkimā}}:",
+       "revdelete-legend": "Nūstatītė veizėmoma aprėbuojėmus",
+       "revdelete-hide-text": "Atmaina tekstos",
+       "revdelete-hide-image": "Kavuotė abruozdielė torėni",
+       "revdelete-hide-name": "Kavuotė tiksla ė doumenis",
        "revdelete-hide-comment": "Keitėma pāiškėnėms",
        "revdelete-hide-user": "Nauduotojė vardos/IP adresos",
+       "revdelete-radio-same": "(namainītė)",
+       "revdelete-radio-set": "Pakavuots",
+       "revdelete-radio-unset": "Veizėms",
        "revdelete-unsuppress": "Šalėntė apribuojėmos atkortuos versėjės",
+       "revdelete-log": "Dingstės:",
        "revdel-restore": "Keistė veizėmuma",
        "pagehist": "Poslapė istuorėjė",
        "deletedhist": "Ėštrinta istuorėjė",
        "mergehistory-from": "Kėlėma poslapisː",
        "mergehistory-into": "Tiksla poslapisː",
        "mergehistory-done": "$3 $1 versėju siekmėngā sojongta so [[:$2]].",
+       "mergehistory-autocomment": "[[:$1]] parnešts ont [[:$2]]",
+       "mergehistory-comment": "[[:$1]] parnešts ont [[:$2]]: $3",
+       "mergehistory-reason": "Dingstės:",
        "revertmerge": "Atskėrtė",
        "history-title": "Poslapė „$1“ istuorėjė",
        "difference-title": "$1 – skėrtoms terp pakeitėmu.",
        "searchprofile-advanced-tooltip": "Ėiškoutė skėrtingūs vardū sėtīs",
        "search-result-size": "$1 ({{PLURAL:$2|1 žuodis|$2 žuodē|$2 žuodiu}})",
        "search-result-category-size": "{{PLURAL:$1|1 narīs|$1 nariū}} ({{PLURAL:$2|1 subkateguorėjuo|$2 subkateguorėju}}, {{PLURAL:$3|1 fails|$3 failu}})",
-       "search-redirect": "(nosokėms $1)",
+       "search-redirect": "(nūsokėms ėš $1)",
        "search-section": "(skėrsnis $1)",
        "search-category": "(kateguorėjė $1)",
        "search-file-match": "(atėtėnk abruozdielė torėni)",
        "prefs-rc": "Vielībė̅jė pakeitėmā",
        "prefs-watchlist": "Keravuojamu sārašos",
        "prefs-editwatchlist": "Keistė keravuojamu sāroša",
+       "prefs-editwatchlist-label": "Mainītė keravuojamu poslapiu īrašėmus:",
        "prefs-editwatchlist-clear": "Ėštrintė keravuojamu sāroša",
        "prefs-watchlist-days": "Kėik dėinū ruodītė keravuojamu sārošė:",
        "prefs-watchlist-days-max": "(daugiausē $1 {{PLURAL:$1|dėina|dėinas|dėinū}})",
        "prefs-watchlist-edits-max": "Dėdliausis skaitlios: 1000",
        "prefs-misc": "Ivairė nustatīmā",
        "prefs-resetpass": "Keistė slaptažuodi",
-       "prefs-changeemail": "Keistė el. pašta adresa",
+       "prefs-changeemail": "Mainītė aba ėšimtė al. pašta adresa",
        "prefs-setemail": "El. pašta adresa parkeitėms",
        "prefs-email": "El. pašta nustatīmā",
        "prefs-rendering": "Ėšruoda",
        "columns": "Štolpalē:",
        "searchresultshead": "Paėiškuos nustatīmā",
        "stub-threshold": "Minimums <a href=\"#\" class=\"stub\">nabėngta poslapė</a> fuormatavėmō:",
+       "stub-threshold-sample-link": "pavīzdīs",
        "stub-threshold-disabled": "Ėšjongta īr",
        "recentchangesdays": "Ruodomas dėinas vielībūju pakeitėmu sārošė:",
        "recentchangesdays-max": "(daugiausē $1 {{PLURAL:$1|dėina|dėinū|dėinas}})",
        "prefs-files": "Abruozdielē",
        "prefs-custom-css": "Asabėšks CSS",
        "prefs-custom-js": "Asabėšks JavaScript",
+       "prefs-common-css-js": "Bendros CSS/JavaScript vėsuom aplinkuom:",
+       "prefs-reset-intro": "Čiuonās galat grōžintė vėsus sava nūstatīmus ont pradėniu (kap būn tiktās prisijongus).\nTas dalīks nab'atšaukiams.",
        "prefs-emailconfirm-label": "Tėkrā tuokis el. paštos?",
        "youremail": "El. paštos:",
        "username": "{{GENDER:$1|Nauduotuojė vards}}:",
        "yourlanguage": "Aplėnkuos kalba:",
        "yourvariant": "Torėnė kalba:",
        "yournick": "Pasėrinkts slapīvardis:",
+       "prefs-help-signature": "Kap rašuot kon tās i aptarėmu poslapius, pasirašīkat tap: \"<nowiki>~~~~</nowiki>\". Tas dākts atvirs i Tamstas paraša ė parašīma čiesa znuoka.",
        "badsig": "Neteisings parašas; patėkrinkėt HTML žīmės.",
        "badsiglength": "Tamstas parašos īr par ėlgs.\nAna gal sodarītė ne daugiau kāp $1 {{PLURAL:$1|sėmbuolis|sėmbuolē|sėmbuoliu}}.",
        "yourgender": "Lītės:",
-       "gender-unknown": "Nier nuruodīta",
+       "gender-unknown": "Nier nūruodīta",
        "gender-male": "Vīrs",
        "gender-female": "Muoterėška",
+       "prefs-help-gender": "Gėmėnies pasirinkėms nie būtėns.\nJēb ana nūruodīsat, svetainės aplinka kreipsis i Tamsta palē Tamstas gėmėnė. \nTas būs vėsiem žėnuoma.",
        "email": "El. paštos:",
-       "prefs-help-realname": "Tėkrs vards nier privaluoms, vuo jēgo Tamsta ana ivesėt, ons bus nauduojams Tamstas darba pažīmiejėmō.",
+       "prefs-help-realname": "Tėkros vards nier privaluoms, ale jēgo Tamsta ana ivesėt, ons bus nauduojams Tamstas darba pažīmiejėmou.",
        "prefs-help-email": "El. pašta adresos nier būtėns, bat ons leid Tamstā gautė naujė slaptažuodi, jēgo pamėršuot kuoks ons bova, ė tēpuogi Tamsta galėt leistė kėtėims pasėiktė Tamsta par Tamstas nauduotuojė aba nauduotuojė aptarėma poslapi tāp, ka anėi nežėnuotom Tamstas el. pašta adresa.",
        "prefs-help-email-required": "Rēk el. pašta adresa",
        "prefs-info": "Pagrindėnės žėnės",
        "prefs-displayrc": "Ruodītė nustatīmus",
        "prefs-displaywatchlist": "Ruodītė nustatīmus",
        "prefs-diffs": "Skėrtomā",
+       "prefswarning-warning": "Tamsta pamainėt sava nūstatīmus, ale anūm da naėšsauguojėt.\nJēb paliksat poslapi napaspaudus ont $1, Tamstas nūstatīmā napasikeis.",
        "userrights": "Nauduotuoju teisiu valdīms",
        "userrights-lookup-user": "Tvarkītė nauduotuojė gropės",
        "userrights-user-editname": "Iveskėt nauduotuojė varda:",
-       "editusergroup": "Redagoutė nauduotuojė gropes",
+       "editusergroup": "Mainītė nauduotuoja gropės",
        "editinguser": "Teisiu keitėms {{GENDER:$1|Nauduotuojō}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Keistė nauduotuoju gropes",
-       "saveusergroups": "Sauguotė nauduotuoju gropes",
+       "saveusergroups": "Sauguotė nauduotuoja gropės",
        "userrights-groupsmember": "Narīs:",
        "userrights-reason": "Dingstės:",
        "group": "Gropė:",
        "grouppage-bureaucrat": "{{ns:project}}:Biorokratā",
        "right-read": "Skaitītė poslapius",
        "right-edit": "Keistė poslapius",
+       "right-minoredit": "Žīmietė ketėmus kap mažus",
+       "right-move": "Parvadintė poslapius",
+       "right-move-subpages": "Parvadinė poslapius ėr anūm pūposlapius",
+       "right-move-categorypages": "Parvadintė kateguorėjės",
+       "right-movefile": "Parvadintė abruozdielius",
        "right-upload": "Ikeltė failus",
        "right-writeapi": "Nauduotė API rašīmō",
        "right-delete": "Trintė poslapius",
        "right-browsearchive": "Ėiškuotė ėštrintū poslapiu",
        "right-undelete": "Tou poslapi padėrbtė apent",
+       "grant-createeditmovepage": "Dėrbtė, keistė ė parvadintė poslapius",
        "newuserlogpage": "Nauduotuojė kūrėma sārašos",
        "rightslog": "Nauduotuoju teisiu istuorėjė",
        "rightslogtext": "Pateikiams nauduotuoju teisiu pakeitėmu sārašos.",
        "action-move-categorypages": "parvadintė kateguorėjes",
        "action-movefile": "parvadintė šėta faila",
        "action-upload": "ikeltė šėta faila",
-       "action-delete": "trintė ton poslapė",
+       "action-delete": "trintė ton poslapi",
        "action-undelete": "atkortė ta poslapi",
        "action-patrol": "pažīmietė kėtū keitėmus kāp patikrėntus",
        "action-userrights": "keistė vėsū nauduotuoju teises",
+       "action-purge": "atšvėižintė poslapi",
        "nchanges": "$1 {{PLURAL:$1|pakeitėms|pakeitėmā|pakeitėmu}}",
+       "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|nug paskotėnė apsilonkėma}}",
        "enhancedrc-history": "istuorėjė",
        "recentchanges": "Vielībė̄jė pakeitėmā",
-       "recentchanges-legend": "Vielībūju pakeitėmu pasėrinkėmā",
+       "recentchanges-legend": "Vielībūju pakeitėmu pasirinkėmā",
        "recentchanges-summary": "Keravuokat patius vielībuosius wiki pakeitėmus tamė poslapie.",
+       "recentchanges-noresult": "Par nūruodīta čiesa napradėrbts anēvėins Tamstas nuorams pakeitėms.",
        "recentchanges-feed-description": "Keravuokėt patius vielībiausius pakeitėmus pruojektō tamė šaltėnī.",
        "recentchanges-label-newpage": "Šėtuo keitėmuo padėrbts naus poslapis",
        "recentchanges-label-minor": "Tas īr mažos pataisīms",
        "recentchanges-label-plusminus": "Anuo baitu skaitliom pakeists straipsnė apmiers",
        "recentchanges-legend-heading": "<strong>Pāiškėnėmā:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (dā veiziekat [[Special:NewPages|vielībūju straipsniu sāroša]])",
+       "recentchanges-submit": "Ruodītė",
        "rcnotefrom": "Apatiuo {{PLURAL:$5|ruodoms pakeitėms|ruodomė pakeitėmā}} nug <strong>$3, $4</strong> (ne daugiau kāp <strong>$1</strong> ruodoma īr).",
        "rclistfrom": "Ruodītė vielībus pakeitėmus pradedont nug $3 $2",
        "rcshowhideminor": "$1 mažus pakeitėmus",
        "rcshowhidebots": "$1 robuotus",
        "rcshowhidebots-show": "Ruodītė",
        "rcshowhidebots-hide": "Kavuotė",
-       "rcshowhideliu": "$1 prėsėjongusiūm nauduotuojūm pakeitėmus",
+       "rcshowhideliu": "$1 prisijongusiu nauduotuoju pakeitėmus",
        "rcshowhideliu-show": "Ruodītė",
        "rcshowhideliu-hide": "Kavuotė",
        "rcshowhideanons": "$1 nažėnomus nauduotuojus",
        "rcshowhidemine-show": "Ruodītė",
        "rcshowhidemine-hide": "Kavuotė",
        "rcshowhidecategorization": "$1, kap poslapiam doud kateguorėjės",
+       "rcshowhidecategorization-show": "Ruodītė",
+       "rcshowhidecategorization-hide": "Kavuotė",
        "rclinks": "Ruodītė vielībus $1 pakeitėmu par paskuojės $2 dėinas<br />$3",
        "diff": "skėrt",
        "hist": "ist",
        "recentchangeslinked-summary": "Tamė specēliam poslapi sogol vielībė̄jė pakeitėmā poslapiūs, i katrūs īr nuruodoma. Poslapē ėš Tamstas [[Special:Watchlist|keravuojamu sāroša]] ėšruod '''stuorā'''.",
        "recentchangeslinked-page": "Poslapė pavadėnėms:",
        "recentchangeslinked-to": "Ruodītė anūs poslapiu pakeitėmus, katrėi prėgol prī douta poslapė",
+       "recentchanges-page-added-to-category": "[[:$1]] pridieta i kateguorėjė",
        "upload": "Ožkrautė abruozdieli",
        "uploadbtn": "Ikeltė faila",
        "reuploaddesc": "Sogrīžtė i ikielima fuorma.",
        "upload-file-error-text": "Ivīka vėdėnė klaida bandont sokortė laikinaji faila serverī. Prašuom sosėsėiktė so sistemuos admėnėstratuoriom.",
        "upload-misc-error": "Nažėnuoma ikielėma klaida",
        "upload-misc-error-text": "Ivīka nežėnuoma klaida vīkstont ikielėmō. Prašuom patėkrėnt, kū URL teisėngs teipuogi pasėikiams ėr pamiegīkit viel. Jē bieda ėšlėik, sosėsėikėt so sistemuos admėnėstratuoriom.",
+       "upload-http-error": "Nūtėka HTTP klaida: $1",
        "upload-dialog-title": "Ožkrautė abruozdieli",
        "upload-dialog-button-cancel": "Pabengtė",
+       "upload-dialog-button-back": "Atgaliuos",
        "upload-dialog-button-done": "Padėrbt",
        "upload-dialog-button-save": "Ėšsauguotė",
        "upload-dialog-button-upload": "Ožkrautė",
        "upload-form-label-infoform-description": "Aprašīms",
        "upload-form-label-usage-title": "Nauduojėms",
        "upload-form-label-usage-filename": "Abruozdielė pavadėnėms",
+       "upload-form-label-own-work": "Tas muona darbs ī",
+       "upload-form-label-infoform-categories": "Kateguorėjės",
+       "upload-form-label-infoform-date": "Čiesos",
+       "upload-form-label-own-work-message-generic-local": "Sotinko, ka ikeldams ton abruozdieli darou ton palē {{SITENAME}} taisīklės.",
        "backend-fail-notexists": "Abruozdielė „$1“ nie.",
        "backend-fail-alreadyexists": "Abruozdielis „$1“ jau īr.",
+       "uploadstash-thumbnail": "veizietė somažinta",
        "img-auth-accessdenied": "Ožgint prė̄tė",
        "upload-curl-error6": "Napavīkst pasėiktė URL",
        "upload-curl-error6-text": "Pataikts URL nagal būt pasėikts. Prašuom patėkrėntė, kū URL īr teisings ėr svetainė veik.",
        "upload_source_file": " (fails Tamstas kompioterī)",
        "listfiles-delete": "trintė",
        "listfiles-summary": "Tas specēlus poslapis ruod vėsus ikeltus failus.\nPalē numatīma paskiausē ikeltė failā īr ruoduomė sāroša vėršou.\nPaspaude ont štolpelė ontraštės pakeisėt ėšruokavėma.",
+       "listfiles-userdoesnotexist": "Nie tuokė nauduotuoja varda kap „$1“",
        "imgfile": "abruozdielis",
        "listfiles": "Failu sārašos",
        "listfiles_thumb": "Somažints",
        "linkstoimage": "{{PLURAL:$1|Ons poslapis|Anėi poslapē}} ruod ton abruozdielin:",
        "nolinkstoimage": "Abruozdielėp neruod anėjuoks poslapis.",
        "morelinkstoimage": "Veizietė [[Special:WhatLinksHere/$1|daugiau nūruodu]] ton abruozdielėn.",
+       "linkstoimage-redirect": "$1 (abruozdielė nūsokėms) $2",
        "sharedupload": "Tas fails īr ėš $1 ė gal būtė nauduojams kėtūs pruojektūs.",
        "sharedupload-desc-here": "Tas abruozdielis īr nug $1 ė gal būtė nauduojams kėtūs poslapiūs.\nŽinės nug [$2 abruozdielė aprašīma poslapė] prėgol apatiuo.",
        "sharedupload-desc-create": "Šėts abruozdielis īr ėš $1 ė gal būtė nauduonams kėtūs pruojektūs. \nMaž nuorat pamainītė anuo aprašīma [$2 anuo poslapie]?",
        "download": "parsėsiūstė",
        "unwatchedpages": "Nekeravuojėmė poslapē",
        "listredirects": "Paradresavėmu sārašos",
+       "listduplicatedfiles": "Abruozdieliu so doblėkatās sārašos",
        "unusedtemplates": "Nenauduojamė šabluonā",
        "unusedtemplatestext": "Tas poslapis ruod sāraša poslapiu, esontiu vardū srėtie „{{ns:template}}“, katrėi nie iterptė i juoki kėta poslapi. Nepamėrškat patikrėntė kėtū nūruodu prīš anas ėštrėnont.",
        "unusedtemplateswlh": "kėtas nūruodas",
        "randompage": "Bikuoks poslapis",
        "randompage-nopages": "Šėtuo vardū srėti nier anėjuokiu poslapiu.",
        "randomincategory": "Bikuoks poslapis kateguorėjuo",
+       "randomincategory-invalidcategory": "\"$1\" nie gers kateguorėjės pavadėnėms.",
+       "randomincategory-nopages": "[[:Category:$1|$1]] kateguoriejuo poslapiu nie.",
        "randomincategory-category": "Kateguorėjė:",
        "randomincategory-legend": "Bikuoks poslapis kateguorėjuo",
        "randomincategory-submit": "Ēk",
        "randomredirect": "Bikuoks nusokims",
-       "randomredirect-nopages": "Šėtuo vardū srėtie nie anėjuokiu nusokėmu.",
+       "randomredirect-nopages": "Šėtuo vardū srėtie $1 nie anėjuokiu nūsokėmu.",
        "statistics": "Skaitlē",
        "statistics-header-pages": "Poslapiu sklaitlē",
        "statistics-header-edits": "Keitėmu skaitlē",
        "specialloguserlabel": "Nauduotuos:",
        "speciallogtitlelabel": "Pavadėnims:",
        "log": "Specēliūju vīksmū istuorėjė",
-       "all-logs-page": "Vėsos istuorėjės",
+       "all-logs-page": "Vėsas istuorėjės",
        "alllogstext": "Bėndra idietu failu, ėštrīnėmu, ožrakėnėmu, bluokavėmu ė prėvėlėju soteikėmu istuorėjė.\nĪr galėmībė somažintė rezoltatu skaitliu patėkslėnont vēksma tėpa, nauduotuojė a sosėjosė poslapė.",
        "logempty": "Istuorėjuo nier anėjuokiū atitinkontiu atsėtėkimu.",
        "log-title-wildcard": "Ėiškuotė pavadinėmu, katrė prasėded šėtuo teksto",
        "showhideselectedlogentries": "Ruodītė/kavuotė sāraša ponktus, katrūs pasėrėnkot",
        "checkbox-select": "Rinktėis: $1",
        "checkbox-all": "Viskos",
+       "checkbox-none": "Nieka",
+       "checkbox-invert": "Apverstė",
        "allpages": "Vėsė straipsnē",
        "nextpage": "Kėts poslapis ($1)",
        "prevpage": "Onkstesnis poslapis ($1)",
        "categoriesfrom": "Ruodītė kateguorėjės pradedont nu:",
        "deletedcontributions": "Ėštrints nauduotuojė duovis",
        "deletedcontributions-title": "Ėštrints nauduotuojė duovis",
-       "linksearch": "Ėšuorėnės nūruodas",
+       "sp-deletedcontributions-contribs": "duovē",
+       "linksearch": "Ėšuorėniu nūruodu ėiškuojėms",
        "linksearch-ns": "Vardū srėtės:",
        "linksearch-ok": "Ėiškuotė",
        "linksearch-line": "$1 īr sosėits ėš $2",
        "listusers-noresult": "Nerast anėjuokiū nauduotuoju.",
        "listusers-blocked": "(ožgints)",
        "activeusers": "Vēkōs nauduotuojē",
-       "activeusers-hidebots": "Kavuotė robuotus",
-       "activeusers-hidesysops": "Kavuotė admėnėstratorius",
+       "activeusers-count": "$1 {{PLURAL:$1|darbs|darbū}} par {{PLURAL:$3|paskotėnė dėina|$3 paskotėnės dėinas|$3 paskotėniu dėinū}}",
+       "activeusers-from": "Ruodītė nauduotuojus pradedont nug:",
        "activeusers-noresult": "Nerast anėjuokiu nauduotuoju.",
+       "activeusers-submit": "Ruodītė darbštius nauduotuojus",
        "listgrouprights": "Nauduotuoju gropiu teisės",
        "listgrouprights-group": "Gropė",
        "listgrouprights-rights": "Teisės",
        "listgrouprights-members": "(nariū sārašos)",
+       "listgrouprights-namespaceprotection-namespace": "Vardū srėtės",
+       "listgrants-grant": "Leidėms",
+       "listgrants-rights": "Teisės",
        "trackingcategories": "Pruogramėnės keravuojėma kateguorėjės",
        "mailnologin": "Nier adresa",
        "mailnologintext": "Tamstā reik būtė [[Special:UserLogin|prisėjongosiam]]\nė tor būtė ivests teisings el. pašta adresos Tamstas [[Special:Preferences|nustatīmuos]],\nkū siōstomiet el. gruomatas kėtėm nauduotuojam.",
        "wlheader-enotif": "El. pašta primėnėmā ijongtė īr.",
        "wlheader-showupdated": "Poslapē, katrėi pakeistė nu Tamstas paskotėnė apsėlonkėma čiesa anūs, īr pažīmietė '''pastuorintā'''",
        "wlnote": "Ruoduoma '''$1''' paskotėniu pakeitėmu, atlėktū par '''$2''' paskotėniu adīnu.",
-       "wlshowlast": "Ruodītė paskotėniu $1 adīnu, $2 dėinū a  pakeitėmus",
-       "watchlist-options": "Keravuojamu sāroša pasėrinkėmā",
+       "wlshowlast": "Ruodītė paskotėniu $1 adīnu, $2 dėinū pakeitėmus",
+       "watchlist-hide": "Kavuotė",
+       "watchlist-submit": "Ruodītė",
+       "wlshowhideminor": "maži pakeitėmā",
+       "wlshowhidebots": "buotā",
+       "wlshowhideliu": "prisijongė̄ nauduotuojē",
+       "wlshowhideanons": "naprisijongė̄ nauduotuojē",
+       "wlshowhidemine": "mona keitėmā",
+       "watchlist-options": "Keravuojamu sāraša pasirinkėmā",
        "watching": "Kergiama keravuojamu sārošon...",
        "unwatching": "Šalėnama ėš keravuojamu sāraša...",
        "enotif_reset": "Pažīmietė vėsus poslapius kāp aplonkītus",
        "enotif_impersonal_salutation": "{{SITENAME}} nauduotuos",
+       "enotif_subject_deleted": "{{SITENAME}} poslapis $1 bova ėštrints $2",
+       "enotif_subject_created": "{{SITENAME}} poslapis $1 bova padėrbts $2",
+       "enotif_subject_moved": "{{SITENAME}} poslapis $1 bova parvadints $2",
+       "enotif_subject_restored": "{{SITENAME}} poslapis $1 bova grōžints $2",
+       "enotif_subject_changed": "{{SITENAME}} poslapis $1 bova paminīts $2",
+       "enotif_body_intro_deleted": "{{SITENAME}} poslapi $1 $PAGEEDITDATE ėštrīnė $2, veiziekėt $3.",
+       "enotif_body_intro_created": "{{SITENAME}} poslapi $1 $PAGEEDITDATE padėrba $2, veiziekėt vielībiausia atmaina $3.",
+       "enotif_body_intro_moved": "{{SITENAME}} poslapi $1 $PAGEEDITDATE parvadėna $2, veiziekėt vielībiausia atmaina $3.",
+       "enotif_body_intro_restored": "{{SITENAME}} poslapi $1 $PAGEEDITDATE grōžėna $2, veiziekėt vielībiausia atmaina $3.",
+       "enotif_body_intro_changed": "{{SITENAME}} poslapi $1 $PAGEEDITDATE pamainė $2, veiziekėt vielībiausia atmaina $3.",
+       "enotif_lastvisited": "Veiziekėt $1, ka žėnuotomėt vėsus pakeitėmus nug Tamstas paskotėnė apsilonkīma.",
+       "enotif_lastdiff": "Veiziekėt $1, ka paveizietomėt ton pakeitėma.",
        "enotif_anon_editor": "anuonėminis nauduotuos $1",
        "created": "sokūrė",
        "changed": "pakeitė",
        "deletepage": "Trintė poslapi",
        "confirm": "Tėkrā tāp",
        "excontent": "bovis torėnīs: „$1“",
-       "excontentauthor": "bovis torėnīs: „$1“ (dėrba tėktās „[[Special:Contributions/$2|$2]]“)",
+       "excontentauthor": "bovė̄s torėnīs: „$1“ (dėrba tėktās „[[Special:Contributions/$2|$2]] [[User talk:$2|aptarėms]]“)",
        "exbeforeblank": "prīš ėštrinont torėnīs bova: „$1“",
        "delete-confirm": "Trintė „$1“",
        "delete-legend": "Trīnėms",
        "historywarning": "<strong>Atėdės:</strong> Poslapis, katron nuorat ėštrintė, bova pakeists $1 {{PLURAL:$1|sīki|sīkius|sīkiu}}:",
+       "historyaction-submit": "Ruodītė",
        "confirmdeletetext": "Tamsta pasėrėnkuot ėštrėntė poslapi a abruozdieli draugum so vėsa anuo istuorėjė.\nPrašuom patvėrtėntė, kū Tamsta tėkrā nuorėt šėtu padarītė, žėnuot aple galėmus padarėnius, ė kū Tamsta šėtā daruot atsėžvelgdamė i [[{{MediaWiki:Policy-url}}|puolitėka]].",
        "actioncomplete": "Vēksmos padėrbts īr",
        "actionfailed": "Vēksmos atšaukts īr",
        "deletereasonotherlist": "Kėta dingstės",
        "deletereason-dropdown": "* Tonkiausės ėštrėnėma dingstisː\n** Šiokšlėnėms\n** Zaunū/bikuo rašīms\n** Pažeistas dėrbieju teisės\n** Patėis nauduotuojė prašīms\n** Bluogs poslapė nusokėms",
        "delete-edit-reasonlist": "Mainītė trīnėma dingstis",
+       "deleteprotected": "Tamsta nagalėt ėštrintė ton poslapė, ba ons apsergiets ī.",
+       "deleting-backlinks-warning": "<strong>Atėduos:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Kėti poslapē]] tora nūruodas aba apjėm ton poslapi, katra nuorėt trintė.",
        "rollback": "Atmestė pakeitėmus",
        "rollbacklink": "atmestė",
        "rollbacklinkcount": "sogrōžintė $1 {{PLURAL:$1|pakeitėma|pakeitėmo|pakeitėmus|pakeitėmu}}",
        "editcomment": "Padėrbėma paāškėnėms bova: <em>$1</em>.",
        "revertpage": "Atmests [[Special:Contributions/$2|$2]] ([[User talk:$2|aptarėms]]) pakeitėms; sogrōžints atmains, katron padėrba nauduotuos [[User:$1|$1]]",
        "rollback-success": "Atmestė $1 padėrbtė keitėmā; grōžints $2 padėrbts atmains.",
+       "rollback-success-notify": "Atmestė $1 padėrbtė keitėmā; grōžints $2 padėrbts atmains. [$3 ruodītė keitėmus]",
+       "sessionfailure-title": "Sesėjės klaida",
        "sessionfailure": "Atruod ka īr biedū so Tamstas prėsėjongėmo; tas vēksmos bova grōžints kāp atsargoma prėimonė nu sesėjės vuogėma.\nPrašoum mīgtė „atgal“ ėr parkrautė poslapi ėš katruo atiejėt, ė pamieginkėt apent.",
        "changecontentmodel-title-label": "Poslapė pavadėnėms",
        "changecontentmodel-reason-label": "Dingstės:",
        "modifiedarticleprotection": "pamainīts „[[$1]]“ apserguos miers",
        "unprotectedarticle": "nujėmė apserga nug „[[$1]]“",
        "movedarticleprotection": "apsergiejėma nustatīma parkeltė nug \"[[$2]]\" i \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|Apsergiejė}} \"[[$1]]\"",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Pamainė}} \"[[$1]]\" apserga",
+       "unprotectedarticle-comment": "{{GENDER:$2|Bengė}} \"[[$1]]\" apserga",
        "protect-title": "Nustatuoms apsauguojėma līgis poslapiō „$1“",
+       "protect-title-notallowed": "Veizietė \"$1\" apserga",
        "prot_1movedto2": "Straipsnis [[$1]] parvadints i [[$2]]",
        "protect-legend": "Tėkrā tuokis apsergiejėms?",
        "protectcomment": "Dingstės:",
        "sp-contributions-username": "IP adresos a nauduotuojė vards:",
        "sp-contributions-toponly": "Ruodītė tėktās paskiausius keitėmus",
        "sp-contributions-newonly": "Ruodītė tėktās tūs keitėmus, katrās padėrbtė straipsnē",
+       "sp-contributions-hideminor": "Kavuotė mažus pakeitėmus",
        "sp-contributions-submit": "Ėiškuotė",
        "whatlinkshere": "Sosėjė̄ straipsnē",
        "whatlinkshere-title": "Poslapē, katrėi ruod i \"$1\"",
        "whatlinkshere-hidelinks": "$1 nūruodas",
        "whatlinkshere-hideimages": "$1 abruozdieliu nūruodas",
        "whatlinkshere-filters": "Kuošeklē",
+       "whatlinkshere-submit": "Ēk",
        "block": "Ožgintė nauduotuoji",
        "unblock": "Nauduotuojė ožgīnėma bengtė",
        "blockip": "Ožgintė {{GENDER:$1|nauduotoji}}",
        "blockip-legend": "Ožgintė nauduotuoji",
-       "blockiptext": "Nauduokėt šėta fuorma noriedamė oždraustė redagavėma teises nuruodīto IP adreso a nauduotuojo. Tas torietu būt atlėikama tam, kū sostabdītomiet vandalėzma, ė vagol [[{{ns:project}}:Puolitėka|puolitėka]].\nŽemiau nuruodīkėt tėkslē prižastė.",
+       "blockiptext": "Nauduokėt šėta skvarma kap nuorėt ožgintė redagavėma teisės nūruodītou IP adresou a nauduotuojou. Tas torietom būtė dėrbama, ka apsergietomėt poslapius nug gadėnėma, ė palē [[{{MediaWiki:Policy-url}}|sotarėma]].\n\nKap ožgėnat, nūruodīkėt tikslē, ož kon.",
        "ipaddressorusername": "IP adresos a nauduotuojė vards",
        "ipbexpiry": "Vēkėma čiesos",
        "ipbreason": "Dingstės:",
        "ipbreason-dropdown": "*Tonkiausės ožgīnėma dingstisː\n** Neteisībės rašīms\n** Torėnė trīnims ėš poslapiu\n** Šiokšlėnėms\n** Zaunu/bikuo rašīms i poslapius\n** Gondėnėmā/Pėktžuodiavėmā\n** Nauduojėms daugiaus kāp vėinuos paskīruos\n** Natinkams nauduotuojė vards",
+       "ipb-hardblock": "Nalaistė prisijongosėm nauduotuojėm dėrbtė pakeitėmu ėš ton IP adresa",
        "ipbcreateaccount": "Nelaistė dėrbtė paskīrū",
        "ipbemailban": "Nelaistė nauduotuojō siōstė el. gromatas",
        "ipbenableautoblock": "Autuomatėškā blokoutė tuo nauduotuojė paskiausē nauduota IP adresa, ė bikuokius paskesnius IP adresus, ėš katrū ons miegin redagoutė",
        "ipbsubmit": "Ožgintė ton nauduotuoji",
        "ipbother": "Kėtuoks čiesos",
        "ipboptions": "2 adīnė:2 hours,1 dėina:1 day,3 dėinas:3 days,1 nedielė:1 week,2 nedielė:2 weeks,1 mienou:1 month,3 mienesē:3 months,6 mienesē:6 months,1 metā:1 year,omžėms:infinite",
+       "ipbhidename": "Kavuotė nauduotuoja varda pakeitėmūs ė sārašūs",
        "ipbwatchuser": "Keravuotė tuo nauduotuojė poslapi ėr anuo aptarėma poslapi",
+       "ipb-disableusertalk": "Nalaistė nauduotuojou rašītė i sava aptarėmu poslapi kap ons ožgints ī",
        "ipb-change-block": "Parblokoutė ta nauduotuoja so šėtās nustatīmās",
        "ipb-confirm": "Tėkrā ožgintė?",
        "badipaddress": "Nelaistėns IP adresos",
        "blockipsuccesssub": "Nauduotuos bova ožgints",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] bova ožgints.\n<br />Aplonkīkat [[Special:BlockList|IP ožginėmu istuorėjė]], jēgo nuorat anou parveizietė.",
+       "ipb-blockingself": "Tamsta tūjaus ožginsėt savėi pati! A tėkrā tap nuorėt?",
        "ipb-edit-dropdown": "Mainītė ožgīnėma dingstis",
        "ipb-unblock-addr": "Nug $1 nujėmtė ožgīnėma",
        "ipb-unblock": "Nug nauduotuojė varda a IP adresa nujėmtė ožgīnėma",
        "ipb-blocklist": "Ruodītė vielībousius ožgīnėmus",
        "ipb-blocklist-contribs": "$1 duovis",
+       "ipb-blocklist-duration-left": "palėka $1",
        "unblockip": "Nauduotuojė ožgīnėma bengtė",
        "unblockiptext": "Nauduokėt šėta fuorma, kū atkortomiet rašīma teises\nonkstiau ožbluokoutam IP adresō a nauduotuojō.",
        "ipusubmit": "Ton ožgīnėma nojėmtė",
        "block-log-flags-angry-autoblock": "vēk prapliests ožgīnėms",
        "block-log-flags-hiddenname": "nauduotuojė vards pakavuots īr",
        "ipb_expiry_invalid": "Galiuojėma čiesos nelaistėns.",
+       "ipb_expiry_old": "Galiuojėma čiesos īr praeitie.",
        "ipb_already_blocked": "„$1“ jau ožgints",
        "ipb-needreblock": "$1 jau īr ožblokouts. A nuorėt pakeistė nustatīmus?",
        "ipb-otherblocks-header": "{{PLURAL:$1|Kėts ožgīnėms|Kėtė ožgīnėmā}}",
        "move-page": "Parvadintė $1",
        "move-page-legend": "Poslapė parvadėnėms",
        "movepagetext": "Nauduojont ta skvarma, katra apatiuo īr, parvadinsat poslapi ėr ėšlaikīsat anuo istuorėjė.\nOnkstesnis pavadėnėms palėks nosokėmo - ons ruodīs poslapin naujė varda.\nTamsta esat atsakėngs, ka nūruodas ruodītom tenā, kor ė rēk.\n\nAtminkat, ka poslapis '''nabus''' parvadints, jēgo jau īr poslapis naujo pavadinėmo, tėktās jēgo ons īr dīks aba netor keitėmu istuorėjės.\nTumet, Tamsta galat parvadintė poslapi seniou nauduoto vardo, jēgo priš šėta ons bova par klaida parvadints, ar esontiu poslapiu sogadintė negalat.\n\n'''ATĖDĖS!'''\nJēgo parvadinat tonkē nauduojama poslapi, ta galat prėdėrbtė ėškadas. Tudie kervauokat, ka dėrbat.",
+       "movepagetext-noredirectfixer": "So ton skvarma apatiuo Tamsta parvadinsat poslapi ė parkelsat vėsa anou istuorėjė.\nSens poslapis paliks nūsokėmo i nauja straipsnė varda.\nSotikrinkėt, ka napalėikat [[Special:DoubleRedirects|dvėgobu]] aba [[Special:BrokenRedirects|navēkontiu nūsokėmu]].\nTamsta pasilėikat atsakings, ka nūruodas ė tuoliaus ruodītom tenās, kor ė rēk.\n\nToriekat uomenie, ka poslapis '''nabūs''' parvadins, jēb jau poslapis so tuokio vardo ī (nabentās, ons būtom tėktās nūsokėms ba istuorėjės).\nTas rēšk, ka Tamsta galiesat sogrōžintė poslapi ont sena anou varda, jēb padarīsat klaida.\n\n'''ATĖDĖS:'''\nJēb parvadinat gausē nauduojama poslapi, ta galat prīdėrbtė ėškadas;\nTudie kervauokat, ka dėrbat!",
        "movepagetalktext": "Sosėits aptarėma poslapis bus autuomatėškā parkelts draugom so ano, '''ėšskīrus:''':\n*Poslapis nauju pavadinėmo tor netoštė aptarėma poslapi, a\n*Paliksėt žemiau asontė varnale nepažīmieta.\nŠėtās atviejās Tamsta sava nužiūra torėt parkeltė a apjongtė aptarėma poslapi.",
        "moveuserpage-warning": "<strong>Atėdės:</strong> Tamsta parvadėnsat nauduotuojė poslapi. Žėnuokat, ka tėktās poslapis bat <em>ne patsā nauduotuos</em> bos parvadints.",
        "movecategorypage-warning": "<strong>Atėdės:</strong> Tamsta parvadinsat kateguorėjės poslapi. Žėnuokat, ka tėktas poslapis bos parvadints, bat <em>poslapē, katrėi anon prėgol,</em> tor būtė sokergtė apent.",
        "tooltip-pt-watchlist": "Poslapiu, katrūs Tamsta pasirinkuot keravuotė, sārašos.",
        "tooltip-pt-mycontris": "Tamstas dėrbtū keitėmu sārašos",
        "tooltip-pt-login": "Kvėitam prėsėjongtė, nuors tas ė nie būtėna.",
-       "tooltip-pt-logout": "Atsėjongtė",
+       "tooltip-pt-logout": "Atsijongtė",
        "tooltip-pt-createaccount": "Tamstā kvėitam padėrbtė paskīra ė prėsėjongtė; bat tas nie būtėina",
        "tooltip-ca-talk": "Poslapė torėnė aptarėms",
-       "tooltip-ca-edit": "Taisītė ton poslapė",
+       "tooltip-ca-edit": "Taisītė ton poslapi",
        "tooltip-ca-addsection": "Pradietė naujė skėrsneli",
        "tooltip-ca-viewsource": "Ons poslapis apsergiets īr. Galat tėktās parveiziet kas anamė ožrašīta.",
        "tooltip-ca-history": "Onkstesnė ton poslapė atmainā.",
index 09392ad..6e3d91c 100644 (file)
        "yourpasswordagain": "Ponovo upišite šifru / Поново упишите шифру",
        "createacct-yourpasswordagain": "Potvrdite lozinku/zaporku",
        "createacct-yourpasswordagain-ph": "Unesite lozinku/zaporku ponovno",
-       "remembermypassword": "Upamti moju lozinku na ovom kompjuteru (za maksimum od $1 {{PLURAL:$1|dan|dana}})",
        "userlogin-remembermypassword": "Zapamti prijavu",
        "userlogin-signwithsecure": "Koristite sigurnu vezu",
        "yourdomainname": "Vaš domen:",
        "activeusers-intro": "Ovo je spisak korisnika koji su napravili neku aktivnost u {{PLURAL:$1|zadnji $1 dan|zadnja $1 dana|zadnjih $1 dana}}.",
        "activeusers-count": "{{PLURAL:$1|$1 izmjena|$1 izmjene|$1 izmjena}} u {{PLURAL:$3|posljednji $3 dan|posljednja $3 dana|posljednjih $3 dana}}",
        "activeusers-from": "Prikaži korisnike koji počinju sa:",
-       "activeusers-hidebots": "Sakrij botove",
-       "activeusers-hidesysops": "Sakrij administratore",
        "activeusers-noresult": "Nije pronađen korisnik.",
        "listgrouprights": "Prava korisničkih grupa",
        "listgrouprights-summary": "Slijedi spisak korisničkih grupa na ovoj wiki, s njihovim pravima pristupa.\nO svakoj od njih postoje i [[{{MediaWiki:Listgrouprights-helppage}}|dodatne informacije]].",
        "htmlform-no": "Ne",
        "htmlform-yes": "Da",
        "htmlform-chosen-placeholder": "Odaberi opciju",
-       "sqlite-has-fts": "$1 sa podrškom pretrage cijelog teksta",
-       "sqlite-no-fts": "$1 bez podrške pretrage cijelog teksta",
        "logentry-delete-delete": "$1 je {{GENDER:$2|obrisao|obrisala}} stranicu $3",
        "logentry-delete-restore": "$1 je {{GENDER:$2|vratio|vratila}} stranicu $3",
        "logentry-delete-event": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost {{PLURAL:$5|događaja|$5 događaja}} u evidenciji na $3: $4",
index 71a8157..f84e6e2 100644 (file)
        "yourname": "smiyt o-msxdam:",
        "yourpassword": "awal iḥdan:",
        "yourpasswordagain": "Зawd ara awal iḥdan:",
-       "remembermypassword": "Askti nu ukcum ɣ Urdinaturad (Iɣ kullu tggut $1 {{PLURAL:$1|Ass|Ass}})",
        "yourdomainname": "Taɣult nek",
        "externaldberror": "Imma tlla ɣin kra lafut ɣu ukcumnk ulla urak ittuyskar at tsbddelt lkontnk nbrra.",
        "login": "Kcm ɣid",
index 9d36abb..eafaea6 100644 (file)
        "category-file-count-limited": "ဢၼ်ပဵၼ် {{PLURAL:$1|ၾၢႆႇၼႆႉ|$1 ၾၢႆႇၸိူဝ်းၼႆႉ}} မီးဝႆႉတီႈၼႂ်း တွၼ်ႈၵၼ်ၼႆ့။",
        "listingcontinuesabbrev": "သိုပ်ႇ",
        "index-category": "ၼႃႈလိၵ်ႈ ၸိူဝ်းၸီ့ဝႆ့",
-       "noindex-category": "ၼႃႈလိၵ်ႈ ၸိူဝ်းၸီ့ဝႆ့",
+       "noindex-category": "ၼႃႈလိၵ်ႈၸိူဝ်း ဢမ်ႇမီး တူဝ်ၸီႉ",
        "broken-file-category": "ၼႃႈလိၵ်ႈၸိူဝ်းမီးဝႆႉ ႁဵင်းၵွင်ႉၾၢႆႇဢၼ်လူ့လႅဝ်",
        "about": "လွင်ႈတၢင်း",
        "article": "ၼမ်းၼႂ်း",
        "newwindow": "(ပိုတ်ႇၼင်ႇဝိၼ်းတူဝ်း ဢၼ်မႂ်ႇ)",
        "cancel": "ဢမ်ႇႁဵတ်း",
        "moredotdotdot": "ထႅင်ႈ...",
-       "morenotlisted": "သဵၼ်ႈမၢႆဢၼ်ၼႆႉ ဢမ်ႇတဵမ်ထူၼ်ႈ။",
+       "morenotlisted": "á\80\9eá\80µá\81¼á\80ºá\82\88á\80\99á\81¢á\82\86á\80¢á\81¼á\80ºá\81¼á\82\86á\82\89 á\80¢á\80\99á\80ºá\82\87á\80¢á\81¢á\80\95á\80ºá\82\88á\80\90á\80µá\80\99á\80ºá\80\91á\80°á\81¼á\80ºá\82\88á\81\8b",
        "mypage": "ၼႃႈလိၵ်ႈ",
        "mytalk": "တွၼ်ႈဢုပ်ႇ",
        "anontalk": "တွၼ်ႈဢုပ်ႇ",
        "talk": "တႃႇဢုပ်ႇ",
        "views": "လူတူၺ်း",
        "toolbox": "ၶိူင်ႈၵမ်ႉၵႅမ်",
+       "tool-link-userrights": "လႅၵ်ႈလၢႆႈ {{GENDER:$1|ၽူႈၸႂ်ႉတိုဝ်း}} ၸုမ်း",
+       "tool-link-emailuser": "သူင်ႇဢီးမေးလ်ဢၼ်ၼႆႉ {{GENDER:$1|ၽူႈၸႂ်ႉတိုဝ်း}}",
        "userpage": "တူၺ်းၼႃႈလိၵ်ႈၽူႈၸႂ်ႉတိုဝ်း",
        "projectpage": "တူၺ်းၼႃႈလိၵ်ႈ ပရေႃးၵျႅၵ်ႉ",
        "imagepage": "တူၺ်းၼႃႈလိၵ်ႈၾၢႆႇ",
        "yourpasswordagain": "ၶိုၼ်းပေႃႉပၼ် ၶေႃႈလပ်ႉ :",
        "createacct-yourpasswordagain": "ၼႄႉၼွၼ်းပၼ် ၶေႃႈလပ်ႉ",
        "createacct-yourpasswordagain-ph": "ပေႃႉသႂ်ႇၶေႃႈလပ်ႉထႅင်ႈၵမ်းၼိုင်ႈ",
-       "remembermypassword": "တွင်းဝႆႉပၼ် လွၵ်ႉဢိၼ်ႇၵဝ်ၶႃႈ တီႈၼႂ်း ၶိူင်ႈပိုတ်ႇဝႆႉၼႆႉ  (တီႈႁိုင်ႁိုင်မၼ်း $1 {{PLURAL:$1|ၼိုင်ႈဝၼ်း|ဝၼ်း}})",
        "userlogin-remembermypassword": "သိုပ်ႇဢဝ်ၵဝ်ၶႃႈ လွၵ်ႉဢိၼ်ႇဝႆႉလႄႈ",
        "userlogin-signwithsecure": "ၸႂ်ႉၵွင်ႉသၢၼ် ႁူမ်ႇလူမ်ႈ",
+       "cannotlogin-title": "ဢမ်ႇၸၢင်ႈၶဝ်ႈ လွၵ်ႉဢိၼ်ႇ",
+       "cannotlogin-text": "လွင်ႈၶဝ်ႈလွၵ်ႉဢိၼ်ႇ ဢမ်ႇပႆႇပဵၼ်လႆႈ",
        "cannotloginnow-title": "ဢမ်ႇၸၢင်ႈၶဝ်ႈ လွၵ်ႉဢိၼ်ႇ ယၢမ်းလဵဝ်",
        "cannotloginnow-text": "တေဢမ်ႇၸၢင်ႈ လွၵ်ႉၶဝ်ႈ ၽွင်းမိူဝ်ႈၸႂ်ႉ $1",
+       "cannotcreateaccount-title": "ဢမ်ႇၸၢင်ႈၵေႃႇတင်ႈ ဢၶွင်ႉ",
+       "cannotcreateaccount-text": "​လွင်ႈၵေႃႇတင်ႈဢၶွင်ႉၵမ်းသိုဝ်ႈၼၼ်ႉ ဢမ်ႇလႆႈပိုတ်ႇဝႆႉပၼ်ၵႃႈတီႈ ဝီႇၶီႇၼႆႉ။",
        "yourdomainname": "တူဝ်ႇမဵင်း ၸဝ်ႈၵဝ်ႇ :",
        "password-change-forbidden": "ၸဝ်ႈၵဝ်ႇတေဢမ်ႇၸၢင်ႈ ​လႅၵ်ႈလၢႆႈ ၶေႃႈလပ်ႉ ၵႃႈတီႈၼိူဝ် ဝီႇၶီႇၼႆႉ",
+       "externaldberror": "ၼႆႉမၼ်းလႆႈပဵၼ် ယွၼ်ႉ လွင်ႈၽိတ်းပိူင်ႈ ၵၢၼ်လူတ်းပွႆႇ ယွင်ၶေႃႈမုၼ်း ဢမ်ႇၼၼ် ယွၼ်ႉပိူဝ်ႈ ၸဝ်ႈၵဝ်ႇၼႆႉ ဢမ်ႇထုၵ်ႇၶႂၢင်းပၼ် တႃႇတေႁဵတ်း ဢၢပ်ႉတိတ်ႉ ဢၶွင်ႉၽၢႆႇၼွၵ်ႈ။",
        "login": "လွၵ်ႉဢိၼ်ႇ",
        "login-security": "ၼႄႉၼွၼ်း မၢႆၽၢင်ၸဝ်ႈၵဝ်ႇ",
        "nav-login-createaccount": "လွၵ်ႉဢိၼ်ႇ / သၢင်ႈဢၶွင်ႉ",
        "createacct-email-ph": "ပေႃႉသႂ်ႇပၼ် ႁဵင်းလိၵ်ႈ ဢီးမေးၸဝ်ႈၵဝ်ႇ",
        "createacct-another-email-ph": "ပေႃႉသႂ်ႇပၼ် ႁဵင်းလိၵ်ႈ ဢီးမေးလ်",
        "createaccountmail": "ၸႂ်ႉပၼ် ၶေႃႈလပ်ႉၸူဝ်ႈၵႅပ်ႉ သူင်ႇၼၼ်ႉၵႂႃႇၸူး ႁဵင်းလိၵ်ႈဢီးမေးလ် ဢၼ်မၵ်းမၼ်ႈဝႆႉ ပၼ်ၼၼ်ႉ။",
+       "createaccountmail-help": "ပေႃးဢမ်ႇမီး လွင်ႈလဵပ်ႈႁဵၼ်း ၶေႃႈလပ်ႉၼႆ တေဢမ်ႇၸၢင်ႈဢဝ်ၸႂ်ႉ တႃႇတေၵေႃႇတင်ႈ ဢၶွင်ႉတွၼ်ႈတႃႇ ၵူၼ်းတၢင်ႇၵေႃႉ။",
        "createacct-realname": "ၸိုဝ်ႈတႄႉတႄႉ (ဢဝ်ၸႂ်ဝႃႈ)",
        "createaccountreason": "လွင်ႈတၢင်း :",
        "createacct-reason": "လွင်ႈတၢင်း :",
        "loginerror": "လွၵ်ႉဢိၼ်ႇ ၽိတ်းပိူင်ႈ",
        "createacct-error": "ၵၢၼ်ၵေႃႇသၢင်ႈ ဢၶွင်ႉ ၽိတ်းပိူင်ႈ",
        "createaccounterror": "ဢမ်ႇၸၢင်ႈၵေႃႇသၢင်ႈ ဢၶွင်ႉ : $1",
+       "nocookiesnew": "ဢၶွင်ႉ ၽူႈၸႂ်ႉတိုဝ်းၼႆႉ ထုၵ်ႇၵေႃႇသၢင်ႈယဝ်ႉယဝ်ႈ၊ ၵူၺ်းၵႃႈ ၸဝ်ႈၵဝ်ႇဢမ်ႇပႆႇလႆႈၶဝ်ႈ လွၵ်ႉဢိၼ်ႇဝႆႉ။ {{SITENAME}} ၸႂ်ႉ ၶုၵ်ႉၵီး တႃႇတေၶဝ်ႈလွၵ်ႉဢိၼ်ႇ ၽူႈၸႂ်ႉတိုဝ်း။\nၸဝ်ႈၵဝ်ႇလႆႈဢိုတ်းဝႆႉ ၶုၵ်ႉၵီး။\nၶႅၼ်ႈတေႃႈ ပိုတ်ႇပၼ်ၸိူဝ်းၼၼ်ႉသေ ၶဝ်ႈလွၵ်ႉဢိၼ်ႇပၼ်တင်း ၸိုဝ်ႈၽူႈၸႂ်ႉတိုဝ်း ၸဝ်ႈၵဝ်ႇ ဢၼ်မႂ်ႇလႄႈတင်း ၶေႃႈလပ်ႉၼၼ်ႉလႄႈ။",
+       "nocookieslogin": "{{SITENAME}} ၸႂ်ႉ ၶုၵ်ႉၵီး တႃႇတေၶဝ်ႈလွၵ်ႉဢိၼ်ႇ ၽူႈၸႂ်ႉတိုဝ်း။\nၸဝ်ႈၵဝ်ႇလႆႈဢိုတ်းဝႆႉ ၶုၵ်ႉၵီး။\nၶႅၼ်ႈတေႃႈ ပိုတ်ႇပၼ်ၸိူဝ်းၼၼ်ႉသေ ၶတ်းၸႂ်တူၺ်းထႅမ်ႈလႄႈ။",
+       "nocookiesfornew": "ဢၶွင်ႉၽူႈၸႂ်ႉတိုဝ်းၼႆႉ ဢမ်ႇထုၵ်ႇၵေႃႇသၢင်ႈ ယွၼ်ႉပိူဝ်ႈႁဝ်းၶႃႈ ဢမ်ႇၸၢင်ႈၼႄႉၼွၼ်း ငဝ်ႈငႃႇမၼ်း။\nၶႅၼ်းတေႃႈ ပိုတ်ႇပၼ် ၶုၵ်ႉၵီးၸဝ်ႈၵဝ်ႇယဝ်ႉသေ ၶိုၼ်းတူင်ႉပိုတ်ႇၼႃႈလိၵ်ႈၼႆႉသေ ၶတ်းၸႂ်တူၺ်းထႅင်ႈၶႃႈလႄႈ။",
+       "createacct-loginerror": "ဢၶွင်ႉ ၵေႃႇတင်ႈၶႅမ်ႉလႅပ်ႈၵႂႃႇသေတႃႉ ၸဝ်ႈၵဝ်ႇ တေဢမ်ႇပႆႇၸၢင်ႈၶဝ်ႈ လွၵ်ႉဢိၼ်ႇ ႁင်းၶေႃႈ။ ၶႅၼ်းတေႃႈ ႁဵတ်းတႃႇ  [[Special:UserLogin|manual login]].",
        "noname": "ၸဝ်ႈၵဝ်ႇ ဢမ်ႇလႆႈ မၵ်းမၼ်ႈဝႆႉပၼ် ၸိုဝ်ႈၽူႈၸႂ်ႉတိုဝ်း ဢၼ်ၸႂ်ႉလႆႈ။",
        "loginsuccesstitle": "လွၵ်ႉဢိၼ်ႇဝႆႉယဝ်ႉ",
        "loginsuccess": "<strong>ၸဝ်ႈၵဝ်ႇ လွၵ်ႉဢိၼ်ႇၶဝ်ႈၸူး  {{SITENAME}} ၼင်ႇ \"$1\".</strong> ယဝ်ႉဢေႃႈ ယၢမ်းလဵဝ်",
+       "nosuchuser": "ၸိုဝ်ႈ တွၼ်ႈတႃႇတႃႇၽူႈၸႂ်ႉတိုဝ်း \"$1\" ဢၼ်ၼႆႉ မၼ်းဢမ်ႇမီးဝႆႉ။\nၸိုဝ်ႈၽူႈၸႂ်ႉတိုဝ်းၼႆႉ မၼ်းမီးလိူင်ႈတူဝ်လဵၵ်ႉတူဝ်ယႂ်ႇ။\nၵူတ်ႇထတ်းတူၺ်း တူဝ်လေႃးမၼ်း ဢမ်ႇၼၼ် [[Special:CreateAccount|create a new account]].",
        "nosuchusershort": "ဢၼ်ပဵၼ်ၸိုဝ်ႈ ၽူႈၸႂ်ႉတိုဝ်း \"$1\" ဢၼ်ၼႆႉ မၼ်းဢမ်ႇမီး။\nမႄးၵူတ်ႇတူၺ်း တူဝ်လိၵ်ႈမၼ်းလီလီလႄႈ။",
        "nouserspecified": "ၸဝ်ႈၵဝ်ႇ ထုၵ်ႇလီမၵ်းမၼ်ႈ ၸိုဝ်ႈၽူႈၸႂ်ႉတိုဝ်း",
        "login-userblocked": "ၽူႈၸႂ်ႉတိုဝ်းၵေႃႉၼႆႉ ထုၵ်ႇႁႄႉတတ်းဝႆႉ။ ဢမ်ႇမီးသုၼ်ႇတႃႇ လွၵ်ႉဢိၼ်ႇ",
        "passwordreset-emailelement": "ၸိုဝ်ႈၽူႈၸႂ်ႉတိုဝ်း:\n$1\n\nၶေႃႈလပ်ႉ ၸူဝ်ႈၵႅပ်ႉ:\n$2",
        "passwordreset-emailsentemail": "ႁဵင်းလိၵ်ႈ ဢီးမေးလ်ဢၼ်ၼႆႉၼႆႉ မၼ်းၵပ်းၵၢႆႇၵၼ်တင်း ဢၶွင်ႉၸဝ်ႈၵဝ်ႇ၊ ဢၼ်ပဵၼ် ဢီးမေးလ် တႃႇတင်ႈၶိုၼ်းမၢႆလပ်ႉၼၼ်ႉ တေထုၵ်ႇသူင်ႇၸူးယူႇ.",
        "passwordreset-emailsentusername": "ႁဵင်းလိၵ်ႈ ဢီးမေးလ်ဢၼ်ၼႆႉၼႆႉ မၼ်းၵပ်းၵၢႆႇၵၼ်တင်း ၸိုဝ်ႈၽူႈၸႂ်ႉတိုဝ်း ဢၼ်ၼႆႉ၊ ဢၼ်ပဵၼ် ဢီးမေးလ် တႃႇတင်ႈၶိုၼ်းမၢႆလပ်ႉၼၼ်ႉ တေထုၵ်ႇသူင်ႇၸူးယူႇ.",
-       "passwordreset-emailsent-capture": "ဢီးမေးလ် ၵၢၼ်တင်ႈၶိုၼ်း ​မၢႆလပ်ႉၼၼ်ႉ ထုၵ်ႇသူင်ႇၵႂႃႇၸူး ဢၼ်ၼႄဝႆႉၼင်ႇ ၽၢႆႇတႂ်ႈၼႆႉ။",
-       "passwordreset-invalideamil": "ႁဵင်းလိၵ်ႈ ဢီႈမေးလ် ၽိတ်းဝႆႉ။",
+       "passwordreset-invalidemail": "ႁဵင်းလိၵ်ႈ ဢီႈမေးလ် ၽိတ်းဝႆႉ။",
        "passwordreset-nodata": "ၸိုဝ်ႈၽူႈၸႂ်ႉတိုဝ်းလႄႈ ႁဵင်းလိၵ်ႈဢီးမေးလ် ဢမ်ႇလႆႈၵမ်ႉထႅမ်ဝႆႉ သေဢၼ်။",
        "changeemail": "လႅၵ်ႈလၢႆႈ ဢမ်ႇၼၼ် ထွၼ်ပႅတ်ႈ ႁဵင်းလိၵ်ႈ ဢီးမေးလ်",
        "changeemail-no-info": "တႃႇၸဝ်ႈၵဝ်ႇ တေၸၢင်ႈၸႂ်ႉလႆႈ ၼႃႈလိၵ်ႈၼႆႉ ၵမ်းသိုဝ်ၼၼ်ႉၼႆ ၸဝ်ႈၵဝ်ႇ တေလႆႈ ၶဝ်ႈလွၵ်ႉဢိၼ်ႇဝႆႉဢေႃႈ။",
        "minoredit": "ပဵၼ်လွင်ႈမူၼ်ႉမႄးဢိတ်းဢီႈ",
        "watchthis": "တူၺ်းၼႃႈလိၵ်ႈၼႆႉ",
        "savearticle": "ၵဵပ်းသိမ်း ၼႃႈလိၵ်ႈ",
+       "savechanges": "သိမ်းလွင်ႈလႅၵ်ႈလၢႆႈ",
        "publishpage": "ပိုၼ်ဢွၵ်ႇ ၼႃႈလိၵ်ႈ",
+       "publishchanges": "ပိုတ်ႇဢွၵ်ႇ လွင်ႈလႅၵ်ႈလၢႆႈ",
        "preview": "တူၺ်းလူင်ႈၼႃႈ",
        "showpreview": "ၼႄတူဝ်ယၢင်ႇ",
        "showdiff": "ၼႄလွင်ႈလႅၵ်ႈလၢႆႈ",
        "content-json-empty-object": "ၵၢၼ်ပဝ်ႇ",
        "content-json-empty-array": "ထႅဝ်ပဝ်ႇ",
        "post-expand-template-inclusion-warning": "<strong>ၶေႃႈၽၢင်ႉ</strong> - ပိူင်ဢဝ်မႃးႁူမ်ႈၼၼ်ႉယႂ်ႇပူၼ်ႉၼႃႇ။\nပိူင်မၢင်ၼႃႈတေဢမ်ႇႁူမ်ႈပႃးၸွမ်း။",
-       "cantcreateaccounttitle": "ဢမ်ႇၸၢင်ႈၵေႃႇသၢင်ႈ ဢၶွင်ႉ",
        "viewpagelogs": "တူၺ်းသၢႆမၢႆ တွၼ်ႈတႃႇၼႃႈလိၵ်ႈၼႆႉ",
        "nohistory": "တီႈၼႆႈ ဢမ်ႇမီး ပိုၼ်းထတ်းသၢင်ႈ တွၼ်ႈတႃႇၼႃႈလိၵ်ႈၼႆႉ",
        "currentrev": "ၵၢၼ်ၶူၼ်ႉလူ ၵမ်းလိုၼ်းသုတ်း",
        "rightslogtext": "ဢၼ်ၼႆႉပဵၼ် သဵၼ်ႈမၢႆ လွင်ႈလႅၵ်ႈလၢႆႈ သုၼ်ႈလႆႈ ၽူႈၸႂ်ႉတိုဝ်း",
        "action-read": "လူၼႃႈလိၵ်ႈၼႆႉ",
        "action-edit": "မူၼ်ႉမႄး ၼႃႈလိၵ်ႈၼႆႉ",
-       "action-createpage": "á\81µá\80±á\82\83á\82\88á\80\9eá\81¢á\80\84á\80ºá\82\88 á\81¼á\82\83á\82\88á\80\9cá\80­á\81µá\80ºá\82\88",
-       "action-createtalk": "ၵေႃႇသၢင်ႈ ၼႃႈလိၵ်ႈ ဢုပ်ႇဢူဝ်းၵၼ်",
+       "action-createpage": "á\81µá\80±á\82\83á\82\87á\80\9eá\81¢á\80\84á\80ºá\82\88 á\81¼á\82\83á\82\88á\80\9cá\80­á\81µá\80ºá\82\88á\81¼á\82\86á\82\89",
+       "action-createtalk": "ၵေႃႇသၢင်ႈ ၼႃႈလိၵ်ႈ ဢုပ်ႇဢူဝ်းၵၼ်ဢၼ်ၼႆႉ",
        "action-createaccount": "ၵေႃႇသၢင်ႈ ဢၶွင်ႉၽူႈၸႂ်ႉတိုဝ်း ဢၼ်ၼႆႉ",
        "action-autocreateaccount": "ၵေႃႇသၢင်ႈ ဢၶွင်ႉၽူႈၸႂ်ႉတိုဝ်း ၽၢႆႇၼွၵ်ႈ ႁင်းတူဝ်",
        "action-history": "တူၺ်း ပိုၼ်းၼႃႈလိၵ်ႈဢၼ်ၼႆႉ",
        "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 ၼႆႉ မၼ်းဢမ်ႇလႆႈမီးဝႆႉ။",
+       "backend-fail-hashes": "ဢမ်ႇၸၢင်ႈဢဝ် ၾၢႆႇဢၼ်ယွႆႈ တွၼ်ႈတႃႇတေမႃး ၶဵင်ႇထတ်းၵၼ်။",
+       "backend-fail-notsame": "ၾၢႆႇဢၼ်ဢမ်ႇပႆႇလႆႈ ထတ်းသၢင်ႈၼၼ်ႉ မီးဝႆႉလူင်ႈၼႃႈ ၵႃႈတီႈ \"$1\" ။",
+       "backend-fail-invalidpath": "\"$1\" ၼႆႉ သၢႆတၢင်းတႃႇတေသိမ်းမၼ်း ၽိတ်းဝႆႉ။",
+       "backend-fail-delete": "ဢမ်ႇၸၢင်ႈမွတ်ႇပႅတ်ႈ ၾၢႆႇ \"$1\".",
+       "backend-fail-describe": "ဢမ်ႇၸၢင်ႈလႅၵ်ႈလၢႆႈ ၶေႃႈမုၼ်းၽၢႆႇလင် တွၼ်ႈတႃႇၾၢႆႇ \"$1\" ။",
+       "backend-fail-alreadyexists": "ၾၢႆႇ \"$1\" မီးဝႆႉထႃႈယဝ်ႉ။",
+       "backend-fail-store": "ဢမ်ႇၸၢင်ႈသိမ်းၾၢႆႇ \"$1\" ၵႃႈတီႈ \"$2\" ။",
+       "backend-fail-copy": "ဢမ်ႇၸၢင်ႈထုတ်ႇဢဝ် ၾၢႆႇ \"$1\" ၸူး \"$2\".",
+       "backend-fail-move": "ဢမ်ႇၸၢင်ႈၶၢႆႉၾၢႆႇ \"$1\" ၸူး \"$2\" ။",
+       "backend-fail-opentemp": "ဢမ်ႇၸၢင်ႈပိုတ်ႇၾၢႆႇတိုဝ်းၸူဝ်ႈၵႅပ်ႉ။",
+       "backend-fail-writetemp": "ဢမ်ႇၸၢင်ႈတႅမ်ႈသႂ်ႇၸူး ၾၢႆႇတိုဝ်းၸူဝ်ႈၵႅပ်ႉ။",
+       "backend-fail-closetemp": "ဢမ်ႇၸၢင်ႈဢိုတ်း ၾၢႆႇတိုဝ်းၸူဝ်ႈၵႅပ်ႉ။",
+       "backend-fail-read": "ဢမ်ႇၸၢင်ႈလူၾၢႆႇ \"$1\" ။",
+       "backend-fail-create": "ဢမ်ႇၸၢင်ႈတႅမ်ႈၾၢႆႇ \"$1\" ။",
+       "backend-fail-maxsize": "ဢမ်ႇၸၢင်ႈတႅမ်ႈၾၢႆႇ \"$1\" ယွၼ်ႉပိူဝ်ႈဝႃႈ မၼ်းၼႆႉ ယႂ်ႇလိူဝ်သေ {{PLURAL:$2|ၼိုင်ႈပၢႆႉ|$2 ပၢႆႉ}}",
+       "backend-fail-readonly": "တီႈသိမ်းသုတ်းလင် \"$1\" ၼႆႉ ယၢမ်းလဵဝ် မၼ်းတေၸၢင်ႈလူလႆႈၵူၺ်း။ လွင်ႈတၢင်း ဢၼ်လႆႈပၼ်ဝႆႉတႄႉ ပဵၼ် <em>$2</em>",
+       "backend-fail-synced": "ၾၢႆႇ \"$1\" ၼႆႉ မၼ်းပဵၼ်သၢႆႇငၢႆ ဢၼ်ဢမ်ႇမႃးငမ်ႇမႅၼ်ႈၵၼ် တီႈၼႂ်း ဢွင်ႈသိမ်းသုတ်းလင် ၽၢႆႇၼႂ်း။",
+       "backend-fail-connect": "ဢမ်ႇၸၢင်ႈၵွင်ႉသိုပ်ႇၸူး ဢွင်ႈသိမ်းသုတ်းလင် \"$1\" ။",
+       "backend-fail-internal": "လွင်ႈၽိတ်းပိူင်ႈ ဢၼ်ဢမ်ႇႁူႉလွင်ႈမၼ်း လႆႈပဵၼ်ဝႆႉ ၵႃႈတီႈၼႂ်း ဢွင်ႈသိမ်းသုတ်းလင် \"$1\" ။",
+       "backend-fail-contenttype": "ဢမ်ႇၸၢင်ႈတႅပ်းတတ်းလိူင်ႈၾၢႆႇ ဢၼ်တႃႇတေသိမ်းၵႃႈတီႈ \"$1\" ။",
+       "backend-fail-batchsize": "ဢွင်ႈတီႈသိမ်းသုတ်းလင် ထုၵ်ႇပၼ်ဝႆႉ ၸုမ်းၾၢႆႇ $1 ၾၢႆႇ\n{{PLURAL:$1|ၵၢၼ်ႁဵတ်း|ၵၢၼ်ႁဵတ်း}}; တီႈမၵ်းၶၢၼ်းမၼ်းပဵၼ် $2\n{{PLURAL:$2|ၵၢၼ်ႁဵတ်း|ၵၢၼ်ႁဵတ်း}}.",
+       "backend-fail-usable": "ဢမ်ႇၸၢင်ႈလူ ဢမ်ႇၼၼ် ဢမ်ႇၸၢင်ႈတႅမ်ႈ ၾၢႆႇ \"$1\" ယွၼ်ႉပိူဝ်ႈဝႃႈ ၵၢၼ်လူတ်းပွႆႇ ဢမ်ႇတဵမ်ထူၼ်ႈ ဢမ်ႇၼၼ် ႁၢမ်းဝႆႉ ဢွင်ႈတီႈသိမ်း။",
+       "filejournal-fail-dbconnect": "ဢမ်ႇၸၢင်ႈၵွင်ႉသိုပ်ႇၸူး ယေးၶေႃႈမုၼ်း ၵျႃႇၼႄႇ တွၼ်ႈတႃႇ ဢွင်ႈတီႈသိမ်းသုတ်းလင် \"$1\" ။",
+       "filejournal-fail-dbquery": "ဢမ်ႇၸၢင်ႈဢၢပ်ႉတိတ်ႉ ယေးၶေႃႈမုၼ်း ၵျႃႇၼႄႇ တွၼ်ႈတႃႇ ဢွင်ႈတီႈသိမ်းသုတ်းလင် \"$1\" ။",
        "lockmanager-notlocked": "ဢမ်ႇၸၢင်ႈ ပိုတ်ႇသေႃး \"$1\"; ၼၼ်ႉမၼ်းဢမ်ႇလႆႈ ၶတ်းဝႆႉ။",
        "lockmanager-fail-closelock": "ဢမ်ႇၸၢင်ႈဢိုတ်း ၾၢႆႇဢၼ်ၶတ်းဝႆႉ တွၼ်ႈတႃႇ \"$1\" ။",
        "lockmanager-fail-deletelock": "ဢမ်ႇၸၢင်ႈမွတ်ႇပႅတ်ႈ ၾၢႆႇဢၼ်ၶတ်းဝႆႉ တွၼ်ႈတႃႈ \"$1\".",
        "lockmanager-fail-acquirelock": "ဢမ်ႇၸၢင်ႈဢဝ် ၶတ်းတွၼ်ႈတႃႇ \"$1\" ။",
        "lockmanager-fail-openlock": "ဢမ်ႇၸၢင်ႈဢိုတ်း ၾၢႆႇဢၼ်ၶတ်းဝႆႉ တွၼ်ႈတႃႇ \"$1\" ။",
        "lockmanager-fail-releaselock": "ဢမ်ႇၸၢင်ႈပွႆႇပၼ် ဢၼ်ၶတ်း တွၼ်ႈတႃႈ \"$1\" ။",
+       "lockmanager-fail-db-bucket": "ဢမ်ႇၸၢင်ႈၵပ်းသိုပ်ႇလႆႈ ယေးၶေႃႈမုၼ်းဢၼ်ၶတ်းဝႆႉ ၵႃႈတီႈၼႂ်း ပုင်း $1 ၼၼ်ႉ။",
        "lockmanager-fail-db-release": "ဢမ်ႇၸၢင်ႈပွႆႇပၼ်ၵၢၼ်ၶတ်း ၵႃႈတီႈ ယွင်ၶေႃႈမုၼ်း $1 ။",
        "lockmanager-fail-svr-acquire": "ဢမ်ႇၸၢင်ႈဢဝ်လႆႈ ၵၢၼ်ၶတ်း ၵႃႈတီႈၼိူဝ် သႃႇပိူဝ်ႇ $1 ။",
        "lockmanager-fail-svr-release": "ဢမ်ႇၸၢင်ႈပွႆႇပၼ် ၵၢၼ်ၶတ်း ၵႃႈတီႈၼိူဝ် သႃႇပိူဝ်ႇ $1 ။",
+       "zip-file-open-error": "ၽွင်းမိူဝ်ႈပိုတ်ႇၽၢႆႇ တွၼ်ႈတႃႇ ၵူတ်ႇထတ်း ZIP ၼၼ်ႉ လႆႈထူပ်းၺႃး လွင်ႈၽိတ်းပိူင်ႈ။",
        "zip-wrong-format": "ၾၢႆႇဢၼ်မၵ်းမၼ်ႈဝႆႉပၼ်ၼၼ်ႉ မၼ်းဢမ်ႇၸႂ်ႈ ၾၢႆႇ ZIP ။",
        "zip-bad": "ၾၢႆႇၼႆႉ မၼ်းၵွႆဝႆႉ ဢမ်ႇၼၼ် မၼ်းပဵၼ် ၾၢႆႇ ZIP ဢၼ်ဢမ်ႇလူႇလႆႈ။\nမၼ်းဢမ်ႇၸၢင်ႈ ၵူတ်ႇတူၺ်း တွၼ်ႈတႃႇ ပၢႆးႁူမ်ႇလူမ်ႈ လႆႈလီလီ။",
        "zip-unsupported": "ၾၢႆႇၼႆႉပဵၼ် ZIP ၾၢႆႇ ဢၼ်ၸႂ်ႉဝႆႉ ၽၢင်ႁၢင်ႈၵၢၼ် ZIP ဢၼ် သိူဝ်ႇၶၢဝ်ႇဝီႇၶီႇ ဢမ်ႇၵမ်ႉထႅမ်ဝႆႉ။  မၼ်းဢမ်ႇၸၢင်ႈ ၵူတ်ႇတူၺ်း တွၼ်ႈတႃႇ ပၢႆးႁူမ်ႇလူမ်ႈ လႆႈလီလီ။",
        "uploadstash": "လူတ်ႇၶိုၼ်ႈ ၵၢၼ်သိူင်ႇ",
+       "uploadstash-summary": "ၼႃႈလိၵ်ႈၼႆႉ ၵမ်ႉထႅမ်ပၼ် တႃႇၶဝ်ႈၸႂ်ႉ ၾၢႆႇဢၼ်လူတ်ႇၶိုၼ်ႈဝႆႉ ဢမ်ႇၼၼ် ဢၼ်တိုၵ်ႉမီးၼႂ်းၵၢၼ်လူတ်ႇၶိုၼ်ႈၼၼ်ႉ၊ ၵူၺ်းၵႃႈ တေပဵၼ်ၸိူဝ်းဢၼ်ဢမ်ႇပႆႇလႆႈ ​ပိုတ်ႇၽႄ ၸူးၵႃႈတီႈ ဝီႇၶီႇ။ ၾၢႆႇၸိူဝ်းၼႆႉၼႆႉ ၵူၼ်းတၢင်ႇၸိူဝ်းတေဢမ်ႇလႆႈႁၼ်၊ ၵူၺ်းၵႃႈဝႃႈ ၵူၼ်းၸိူဝ်းလူတ်ႇၶိုၼ်ႈၶဝ်ႈတႄႉ တေၸၢင်ႈႁၼ်လႆႈယူႇ။",
        "uploadstash-clear": "ၽဵဝ်ႈလၢင်ႈ ၾၢႆႇၸိူဝ်းသိူင်ႇသိမ်းဝႆႉ",
        "uploadstash-nofiles": "တီႈၸဝ်ႈၵဝ်ႇ ဢမ်ႇမီးၾၢႆႇသိူင်ႇသိမ်းသင်။",
+       "uploadstash-badtoken": "ႁဵတ်းသၢင်ႈ ၸိူဝ်းလွင်ႈႁဵတ်းဢၼ်လႆႈ တူၵ်းသုမ်းၵႂႃႇၼၼ်ႉ၊ မၢင်ၽဝ်ႇတေပဵၼ်ယွၼ်ႉလူၺ်ႈ ၶေႃႈၵမ်ႉတူဝ် ၵၢၼ်မႄးထတ်းၸဝ်ႈၵဝ်ႇၼၼ်ႉ ဢႃႇယုသုတ်းၵႂႃႇလႄႈႁိုဝ်။ ၶိုၼ်းမႄး ၶတ်းၸႂ်တူၺ်းထႅင်ႈၵမ်းၼိုင်ႈလႄႈ။",
        "uploadstash-errclear": "လွင်ႈၽဵဝ်ႈလၢင်ႉၾၢႆႇဢမ်ႇၶႅမ်ႉလႅပ်ႈ။",
        "uploadstash-refresh": "သၢႆႇၶိုၼ်း သဵၼ်ႈမၢႆၾၢႆႇ",
        "uploadstash-thumbnail": "တူၺ်းၼင်ႇ ႁၢင်ႈလဵၵ်ႉ",
+       "uploadstash-exception": "ဢမ်ႇၸၢင်ႈသိမ်း ၵၢၼ်လူတ်ႇၶိုၼ်ႈ ၵႃႈတီႈၼႂ်း တီႈသိူင်ႇ($1): \"$2\" ။",
+       "invalid-chunk-offset": "ပွတ်းတူဝ်ၵၢမ်း ၽိတ်းပိူင်ႈ",
        "img-auth-accessdenied": "ၵၢၼ်ၸႂ်ႉတိုဝ်း ထုၵ်ႇထဵင်ၶိုၼ်း။",
+       "img-auth-notindir": " သၢႆတၢင်းဢၼ်တုၵ်းယွၼ်းမႃးၼၼ်ႉ မၼ်းဢမ်ႇမီးၵႃႈတီႈၼႂ်း သၢႆတၢင်းလူတ်ႇၶိုၼ်ႈ ဢၼ်မႄးၵုမ်းဝႆႉ။",
        "img-auth-nologinnWL": "ၸဝ်ႈၵဝ်ႇ ဢမ်ႇလႆႈၶဝ်ႈ လွၵ်ႉဢိၼ်ဝႆႉသေ \"$1\" ၼႆႉ မၼ်းဢမ်ႇမီးဝႆႉ တီႈၼႂ်း သဵၼ်ႈမၢႆၶၢဝ်။",
        "img-auth-nofile": "ၾၢႆႇ \"$1\" ၼႆႉ မၼ်းဢမ်ႇမီးဝႆႉ။",
        "img-auth-isdir": "ၸဝ်ႈၵဝ်ႇ တိုၵ်ႉၶတ်းၸႂ်ႉ ၶဝ်ႈၸႂ်ႉ ၾူဝ်ႇတိူဝ်ႇ \"$1\" ယူႇ။\nၶႂၢင်းဝႆႉပၼ် ၵၢၼ်ၸႂ်ႉတိုဝ်းၾၢႆႇၵူၺ်း။",
        "unusedtemplates": "လွၵ်းပိူင် ဢၼ်ဢမ်ႇၸႂ်ႉဝႆႉ",
        "unusedtemplateswlh": "ႁဵင်းၵွင်ႉ တၢင်ႇၸိူဝ်း",
        "randompage": "ဢဝ်ၼႃႈလိၵ်ႈသၢင်ႇထုၵ်ႇဝႃႈ",
-       "randompage-nopages": "á\81¸á\80½á\80\99á\80ºá\80¸á\81¼á\80\84á\80ºá\82\87á\80\95á\82\83á\82\88á\80\90á\82\82á\80ºá\82\88á\81¼á\82\86á\82\89 á\80\99á\81¼á\80ºá\80¸á\80¢á\80\99á\80ºá\82\87á\80\99á\80®á\80¸ ဝႆႉ ၼႃႈလိၵ်ႈသင်\n{{PLURAL:$2|လွၵ်းၸိုဝ်ႈ|လွၵ်းၸိုဝ်ႈ}}: $1.",
+       "randompage-nopages": "á\80\90á\81¢á\80\84á\80ºá\80¸á\81½á\81¢á\82\86á\82\87á\80\90á\82\82á\80ºá\82\88á\81¼á\81¼á\80ºá\82\89 á\80¢á\80\99á\80ºá\82\87á\80\99á\80®á\80¸ဝႆႉ ၼႃႈလိၵ်ႈသင်\n{{PLURAL:$2|လွၵ်းၸိုဝ်ႈ|လွၵ်းၸိုဝ်ႈ}}: $1.",
        "randomincategory": "ၼႃႈလိၵ်ႈၵမ်ႉသၢင်ႇတေႃႇ ၵႃႈတီႈၼႂ်း လိူင်ႈ",
        "randomincategory-invalidcategory": "\"$1\" ၼႆႉ ပဵၼ်ၸိုဝ်ႈလိူင်ႈ ဢၼ်ဢမ်ႇပဵၼ်လႆႈ။",
        "randomincategory-nopages": "မၼ်းဢမ်ႇမီးဝႆ ၼႃႈလိၵ်ႈသင် ၵႃႈတီႈၼႂ်း [[:Category:$1|$1]] လိူင်ႈ။",
        "nbytes": "$1 {{PLURAL:$1|ၿႆႉ|ၿႆႉ}}",
        "ncategories": "{{PLURAL:$1|လိူင်ႈ|လိူင်ႈတင်းလၢႆ}}",
        "ninterwikis": "$1 {{PLURAL:$1|ဝီႇၶီႇၽၢႆႇၼႂ်း|ဝီႇၶီႇၸိူဝ်းၽၢႆႇၼႂ်း}}",
-       "nlinks": "$1 {{PLURAL:$1|ႁဵင်းၵွင်ႉ|ႁဵင်းၵွင်ႉ}}",
+       "nlinks": "$1 {{PLURAL:$1|ႁဵင်းၵွင်ႉ|ႁဵင်းၵွင်ႉၼမ်}}",
        "nmembers": "$1 {{PLURAL:$1|member|ၽူႈၶဝ်ႈၸုမ်း}}",
-       "nmemberschanged": "$1 → $2 {{PLURAL:$2|ၽူႈၶဝ်ႈၸုမ်း|ၽူႈၶဝ်ႈၸုမ်း}}",
+       "nmemberschanged": "$1 → $2 {{PLURAL:$1|member|ၽူႈၶဝ်ႈၸုမ်း}}",
        "nrevisions": "$1 {{PLURAL:$1|​ၶေႃႈၶူၼ်ႉလူ|ၶေႃႈၶူၼ်ႉလူ}}",
-       "nimagelinks": "á\81¸á\82\82á\80ºá\82\89á\80\9dá\82\86á\82\89á\81µá\82\83á\82\88á\80\90á\80®á\82\88á\81¼á\80­á\80°á\80\9dá\80º $1 {{PLURAL:$1|á\81¼á\82\83á\82\88á\80\9cá\80­á\81µá\80ºá\82\88|ၼႃႈလိၵ်ႈ}}",
-       "ntransclusions": "ၸႂ်ႉဝႆႉၵႃႈတီႈၼိူဝ် $1 {{PLURAL:$1|ၼႃႈလိၵ်ႈ|ၼႃႈလိၵ်ႈ}}",
+       "nimagelinks": "á\81¸á\82\82á\80ºá\82\88á\80\9dá\82\86á\82\89 á\80\90á\80®á\82\88 $1 {{PLURAL:$1|page|ၼႃႈလိၵ်ႈ}}",
+       "ntransclusions": "ၸႂ်ႉဝႆႉၵႃႈတီႈၼိူဝ် $1 {{PLURAL:$|page|ၼႃႈလိၵ်ႈ}}",
        "specialpage-empty": "တွၼ်ႈတႃႇ ၶေႃႈပွင်ႇၼႄ ဢၼ်ၼႆႉၼႆႉ မၼ်းဢမ်ႇမီး ၽွၼ်းလႆႈ။",
        "lonelypages": "ၼႃႈလိၵ်ႈ ႁၢမ်းႁိူၼ်း",
        "lonelypagestext": "ၼႃႈလိၵ်ႈၸိူဝ်းပႃႈတႂ်ႈၼႆႉ မၼ်းဢမ်ႇလႆႈ ၵွင်ႉဝႆႉ ဢမ်ႇၼၼ် ဢမ်ႇလႆႈၶဝ်ႈပႃႈဝႆႉ တႂ်ႈၼႂ်း ၼႃႈလိၵ်ႈတႃႇၸိူဝ်း ၼင်ႇ  {{SITENAME}} ၼႆႉ။",
        "listusers-editsonly": "ၼႄပၼ် ၽူႈၸႂ်ႉတိုဝ်း ၸိူဝ်းမႄးထတ်းၼၼ်ႉၵူၺ်း",
        "listusers-creationsort": "ၶပ်ႉၸႅၼ်ၸွမ်း ဝၼ်းထီႉ ၵေႃႇသၢင်ႈ",
        "listusers-desc": "ၶပ်ႉၸႅၼ်ႇၸွမ်း မၢႆၶပ်ႉတူဝ်လဵၵ်ႉ",
-       "usereditcount": "$1 {{PLURAL:$1|မႄးထတ်း|မႄးထတ်း}}",
+       "usereditcount": "$1 {{PLURAL:$1|edit|မႄးထတ်း}}",
        "usercreated": "{{GENDER:$3|ၵေႃႇသၢင်ႈယဝ်ႉ}} မိူဝ်ႈ $1 မိူဝ်ႈ$2",
        "newpages": "ၼႃႈလိၵ်ႈမႂ်ႇ",
        "newpages-submit": "ၼႄ",
        "notargettext": "ၸဝ်ႈၵဝ်ႇ ဢမ်ႇလႆႈမၵ်းမၼ်ႈဝႆႉ ၼႃႈလိၵ်ႈတီႈယိူင်း ဢမ်ႇၼၼ် ၽူႈၸႂ်ႉတိုဝ်း တွၼ်ႈတႃႇႁဵတ်း ၼႃႈၵၢၼ်ၼႆႉ။",
        "nopagetitle": "ဢမ်ႇမီး ၼႃႈလိၵ်ႈ တီႈယိူင်းၸူး",
        "pager-older-n": "{{PLURAL:$1|older 1|ဢၼ်ၵဝ်ႇၵဝ်ႇ $1}}",
+       "apisandbox-reset": "ၽဵဝ်ႈလၢင်ႉ",
+       "apisandbox-retry": "ၶိုၼ်းၶတ်းၸႂ်တူၺ်း",
+       "apisandbox-loading": "တိုၵ်ႉပိုတ်ႇ လွၼ်ႉၶၢဝ်ႇတႃႇ module APL \"$1\"...",
+       "apisandbox-load-error": "ၽွင်းမိူဝ်ႈတိုၵ်ႉပိုတ်ႇ လွၼ်ႉၶၢဝ်ႇ module API \"$1\" : $2 ၼၼ်ႉ မၼ်းမီးဝႆႉ လွင်ႈၽိတ်းပိူင်ႈ",
+       "apisandbox-no-parameters": "​API module ဢၼ်ၼႆႉ မၼ်းဢမ်ႇမီးဝႆႉ ပႃႇရႃႇမီႇတႃႇ။",
+       "apisandbox-helpurls": "ႁဵင်းၵွင်ႉ တၢင်းၸွႆႈထႅမ်",
+       "apisandbox-examples": "တူဝ်ယၢင်ႇ",
+       "apisandbox-dynamic-parameters": "ပႃႇရႃႇမီႇတႃႇ ဢၼ်ၵႅမ်",
+       "apisandbox-dynamic-parameters-add-label": "ထႅမ်သႂ်ႇ ပႃႇရႃႇမီႇတႃႇ :",
+       "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": "ၵႃႈၶၼ်တွၼ်ႈတႃႇ လွၵ်းဢၼ်ၼႆႉ မၼ်းဢမ်ႇၸႂ်ႉလႆႈ",
+       "apisandbox-continue": "သိုပ်ႇၼႃႈ",
+       "apisandbox-continue-clear": "ၽဵဝ်ႈလၢင်ႉ",
        "booksources": "ငဝ်ႈငႃႇ ပပ်ႉလိၵ်ႈ",
        "booksources-search-legend": "ၶူၼ်ႉႁႃတႃႇ ငဝ်ႇငႃႇပပ်ႉ",
        "booksources-search": "ၶူၼ်ႉႁႃ",
+       "booksources-invalid-isbn": "ISBN ဢၼ်ပၼ်ဝႆႉၼၼ်ႉ မၼ်းဢွၵ်ႇၼႄဝႃႈ ဢမ်ႇၸႂ်ႈလႆႈ၊ ၵူတ်ႇတူၺ်း လွင်ႇထုတ်ႇဢဝ် ၵႃႈတီႈ ငဝ်ႈတိုၼ်း မၼ်းၼၼ်ႉလႄႈ။",
+       "specialloguserlabel": "တူဝ်​ႁဵတ်းသၢင်ႈ :",
+       "speciallogtitlelabel": "တီႈယိူင်း (ႁူဝ်ၶေႃႈ ဢမ်ႇၼၼ် {{ns:user}}: ၸိုဝ်ႈၽူႈၸႂ်ႉတိုဝ်း တႃႇ ၽူႈၸႂ်ႉတိုဝ်း):",
        "log": "သၢႆမၢႆ",
+       "logeventslist-submit": "ၼႄ",
+       "all-logs-page": "သဵၼ်ႈမၢႆၵူၼ်းတင်းၼမ် တင်းမူတ်း",
+       "logempty": "ဢမ်ႇငမ်ႇၵၼ်တင်း တီႈၼႂ်းသဵၼ်ႈမၢႆ",
+       "log-title-wildcard": "ဢဝ်လိၵ်ႈၸိူဝ်းၼႆႉသေ တႄႇသွၵ်ႈႁႃ ႁူဝ်ၶေႃႈ",
+       "showhideselectedlogentries": "လႅၵ်ႈလၢႆႈ ၵၢၼ်ႁၼ်လႆႈ ၶွင် ၶေႃႈၶူၼ်ႉဢၢၼ်ႇ ၸိူဝ်းလိူၵ်ႈဝႆႉ",
+       "log-edit-tags": "မႄးထတ်ႈမႂ်တိင် ၶွင် ၶေႃႈၶူၼ်ႉဢၢၼ်ႇ ၸိူဝ်းလိူၵ်ႈဝႆႉ",
+       "checkbox-select": "လိူၵ်ႈ : $1",
+       "checkbox-all": "တင်းမူတ်း",
+       "checkbox-none": "ဢမ်ႇမီးသင်",
+       "checkbox-invert": "ပိၼ်ႈၽိုၼ်",
        "allpages": "ၼႃႈ​လိၵ်ႈ​တင်း​သဵင်ႈ",
+       "nextpage": "ၼႃးလိၵ်ႈ တေမႃး ($1)",
+       "prevpage": "ၼႃးလိၵ်ႈ ပူၼ်ႉမႃး ($1)",
+       "allpagesfrom": "ၼႃႈလိၵ်ႈဢၼ်ၼႄ တႄႇတီႈ :",
+       "allpagesto": "ၼႃႈလိၵ်ႈဢၼ်ၼႄ သုတ်းတီႈ :",
        "allarticles": "ၼႃႈ​လိၵ်ႈ​တင်း​သဵင်ႈ",
+       "allinnamespace": "ၼႃႈလိၵ်ႈတင်းမူတ်း ($1 ဢွင်ႈၸိုဝ်ႈ)",
        "allpagessubmit": "ၶူၼ်ႉႁႃ",
+       "allpagesprefix": "ၼႃးလိၵ်ႈဢၼ်ၼႄ ဢိၵ်ႇတင်း ၶေႃႈလူင်ႈၼႃႈ",
        "categories": "လိူင်ႈ",
        "mywatchlist": "သဵၼ်ႈမၢႆပႂ်ႉတူၺ်း",
        "watch": "ပႂ်ႉတူၺ်း",
index cb5735d..59a3ba6 100644 (file)
        "yourpasswordagain": "මුරපදය යළි ඇතුළු කරන්න:",
        "createacct-yourpasswordagain": "මුරපදය සනාථ කරන්න",
        "createacct-yourpasswordagain-ph": "මුරපදය යළි ඇතුළු කරන්න",
-       "remembermypassword": "මාගේ පිවිසීම මෙම ගවේෂක මතකයෙහි (උපරිම ලෙස {{PLURAL:$1|දින|දින}}) $1 ක් මතක තබාගන්න",
        "userlogin-remembermypassword": "මා ප්‍රවිසීම් තත්වයේම තබන්න",
        "userlogin-signwithsecure": "ආරක්‍ෂිත සබඳතාව භාවිතා කරන්න",
        "cannotloginnow-title": "දැන් පිවිසීමට නොහැකිය",
        "passwordreset-emailtext-user": "{{SITENAME}} හි පරිශීලක $1,{{SITENAME}}($4)සඳහා මුරපදය යලි පිහිටුවීමට ඉල්ලා ඇත.\n\n$2\n\n{{PLURAL:$3|මෙම මුරපදය|මෙම මුරපද}}{{PLURAL:$5|එක් දිනකින්|දවස්$5කින්}}කල් ඉකුත් වනු ඇත.\nඔබ දැන් ඇතුළු වී නව මුරපදයක් තේරිය යුතුය.මෙම ඉල්ලීම වෙන කෙනෙකු විසින් හෝ ඔබට ඔබගේ මුල් මුරපදය මතක නම් හෝ ඔබ තව දුරටත් එය වෙනස් කිරීමට අදහස් නොකරයි නම් හෝ ඔබ මෙම පනිවිඩය නොසලකාහැර ඔබගේ පැරණි මුරපදය භාවිතා කරන්න.",
        "passwordreset-emailelement": "පරිශීලක නාමය: \n$1\n\nතාවකාලික මුරපදය: \n$2",
        "passwordreset-emailsentemail": "මුර-පදය නැවත සකස් කිරීම පිළිබඳව විද්‍යුත් තැපෑලක් යවන ලදී.",
-       "passwordreset-invalideamil": "වලංගු නැති ඊමේල් ලිපිනය",
+       "passwordreset-invalidemail": "වලංගු නැති ඊමේල් ලිපිනය",
        "changeemail": "විද්‍යුත් තැපෑල වෙනස් කරන්න හෝ ඉවත් කරන්න",
        "changeemail-header": "ගිණුම් විද්‍යුත් තැපැල් ලිපිනය වෙනස් කරන්න",
        "changeemail-no-info": "මෙම පිටුව සෘජු ලෙස සම්ප්‍රවේශය කෙරුමට පළමුව ඔබ ප්‍රවිෂ්ටව සිටිය යුතුය.",
        "activeusers-intro": "මෙය පසුගිය $1 {{PLURAL:$1|දිනය|දින}}තුළ යම් ක්‍රියාකාරකමක් කළ පරිශීලකයන්ගේ ලැයිස්තුවකි.",
        "activeusers-count": "{{PLURAL:$1|එක් පියවරක්|පියවර $1 ක්}} අවසන් {{PLURAL:$3|දිනය|දින $3}} තුළ",
        "activeusers-from": "මෙයින් ඇරඹෙන පරිශීලකයන් පෙන්වන්න:",
-       "activeusers-hidebots": " bots සඟවන්න",
-       "activeusers-hidesysops": "පරිපාලකයින් සඟවන්න",
        "activeusers-noresult": "කිසිදු පරිශීලකයෙකු හමුනොවිණි.",
        "activeusers-submit": "ක්‍රියාකාරී පරිශීලකයන් පෙන්වන්න",
        "listgrouprights": "පරිශීලක කාණ්ඩ හිමිකම්",
        "htmlform-cloner-create": "තව එක් කරන්න",
        "htmlform-cloner-delete": "ඉවත් කරන්න",
        "htmlform-cloner-required": "අවම වශයෙන් එක් වටිනාකම අවශ්ය වේ.",
-       "sqlite-has-fts": "$1 සම්පූර්ණ-පෙළ සෙවුම් සහය සමග",
-       "sqlite-no-fts": "$1 සම්පූර්ණ-පෙළ සෙවුම් සහය රහිතව",
        "logentry-delete-delete": "$1 විසින් $3 පිටුව {{GENDER:$2|මකා දමන ලදී}}",
        "logentry-delete-restore": "$1 {{GENDER:$2|නැවත පිහිටුවන ලදී}} පිටු $3",
        "logentry-delete-event-legacy": "$1 විසින් $3 හී ලඝු සිදුවීම් වල දෘශ්‍යතාවය වෙනස් කරන ලදී",
index c541349..ef86af1 100644 (file)
@@ -39,8 +39,8 @@
        },
        "tog-underline": "Podčiarkovať odkazy:",
        "tog-hideminor": "V posledných úpravách nezobrazovať drobné úpravy",
-       "tog-hidepatrolled": "Skryť strážené úpravy v Posledných úpravách",
-       "tog-newpageshidepatrolled": "Skryť strážené stránky zo zoznamu nových stránok",
+       "tog-hidepatrolled": "Skryť preverené úpravy v Posledných úpravách",
+       "tog-newpageshidepatrolled": "Skryť preverené stránky v zozname nových stránok",
        "tog-hidecategorization": "Skryť kategorizáciu stránok",
        "tog-extendwatchlist": "Rozšíriť zoznam sledovaných stránok, aby zobrazoval všetky úpravy, nie len posledné",
        "tog-usenewrc": "Zoskupiť zmeny v posledných úpravách a na zozname sledovaných stránok podľa stránky",
@@ -62,7 +62,7 @@
        "tog-enotifminoredits": "Upozorniť ma e-mailom aj na drobné úpravy stránok a súborov",
        "tog-enotifrevealaddr": "Zobraziť moju emailovú adresu v emailoch s upozornením",
        "tog-shownumberswatching": "Zobraziť počet používateľov sledujúcich stránku",
-       "tog-oldsig": "Súčasný podpis:",
+       "tog-oldsig": "Váš súčasný podpis:",
        "tog-fancysig": "Považovať podpisy za wikitext (bez automatických odkazov)",
        "tog-uselivepreview": "Používať živý náhľad",
        "tog-forceeditsummary": "Upozoriť ma, keď nevyplním zhrnutie úprav",
@@ -72,7 +72,7 @@
        "tog-watchlisthideliu": "Skryť úpravy prihlásených používateľov zo zoznamu sledovaných stránok",
        "tog-watchlistreloadautomatically": "Po zmene nastavení automaticky aktualizovať zoznam sledovaných (vyžaduje JavaScript)",
        "tog-watchlisthideanons": "Skryť úpravy anonymných používateľov zo zoznamu sledovaných stránok",
-       "tog-watchlisthidepatrolled": "Skryť strážené úpravy Zozname sledovaných stránok",
+       "tog-watchlisthidepatrolled": "Skryť preverené úpravy v zozname sledovaných stránok",
        "tog-watchlisthidecategorization": "Skryť kategorizáciu stránok",
        "tog-ccmeonemails": "Posielať mi kópie e-mailov, ktoré pošlem ostatným používateľom",
        "tog-diffonly": "Nezobrazovať obsah stránky pod rozdielmi",
        "newwindow": "(otvorí v novom okne)",
        "cancel": "Zrušiť",
        "moredotdotdot": "Viac...",
-       "morenotlisted": "Tento zoznam nie je úplný.",
+       "morenotlisted": "Tento zoznam nemusí byť úplný.",
        "mypage": "Stránka",
        "mytalk": "Diskusia",
        "anontalk": "Diskusia",
        "talk": "Diskusia",
        "views": "Zobrazenia",
        "toolbox": "Nástroje",
+       "tool-link-userrights": "Zmeniť používateľské skupiny {{GENDER:$1|tohoto použivateľa|tejto používateľky}}",
+       "tool-link-emailuser": "Poslať e-mail {{GENDER:$1|tomuto používateľovi|tejto používateľke}}",
        "userpage": "Zobraziť stránku používateľa",
        "projectpage": "Zobraziť projektovú stránku",
        "imagepage": "Zobraziť stránku súboru",
        "content-model-css": "CSS",
        "content-json-empty-object": "Prázdny objekt",
        "content-json-empty-array": "Prázdne pole",
+       "deprecated-self-close-category": "Stránky s neplatnými samouzavrenými HTML značkami",
+       "deprecated-self-close-category-desc": "Stránka obsahuje neplatné samouzatvárajúce HTML značky, napr. <code>&lt;b/></code> alebo <code>&lt;span/></code>. Ich správanie sa v záujme konzistencie so špecifikáciou HTML5 čoskoro zmení a použitie je preto vo wikitexte zastarané.",
        "duplicate-args-warning": "<strong>Upozornenie:</strong> Stránka [[:$1]] volá [[:$2]] s viacerými hodnotami parametra „$3“. Použitá bude len posledná odovzdaná hodnota.",
        "duplicate-args-category": "Stránky s duplicitnými parametrami pri volaniach šablón",
        "duplicate-args-category-desc": "Stránka obsahuje volania šablóny používajúce duplicitné parametere, ako napríklad <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> alebo <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "searchprofile-advanced-tooltip": "Hľadať vo vymenovaných menných priestoroch",
        "search-result-size": "$1 ({{PLURAL:$2|1 slovo|$2 slová|$2 slov}})",
        "search-result-category-size": "{{PLURAL:$1|1 člen|$1 členovia|$1 členov}} ({{PLURAL:$2|1 podkategória|$2 podkategórie|$2 podkategórií}}, {{PLURAL:$3|1 súbor|$3 súbory|$3 súborov}})",
-       "search-redirect": "(presmerovanie $1)",
+       "search-redirect": "(presmerovanie $1)",
        "search-section": "(sekcia $1)",
        "search-category": "($1 kategória)",
+       "search-file-match": "(výskyt v obsahu súboru)",
        "search-suggest": "Mali ste na mysli „$1“?",
        "search-rewritten": "Zobrazujú sa výsledky pre $1. Vyhľadať namiesto toho $2.",
        "search-interwiki-caption": "Sesterské projekty",
        "prefs-watchlist-token": "Token zoznamu sledovaných?",
        "prefs-misc": "Rôzne",
        "prefs-resetpass": "Zmeniť heslo",
-       "prefs-changeemail": "Zmeniť email",
+       "prefs-changeemail": "Zmeniť alebo odstrániť e-mailovú adresu",
        "prefs-setemail": "Nastaviť emailovú adresu",
        "prefs-email": "Možnosti e-mailu",
        "prefs-rendering": "Vzhľad",
        "prefs-files": "Súbory",
        "prefs-custom-css": "Vlastný CSS",
        "prefs-custom-js": "Vlastný JS",
-       "prefs-common-css-js": "Spoločné CSS/JS pre všetky témy vzhľadu:",
+       "prefs-common-css-js": "Spoločné CSS/JS pre všetky témy:",
        "prefs-reset-intro": "Túto stránku môžete použiť na vrátenie predvolených hodnôt vašich nastavení.\nTúto operáciu nemožno vrátiť.",
        "prefs-emailconfirm-label": "Overenie e-emailu:",
        "youremail": "Váš e-mail²",
        "right-edit": "Upravovať stránky (ktoré nie sú diskusné stránky)",
        "right-createpage": "Vytvárať stránky (ktoré nie sú diskusné stránky)",
        "right-createtalk": "Vytvárať diskusné stránky",
-       "right-createaccount": "Vytvárať nové používateľské účty",
+       "right-createaccount": "Vytvárať nové používateľské kontá",
+       "right-autocreateaccount": "Automatické prihlásenie s externým používateľským kontom",
        "right-minoredit": "Označovať úpravy ako drobné",
        "right-move": "Presúvať stránky",
        "right-move-subpages": "Presunúť stránky aj s podstránkami",
        "right-noratelimit": "Neovplyvnené obmedzeniami",
        "right-import": "Importovať stránky z iných wiki",
        "right-importupload": "Importovať stránky nahraním súboru",
-       "right-patrol": "Označiť úpravy ako strážené",
-       "right-autopatrol": "Nechať úpravy automaticky označiť ako strážené",
-       "right-patrolmarks": "Používať možnosti stráženia posledných úprav",
+       "right-patrol": "Označovanie cudzích úprav ako preverených",
+       "right-autopatrol": "Automatické označovanie vlastných úprav ako preverených",
+       "right-patrolmarks": "Zobrazovanie záznamov o prevereniach v Posledných úpravách",
        "right-unwatchedpages": "Zobraziť zoznam nesledovaných stránok",
        "right-mergehistory": "Zlučovať histórie stránok",
        "right-userrights": "Upravovať oprávnenia ostatných používateľov",
        "right-override-export-depth": "Exportovať stránky vrátane okdazovaných stránok do hĺbky 5 odkazov",
        "right-sendemail": "Posielať e-mail ostatným používateľom",
        "right-passwordreset": "Prezeranie e-mailov pre znovunastavovanie hesla",
+       "right-managechangetags": "Vytvárenie a (de)aktivácia [[Special:Tags|značiek]]",
+       "right-applychangetags": "Pridávanie [[Special:Tags|značiek]] k vlastným úpravám",
+       "right-changetags": "Pridávanie ľubovoľných [[Special:Tags|značiek]] na jednotlivé revízie a záznamy a ich odoberanie",
+       "right-deletechangetags": "Mazanie [[Special:Tags|značiek]] z databázy",
        "grant-generic": "balík práv „$1“",
        "grant-group-page-interaction": "Interagovať so stránkami",
        "grant-group-file-interaction": "Interagovať s multimédiami",
        "grant-basic": "Základné oprávnenia",
        "grant-viewdeleted": "Zobrazovať vymazané súbory a stránky",
        "grant-viewmywatchlist": "Zobrazovať váš zoznam sledovaných stránok",
+       "grant-viewrestrictedlogs": "Prehliadať skryté záznamy",
        "newuserlogpage": "Záznam vytvorených používateľov",
        "newuserlogpagetext": "Toto je záznam naposledy vytvorených používateľských účtov.",
        "rightslog": "Záznam používateľských práv",
        "action-rollback": "rýchlo vrátiť úpravy posledného používateľa, ktorý upravoval danú stránku",
        "action-import": "importovať stránky z inej wiki",
        "action-importupload": "importovať stránky z nahraného súboru",
-       "action-patrol": "označiť úpravy iných ako strážené",
-       "action-autopatrol": "označiť vlastné úpravy ako strážené",
+       "action-patrol": "označovať cudzie úpravy ako preverené",
+       "action-autopatrol": "označovať vlastné úpravy ako preverené",
        "action-unwatchedpages": "zobraziť zoznam nesledovaných stránok",
        "action-mergehistory": "zlúčiť históriu tejto stránky",
        "action-userrights": "upravovať práva všetkých používateľov",
        "recentchanges-label-newpage": "Táto úprava vytvorila novú stránku",
        "recentchanges-label-minor": "Toto je drobná úprava",
        "recentchanges-label-bot": "Túto úpravu vykonal bot",
-       "recentchanges-label-unpatrolled": "Táto úprava zatiaľ nebola strážená",
+       "recentchanges-label-unpatrolled": "Táto úprava zatiaľ nebola preverená",
        "recentchanges-label-plusminus": "Veľkosť stránky sa zmenila o toľkoto bajtov",
        "recentchanges-legend-heading": "<strong>Legenda:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (pozri tiež [[Special:NewPages|zoznam nových stránok]])",
        "rcshowhidebots": "$1 botov",
        "rcshowhidebots-show": "Zobraziť",
        "rcshowhidebots-hide": "Skryť",
-       "rcshowhideliu": "$1 registrovaných používateľov",
+       "rcshowhideliu": "$1 registrovaných",
        "rcshowhideliu-show": "Zobraziť",
        "rcshowhideliu-hide": "Skryť",
-       "rcshowhideanons": "$1 anonymných používateľov",
+       "rcshowhideanons": "$1 anonymov",
        "rcshowhideanons-show": "Zobraziť",
        "rcshowhideanons-hide": "Skryť",
-       "rcshowhidepatr": "$1 úpravy strážených stránok",
+       "rcshowhidepatr": "$1 preverené úpravy",
        "rcshowhidepatr-show": "Zobraziť",
        "rcshowhidepatr-hide": "Skryť",
        "rcshowhidemine": "$1 moje úpravy",
        "rcshowhidemine-show": "Zobraziť",
        "rcshowhidemine-hide": "Skryť",
-       "rcshowhidecategorization": "$1 kategorizáciu stránok",
+       "rcshowhidecategorization": "$1 kategorizáciu",
        "rcshowhidecategorization-show": "Zobraziť",
        "rcshowhidecategorization-hide": "Skryť",
        "rclinks": "Zobraziť posledných $1 úprav za posledných $2 dní<br />$3",
        "upload-copy-upload-invalid-domain": "Kopírovanie nahraných súborov nie je dostupné z tejto domény.",
        "upload-dialog-title": "Nahrať súbor",
        "upload-dialog-button-cancel": "Zrušiť",
+       "upload-dialog-button-back": "Späť",
        "upload-dialog-button-done": "Hotovo",
        "upload-dialog-button-save": "Uložiť",
        "upload-dialog-button-upload": "Nahrať",
        "booksources-search": "Hľadať",
        "booksources-text": "Nižšie je zoznam odkazov na iné stránky, ktoré predávajú nové a použité knihy a tiež môžu obsahovať ďalšie informácie o knihách, ktoré hľadáte:",
        "booksources-invalid-isbn": "Zdá sa, že dané ISBN nie je platné. Skontrolujte, či ste neurobili chybu pri kopírovaní z pôvodného zdroja.",
+       "magiclink-tracking-rfc": "Stránky obsahujúce magické odkazy RFC",
+       "magiclink-tracking-pmid": "Stránky obsahujúce magické odkazy PMID",
+       "magiclink-tracking-isbn": "Stránky obsahujúce magické odkazy ISBN",
        "specialloguserlabel": "Pôvodca:",
        "speciallogtitlelabel": "Cieľ (názov alebo {{ns:user}}:Používateľské meno):",
        "log": "Záznamy",
        "activeusers-intro": "Toto je zoznam používateľov, ktorí $1 {{PLURAL:$1|za posledný 1 deň|za posledné $1 dni|za posledných $1 dní}} vykonali nejakú aktivitu.",
        "activeusers-count": "$1 {{PLURAL:$1|operácia|operácie|operácií}} za {{PLURAL:$3|posledný deň|posledné $3 dni|posledných $3 dní}}",
        "activeusers-from": "Zobraziť používateľov počínajúc:",
-       "activeusers-hidebots": "Skryť robotov",
-       "activeusers-hidesysops": "Skryť správcov",
        "activeusers-noresult": "Neboli nájdení žiadni používatelia.",
        "activeusers-submit": "Zobraziť aktívnych používateľov",
        "listgrouprights": "Práva skupiny používateľov",
        "watchnologin": "Nie ste prihlásený/á",
        "addwatch": "Pridať do zoznamu sledovaných stránok",
        "addedwatchtext": "Stránka „[[:$1]]“ a jej diskusná stránka boli pridané do vášho zoznamu [[Special:Watchlist|sledovaných stránok]].",
+       "addedwatchtext-talk": "„[[:$1]]“ a súvisiaca stránka boli pridané do vášho zoznamu [[Special:Watchlist|sledovaných stránok]].",
        "addedwatchtext-short": "Stránka „$1“ bola pridaná do vášho zoznamu sledovaných.",
        "removewatch": "Odstrániť zo zoznamu sledovaných",
        "removedwatchtext": "Stránka „[[:$1]]“ a jej diskusná stránka boli odstránené z vášho [[Special:Watchlist|zoznamu sledovaných stránok]].",
+       "removedwatchtext-talk": "„[[:$1]]“ a súvisiaca stránka boli odstránené z vášho [[Special:Watchlist|zoznamu sledovaných stránok]].",
        "removedwatchtext-short": "Stránka „$1“ bola odstránená z vášho zoznamu sledovaných.",
        "watch": "Sledovať",
        "watchthispage": "Sledovať túto stránku",
        "revertpage": "Posledné úpravy používateľa [[Special:Contributions/$2|$2]] ([[User talk:$2|diskusia]]) vrátené; bola obnovená posledná úprava $1",
        "revertpage-nouser": "Vrátené úpravy od skrytého používateľa na poslednú revíziu od {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Úpravy $1 vrátené; obnovená posledná verzia od $2.",
+       "rollback-success-notify": "Úpravy používateľa $1 boli vrátené;\nobnovená posledná revízia od používateľa $2. [$3 Zobraziť zmeny]",
        "sessionfailure-title": "Chyba relácie",
        "sessionfailure": "Zdá sa, že je problém s vašou prihlasovacou reláciou;\ntáto akcia bola zrušená ako prevencia proti zneužitiu relácie (session).\nProsím, stlačte \"naspäť\", obnovte stránku, z ktorej ste sa sem dostali, a skúste to znova.",
        "changecontentmodel": "Zmeniť model obsahu stránky",
        "modifiedarticleprotection": "zmenená úroveň ochrany „[[$1]]“",
        "unprotectedarticle": "odstránil ochranu stránky „[[$1]]“",
        "movedarticleprotection": "nastavenia zamknutia stránky presunuté z „[[$2]]” na „[[$1]]”",
+       "protectedarticle-comment": "{{GENDER:$2|Zamkol|Zamkla}} stránku „[[$1]]“",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Zmenil|Zmenila}} úroveň ochrany stránky „[[$1]]“",
+       "unprotectedarticle-comment": "{{GENDER:$2|Odomkol|Odomkla}} stránku „[[$1]]“",
        "protect-title": "Zamykám „$1“",
        "protect-title-notallowed": "Zobraziť úroveň ochrany \" $1 \"",
        "prot_1movedto2": "[[$1]] premiestnená na [[$2]]",
        "movelogpagetext": "Tu je zoznam posledných presunutí.",
        "movesubpage": "{{PLURAL:$1|Podstránka|Podstránky}}",
        "movesubpagetext": "Táto stránka má $1 {{PLURAL:$1|podstránku, ktorá je zobrazená nižšie|podstránky, ktoré sú zobrazené nižšie|podstránok, ktoré sú zobrazené nižšie}}.",
+       "movesubpagetalktext": "Zodpovedajúca diskusná stránka má {{PLURAL:$1|jednu podstránku, zobrazenú|$1 podstránky, zobrazené|$1 podstránok, zobrazených}} nižšie.",
        "movenosubpage": "Táto stránka nemá podstránky.",
        "movereason": "Dôvod:",
        "revertmove": "obnoviť",
        "pageinfo-category-pages": "Počet stránok",
        "pageinfo-category-subcats": "Počet podkategórií",
        "pageinfo-category-files": "Počet súborov",
-       "markaspatrolleddiff": "Označiť ako stráženú",
-       "markaspatrolledtext": "Označiť túto stránku ako stráženú",
-       "markedaspatrolled": "Označené ako strážené",
-       "markedaspatrolledtext": "Vybraná verzia [[:$1]] bola označená ako strážená.",
+       "pageinfo-user-id": "ID používateľa",
+       "markaspatrolleddiff": "Označiť ako preverené",
+       "markaspatrolledtext": "Označiť túto stránku ako preverenú",
+       "markaspatrolledtext-file": "Označiť túto revíziu súboru ako preverenú",
+       "markedaspatrolled": "Označené ako preverené",
+       "markedaspatrolledtext": "Zvolená revízia stránky [[:$1]] bola označená ako preverená.",
        "rcpatroldisabled": "Stráženie posledných úprav bolo vypnuté",
        "rcpatroldisabledtext": "Funkcia stráženia posledných úprav je momentálne vypnutá.",
-       "markedaspatrollederror": "Nie je možné označiť ako strážené",
-       "markedaspatrollederrortext": "Pre označenie ako strážený je potrebné uviesť revíziu, ktorá sa má označiť ako strážená.",
-       "markedaspatrollederror-noautopatrol": "Nie je vám umožnené označiť vlastné úpravy za strážené.",
-       "markedaspatrollednotify": "Táto zmena stránky $1 bola označená ako strážená.",
-       "markedaspatrollederrornotify": "Označenie ako strážená zlyhalo.",
-       "patrol-log-page": "Záznam strážení",
-       "patrol-log-header": "Toto je záznam strážených revízií.",
-       "log-show-hide-patrol": "záznam stráženia $1",
-       "log-show-hide-tag": "záznam značiek $1",
+       "markedaspatrollederror": "Nie je možné označiť ako preverené",
+       "markedaspatrollederrortext": "Musíte zvoliť revíziu, ktorá má byť označená ako preverená.",
+       "markedaspatrollederror-noautopatrol": "Nemáte povolené označovať vlastné úpravy ako preverené.",
+       "markedaspatrollednotify": "Táto úprava stránky $1 bola označená ako preverená.",
+       "markedaspatrollederrornotify": "Nepodarilo sa označiť ako preverené.",
+       "patrol-log-page": "Záznam preverených úprav",
+       "patrol-log-header": "Toto je záznam preverených revízií.",
+       "log-show-hide-patrol": "$1 záznam preverených úprav",
+       "log-show-hide-tag": "$1 záznam značiek",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Označiť revíziu $3 stránky $2 ako preverenú?",
        "deletedrevision": "Zmazať staré verzie $1",
        "filedeleteerror-short": "Chyba pri mazaní súboru: $1",
        "filedeleteerror-long": "Vyskytli sa chyby pri mazaní súboru:\n\n$1",
        "tags-active-yes": "Áno",
        "tags-active-no": "Nie",
        "tags-source-extension": "Definované softvérom",
+       "tags-source-manual": "Pridané manuálne používateľmi a botmi",
        "tags-source-none": "Už sa nepoužíva",
        "tags-edit": "upraviť",
        "tags-delete": "zmazať",
        "htmlform-cloner-create": "Pridať ďalšie",
        "htmlform-cloner-delete": "Odstrániť",
        "htmlform-cloner-required": "Je povinná najmenej jedna hodnota.",
+       "htmlform-date-placeholder": "RRRR-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "RRRR-MM-DD HH:MM:SS",
        "logentry-delete-delete": "$1 zmazal stránku $3",
        "logentry-delete-restore": "$1 obnovil stránku $3",
        "logentry-delete-event": "$1 zmenil viditeľnosť {{PLURAL:$5|záznamu udalostí|$5 záznamov udalostí}} k stránke $3: $4",
        "feedback-bugornote": "Ak ste pripravený podrobne popísať technický problém, prosím pošlite [$1 hlásenie o chybe]. \nV opačnom prípade môžete použiť zjednodušený formulár nižšie. Váš komentár sa pridá na stránku „[$3 $2]“ spolu s vašim používateľským meno a prehliadačom, ktorý používate.",
        "feedback-cancel": "Zrušiť",
        "feedback-close": "Hotovo",
+       "feedback-external-bug-report-button": "Založiť technickú úlohu",
        "feedback-dialog-title": "Odoslať názor",
-       "feedback-error-title": "Chyba",
+       "feedback-dialog-intro": "Pomocou formulára nižšie môžete odoslať svoj názor. Váš komentár sa spolu s vašim použivateľským menom pridá na stránku „$1“.",
        "feedback-error1": "Chyba: Nerozpoznaný výsledok z API",
        "feedback-error2": "Chyba: Úprava sa nepodarila",
        "feedback-error3": "Chyba: Žiadna odpoveď z API",
        "feedback-message": "Správa:",
        "feedback-subject": "Predmet:",
        "feedback-submit": "Odoslať",
+       "feedback-terms": "Beriem na vedomie, že informácie o mojom prehliadači zahŕňajú jeho presnú verziu spolu s verziou operačného systému a budú zverejnené pri mojom komentári.",
+       "feedback-termsofuse": "Súhlasím s tým, že budem poskytovať spätnú väzbu v súlade s Podmienkami použitia.",
        "feedback-thanks": "Ďakujeme. Váš komentár bol odoslaný na stránku „[$2 $1]“.",
        "feedback-thanks-title": "Ďakujeme",
        "feedback-useragent": "Prehliadač:",
        "searchsuggest-search": "Hľadať",
        "searchsuggest-containing": "obsahuje...",
+       "api-error-autoblocked": "Vaše IP adresa bola automaticky zablokovaná, pretože ju používal zablokovaný používateľ.",
        "api-error-badaccess-groups": "Nemáte oprávnenie nahrávať súbory na tejto wiki.",
        "api-error-badtoken": "Vnútorná chyba: Zlý token.",
+       "api-error-blocked": "Možnosť editovať vám bola zablokovaná.",
        "api-error-copyuploaddisabled": "Nahrávanie z URL je na tomto serveri zakázané.",
        "api-error-duplicate": "{{PLURAL:$1|ďalší súbor|ďalšie súbory}} s rovnakým obsahom už na tejto wiki existujú",
        "api-error-duplicate-archive": "{{PLURAL:$1|ďalší súbor|ďalšie súbory}} s rovnakým obsahom už na tejto wiki existoval, ale {{PLURAL:$1|bol zmazaný|boli zmazané}}.",
        "expand_templates_generate_xml": "Zobraziť strom XML",
        "expand_templates_generate_rawhtml": "Zobraziť surové HTML",
        "expand_templates_preview": "Náhľad",
-       "pagelanguage": "Voľba jazyka stránky",
+       "pagelanguage": "Zmeniť jazyk stránky",
        "pagelang-name": "Stránka",
        "pagelang-language": "Jazyk",
        "pagelang-use-default": "Použiť predvolený jazyk",
        "pagelang-select-lang": "Vybrať jazyk",
+       "pagelang-submit": "Odoslať",
        "right-pagelang": "Zmeniť jazyk stránky",
        "action-pagelang": "meniť jazyk stránky",
        "default-skin-not-found": "Uups! Základná tapeta pre Vašu wiki, popísanú v <code dir=\"ltr\">$wgDefaultSkin</code> ako <code>$1</code>, nie je dostupná. \n\nVaša inštalácia pravdepodobne obsahuje nasledovné tapety. Pozri [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] pre viac informácii o ich aktivácii a zvoľte základnú.\n\n$2\n\n; Ak ste MediaWiki len teraz nainštalovali\n; Zrejme ste to nainštalovali z gitu alebo priamo zo zdrojového kódu inou metódou. Je to očakávané. Skúste nainštalovať nejaké tapety z [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory];\n:*Stiahnutím [https://www.mediawiki.org/wiki/Download tarball installer], ktorý ponúka viacero tapiet a rozšírení. Skopírovať a nalepiť možno priamo z <code>skins/</code>.\n:*Klonovanie jednej zo <code>mediawiki/skins/*</code> schránok cez git do <code dir=\"ltr\">skins/</code> priečinku Vašej Media Wiki inštalácie.\n: S existujúcou git schránkou, ak ste vývojár MediaWiki, by nemal byť konflikt.\n\n: Ak ste upgradeovali MediaWiki\n: MediaWiki 1.24 a novšie už tapety automaticky neaktivujú. (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). Nasledovný kód môžete skopírovať do <code>LocalSettings.php</code> pre aktivovanie všetkých dostupných tapiet.\n\n<pre dir=\"ltr\">$3</pre>\n\n; Ak ste upravili <code>LocalSettings.php</code>:\n: Skontrolujte chyby.",
        "mediastatistics-header-text": "Text",
        "mediastatistics-header-executable": "Spustiteľné súbory",
        "mediastatistics-header-archive": "Komprimované formáty",
+       "mediastatistics-header-total": "Všetky súbory",
        "json-warn-trailing-comma": "Z JSONu {{PLURAL:$1|bola odstránená 1 koncová čiarka|boli odstránené $1 koncové čiarky|bolo odstránených $1 koncových čiarok}}",
        "json-error-unknown": "Došlo k problému s JSONom. Chyba: $1",
        "json-error-depth": "Maximálna hĺbka zásobníka bola prekročená",
        "special-characters-group-ipa": "IPA",
        "special-characters-group-symbols": "Symboly",
        "special-characters-group-greek": "Grécke",
+       "special-characters-group-greekextended": "Grécke rozšírené",
        "special-characters-group-cyrillic": "Azbuka",
        "special-characters-group-arabic": "Arabské",
        "special-characters-group-arabicextended": "Arabské rozšírené",
        "mw-widgets-dateinput-placeholder-month": "RRRR-MM",
        "mw-widgets-titleinput-description-new-page": "stránka zatiaľ neexistuje",
        "mw-widgets-titleinput-description-redirect": "presmerovanie na $1",
-       "randomrootpage": "Náhodná koreňová stránka"
+       "randomrootpage": "Náhodná koreňová stránka",
+       "changecredentials": "Zmena prihlasovacích údajov",
+       "removecredentials": "Odstránenie prihlasovacích údajov"
 }
index 71cc9ad..a5367a4 100644 (file)
        "botpasswords-label-delete": "Izbriši",
        "botpasswords-label-resetpassword": "Ponastavi geslo",
        "botpasswords-label-grants": "Veljavne pravice:",
-       "botpasswords-help-grants": "Vsaka pravica dodeli dostop do navedenih uporabniških pravic, ki jih uporabniški račun že ima. Za več informacij si oglejte [[Special:ListGrants|tabelo pravic]].",
+       "botpasswords-help-grants": "Pravice omogočajo dostop do pravic, ki jih vaš uporabniški račun že ima. Tukajšnja omogočitev pravice ne podeli dostopa do katere koli pravice, ki je vaš uporabniški račun drugače še nima. Za več informacij si oglejte [[Special:ListGrants|tabelo pravic]].",
        "botpasswords-label-grants-column": "Odobreno",
        "botpasswords-bad-appid": "Ime bota »$1« ni veljavno.",
        "botpasswords-insert-failed": "Dodajanje imena bota »$1« ni uspelo. Ste ga že dodali?",
        "passwordreset-nocaller": "Podati morate klicatelja",
        "passwordreset-nosuchcaller": "Klicatelj ne obstaja: $1",
        "passwordreset-ignored": "Ponastavitve gesla nismo izvedli. Morda ni nastavljen noben ponudnik?",
-       "passwordreset-invalideamil": "Neveljavni e-poštni naslov",
+       "passwordreset-invalidemail": "Neveljavni e-poštni naslov",
        "passwordreset-nodata": "Navedli niste ne uporabniškega imena ne e-poštnega naslova",
        "changeemail": "Sprememba ali odstranitev e-poštnega naslova",
        "changeemail-header": "Izpolnite obrazec za spremembo vašega e-poštnega naslova. Če želite s svojega računa odstraniti povezavo s katerim koli e-poštnim naslovom, pustite polje za nov e-poštni naslov med potrjevanje obrazca prazno.",
        "searchprofile-advanced-tooltip": "Iskanje v imenskih prostorih po meri",
        "search-result-size": "$1 ({{PLURAL:$2|1 beseda|2 besedi|$2 besede|$2 besed|$2 besed}})",
        "search-result-category-size": "$1 {{PLURAL:$1|član|člana|člani|članov}} ($1 {{PLURAL:$2|podkategorija|podkategoriji|podkategorije|podkategorij}}, $1 {{PLURAL:$3|datoteka|datoteki|datoteke|datotek}})",
-       "search-redirect": "(preusmeritev $1)",
+       "search-redirect": "(preusmeritev s strani $1)",
        "search-section": "(razdelek $1)",
        "search-category": "(kategorija $1)",
        "search-file-match": "(ujema se z vsebino datoteke)",
        "grant-basic": "Osnovne pravice",
        "grant-viewdeleted": "Ogled izbrisanih datotek in strani",
        "grant-viewmywatchlist": "Ogled svojega spiska nadzorov",
+       "grant-viewrestrictedlogs": "Ogled omejenih dnevniških vnosov",
        "newuserlogpage": "Dnevnik registracij uporabnikov",
        "newuserlogpagetext": "Prikazan je dnevnik nedavnih registracij novih uporabnikov.",
        "rightslog": "Dnevnik uporabniških pravic",
        "upload-dialog-disabled": "Nalaganj datotek z uporabo tega obrazca je na wikiju onemogočeno.",
        "upload-dialog-title": "Naloži datoteko",
        "upload-dialog-button-cancel": "Prekliči",
+       "upload-dialog-button-back": "Nazaj",
        "upload-dialog-button-done": "Končano",
        "upload-dialog-button-save": "Shrani",
        "upload-dialog-button-upload": "Naloži",
        "apisandbox-results-fixtoken-fail": "Pridobivanje žetona »$1« je spodletelo.",
        "apisandbox-alert-page": "Polja na strani niso veljavna.",
        "apisandbox-alert-field": "Vrednost polja ni veljavna.",
+       "apisandbox-continue": "Nadaljuj",
+       "apisandbox-continue-clear": "Počisti",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} bo [https://www.mediawiki.org/wiki/API:Query#Continuing_queries nadaljevalo] zadnjo zahtevo; {{int:apisandbox-continue-clear}} bo počistilo parametre, povezane z nadaljevanjem.",
+       "apisandbox-param-limit": "Vnesite <kbd>max</kbd>, da uporabite največjo omejitev.",
        "booksources": "Viri knjig",
        "booksources-search-legend": "Išči knjižne vire",
        "booksources-search": "Išči",
        "booksources-text": "Sledi seznam povezav do drugi spletnih strani, ki prodajajo nove in rabljene knjige, in imajo morda nadaljnje informacije o knjigah, ki jih iščete:",
        "booksources-invalid-isbn": "Za dani ISBN se ne zdi, da je veljaven; preverite za morebitne napake pri kopiranju iz prvotnega vira.",
+       "magiclink-tracking-rfc": "Strani, ki uporabljajo čarobne povezave RFC",
+       "magiclink-tracking-rfc-desc": "Stran uporablja čarobne povezave RFC. Oglejte si [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] za navodila glede selitve.",
+       "magiclink-tracking-pmid": "Strani, ki uporabljajo čarobne povezave PMID",
+       "magiclink-tracking-pmid-desc": "Stran uporablja čarobne povezave PMID. Oglejte si [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] za navodila glede selitve.",
+       "magiclink-tracking-isbn": "Strani, ki uporabljajo čarobne povezave ISBN",
+       "magiclink-tracking-isbn-desc": "Stran uporablja čarobne povezave ISBN. Oglejte si [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] za navodila glede selitve.",
        "specialloguserlabel": "Izvajalec:",
        "speciallogtitlelabel": "Cilj (naslov ali {{ns:user}}:uporabniškoime za uporabnika):",
        "log": "Dnevniki",
        "activeusers-intro": "Seznam uporabnikov, ki so bili kakorkoli aktivni v {{PLURAL:$1|zadnjem $1 dnevu|zadnjih $1 dneh}}.",
        "activeusers-count": "$1 {{PLURAL:$1|dejanje|dejanji|dejanja|dejanj}} v {{PLURAL:$3|preteklem dnevu|preteklih $3 dneh}}",
        "activeusers-from": "Prikaži uporabnike začenši z:",
-       "activeusers-hidebots": "Skrij bote",
-       "activeusers-hidesysops": "Skrij administratorje",
+       "activeusers-groups": "Prikaži uporabnike, ki pripadajo skupinam:",
        "activeusers-noresult": "Noben uporabnik ni bil najden.",
        "activeusers-submit": "Prikaži dejavne uporabnike",
        "listgrouprights": "Pravice uporabniških skupin",
        "modifiedarticleprotection": "spremenjena stopnja zaščite »[[$1]]«",
        "unprotectedarticle": "odstranil(-a) zaščito »[[$1]]«",
        "movedarticleprotection": "nastavitve zaščite so prestavljene iz »[[$2]]« na »[[$1]]«",
+       "protectedarticle-comment": "{{GENDER:$2|Zaščitil|Zaščitila|Zaščitil(-a)}} »[[$1]]«",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Spremenil|Spremenila|Spremenil(-a)}} stopnjo zaščite »[[$1]]«",
+       "unprotectedarticle-comment": "{{GENDER:$2|Odstranil|Odstranil|Odstranil(-a)}} zaščito »[[$1]]«",
        "protect-title": "Zaščita strani »$1«",
        "protect-title-notallowed": "Ogled stopnje zaščite »$1«",
        "prot_1movedto2": "je prestavil(-a) [[$1]] na [[$2]]",
        "movelogpagetext": "Prikazujem seznam prestavljenih strani.",
        "movesubpage": "{{PLURAL:$1|Podstran|Podstrani}}",
        "movesubpagetext": "Ta stran ima $1 {{PLURAL:$1|podstran prikazano|podstrani prikazane}} spodaj.",
+       "movesubpagetalktext": "Pripadajoča stran ima $1 {{PLURAL:$1|podstran, prikazano|podstrani, prikazani|podstrani, prikazane|podstrani, prikazanih}} spodaj.",
        "movenosubpage": "Ta stran nima podstrani.",
        "movereason": "Razlog:",
        "revertmove": "vrni",
        "pageinfo-category-pages": "Število strani",
        "pageinfo-category-subcats": "Število podkategorij",
        "pageinfo-category-files": "Število datotek",
+       "pageinfo-user-id": "ID uporabnika",
        "markaspatrolleddiff": "Označite kot nadzorovano",
        "markaspatrolledtext": "Označite stran kot nadzorovano",
        "markaspatrolledtext-file": "Označite različico datoteke kot nadzorovano",
        "patrol-log-header": "To je dnevnik nadzorovanih redakcij.",
        "log-show-hide-patrol": "$1 dnevnik nadzora",
        "log-show-hide-tag": "$1 dnevnik oznak",
+       "confirm-markpatrolled-button": "V redu",
+       "confirm-markpatrolled-top": "Označimo redakcijo $3 strani $2 kot nadzorovano?",
        "deletedrevision": "Prejšnja redakcija $1 je izbrisana",
        "filedeleteerror-short": "Napaka pri brisanju datoteke: $1",
        "filedeleteerror-long": "Pri brisanju datoteke so se pojavile napake:\n\n$1",
        "newimages-showbots": "Prikaži nalaganja botov",
        "newimages-hidepatrolled": "Skrij nadzorovana nalaganja",
        "noimages": "Nič ni videti.",
+       "gallery-slideshow-toggle": "Preklopi sličice",
        "ilsubmit": "Išči",
        "bydate": "po datumu",
        "sp-newimages-showfrom": "Prikaži datoteke, naložene od $2, $1 naprej",
        "tags-deactivate": "dezaktiviraj",
        "tags-hitcount": "$1 {{PLURAL:$1|sprememba|spremembi|spremembe|sprememb|sprememb}}",
        "tags-manage-no-permission": "Nimate dovoljenja za upravljanje z oznakami sprememb.",
-       "tags-manage-blocked": "Med blokado ne morete upravljati oznak sprememb.",
+       "tags-manage-blocked": "Med blokado {{GENDER:$1|ne morete}} upravljati oznak sprememb.",
        "tags-create-heading": "Ustvari novo oznako",
        "tags-create-explanation": "Privzeto bodo novo ustvarjene oznake na voljo uporabnikom in botom.",
        "tags-create-tag-name": "Ime oznake:",
        "tags-deactivate-not-allowed": "Oznake »$1« ni možno dezaktivirati.",
        "tags-deactivate-submit": "Dezaktiviraj",
        "tags-apply-no-permission": "Nimate dovoljenja za uveljavljanje sprememb oznak skupaj z vašimi spremembami.",
-       "tags-apply-blocked": "Med blokado ne morete uveljaviti oznak sprememb skupaj s svojimi spremembami.",
+       "tags-apply-blocked": "Med blokado {{GENDER:$1|ne morete}} uveljaviti oznak sprememb skupaj s svojimi spremembami.",
        "tags-apply-not-allowed-one": "Oznake »$1« ni mogoče uveljaviti ročno.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|Naslednje oznake|Naslednji oznaki|Naslednjih oznak}} ni mogoče ročno uveljaviti: $1",
        "tags-update-no-permission": "Nimate dovoljenja za dodajanje ali odstranjevanje oznak na posameznih redakcijah ali dnevniških vnosih.",
-       "tags-update-blocked": "Med blokado ne morete dodati ali odstraniti oznak sprememb.",
+       "tags-update-blocked": "Med blokado {{GENDER:$1|ne morete}} dodati ali odstraniti oznak sprememb.",
        "tags-update-add-not-allowed-one": "Oznake »$1« ni mogoče dodati ročno.",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|Naslednje oznake|Naslednji oznaki|Naslednjih oznak}} ni mogoče dodati ročno: $1",
        "tags-update-remove-not-allowed-one": "Oznake »$1« ni mogoče odstraniti.",
        "htmlform-cloner-create": "Dodaj več",
        "htmlform-cloner-delete": "Odstrani",
        "htmlform-cloner-required": "Zahtevana je vsaj ena vrednost.",
+       "htmlform-date-placeholder": "LLLL-MM-DD",
+       "htmlform-time-placeholder": "UU:MM:SS",
+       "htmlform-datetime-placeholder": "LLLL-MM-DD UU:MM:SS",
+       "htmlform-date-invalid": "Navedena vrednost ni prepoznan datum. Poskusite uporabiti obliko LLLL-MM-DD.",
+       "htmlform-time-invalid": "Navedena vrednost ni prepoznan čas. Poskusite uporabiti obliko UU:MM:SS.",
+       "htmlform-datetime-invalid": "Navedena vrednost ni prepoznan datum in čas. Poskusite uporabiti obliko LLLL-MM-DD UU:MM:SS.",
+       "htmlform-date-toolow": "Navedena vrednost je časovno pred najzgodnejšim dovoljenim datumom $1.",
+       "htmlform-date-toohigh": "Navedena vrednost je časovno po najpoznejšim dovoljenim datumom $1.",
+       "htmlform-time-toolow": "Navedena vrednost je časovno pred najzgodnejšim dovoljenim časom $1.",
+       "htmlform-time-toohigh": "Navedena vrednost je časovno po najpoznejšim dovoljenim časom $1.",
+       "htmlform-datetime-toolow": "Navedena vrednost je časovno pred najzgodnejšim dovoljenim datumom in časom $1.",
+       "htmlform-datetime-toohigh": "Navedena vrednost je časovno po najpoznejšim dovoljenim datumom in časom $1.",
        "htmlform-title-badnamespace": "[[:$1]] ni v imenskem prostoru »{{ns:$2}}«.",
        "htmlform-title-not-creatable": "»$1« je naslov strani, ki ga ni mogoče ustvariti",
        "htmlform-title-not-exists": "$1 ne obstaja.",
        "feedback-external-bug-report-button": "Vloži tehnično opravilo",
        "feedback-dialog-title": "Pošljite povratne informacije",
        "feedback-dialog-intro": "Spodnji enostavni obrazec lahko uporabite za pošiljanje povratnih informacij. Vašo pripombo bomo dodali na stran »$1« skupaj z vašim uporabniškim imenom.",
-       "feedback-error-title": "Napaka",
        "feedback-error1": "Napaka: Neznan rezultat iz API",
        "feedback-error2": "Napaka: Urejanje je spodletelo",
        "feedback-error3": "Napaka: Ni odgovora od API",
        "feedback-thanks": "Havala! Vaše povratne informacije smo objavili na strani »[$2 $1]«.",
        "feedback-thanks-title": "Hvala!",
        "feedback-useragent": "Uporabniški agent:",
-       "searchsuggest-search": "Iskanje",
+       "searchsuggest-search": "Iskanje po {{GRAMMAR:dajalnik|{{SITENAME}}}}",
        "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.",
        "authmanager-authn-autocreate-failed": "Samodejno ustvarjanje lokalnega računa je spodletelo: $1",
        "authmanager-change-not-supported": "Navedenih poverilnic nismo mogli spremeniti, saj jih ne bi nič uporabljalo.",
        "authmanager-create-disabled": "Ustvarjanje računov je onemogočeno.",
-       "authmanager-create-from-login": "Da ustvarite svoj račun, prosimo, izpolnite spodnja polja.",
+       "authmanager-create-from-login": "Da ustvarite svoj račun, prosimo, izpolnite polja.",
        "authmanager-create-not-in-progress": "Ustvarjanje računa ni v teku ali pa smo izgubili podatke seje. Prosimo, pričnite znova od začetka.",
        "authmanager-create-no-primary": "Navedenih poverilnic ne moremo uporabiti za ustvarjanje računa.",
        "authmanager-link-no-primary": "Navedenih poverilnic ne moremo uporabiti za povezovanje računa.",
        "usercssispublic": "Pomnite: Podstrani CSS naj ne vsebujejo zaupnih podatkov, saj so vidne tudi drugim uporabnikom.",
        "restrictionsfield-badip": "Neveljaven IP-naslov ali obseg: $1",
        "restrictionsfield-label": "Dovoljeni IP-obsegi:",
-       "restrictionsfield-help": "En IP-naslov ali CIDR-območje na vrstico. Da omogočite vse, uporabite<br><code>0.0.0.0/0</code><br><code>::/0</code>"
+       "restrictionsfield-help": "En IP-naslov ali CIDR-območje na vrstico. Da omogočite vse, uporabite<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Napaka: $1",
+       "edit-error-long": "Napake:\n\n$1"
 }
index cd2f351..5e04c16 100644 (file)
        "yourname": "Benutzernoame:",
        "yourpassword": "Passwort:",
        "yourpasswordagain": "Passwort wiederhola:",
-       "remembermypassword": "Mit diesem Browser dauerhaft angemeldet bleiben (maximal $1 {{PLURAL:$1|Tag|Tage}})",
        "yourdomainname": "Denne Domain:",
        "externaldberror": "Entweder is leit a Fahler bei der externa Authentifizierung vur, oder du darfst dei externes Benutzerkonto ne aktualisiera.",
        "login": "Oanmelda",
        "undo-failure": "De Änderung konnte ne rickgängig gemacht waan, do dar betroffene Obschnitt zwischazeitlich verändert wurde.",
        "undo-norev": "De Beoarbeetung konnte ne rickgängig gemacht waan, do se ne vorhanden ies oder geläscht wurde.",
        "undo-summary": "Änderung $1 vu [[Special:Contributions/$2|$2]] ([[User talk:$2|Dischkur]]) wurde rickgängig gemacht.",
-       "cantcreateaccounttitle": "Nutzerkonto koan ne erstallt waan",
        "cantcreateaccount-text": "De Erstellung annes Nutzerkontos vu dar IP-Atresse '''($1)''' aus wurde durch [[User:$3|$3]] gesperrt.\n\nGrund dar Sperre: ''$2''",
        "viewpagelogs": "Logbicher fier diese Seite oazeega",
        "nohistory": "'S gitt kenne Versionsgeschichte fier diese Seite.",
index fce5916..6df0bf4 100644 (file)
        "nstab-special": "Bogga khaaska ah",
        "nstab-project": "Bogga mashruuca",
        "nstab-image": "Gal",
-       "nstab-mediawiki": "Fariin",
+       "nstab-mediawiki": "Farriin",
        "nstab-template": "Tusmo",
        "nstab-help": "Bogga caawinaada",
        "nstab-category": "Qeybta",
        "yourpasswordagain": "Markale qor ereysirka:",
        "createacct-yourpasswordagain": "Hubi erey sirta",
        "createacct-yourpasswordagain-ph": "Mar kale gali erey sirta",
-       "remembermypassword": "Kumbuyuutarkaan ku xasuusnaaw magaceyga gudagalka (ilaa  $1 {{PLURAL:$1|maalin|maalmood}})",
        "userlogin-remembermypassword": "Ka dhig mid diyaar ah mar waliba",
        "userlogin-signwithsecure": "Adeegso khad la hubo",
        "yourdomainname": "Magacaga shabakada",
        "eauthentsent": "Xaqiijin e-mail ah ayaa loo  diray e-mailkan aad dooratay.\nIntii aadan wax e-mail ah lagu soo dirin koontada, waa in aad daba kacdaa waxa kuugu jiro e-mailka, si aad u xaqiijisid  in aad adiga  leedahay akoon'ka.",
        "mailerror": "Qalad dirida e-mailka: $1",
        "acct_creation_throttle_hit": "Dadka soo booqanaayo wiki:gaan oo isticmaalaayo cinwaankaaga IP:ka waxay sameeyeen {{PLURAL:$1|1 magac gudagale ah|$1 magac  gudagalayaal ah}} maalintii ugu dambeysay, taasina waa inta ugu badan ee la'ogolyahay muddadaas. Sidaas daraadeed, booqoshadayaasha isticmaalaya cinwaankaan-IP:ka hadda ma'sameysankaraan magac gudagale danbe.",
-       "emailauthenticated": "E-mailkaada waxaa lagu xaqiijiyay $2 markey ahayd $3.",
+       "emailauthenticated": "E-mailkaada waxaa la xaqiijiyay $2 saacadduna ahayd $3.",
        "emailnotauthenticated": "Ciwaankaada e-mailka weli lama xaqiijinin.\nWax e-mail ah oo ku saabsan arrimaha soo socdo looma soo diridoono.",
        "emailconfirmlink": "Soo xaqiiji ciwaankaada e-mailka",
        "invalidemailaddress": "e-mailkaan lama ogolaan karo ayada oo ku ku jirto format la aqoonsan..\nFadlan ku qor ciwaan leh format sax ah ama ebar ka dhig  meesha.",
        "moveddeleted-notice": "Boggaan waa la tirtiray.\nTirtiraha iyo wareejinta gudagalaha boggaan waxaad ka arki kartaa hoostaan.",
        "edit-conflict": "Wax bedel isku dhacay",
        "edit-already-exists": "Bog cusub lama samayn karo, wuu jiraa bogaan.",
+       "duplicate-args-warning": "<strong>Digniin:</strong> [[:$1]] u yeeris [[:$2]] in ka badan hal qiimayn ee ku saabsan \"$3\" cabbiraad. Kaliya qiimihii ugu dambaysay baa la adeegsan doonaa.",
        "post-expand-template-inclusion-warning": "'''Digniin:''' Aad oo u weyn yahay tusmo'da aad ku dartay.\nTusmooyinka qaar lagumo dari doono.",
        "post-expand-template-inclusion-category": "Boggaga ku xad gudbay weyninka tusmo'da",
        "post-expand-template-argument-warning": "'''Digniin:'''Boggaan waxaa ku jira ugu yaraan hal iyo wixii ka badan oo template ah, waxaana ku xiran kuwa kale.",
        "stub-threshold-sample-link": "tusaale",
        "stub-threshold-disabled": "Howlgab",
        "recentchangesdays": "Tirada maalmaha lagu tusaayo isbedelada dhow:",
+       "recentchangescount": "Tirada isbedellada guud ahaan muuqda:",
        "savedprefs": "Dooqyadaada waa la keydiyey.",
        "timezonelegend": "Soonaha waqtiga:",
        "localtime": "Waqtigaaga",
        "yournick": "Saxiix cusub:",
        "prefs-help-signature": "Waan in la saxiixaa wadahdalada ku dhaca bogga wadhadalka adigoo adeegsaanaya \"<nowiki>~~~~</nowiki>\", kaasoo u rogi doona saxiixa iyo waqtiga.",
        "badsiglength": "Naaneysta aad bey u dheertahay.\nWaa in aysan ka badanin $1 {{PLURAL:$1|eray|erayo}}.",
-       "yourgender": "Jinsi:",
-       "gender-unknown": "Aana la qeexin",
-       "gender-male": "Lab",
-       "gender-female": "Dhedig",
+       "yourgender": "Qaabkee baad doonayssaa in laguu qeeqo?",
+       "gender-unknown": "Haddii lagu soo hadal qaado, barnaamijka waxa uu adeegsan doonaa ereyo nooc dhexdhexaad ah goor weliba ay suuragal tahay",
+       "gender-male": "Wuxuu wax ka bedelaa bogagga wikiga",
+       "gender-female": "Waxa ay wax ka bedeshaa bogagga wikipedia",
        "prefs-help-gender": "Ahaysiinta xulashaan waa mid dooqasha ah.\nBarnaamijkaan adeegsigiisa waxay qiima u yeelaysaa wadahadalkaada iyo kuwa kale iyadoo bedelaysa habka qofka sida lab ama dheddig.\nMacluumadkaan waa mid la wada arkayo.",
        "email": "E-mail",
-       "prefs-help-realname": "Optional: if you choose to provide it this will be used for giving you attribution for your work.",
+       "prefs-help-realname": "Magaca runta ah waa dooqasho.\nHaddii aad doorato in aan keento, waxaa loo adeegsan karaa mid tilmaama howshaada.",
        "prefs-help-email": "E-mail waa wax aad xor u leedahay. laakiin waa loo baahanyahay hadii aad eraysirka badaleesid, hadii aad ilaawdo eraygaaga sirta ah",
        "prefs-help-email-others": "Waxaa kale oo aad u isticmaali kartaa in ee dadka kale kugula soo xiriiraan e-mail ayaga oo isticmaalaayo linki isticmaalahaada ama bogga wadahadalka.\nE-mailkaada mala sheegaayo markii ee dadka kale kula soo xiriirayaan.",
        "prefs-help-email-required": "Waxaa loo baahanyahay e-mail.",
        "prefs-info": "Macluumaadka asaasiga ah",
        "prefs-i18n": "Caalamiyeen",
        "prefs-signature": "Saxiixa",
+       "prefs-advancedediting": "Xulasho guud",
        "prefs-advancedrc": "Xulasho horumarin ah",
+       "prefs-displayrc": "Dooga bandhigista",
        "prefs-diffs": "Farqiga",
        "prefs-help-prefershttps": "Waxaa lahagaajin doonaan dooqaan marka xiga ee aad soo gasho",
        "saveusergroups": "Kaydi kooxaha isticmaalayaasha",
index c82f7ff..f3f52f1 100644 (file)
@@ -49,6 +49,7 @@
        "tog-watchdefault": "Shto faqet dhe skedat e redaktuara prej meje tek lista e faqeve nën mbikqyrje",
        "tog-watchmoves": "Shto faqet dhe skedat e zhvendosura prej meje tek lista e faqeve nën mbikqyrje",
        "tog-watchdeletion": "Shto faqet dhe skedat e grisura prej meje tek lista e faqeve  nën mbikqyrje",
+       "tog-watchuploads": "Shtoni fotografitë e rreja që ngarkoj në listën mbikëqyrëse",
        "tog-watchrollback": "Shto faqet ku unë kam kryer një rikthim tek lista ime mbikqyrëse",
        "tog-minordefault": "Shëno të gjitha redaktimet si të vogla automatikisht",
        "tog-previewontop": "Trego se si do të duket faqja mbi kutinë redaktimit",
@@ -58,7 +59,7 @@
        "tog-enotifminoredits": "Më njofto me email edhe kur ka redaktime të vogla të faqeve dhe skedave",
        "tog-enotifrevealaddr": "Trego adresën time të emailit në emailet njoftuese",
        "tog-shownumberswatching": "Trego numrin e përdoruesve që vëzhgojnë këtë faqe",
-       "tog-oldsig": "Nënshkrimi ekzistues:",
+       "tog-oldsig": "Nënshkrimi juaj ekzistues:",
        "tog-fancysig": "Mbaje nënshkrimin si wikitekst (pa lidhje automatike)",
        "tog-uselivepreview": "Trego parapamjen drejtpërdrejt",
        "tog-forceeditsummary": "Më njofto kur përmbledhjen e redaktimit e lë bosh",
@@ -66,6 +67,7 @@
        "tog-watchlisthidebots": "Fshih redaktimet e robotëve nga lista e faqeve të vëzhguara",
        "tog-watchlisthideminor": "Fshih redaktimet e vogla nga lista e faqeve të vëzhguara",
        "tog-watchlisthideliu": "Fshih redaktimet e përdoruesve nga lista e faqeve të vëzhguara",
+       "tog-watchlistreloadautomatically": "Rifreskoni listën mbikëqyrëse automatikisht sa herë një filtër ndryshohet (JavaScript e domosdoshme)",
        "tog-watchlisthideanons": "Fshih redaktimet përdoruesve anonim nga lista e faqeve të vëzhguara",
        "tog-watchlisthidepatrolled": "Fshih redaktimet e vrojtuara nga lista e faqeve të vëzhguara",
        "tog-watchlisthidecategorization": "Fshih kategorizimin e faqeve",
        "newwindow": "(hapet në një dritare të re)",
        "cancel": "Anulo",
        "moredotdotdot": "Më shumë...",
-       "morenotlisted": "Kjo listë nuk është e plotë.",
+       "morenotlisted": "Kjo listë mund të mos jetë e plotë.",
        "mypage": "Faqja",
        "mytalk": "Diskuto",
        "anontalk": "Diskutimi",
        "yourpasswordagain": "Fusni fjalëkalimin përsëri",
        "createacct-yourpasswordagain": "Konfirmoni fjalëkalimin",
        "createacct-yourpasswordagain-ph": "Shtypni fjalëkalimin përsëri",
-       "remembermypassword": "Mbaj mënd fjalëkalimin tim për tërë vizitat e ardhshme (për një kohë maksimale prej $1 {{PLURAL:$1|dite|ditësh}})",
        "userlogin-remembermypassword": "Më mbaj të kyçur",
        "userlogin-signwithsecure": "Përdor lidhje të sigurtë",
        "yourdomainname": "Faqja juaj",
        "minoredit": "Ky është një redaktim i vogël",
        "watchthis": "Vëzhgoje këtë faqe",
        "savearticle": "Kryej ndryshimet",
+       "savechanges": "Ruaj ndryshimet",
        "publishpage": "Publiko faqen",
        "publishchanges": "Publiko ndryshimet",
        "preview": "Shqyrto",
        "defaultmessagetext": "Teksti i porosisë së parazgjedhur",
        "invalid-content-data": "Të pavlefshme të dhënave e përmbajtjes",
        "editwarning-warning": "Duke e lënë këtë faqe mund të shkaktojë ju për të humbur të gjitha ndryshimet që keni bërë ju.\nNëse ju jeni regjistruar, ju mund të çaktivizoni këtë paralajmërim në \"{{int:prefs-editing}}\" seksionin e preferencave tuaja.",
+       "content-model-wikitext": "wikitekst",
        "content-model-text": "tekst i thejshtë",
        "content-model-javascript": "JavaScript",
        "content-json-empty-object": "Objekt bosh",
        "content-json-empty-array": "Fushë boshe",
+       "deprecated-self-close-category": "Faqet përdorin tag HTML mbyllës jo të sakt",
        "expensive-parserfunction-warning": "Kujdes: Kjo faqe ka shumë kërkesa që kërkojnë analizë gramatikore të kushtueshme për sistemin.\n\nDuhet të ketë më pakë se $2, {{PLURAL:$2|kërkesë|kërkesa}}, kurse tani {{PLURAL:$1|është $1 kërkesë|janë $1 kërkesa}}.",
        "expensive-parserfunction-category": "Faqe me shumë shprehje të kushtueshmë për analizë gramatikore",
        "post-expand-template-inclusion-warning": "'''Kujdes''': Numri i shablloneve që perfshihen është shumë i madh.\nDisa shabllone nuk do të përfshihen.",
        "columns": "Kollona:",
        "searchresultshead": "Kërkimi",
        "stub-threshold": "Kufiri për formatin e <a href=\"#\" class=\"stub\">lidhjeve cung</a> (B):",
+       "stub-threshold-sample-link": "shembull",
        "stub-threshold-disabled": "Çaktivizuar",
        "recentchangesdays": "Numri i ditëve të treguara në ndryshime së fundmi:",
        "recentchangesdays-max": "(maksimum $1 {{PLURAL:$1|dit|ditë}})",
        "right-managechangetags": "Krijoni dhe fshini [[Special:Tags|tags]] nga baza e të dhënave",
        "right-applychangetags": "Aplikoni [[Special:Tags|tags]] së bashku me ndryshimet",
        "right-changetags": "Shtoni dhe të largoni në mënyrë arbitrare [[Special:Tags|tags]] në rishikimet individuale dhe regjistrimet e historikut",
+       "grant-group-email": "Dërgoni email",
+       "grant-group-administration": "Kryej veprime administrative",
+       "grant-group-private-information": "Qasu të dhënave private në lidhje me ju",
+       "grant-group-other": "Veprimtari të ndryshme",
        "grant-blockusers": "Blloko dhe zhblloko përdoruesit",
+       "grant-createaccount": "Krijo llogari",
+       "grant-createeditmovepage": "Krijoni, redaktoni, dhe lëvizni faqet",
+       "grant-editmywatchlist": "Redaktoni listën tuaj mbikqyrëse",
+       "grant-editpage": "Redaktoni faqet ekzistuese",
+       "grant-editprotected": "Redakto faqet e mbrojtura",
        "newuserlogpage": "Regjistri i llogarive",
        "newuserlogpagetext": "Ky është një regjistër i llogarive të fundit që janë hapur",
        "rightslog": "Regjistri i privilegjeve të përdoruesit",
        "recentchanges-label-plusminus": "Madhësia e faqes ndryshoi me këtë numër bajtësh",
        "recentchanges-legend-heading": "<strong>Legjenda:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (shiko gjithashtu [[Special:NewPages|listën e faqeve të reja]])",
+       "recentchanges-submit": "Shfaq",
        "rcnotefrom": "Më poshtë {{PLURAL:$5|është shfaqur ndryshimi|janë shfaqur ndryshimet}} që nga <strong>$3, $4</strong> (deri në <strong>$1</strong>).",
        "rclistfrom": "Tregon ndryshime së fundmi duke filluar nga $3 $2",
        "rcshowhideminor": "$1 redaktimet e vogla",
        "rcshowhidemine": "$1 redaktimet e mia",
        "rcshowhidemine-show": "Shfaq",
        "rcshowhidemine-hide": "Fshih",
+       "rcshowhidecategorization-show": "Shfaq",
+       "rcshowhidecategorization-hide": "Fshih",
        "rclinks": "Trego $1 ndryshime gjatë $2 ditëve<br />$3",
        "diff": "ndrysh",
        "hist": "hist",
        "upload-copy-upload-invalid-domain": "Ngarkesat e kopjimit nuk janë në dispozicion nga ky domein.",
        "upload-dialog-title": "Ngarko skedën",
        "upload-dialog-button-cancel": "Anulo",
+       "upload-dialog-button-back": "Prapa",
        "upload-dialog-button-done": "Mbyll",
        "upload-dialog-button-save": "Ruaj",
        "upload-dialog-button-upload": "Ngarko",
+       "upload-form-label-infoform-title": "Detaje",
+       "upload-form-label-infoform-name": "Emri",
+       "upload-form-label-usage-title": "Përdorimi",
+       "upload-form-label-usage-filename": "Emri i skedarit",
+       "upload-form-label-own-work": "Kjo është e puna ime",
+       "upload-form-label-infoform-categories": "Kategoritë",
+       "upload-form-label-infoform-date": "Data",
        "backend-fail-stream": "Nuk mund të kalojë skedën $1.",
        "backend-fail-backup": "Nuk mund të rezervojë skedën $1.",
        "backend-fail-notexists": "Skeda $1 nuk ekziston.",
        "license": "Licencimi:",
        "license-header": "Licencimi:",
        "nolicense": "Asnjë nuk është zgjedhur",
+       "licenses-edit": "Redakto opsionet e licencës",
        "license-nopreview": "(Nuk ka parapamje)",
        "upload_source_url": " (URL e vlefshme, publikisht e përdorshme)",
        "upload_source_file": " (skeda në kompjuterin tuaj)",
        "mostrevisions": "Artikuj më të redaktuar",
        "prefixindex": "Të gjitha faqet me parashtesa",
        "prefixindex-namespace": "Të gjitha faqet me parashtesë (hapësira $1)",
+       "prefixindex-submit": "Shfaq",
        "shortpages": "Artikuj të shkurtër",
        "longpages": "Artikuj të gjatë",
        "deadendpages": "Artikuj pa rrugëdalje",
        "protectedpages": "Faqe të mbrojtura",
        "protectedpages-indef": "Vetëm mbrojtjet pa afat",
        "protectedpages-cascade": "Vetëm mbrojtjet",
+       "protectedpages-noredirect": "Fshih përcjellimet",
        "protectedpagesempty": "Nuk ka faqe të mbrojtura me të dhënat e kërkuara.",
        "protectedpages-page": "Faqja",
        "protectedpages-expiry": "Skadon",
        "protectedpages-reason": "Arsyeja",
+       "protectedpages-submit": "Shfaq faqet",
+       "protectedpages-unknown-timestamp": "E panjohur",
+       "protectedpages-unknown-performer": "Përdorues i panjohur",
        "protectedtitles": "Titujt e mbrojtur",
+       "protectedtitles-summary": "Kjo faqe liston titujt që aktualisht janë të mbrojtura nga krijimi. Për një listë të faqeve ekzistuese që janë të mbrojtura, shih [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Asnjë titull i mbrojtur nuk u gjet në këtë hapësirë.",
+       "protectedtitles-submit": "Shfaq titujt",
        "listusers": "Lista e përdoruesve",
        "listusers-editsonly": "Trego vetëm përdoruesit me redaktime",
        "listusers-creationsort": "Radhiti sipas datës së krijimit",
        "usereditcount": "$1 {{PLURAL:$1|redaktim|redaktime}}",
        "usercreated": "{{GENDER:$3|Krijuar}} më $1 në $2",
        "newpages": "Artikuj të rinj",
+       "newpages-submit": "Shfaq",
        "newpages-username": "Përdoruesi:",
        "ancientpages": "Artikuj më të vjetër",
        "move": "Zhvendose",
        "pager-older-n": "{{PLURAL:$1|1 më i vjetër|$1 më të vjetra}}",
        "suppress": "Shtypur",
        "querypage-disabled": "Kjo faqe speciale është çaktivizuar për arsye të performancës.",
+       "apihelp": "API ndihmë",
        "apihelp-no-such-module": "Moduli \"$1\" nuk u gjet.",
+       "apisandbox": "API livadhi",
+       "apisandbox-jsonly": "JavaScript është e domosdoshme që të përdorni API livadhi.",
+       "apisandbox-api-disabled": "API nuk është në dispozicion për këtë faqe.",
+       "apisandbox-unfullscreen": "Shfaq faqen",
+       "apisandbox-submit": "Bëj kërkesë",
+       "apisandbox-reset": "Pastro",
+       "apisandbox-retry": "Riprovo",
+       "apisandbox-examples": "Shembuj",
+       "apisandbox-dynamic-parameters": "Parametra shtesë",
+       "apisandbox-dynamic-parameters-add-label": "Shto parametër:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Emri i parametrit",
+       "apisandbox-results": "Rezultatet",
        "booksources": "Burime librash",
        "booksources-search-legend": "Kërkim burimor librash",
        "booksources-search": "Kërko",
        "activeusers-intro": "Kjo është një listë e përdoruesve që kanë qenë aktivë për $1 {{PLURAL:$1|ditë|ditë}}.",
        "activeusers-count": "$1 {{PLURAL:$1|redaktim|redaktime}} në {{PLURAL:$3|ditën|$3 ditët}} e fundit",
        "activeusers-from": "Trego përdoruesit duke filluar prej te:",
-       "activeusers-hidebots": "Fshih robotët",
-       "activeusers-hidesysops": "Fshih administratorët",
        "activeusers-noresult": "Asnjë përdorues nuk u gjet.",
        "listgrouprights": "Grupime përdoruesish me privilegje",
        "listgrouprights-summary": "Më poshtë jepet grupimi i përdoruesve sipas privilegjeve që ju janë dhënë në këtë wiki. Më shumë informacion rreth privilegjeve në veçanti mund të gjendet [[{{MediaWiki:Listgrouprights-helppage}}|këtu]].",
        "htmlform-submit": "Dërgo",
        "htmlform-reset": "Zhbëj ndryshimin",
        "htmlform-selectorother-other": "Gjitha",
-       "sqlite-has-fts": "$1 me mbështetje të kërkimit me teskt të plotë",
-       "sqlite-no-fts": "$1 pa mbështetje të kërkimit me teskt të plotë",
        "logentry-delete-delete": "$1 {{GENDER:$2|grisi}} faqen $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|riktheu}} faqen $3",
        "logentry-delete-event": "$1 {{GENDER:$2|ndryshoi}} dukshmërinë e {{PLURAL:$5|e një ngjarjeje regjistri|$5 ngjarjeve regjistri}} në $3: $4",
index 176528f..2cd4d4c 100644 (file)
        "qbfind": "Пронађи",
        "qbbrowse": "Потражи",
        "qbedit": "Уреди",
-       "qbpageoptions": "Ð\9fоÑ\81Ñ\82авке Ñ\81Ñ\82Ñ\80аниÑ\86е",
+       "qbpageoptions": "Ð\9eва Ñ\81Ñ\82Ñ\80аниÑ\86а",
        "qbmyoptions": "Моје странице",
        "faq": "НПП",
        "faqpage": "Project:НПП",
        "talk": "Разговор",
        "views": "Прегледи",
        "toolbox": "Алатке",
+       "tool-link-userrights": "Уреди {{GENDER:$1|корисничке}} групе",
+       "tool-link-emailuser": "Пошаљи {{GENDER:$1|имејл}}",
        "userpage": "Погледај корисничку страницу",
        "projectpage": "Погледај страницу пројекта",
        "imagepage": "Погледај страницу датотеке",
        "translateinterface": "Да додате или промените преводе за све викије, посетите [https://translatewiki.net/ Транслејтвики], пројекат за локализацију Медијавикија.",
        "cascadeprotected": "Ова страница је закључана јер садржи {{PLURAL:$1|следећу страницу која је заштићена|следеће странице које су заштићене}} „преносивом“ заштитом:\n$2",
        "namespaceprotected": "Немате дозволу да уређујете странице у именском простору <strong>$1</strong>.",
-       "customcssprotected": "Ð\9dемаÑ\82е Ð´Ð¾Ð·Ð²Ð¾Ð»Ñ\83 Ð´Ð° Ð¼ÐµÑ\9aаÑ\82е Ð¾Ð²Ñ\83 CSS Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 Ñ\98еÑ\80 Ñ\81адÑ\80жи Ð»Ð¸Ñ\87не Ð¿Ð¾Ñ\81Ñ\82авке другог корисника.",
+       "customcssprotected": "Ð\9dемаÑ\82е Ð´Ð¾Ð·Ð²Ð¾Ð»Ñ\83 Ð´Ð° Ð¼ÐµÑ\9aаÑ\82е Ð¾Ð²Ñ\83 CSS Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 Ñ\98еÑ\80 Ñ\81адÑ\80жи Ð»Ð¸Ñ\87на Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа другог корисника.",
        "customjsprotected": "Немате дозволу да мењате ову страницу јаваскрипта јер садржи личне поставке другог корисника.",
        "mycustomcssprotected": "Немате дозволу за мењање ове CSS странице.",
        "mycustomjsprotected": "Немате дозволу за мењање ове JavaScript странице.",
        "userlogin": "Пријава/регистрација",
        "userloginnocreate": "Пријава",
        "logout": "Одјава",
-       "userlogout": "Ð\9eдÑ\98ави Ð¼Ðµ",
+       "userlogout": "Ð\9eдÑ\98ава",
        "notloggedin": "Нисте пријављени",
        "userlogin-noaccount": "Немате налог?",
        "userlogin-joinproject": "Отворите га",
        "noemailcreate": "Морате навести исправну имејл адресу.",
        "passwordsent": "Нова лозинка је послата на имејл адресу {{GENDER:$1|корисника|кориснице|корисника}} $1.\nПријавите се пошто је примите.",
        "blocked-mailpassword": "Ваша IP адреса има забрану уређивања. Ради спречавања злоупотребе, није дозвољено враћање лозинке са ње.",
-       "eauthentsent": "Ð\9dа Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ñ\83 Ð¸Ð¼ÐµÑ\98л Ð°Ð´Ñ\80еÑ\81Ñ\83 Ñ\98е Ð¿Ð¾Ñ\81лаÑ\82 Ð¿Ð¾Ñ\82вÑ\80дни ÐºÐ¾Ð´.\nÐ\9fÑ\80е Ð½ÐµÐ³Ð¾ Ñ\88Ñ\82о Ð¿Ð¾Ñ\88аÑ\99емо Ð´Ð°Ñ\99Ñ\9aе Ð¿Ð¾Ñ\80Ñ\83ке, Ð¿Ñ\80аÑ\82иÑ\82е Ñ\83пÑ\83Ñ\82Ñ\81Ñ\82ва Ñ\81 Ð¸Ð¼ÐµÑ\98ла Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð¿Ð¾Ñ\82вÑ\80дили Ð´Ð° Ñ\81Ñ\82е Ð²и отворили налог.",
+       "eauthentsent": "Ð\9dа Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ñ\83 Ð¸Ð¼ÐµÑ\98л Ð°Ð´Ñ\80еÑ\81Ñ\83 Ñ\98е Ð¿Ð¾Ñ\81лаÑ\82 Ð¿Ð¾Ñ\82вÑ\80дни ÐºÐ¾Ð´.\nÐ\9fÑ\80е Ð½ÐµÐ³Ð¾ Ñ\88Ñ\82о Ð¿Ð¾Ñ\88аÑ\99емо Ð´Ð°Ñ\99Ñ\9aе Ð¿Ð¾Ñ\80Ñ\83ке, Ð¿Ñ\80аÑ\82иÑ\82е Ñ\83пÑ\83Ñ\82Ñ\81Ñ\82ва Ñ\81 Ð¸Ð¼ÐµÑ\98ла Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð¿Ð¾Ñ\82вÑ\80дили Ð´Ð° Ñ\81Ñ\82е Ð\92и отворили налог.",
        "throttled-mailpassword": "Порука за промену лозинке је послата у {{PLURAL:$1|1=последњих сат времена|последња $1 сата|последњих $1 сати}}.\nДа бисмо спречили злоупотребу, подсетник шаљемо само једном у року од {{PLURAL:$1|1=сат времена|$1 сата|$1 сати}}.",
        "mailerror": "Грешка при слању поруке: $1",
-       "acct_creation_throttle_hit": "Посетиоци овог викија који користе вашу ИП адресу су већ отворили {{PLURAL:$1|1=један налог|$1 налога|$1 налога}} претходни дан, што је највећи дозвољени број у том временском периоду.\nЗбог тога посетиоци с ове ИП адресе тренутно не могу отворити више налога.",
+       "acct_creation_throttle_hit": "Посетиоци овог викија који користе вашу ИП адресу су већ отворили {{PLURAL:$1|1=један налог|$1 налога}} претходни $2, што је највећи дозвољени број у том временском периоду.\nЗбог тога посетиоци с ове ИП адресе тренутно не могу отворити више налога.",
        "emailauthenticated": "Ваша имејл адреса је потврђена $2 у $3.",
-       "emailnotauthenticated": "Ð\92аÑ\88а Ð¸Ð¼ÐµÑ\98л Ð°Ð´Ñ\80еÑ\81а Ñ\98оÑ\88 Ð½Ð¸Ñ\98е Ð¿Ð¾Ñ\82вÑ\80Ñ\92ена.\nÐ\9fоÑ\80Ñ\83ке Ð½ÐµÑ\9bе Ð±Ð¸Ñ\82и Ð¿Ð¾Ñ\81лаÑ\82е ни у једном од следећих случајева.",
+       "emailnotauthenticated": "Ð\92аÑ\88а Ð¸Ð¼ÐµÑ\98л Ð°Ð´Ñ\80еÑ\81а Ñ\98оÑ\88 Ð½Ð¸Ñ\98е Ð¿Ð¾Ñ\82вÑ\80Ñ\92ена.\nÐ\98меÑ\98л Ð½ÐµÑ\9bе Ð±Ð¸Ñ\82и Ð¿Ð¾Ñ\81лаÑ\82 ни у једном од следећих случајева.",
        "noemailprefs": "Унесите имејл адресу како би ове могућности радиле.",
        "emailconfirmlink": "Потврдите своју имејл адресу",
        "invalidemailaddress": "Имејл адреса не може бити прихваћена јер је неисправног облика.\nУнесите исправну адресу или оставите празно поље.",
        "pt-createaccount": "Отвори налог",
        "pt-userlogout": "Одјави ме",
        "php-mail-error-unknown": "Непозната грешка у функцији PHP mail().",
-       "user-mail-no-addy": "Ð\9fокÑ\83Ñ\88али Ñ\81Ñ\82е Ð´Ð° Ð¿Ð¾Ñ\88аÑ\99еÑ\82е Ð¿Ð¾Ñ\80Ñ\83кÑ\83 без имејл адресе.",
+       "user-mail-no-addy": "Ð\9fокÑ\83Ñ\88али Ñ\81Ñ\82е Ð´Ð° Ð¿Ð¾Ñ\88аÑ\99еÑ\82е Ð¸Ð¼ÐµÑ\98л без имејл адресе.",
        "user-mail-no-body": "Покушано слање имејла с празним или неразумно кратким садржајем.",
        "changepassword": "Промени лозинку",
        "resetpass_announce": "Да бисте завршили пријаву, подесите нову лозинку овде.",
        "resetpass_submit": "Постави лозинку и пријави ме",
        "changepassword-success": "Ваша лозинка је успешно промењена!",
        "changepassword-throttled": "Превише пута сте покушали да се пријавите.\nМолимо вас да сачекате $1 пре него што покушате поново.",
+       "botpasswords": "Лозинке ботова",
+       "botpasswords-label-appid": "Име бота:",
+       "botpasswords-label-create": "Направи",
+       "botpasswords-label-update": "Ажурирај",
        "botpasswords-label-cancel": "Откажи",
        "botpasswords-label-delete": "Обриши",
+       "botpasswords-label-grants-column": "Одобрено",
        "resetpass_forbidden": "Лозинка не може бити промењена",
        "resetpass-no-info": "Морате бити пријављени да бисте приступили овој страници.",
        "resetpass-submit-loggedin": "Промени лозинку",
        "resetpass-submit-cancel": "Откажи",
        "resetpass-wrong-oldpass": "Неисправна привремена или текућа лозинка.\nМожда сте већ променили лозинку или сте затражили нову привремену лозинку.",
        "resetpass-recycled": "Унели сте садашњу лозинку, да бисте ресетовали лозинку морате унети нову.",
-       "resetpass-temp-emailed": "Ð\9fÑ\80иÑ\98авили Ñ\81Ñ\82е Ñ\81е Ñ\81а Ð¿Ñ\80ивÑ\80еменим ÐºÐ¾Ð´Ð¾Ð¼ Ð¸Ð· Ðµ-поÑ\88Ñ\82е.\nДа бисте завршили пријављивање морате поставити нову лозинку овде:",
+       "resetpass-temp-emailed": "Ð\9fÑ\80иÑ\98авили Ñ\81Ñ\82е Ñ\81е Ñ\81а Ð¿Ñ\80ивÑ\80еменим ÐºÐ¾Ð´Ð¾Ð¼ Ð¸Ð· Ð¸Ð¼ÐµÑ\98ла.\nДа бисте завршили пријављивање морате поставити нову лозинку овде:",
        "resetpass-temp-password": "Привремена лозинка:",
        "resetpass-abort-generic": "Промену лозинке је спречио додатак.",
        "resetpass-expired": "Ваша лозинка је истекла. Поставите нову лозинку да бисте се пријавили.",
        "passwordreset-emaildisabled": "Имејл је онемогућен на овом викију.",
        "passwordreset-username": "Корисничко име:",
        "passwordreset-domain": "Домен:",
-       "passwordreset-capture": "Погледати крајњу поруку?",
-       "passwordreset-capture-help": "Ако означите ову кућицу, имејл с привременом лозинком ће бити приказан и послат кориснику.",
+       "passwordreset-capture": "Погледати крајњи имејл?",
+       "passwordreset-capture-help": "Ако означите ову кућицу, имејл (с привременом лозинком) ће бити приказан и послат кориснику.",
        "passwordreset-email": "Имејл адреса:",
        "passwordreset-emailtitle": "Детаљи налога на викију {{SITENAME}}",
        "passwordreset-emailtext-ip": "Неко (вероватно Ви, са ИП адресе $1) је затражио нову лозинку на викију {{SITENAME}} ($4).\nСледећи {{PLURAL:$3|кориснички налог је повезан|кориснички налози су повезани}} с овом имејл адресом:\n\n$2\n\n{{PLURAL:$3|Привремена лозинка истиче|Привремене лозинке истичу}} за {{PLURAL:$5|један дан|$5 дана}}.\nПријавите се и изаберите нову лозинку. Ако је неко други захтевао ову радњу или сте се сетили лозинке и не желите да је мењате, занемарите ову поруку и наставите користити стару лозинку.",
        "changeemail-newemail": "Нова имејл адреса:",
        "changeemail-none": "(ништа)",
        "changeemail-password": "Ваша лозинка:",
-       "changeemail-submit": "Промени",
+       "changeemail-submit": "Промени имејл",
        "changeemail-throttled": "Превише пута сте покушали да се пријавите.\nМолимо вас да сачекате $1 пре него што покушате поново.",
        "changeemail-nochange": "Унесите другу имејл адресу.",
        "resettokens": "Ресетовање жетона",
        "subject-preview": "Преглед теме:",
        "previewerrortext": "Догодила се грешка приликом приказивања ваших измена.",
        "blockedtitle": "Корисник је блокиран",
-       "blockedtext": "<strong>Ваше корисничко име или ИП адреса је блокирана.</strong>\n\nБлокирање је {{GENDER:$4|извршио|извршила}} $1.\nРазлог: <em>$2</em>.\n\n* Датум блокирања: $8\n* Блокирање истиче: $6\n* Име корисника: $7\n\nОбратите се {{GENDER:$4|кориснику|корисници}} $1 или [[{{MediaWiki:Grouppage-sysop}}|администратору]] да разјасните ствар.\nНе можете користити могућност „Пошаљи имејл овом кориснику“ ако нисте унели исправну имејл адресу у [[Special:Preferences|подешавањима]].\nВаша блокирана ИП адреса је $3, а ID блокирања $5.\nНаведите све податке изнад при стварању било каквих упита.",
+       "blockedtext": "<strong>Ваше корисничко име или ИП адреса је блокирана.</strong>\n\nБлокирање је {{GENDER:$4|извршио|извршила}} $1.\nРазлог је <em>$2</em>.\n\n* Датум блокирања: $8\n* Блокирање истиче: $6\n* Име корисника: $7\n\nОбратите се {{GENDER:$4|кориснику|корисници}} $1 или [[{{MediaWiki:Grouppage-sysop}}|администратору]] да разјасните ствар.\nНе можете користити могућност „Пошаљи имејл овом кориснику“ ако нисте унели исправну имејл адресу у [[Special:Preferences|подешавањима]].\nВаша блокирана ИП адреса је $3, а ID блокирања $5.\nНаведите све податке изнад при стварању било каквих упита.",
        "autoblockedtext": "Ваша ИП адреса је блокирана јер ју је употребљавао други корисник, кога је {{GENDER:$4|блокирао|блокирала}} $1.\nРазлог:\n\n:<em>$2</em>\n\n* Датум блокирања: $8\n* Блокирање истиче: $6\n* Име корисника: $7\n\nОбратите се {{GENDER:$4|кориснику|корисници}} $1 или [[{{MediaWiki:Grouppage-sysop}}|администратору]] да разјасните ствар.\n\nНе можете користити могућност „Пошаљи имејл овом кориснику“ ако нисте унели исправну имејл адресу у [[Special:Preferences|подешавањима]].\n\nВаша блокирана ИП адреса је $3, а ID $5.\nНаведите све податке изнад при стварању било каквих упита.",
        "blockednoreason": "разлог није наведен",
        "whitelistedittext": "За уређивање странице је потребно да будете $1.",
        "revdelete-show-no-access": "Грешка при приказивању ставке од $1, $2: означена је као „ограничена“.\nНемате приступ до ње.",
        "revdelete-modify-no-access": "Грешка при мењању ставке од $1, $2: означена је као „ограничена“.\nНемате приступ до ње.",
        "revdelete-modify-missing": "Грешка при мењању ИБ ставке $1: она не постоји у бази података.",
-       "revdelete-no-change": "'''Упозорење:''' ставка од $1, $2 већ поседује затражене поставке видљивости.",
+       "revdelete-no-change": "<strong>Упозорење:</strong> ставка од $1, $2 већ поседује затражена подешавања видљивости.",
        "revdelete-concurrent-change": "Грешка при мењању ставке од $1, $2: њено стање је у међувремену промењено од стране другог корисника.\nПогледајте историју.",
        "revdelete-only-restricted": "Грешка при сакривању ставке од $1, $2: не можете сакрити ставке од администратора без избора других могућности видљивости.",
        "revdelete-reason-dropdown": "*Уобичајени разлози за брисање\n** Кршење ауторског права\n** Неприкладан коментар или лични подаци\n** Неприкладно корисничко име\n** Увредљиви подаци",
        "searchprofile-advanced-tooltip": "Претражите прилагођене именске просторе",
        "search-result-size": "$1 ({{PLURAL:$2|1 реч|$2 речи|$2 речи}})",
        "search-result-category-size": "{{PLURAL:$1|1 члан|$1 члана|$1 чланова}}, ({{PLURAL:$2|1 поткатегорија|$2 поткатегорије|$2 поткатегорија}}, {{PLURAL:$3|1 датотека|$3 датотеке|$3 датотека}})",
-       "search-redirect": "(преусмерење $1)",
+       "search-redirect": "(преусмерено са $1)",
        "search-section": "(одељак $1)",
        "search-category": "(категорија $1)",
        "search-file-match": "(подудара се садржај датотеке)",
        "right-move-categorypages": "премештање категорија",
        "right-movefile": "премештање датотека",
        "right-suppressredirect": "премештање страница без остављања преусмерења",
-       "right-upload": "отпремање датотека",
+       "right-upload": "Ð\9eтпремање датотека",
        "right-reupload": "замењивање постојећих датотека",
        "right-reupload-own": "замењивање сопствених датотека",
        "right-reupload-shared": "мењање датотека на дељеном складишту мултимедије",
-       "right-upload_by_url": "оÑ\82пÑ\80емаÑ\9aе Ð´Ð°Ñ\82оÑ\82ека Ñ\81а Ð²ÐµÐ± адресе",
+       "right-upload_by_url": "Ð\9eÑ\82пÑ\80емаÑ\9aе Ð´Ð°Ñ\82оÑ\82ека Ñ\81а Ð²ÐµÐ±-адресе",
        "right-purge": "чишћење кеш меморије странице без потврде",
        "right-autoconfirmed": "без ограничавања ставки за ИП адресе",
        "right-bot": "сматрање измена као аутоматски процес",
        "right-viewsuppressed": "прегледање измена скривених од свих корисника",
        "right-suppressionlog": "прегледање приватних дневника",
        "right-block": "блокирање даљих измена других корисника",
-       "right-blockemail": "онемогÑ\83Ñ\9bаваÑ\9aе ÐºÐ¾Ñ\80иÑ\81ниÑ\86има Ð´Ð° Ñ\88аÑ\99Ñ\83 Ð¸Ð¼ÐµÑ\98лове",
+       "right-blockemail": "Ð\91локиÑ\80аÑ\98 ÐºÐ¾Ñ\80иÑ\81никÑ\83 Ñ\81лаÑ\9aе Ð¸Ð¼ÐµÑ\98ла",
        "right-hideuser": "блокирање корисничког имена и његово сакривање од јавности",
        "right-ipblock-exempt": "заобилажење блокирања ИП адресе, аутоматска блокирања и блокирања опсега",
        "right-unblockself": "деблокирање самог себе",
        "right-editmyuserjs": "уређивање сопствених JavaScript датотека",
        "right-viewmywatchlist": "види сопствени списак надгледања",
        "right-editmywatchlist": "уређивање сопственог списка надгледања; неке предузете радње ће свеједно додати странице на списак и без овог права",
-       "right-viewmyprivateinfo": "видиÑ\82е Ñ\81воÑ\98е Ð»Ð¸Ñ\87не Ð¿Ð¾Ð´Ð°Ñ\82ке (нпÑ\80. Ð°Ð´Ñ\80еÑ\81Ñ\83 Ðµ-поÑ\88Ñ\82е, право име)",
-       "right-editmyprivateinfo": "уређивање сопствених личних података (нпр. имејл адреса, право име)",
+       "right-viewmyprivateinfo": "Ð\92идиÑ\82е Ñ\81воÑ\98е Ð»Ð¸Ñ\87не Ð¿Ð¾Ð´Ð°Ñ\82ке (нпÑ\80. Ð¸Ð¼ÐµÑ\98л Ð°Ð´Ñ\80еÑ\81Ñ\83, право име)",
+       "right-editmyprivateinfo": "Уређивање сопствених личних података (нпр. имејл адреса, право име)",
        "right-editmyoptions": "уређивање сопствених подешавања",
        "right-rollback": "брзо враћање измена последњег корисника који је мењао одређену страницу",
        "right-markbotedits": "означавање враћених измена као измене бота",
        "right-userrights-interwiki": "уређивање корисничких права на другим викијима",
        "right-siteadmin": "закључавање и откључавање базе података",
        "right-override-export-depth": "извоз страница укључујући и повазене странице до дубине од пет веза",
-       "right-sendemail": "слање имејла другим корисницима",
+       "right-sendemail": "Пошаљи имејл другим корисницима",
        "right-passwordreset": "прегледање порука за обнављање лозинке",
        "right-managechangetags": "прављење и (де)активирање [[Special:Tags|ознака]]",
        "right-applychangetags": "примењивање [[Special:Tags|ознака]] на нечије измене",
        "grant-rollback": "Враћање измена",
        "grant-sendemail": "Слање имејлова другим корисницима",
        "grant-uploadeditmovefile": "Отпремање, замена и премештање датотека",
-       "grant-uploadfile": "Слање нових датотека",
+       "grant-uploadfile": "Ð\9eÑ\82пÑ\80емање нових датотека",
        "grant-basic": "Основна права",
        "grant-viewdeleted": "Преглед обрисаних страница и датотека",
        "grant-viewmywatchlist": "Преглед вашег списак надгледања",
        "action-move-rootuserpages": "премештање основних корисничких страница",
        "action-move-categorypages": "премештање категорија",
        "action-movefile": "премештање ове датотеке",
-       "action-upload": "слање ове датотеке",
+       "action-upload": "отпреми ову датотеку",
        "action-reupload": "замењивање постојеће датотеке",
        "action-reupload-shared": "постављање ове датотеке на заједничко складиште",
-       "action-upload_by_url": "слање ове датотеке преко URL адресе",
+       "action-upload_by_url": "отпремање ове датотеке преко веб-адресе",
        "action-writeapi": "писање АПИ-ја",
        "action-delete": "брисање ове странице",
        "action-deleterevision": "брисање ове измене",
        "action-managechangetags": "прављење и (де)активирање ознака",
        "action-applychangetags": "додавање ознака на ваше измене",
        "action-changetags": "додавање и уклањање разних ознака на појединачним изменама и уносима у дневницима",
+       "action-purge": "чишћење привремене меморије ове странице",
        "nchanges": "$1 {{PLURAL:$1|измена|измене|измена}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|измена од ваше последње посете}}",
        "enhancedrc-history": "историја",
        "recentchanges-page-removed-from-category": "[[:$1]] је уклоњена из категорије",
        "recentchanges-page-removed-from-category-bundled": "[[:$1]] и још [[Special:WhatLinksHere/$1|{{PLURAL:$2|једна страница|$2 странице}}]] су уклоњене из категорије",
        "autochange-username": "Медијавики аутоматска измена",
-       "upload": "Ð\9fоÑ\88аÑ\99и датотеку",
-       "uploadbtn": "Ð\9fоÑ\88аÑ\99и датотеку",
+       "upload": "Ð\9eÑ\82пÑ\80еми датотеку",
+       "uploadbtn": "Ð\9eÑ\82пÑ\80еми датотеку",
        "reuploaddesc": "Назад на образац за отпремање",
        "upload-tryagain": "Пошаљи измењени опис датотеке",
        "uploadnologin": "Нисте пријављени",
-       "uploadnologintext": "Морате бити $1 да бисте отпремали датотеке.",
+       "uploadnologintext": "$1 да бисте отпремали датотеке.",
        "upload_directory_missing": "Фасцикла за слање ($1) недостаје и сервер је не може направити.",
        "upload_directory_read_only": "Сервер не може да пише по фасцикли за слање ($1).",
        "uploaderror": "Грешка при отпремању",
        "uploadwarning-text": "Измените опис датотеке и покушајте поново.",
        "savefile": "Сачувај датотеку",
        "uploaddisabled": "Отпремање је онемогућено.",
-       "copyuploaddisabled": "СлаÑ\9aе Ð¿Ñ\83Ñ\82ем URL адресе је онемогућено.",
+       "copyuploaddisabled": "Ð\9eÑ\82пÑ\80емаÑ\9aе Ð¿Ñ\83Ñ\82ем Ð²ÐµÐ±-адресе је онемогућено.",
        "uploaddisabledtext": "Отпремање датотека је онемогућено.",
-       "php-uploaddisabledtext": "СлаÑ\9aе Ð´Ð°Ñ\82оÑ\82ека Ñ\98е Ð¾Ð½ÐµÐ¼Ð¾Ð³Ñ\83Ñ\9bено Ñ\83 PHP-Ñ\83.\nÐ\9fÑ\80овеÑ\80иÑ\82е Ð¿Ð¾Ñ\81Ñ\82авке file_uploads.",
+       "php-uploaddisabledtext": "Ð\9eÑ\82пÑ\80емаÑ\9aе Ð´Ð°Ñ\82оÑ\82ека Ñ\98е Ð¾Ð½ÐµÐ¼Ð¾Ð³Ñ\83Ñ\9bено Ñ\83 PHP-Ñ\83.\nÐ\9fÑ\80овеÑ\80иÑ\82е Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aа file_uploads.",
        "uploadscripted": "Датотека садржи HTML или скриптни код који може бити погрешно протумачен од стране прегледача.",
        "upload-scripted-pi-callback": "Датотека која садржи инструкције за обраду XML стилског облика се не може отпремити.",
        "uploaded-script-svg": "Пронађен скриптни елеменат „$1“ у постављеној SVG датотеци.",
        "destfilename": "Назив:",
        "upload-maxfilesize": "Максимална величина датотеке: $1",
        "upload-description": "Опис датотеке",
-       "upload-options": "Поставке слања",
+       "upload-options": "Поставке отпремања",
        "watchthisupload": "Надгледај ову датотеку",
        "filewasdeleted": "Датотека с овим називом је раније послата, али је обрисана.\nПроверите $1 пре него што наставите с поновним слањем.",
        "filename-bad-prefix": "Назив датотеке коју шаљете почиње са <strong>„$1“</strong>, а њега обично додељују дигитални фотоапарати.\nИзаберите назив датотеке који описује њен садржај.",
        "upload-copy-upload-invalid-domain": "Примерци отпремања нису доступни на овом домену.",
        "upload-dialog-title": "Отпремање датотека",
        "upload-dialog-button-cancel": "Откажи",
+       "upload-dialog-button-back": "Назад",
        "upload-dialog-button-done": "Готово",
        "upload-dialog-button-save": "Сачувај",
-       "upload-dialog-button-upload": "Ð\9fоÑ\88аÑ\99и",
+       "upload-dialog-button-upload": "Ð\9eÑ\82пÑ\80еми",
        "upload-form-label-infoform-title": "Детаљи",
        "upload-form-label-infoform-name": "Назив",
        "upload-form-label-infoform-description": "Опис",
        "invalid-chunk-offset": "Неисправна полазна тачка",
        "img-auth-accessdenied": "Приступ је одбијен",
        "img-auth-nopathinfo": "Недостаје PATH_INFO.\nВаш сервер није подешен да прослеђује овакве податке.\nМожда је заснован на CGI-ју који не подржава img_auth.\nПогледајте https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization?uselang=sr-ec.",
-       "img-auth-notindir": "Захтевана путања није у подешеној фасцикли за слање.",
+       "img-auth-notindir": "Захтевана путања није у подешеној фасцикли за отпремање.",
        "img-auth-badtitle": "Не могу да створим исправан наслов за „$1“.",
        "img-auth-nologinnWL": "Нисте пријављени и „$1“ није на списку дозвољених.",
        "img-auth-nofile": "Датотека „$1“ не постоји.",
        "http-bad-status": "Дошло је до проблема током захтева HTTP: $1 $2",
        "upload-curl-error6": "Не могу да приступим адреси",
        "upload-curl-error6-text": "Не могу да приступим наведеној адреси.\nПроверите да ли је адреса исправна и доступна.",
-       "upload-curl-error28": "Слање је истекло",
+       "upload-curl-error28": "Ð\9eÑ\82пÑ\80емање је истекло",
        "upload-curl-error28-text": "Сервер не одговара на упит.\nПроверите да ли сајт ради, мало осачекајте и покушајте поново.\nПробајте касније када буде мање оптерећење.",
        "license": "Лиценца:",
        "license-header": "Лиценца:",
        "sharedupload-desc-create": "Ова датотека се налази на $1 и може да се користи на другим пројектима.\nЊен опис можете да измените на [$2 одговарајућој страници].",
        "filepage-nofile": "Не постоји датотека с овим називом.",
        "filepage-nofile-link": "Не постоји датотека с овим називом, али је можете [$1 послати].",
-       "uploadnewversion-linktext": "Ð\9fоÑ\88аÑ\99и нову верзију ове датотеке",
+       "uploadnewversion-linktext": "Ð\9eÑ\82пÑ\80еми нову верзију ове датотеке",
        "shared-repo-from": "из $1",
        "shared-repo": "заједничко складиште",
        "shared-repo-name-wikimediacommons": "Викимедијина остава",
        "apisandbox-reset": "Очисти",
        "apisandbox-results": "Резултати",
        "apisandbox-request-url-label": "Адреса захтева:",
+       "apisandbox-continue": "Настави",
+       "apisandbox-continue-clear": "Очисти",
        "booksources": "Штампани извори",
        "booksources-search-legend": "Тражи књижевне изворе",
        "booksources-isbn": "ISBN:",
        "activeusers-intro": "Ово је списак корисника који су били активни {{PLURAL:$1|1=претходни дан|у последња $1 дана|у последњих $1 дана}}.",
        "activeusers-count": "$1 {{PLURAL:$1|радња|радње|радњи}} {{PLURAL:$3|претходни дан|у последња $3 дана|у последњих $3 дана}}",
        "activeusers-from": "Прикажи кориснике почев од:",
-       "activeusers-hidebots": "Сакриј ботове",
-       "activeusers-hidesysops": "Сакриј администраторе",
        "activeusers-noresult": "Корисник није пронађен.",
        "activeusers-submit": "Прикажи активне кориснике",
        "listgrouprights": "Права корисничких група",
        "trackingcategories-nodesc": "Опис није доступан.",
        "trackingcategories-disabled": "Категорија је онемогућена",
        "mailnologin": "Нема адресе за слање",
-       "mailnologintext": "Морате бити [[Special:UserLogin|пријављени]] и имати исправан имејл у [[Special:Preferences|подешавањима]] да бисте слали имејлове другим корисницима.",
+       "mailnologintext": "Морате бити [[Special:UserLogin|пријављени]] и имати исправан имејл адресу у [[Special:Preferences|подешавањима]] да бисте слали имејлове другим корисницима.",
        "emailuser": "Пошаљи имејл",
        "emailuser-title-target": "Слање имејла {{GENDER:$1|кориснику|корисници}}",
        "emailuser-title-notarget": "Слање имејла кориснику",
        "emailpagetext": "Можете да користите доњи образац да пошаљете имејл {{GENDER:$1|овом кориснику|овој корисници}}.\nИмејл који сте унели у вашим [[Special:Preferences|подешавањима]] ће се приказати у пољу „Од“, тако да ће прималац моћи да вам одговори директно.",
-       "defemailsubject": "{{SITENAME}} — Имејл од {{GENDER:$1|корисника|кориснице}} $1",
-       "usermaildisabled": "Ð\9aоÑ\80иÑ\81ниÑ\87ка Ðµ-поÑ\88Ñ\82а Ñ\98е Ð¾Ð½ÐµÐ¼Ð¾Ð³Ñ\83Ñ\9bена",
+       "defemailsubject": "{{SITENAME}} — Имејл од {{GENDER:$1|корисника|кориснице}} „$1”",
+       "usermaildisabled": "Ð\9aоÑ\80иÑ\81ниÑ\87ки Ð¸Ð¼ÐµÑ\98л Ñ\98е Ð¾Ð½ÐµÐ¼Ð¾Ð³Ñ\83Ñ\9bен",
        "usermaildisabledtext": "Не можете да шаљете имејлове другим корисницима на овом викију",
        "noemailtitle": "Нема имејл адресе",
        "noemailtext": "Овај корисник није навео исправну имејл адресу.",
        "emailtarget": "Унос корисничког имена примаоца",
        "emailusername": "Корисничко име:",
        "emailusernamesubmit": "Пошаљи",
-       "email-legend": "СлаÑ\9aе Ð¸Ð¼ÐµÑ\98ла другом кориснику",
+       "email-legend": "Ð\9fоÑ\88аÑ\99и Ð¸Ð¼ÐµÑ\98л другом кориснику",
        "emailfrom": "Од:",
        "emailto": "За:",
        "emailsubject": "Наслов:",
        "emailsend": "Пошаљи",
        "emailccme": "Пошаљи ми копију поруке на мој имејл.",
        "emailccsubject": "Копија ваше поруке кориснику $1: $2",
-       "emailsent": "Ð\9fоÑ\80Ñ\83ка Ñ\98е Ð¿Ð¾Ñ\81лаÑ\82а",
-       "emailsenttext": "Ваш имејл је послат.",
+       "emailsent": "Ð\98меÑ\98л Ñ\98е Ð¿Ð¾Ñ\81лаÑ\82",
+       "emailsenttext": "Ваша имејл порука је послата.",
        "emailuserfooter": "Овај имејл је {{GENDER:$1|послао|послала}} $1 {{GENDER:$2|кориснику|корисници}} $2 помоћу „{{int:emailuser}}“ с викија {{SITENAME}}.",
        "usermessage-summary": "Слање системске поруке.",
        "usermessage-editor": "Уређивач системских порука",
        "enotif_subject_created": "Страницу $1 на {{SITENAME}} {{GENDER:$2|направио је|направила је|направио је}} $2",
        "enotif_subject_moved": "Страницу $1 на {{SITENAME}} {{GENDER:$2|преместио је|преместила је}} $2",
        "enotif_subject_restored": "Страницу $1 на {{SITENAME}} {{GENDER:$2|вратио је|вратила је|вратио је}} $2",
-       "enotif_subject_changed": "Страницу $1 на {{SITENAME}} {{GENDER:$2|променио је|променила је|променио је}} $2",
+       "enotif_subject_changed": "Страницу $1 на {{SITENAME}} {{GENDER:$2|променио|променила}} је $2",
        "enotif_body_intro_deleted": "Страницу $1 на {{SITENAME}} {{GENDER:$2|обрисао|обрисала}} је $2 дана $PAGEEDITDATE Погледајте $3.",
        "enotif_body_intro_created": "Страницу $1 на {{SITENAME}} {{GENDER:$2|направио|направила}} је $2 дана $PAGEEDITDATE Тренутна измена налази се на $3.",
        "enotif_body_intro_moved": "Страницу $1 на {{SITENAME}} {{GENDER:$2|преместио|преместила}} је $2 дана $PAGEEDITDATE Тренутна измена налази се на  $3.",
        "enotif_lastvisited": "Погледајте $1 за све измене од ваше последње посете.",
        "enotif_lastdiff": "Погледајте $1 да видите ову измену.",
        "enotif_anon_editor": "анониман корисник $1",
-       "enotif_body": "Ð\9fоÑ\88Ñ\82овани $WATCHINGUSERNAME,\n \t\n$PAGEINTRO $NEWPAGE\n\nÐ\9eпиÑ\81: $PAGESUMMARY $PAGEMINOREDIT\n\nÐ\9aонÑ\82акÑ\82:\nе-поÑ\88Ñ\82а: $PAGEEDITOR_EMAIL\nвики: $PAGEEDITOR_WIKI\n\nÐ\9dеÑ\9bе Ð±Ð¸Ñ\82и Ð´Ñ\80Ñ\83гиÑ\85 Ð¾Ð±Ð°Ð²ÐµÑ\88Ñ\82еÑ\9aа Ñ\83 Ñ\81лÑ\83Ñ\87аÑ\98Ñ\83 Ð´Ð°Ñ\99иÑ\85 Ð¸Ð·Ð¼ÐµÐ½Ð° Ñ\83колико Ð½Ðµ Ð¿Ð¾Ñ\81еÑ\82иÑ\82е Ð¾Ð²Ñ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 ÐºÐ°Ð´Ð° Ñ\81Ñ\82е Ð¿Ñ\80иÑ\98авÑ\99ени.\nÐ\9cожеÑ\82е Ð¸ Ð´Ð° Ð¿Ð¾Ð½Ð¸Ñ\88Ñ\82иÑ\82е Ð¿Ð¾Ñ\81Ñ\82авке Ð¾Ð±Ð°Ð²ÐµÑ\88Ñ\82еÑ\9aа Ð·Ð° Ñ\81ве Ñ\81Ñ\82Ñ\80аниÑ\86е Ñ\83 Ð²Ð°Ñ\88ем Ñ\81пиÑ\81кÑ\83 Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ñ\9aа.\n\nСÑ\80даÑ\87ан Ð¿Ð¾Ð·Ð´Ñ\80ав, {{SITENAME}}\n\n--\nÐ\94а Ð±Ð¸Ñ\81Ñ\82е Ð¿Ñ\80оменили Ð¿Ð¾Ñ\81Ñ\82авке Ñ\83 Ð²ÐµÐ·Ð¸ Ñ\81а Ðµ-обавеÑ\88Ñ\82еÑ\9aима, Ð¿Ð¾Ñ\81еÑ\82иÑ\82е\n{{canonicalurl:{{#special:Preferences}}}}\n\nÐ\94а Ð±Ð¸Ñ\81Ñ\82е Ð¿Ñ\80оменили Ð¿Ð¾Ñ\81Ñ\82авке Ñ\83 Ð²ÐµÐ·Ð¸ Ñ\81а Ñ\81пиÑ\81ком надгледања, посетите\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nДа бисте уклонили ову страницу са списка надгледања, посетите\n$UNWATCHURL\n\nПодршка и даља помоћ:\n$HELPPAGE",
+       "enotif_body": "Ð\9fоÑ\88Ñ\82овани $WATCHINGUSERNAME,\n \t\n$PAGEINTRO $NEWPAGE\n\nÐ\9eпиÑ\81: $PAGESUMMARY $PAGEMINOREDIT\n\nÐ\9aонÑ\82акÑ\82:\nмеÑ\98л: $PAGEEDITOR_EMAIL\nвики: $PAGEEDITOR_WIKI\n\nÐ\9dеÑ\9bе Ð±Ð¸Ñ\82и Ð´Ñ\80Ñ\83гиÑ\85 Ð¾Ð±Ð°Ð²ÐµÑ\88Ñ\82еÑ\9aа Ñ\83 Ñ\81лÑ\83Ñ\87аÑ\98Ñ\83 Ð´Ð°Ñ\99иÑ\85 Ð¸Ð·Ð¼ÐµÐ½Ð° Ñ\83колико Ð½Ðµ Ð¿Ð¾Ñ\81еÑ\82иÑ\82е Ð¾Ð²Ñ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83 ÐºÐ°Ð´Ð° Ñ\81Ñ\82е Ð¿Ñ\80иÑ\98авÑ\99ени.\nÐ\9cожеÑ\82е Ð¸ Ð´Ð° Ð¿Ð¾Ð½Ð¸Ñ\88Ñ\82иÑ\82е Ð¿Ð¾Ñ\81Ñ\82авке Ð¾Ð±Ð°Ð²ÐµÑ\88Ñ\82еÑ\9aа Ð·Ð° Ñ\81ве Ñ\81Ñ\82Ñ\80аниÑ\86е Ñ\83 Ð²Ð°Ñ\88ем Ñ\81пиÑ\81кÑ\83 Ð½Ð°Ð´Ð³Ð»ÐµÐ´Ð°Ñ\9aа.\n\nСÑ\80даÑ\87ан Ð¿Ð¾Ð·Ð´Ñ\80ав, {{SITENAME}}\n\n--\nÐ\94а Ð±Ð¸Ñ\81Ñ\82е Ð¿Ñ\80оменили Ð¿Ð¾Ñ\81Ñ\82авке Ð¸Ð¼ÐµÑ\98л Ð¾Ð±Ð°Ð²ÐµÑ\88Ñ\82еÑ\9aа, Ð¿Ð¾Ñ\81еÑ\82иÑ\82е\n{{canonicalurl:{{#special:Preferences}}}}\n\nÐ\94а Ð±Ð¸Ñ\81Ñ\82е Ð¿Ñ\80оменили Ð¿Ð¾Ñ\81Ñ\82авке Ñ\81пиÑ\81ка надгледања, посетите\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nДа бисте уклонили ову страницу са списка надгледања, посетите\n$UNWATCHURL\n\nПодршка и даља помоћ:\n$HELPPAGE",
        "created": "направљена",
        "changed": "измењена",
        "deletepage": "Обриши страницу",
        "protectedarticle": "је заштитио „[[$1]]“",
        "modifiedarticleprotection": "промењен степен заштите за „[[$1]]“",
        "unprotectedarticle": "је скинуо заштиту са странице „[[$1]]“",
-       "movedarticleprotection": "је преместио поставке заштите са „[[$2]]“ на „[[$1]]“",
+       "movedarticleprotection": "је преместио подешавања заштите са „[[$2]]“ на „[[$1]]“",
+       "protectedarticle-comment": "{{GENDER:$2|Заштићена}} страница [[$1]]",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Промењен}} ниво заштите [[$1]]",
+       "unprotectedarticle-comment": "{{GENDER:$2|Скинута}} заштита са [[$1]]",
        "protect-title": "Степен заштите за „$1“",
        "protect-title-notallowed": "Преглед степена заштите за „$1“",
        "prot_1movedto2": "је преместио [[$1]] на [[$2]]",
        "restriction-edit": "уређивање",
        "restriction-move": "премештање",
        "restriction-create": "прављење",
-       "restriction-upload": "слање",
+       "restriction-upload": "отпремање",
        "restriction-level-sysop": "потпуно заштићено",
        "restriction-level-autoconfirmed": "полузаштићено",
        "restriction-level-all": "сви нивои",
        "undeletedrevisions": "{{PLURAL:$1|измена враћено}} $1",
        "undeletedrevisions-files": "$1 {{PLURAL:$1|измена|измене|измена}} и $2 {{PLURAL:$2|датотека је враћена|датотеке су враћене|датотека је враћено}}",
        "undeletedfiles": "{{PLURAL:$1|датотека враћено}} $1",
-       "cannotundelete": "Враћање није успело:\n$1",
+       "cannotundelete": "Враћање једне или свих ставник није успјело:\n$1",
        "undeletedpage": "<strong>Страница $1 је враћена</strong>\n\nПогледајте [[Special:Log/delete|дневник брисања]] за записе о скорашњим брисањима и враћањима.",
        "undelete-header": "Погледајте [[Special:Log/delete|историјат брисања]] за недавно обрисане странице.",
        "undelete-search-title": "Претрага обрисаних страница",
        "sp-contributions-newbies-sub": "За нове кориснике",
        "sp-contributions-newbies-title": "Доприноси нових корисника",
        "sp-contributions-blocklog": "дневник блокирања",
-       "sp-contributions-deleted": "обрисани доприноси",
+       "sp-contributions-deleted": "обрисани {{GENDER:$1|доприноси}}",
        "sp-contributions-uploads": "отпремања",
        "sp-contributions-logs": "дневници",
        "sp-contributions-talk": "разговор",
        "ipbreason-dropdown": "*Најчешћи разлози за блокирање\n** Уношење лажних информација\n** Уклањање садржаја са страница\n** Постављање веза до спољашњих сајтова\n** Уношење бесмислица у странице\n** Непристојно понашање\n** Употреба више налога\n** Неприхватљиво корисничко име",
        "ipb-hardblock": "Онемогући пријављеним корисницима да уређују с ове ИП адресе",
        "ipbcreateaccount": "Онемогући отварање налога",
-       "ipbemailban": "Ð\9eнемогÑ\83Ñ\9bи ÐºÐ¾Ñ\80иÑ\81никÑ\83 да шаље имејлове",
+       "ipbemailban": "СпÑ\80еÑ\87и ÐºÐ¾Ñ\80иÑ\81ника да шаље имејлове",
        "ipbenableautoblock": "Аутоматски блокирај последњу ИП адресу овог корисника и све даљње адресе с којих покуша да уређује",
        "ipbsubmit": "Блокирај овог корисника",
        "ipbother": "Друго време:",
        "anononlyblock": "само анонимни",
        "noautoblockblock": "аутоматско блокирање је онемогућено",
        "createaccountblock": "отварање налога је онемогућено",
-       "emailblock": "е-поÑ\88Ñ\82а Ñ\98е Ð±Ð»Ð¾ÐºÐ¸Ñ\80ана",
+       "emailblock": "имеÑ\98л Ñ\98е Ð¾Ð½ÐµÐ¼Ð¾Ð³Ñ\83Ñ\9bен",
        "blocklist-nousertalk": "забрањено уређивање сопствене странице за разговор",
        "ipblocklist-empty": "Списак блокирања је празан.",
        "ipblocklist-no-results": "Тражена ИП адреса или корисничко име није блокирано.",
        "block-log-flags-anononly": "само анонимни корисници",
        "block-log-flags-nocreate": "онемогућено отварање налога",
        "block-log-flags-noautoblock": "аутоматско блокирање је онемогућено",
-       "block-log-flags-noemail": "е-поÑ\88Ñ\82а Ñ\98е Ð±Ð»Ð¾ÐºÐ¸Ñ\80ана",
+       "block-log-flags-noemail": "имеÑ\98л Ñ\98е Ð¾Ð½ÐµÐ¼Ð¾Ð³Ñ\83Ñ\9bен",
        "block-log-flags-nousertalk": "забрањено уређивање сопствене странице за разговор",
        "block-log-flags-angry-autoblock": "проширено аутоматско блокирање је омогућено",
        "block-log-flags-hiddenname": "корисничко име је сакривено",
        "lockdbsuccesstext": "База података је закључана.<br />\nСетите се да је [[Special:UnlockDB|откључате]] када завршите с одржавањем.",
        "unlockdbsuccesstext": "База је откључана.",
        "lockfilenotwritable": "Датотека за закључавање базе није отворена за писање.\nДа бисте закључали и откључали базу, датотека мора бити доступна за писање од стране мрежног сервера.",
+       "databaselocked": "База података је већ закључана.",
        "databasenotlocked": "База није закључана.",
        "lockedbyandtime": "(од $1 дана $2 у $3)",
        "move-page": "Премештање „$1“",
        "tooltip-search": "Претрага",
        "tooltip-search-go": "Идите на страницу с овим именом, ако постоји",
        "tooltip-search-fulltext": "Претражите странице с овим текстом",
-       "tooltip-p-logo": "Ð\9fоÑ\81еÑ\82иÑ\82е Ð½Ð°Ñ\81ловну страну",
-       "tooltip-n-mainpage": "Ð\9fоÑ\81еÑ\82иÑ\82е Ð½Ð°Ñ\81ловну страну",
-       "tooltip-n-mainpage-description": "Ð\9fоÑ\81еÑ\82иÑ\82е Ð½Ð°Ñ\81ловну страну",
+       "tooltip-p-logo": "Ð\9fоÑ\81еÑ\82иÑ\82е Ð³Ð»Ð°вну страну",
+       "tooltip-n-mainpage": "Ð\9fоÑ\81еÑ\82иÑ\82е Ð³Ð»Ð°вну страну",
+       "tooltip-n-mainpage-description": "Ð\9fоÑ\81еÑ\82иÑ\82е Ð³Ð»Ð°вну страну",
        "tooltip-n-portal": "О пројекту, шта можете да радите и где да пронађете ствари",
        "tooltip-n-currentevents": "Сазнајте више о текућим догађајима",
        "tooltip-n-recentchanges": "Списак скорашњих измена на викију",
        "tooltip-t-contributions": "Списак доприноса {{GENDER:$1|овог корисника|ове кориснице}}",
        "tooltip-t-emailuser": "Пошаљите имејл {{GENDER:$1|овом кориснику|овој корисници}}",
        "tooltip-t-info": "Више информација о овој страници",
-       "tooltip-t-upload": "Ð\9fоÑ\88аÑ\99иÑ\82е датотеке",
+       "tooltip-t-upload": "Ð\9eÑ\82пÑ\80еми датотеке",
        "tooltip-t-specialpages": "Списак свих посебних страница",
        "tooltip-t-print": "Верзија ове странице за штампање",
        "tooltip-t-permalink": "Стална веза ка овој измени странице",
        "lastmodifiedatby": "Ову страницу је последњи пут {{GENDER:$4|изменио|изменила|изменио}} $3, $1 у $2.",
        "othercontribs": "Засновано на раду корисника $1.",
        "others": "други",
-       "siteusers": "{{PLURAL:$2|корисник|корисници}} на пројекту {{SITENAME}} $1",
+       "siteusers": "{{PLURAL:$2|1={{GENDER:$1|корисник|корисница}}|корисници}} на пројекту {{SITENAME}} $1",
        "anonusers": "{{PLURAL:$2|анониман корисник|анонимни корисници}} на пројекту {{SITENAME}} $1",
        "creditspage": "Аутори странице",
        "nocredits": "Не постоје подаци о аутору ове странице.",
        "pageinfo-article-id": "ИД странице",
        "pageinfo-language": "Језик садржаја странице",
        "pageinfo-content-model": "Модел садржаја странице",
+       "pageinfo-content-model-change": "промени",
        "pageinfo-robot-policy": "Индексирање од стране робота",
        "pageinfo-robot-index": "Дозвољено",
        "pageinfo-robot-noindex": "Није дозвољено",
        "pageinfo-watchers": "Број надгледача странице",
+       "pageinfo-visiting-watchers": "Број надгледача странице који су посјетили скорашње измјене",
        "pageinfo-few-watchers": "Мање од $1 {{PLURAL:$1|пратиоца|пратилаца}}",
        "pageinfo-redirects-name": "Број преусмерења на ову страницу",
        "pageinfo-subpages-name": "Подстранице ове странице",
        "pageinfo-protect-cascading-yes": "Да",
        "pageinfo-protect-cascading-from": "Странице са преносивом заштитом од",
        "pageinfo-category-info": "Информације о категорији",
+       "pageinfo-category-total": "Укупно",
        "pageinfo-category-pages": "Број страница",
        "pageinfo-category-subcats": "Број поткатегорија",
        "pageinfo-category-files": "Број датотека",
        "patrol-log-header": "Ово је дневник патролираних измена.",
        "log-show-hide-patrol": "$1 дневник патролирања",
        "log-show-hide-tag": "$1 дневник ознака",
+       "confirm-markpatrolled-button": "У реду",
+       "confirm-markpatrolled-top": "Означити измену $3 странице $2 патролираном?",
        "deletedrevision": "Обрисана стара измена $1.",
        "filedeleteerror-short": "Грешка при брисању датотеке: $1",
        "filedeleteerror-long": "Дошло је до грешака при брисању датотеке:\n\n$1",
        "confirmemail_sendfailed": "{{SITENAME}} не може да пошаље имејл потврду.\nПроверите да ли је имејл адреса правилно написана.\n\nГрешка: $1",
        "confirmemail_invalid": "Потврдни код је неисправан. Вероватно је истекао.",
        "confirmemail_needlogin": "Морате бити $1 да бисте потврдили имејл адресу.",
-       "confirmemail_success": "Ваша имејл адреса је потврђена.\nСада можете да се [[Special:UserLogin|пријавите]]. Желимо вам пријатан боравак на викију.",
+       "confirmemail_success": "Ваша имејл адреса је потврђена.\nСада можете да се [[Special:UserLogin|пријавите]] и уживате у викију.",
        "confirmemail_loggedin": "Ваша имејл адреса је сада потврђена.",
        "confirmemail_subject": "{{SITENAME}} – потврда имејл адресе",
-       "confirmemail_body": "Неко, вероватно ви, са ИП адресе $1 \nје променио имејл адресу налога „$2“ у ову адресу на {{SITENAME}}.\n\nДа бисмо потврдили да овај налог стварно припада вама и поново активирали могућности имејла на {{SITENAME}}, отворите следећу везу у прегледачу:\n\n$3\n\nАко налог *не* припада вама, пратите следећу везу да откажете потврду имејл адресе:\n\n$5\n\nОвај потврдни код истиче $4.",
-       "confirmemail_body_changed": "Неко, вероватно ви, са ИП адресе $1 је променио имејл адресу налога „$2“ у ову адресу на викију {{SITENAME}}.\n\nДа бисте потврдили да овај налог стварно припада вама и поново активирали могућности имејла, отворите следећу везу у прегледачу:\n\n$3\n\nАко налог *не* припада вама, пратите следећу везу да откажете потврду имејл адресе:\n\n$5\n\nОвај потврдни код истиче $6 у $7",
-       "confirmemail_body_set": "Неко, вероватно ви, са ИП адресе $1 \nје променио имејл адресу налога „$2“ у ову адресу на {{SITENAME}}.\n\nДа бисмо потврдили да овај налог стварно припада вама и поново активирали могућности имејла на {{SITENAME}}, отворите следећу везу у прегледачу:\n\n$3\n\nАко налог *не* припада вама, пратите следећу везу да откажете потврду имејл адресе:\n\n$5\n\nОвај потврдни код истиче $4.",
+       "confirmemail_body": "Неко, вероватно ви, са ИП адресе $1,\nотворио је налог „$2“ са овом имејл адресом на викију {{SITENAME}}.\n\nДа потврдите да овај налог стварно припада вама и да активирате\nмогућности имејла на викију {{SITENAME}}, отворите ову везу у прегледачу:\n\n$3\n\nУколико налог *не* припада вама, пратите везу\nда откажете потврду имејл адресе:\n\n$5\n\nОвај потврдни код истиче у $4.",
+       "confirmemail_body_changed": "Неко, вероватно ви, са ИП адресе $1,\nпроменио је имејл адресу налога „$2“ у ову адресу на викију {{SITENAME}}.\n\nДа бисте потврдили да овај налог стварно припада вама и поново активирали могућности имејла, отворите следећу везу у прегледачу:\n\n$3\n\nАко налог *не* припада вама, пратите следећу везу да откажете потврду имејл адресе:\n\n$5\n\nОвај потврдни код истиче $6 у $7",
+       "confirmemail_body_set": "Неко, вероватно ви, са ИП адресе $1,\nпроменио је имејл адресу налога „$2“ у ову адресу на {{SITENAME}}.\n\nДа бисмо потврдили да овај налог стварно припада вама и поново активирали\nмогућности имејла на {{SITENAME}}, отворите следећу везу у прегледачу:\n\n$3\n\nАко налог *не* припада вама, пратите следећу везу да откажете потврду имејл адресе:\n\n$5\n\nОвај потврдни код истиче $4.",
        "confirmemail_invalidated": "Потврда имејл адресе је отказана",
        "invalidateemail": "Отказивање потврде имејла",
        "notificationemail_body_changed": "Неко, вероватно Ви је променио имејл адресу налога из $2“ у „$3“ са IP адресе $1 на сајту {{SITENAME}}.\n\nАко ово нисте били Ви, одмах обавестите администраторе сајта.",
        "feedback-cancel": "Откажи",
        "feedback-close": "Урађено",
        "feedback-external-bug-report-button": "Пријави баг",
-       "feedback-error-title": "Грешка",
        "feedback-error1": "Грешка: непрепознат резултат од АПИ-ја",
        "feedback-error2": "Грешка: уређивање није успело",
        "feedback-error3": "Грешка: нема одговора од АПИ-ја",
        "mediastatistics-header-total": "Све датотеке",
        "json-error-syntax": "Грешка у синтакси",
        "headline-anchor-title": "Веза до овог одељка",
-       "special-characters-group-latin": "латиница",
+       "special-characters-group-latin": "Ð\9bатиница",
        "special-characters-group-latinextended": "проширена латиница",
        "special-characters-group-ipa": "ИПА",
        "special-characters-group-symbols": "симболи",
        "log-action-filter-protect-move_prot": "премештање заштите",
        "log-action-filter-rights-rights": "ручно",
        "log-action-filter-rights-autopromote": "аутоматски",
-       "log-action-filter-upload-upload": "ново",
-       "log-action-filter-upload-overwrite": "промена постојећег"
+       "log-action-filter-upload-upload": "Ново отпремање",
+       "log-action-filter-upload-overwrite": "промена постојећег",
+       "authmanager-email-label": "Имејл",
+       "authmanager-email-help": "Имејл адреса",
+       "changecredentials": "Промјена акредитива"
 }
index 252b76a..6bdd3b5 100644 (file)
@@ -45,9 +45,9 @@
        "tog-previewontop": "Prikaži pregled pre okvira za uređivanje",
        "tog-previewonfirst": "Prikaži pregled na prvoj izmeni",
        "tog-enotifwatchlistpages": "Pošalji mi imejl kada se promeni stranica/datoteka koju nadgledam",
-       "tog-enotifusertalkpages": "Pošalji mi e-poruku kada se promeni moja stranica za razgovor",
-       "tog-enotifminoredits": "Pošalji mi e-poruku i za manje izmene u stranicama i datotekama",
-       "tog-enotifrevealaddr": "Prikaži moju e-adresu u porukama obaveštenja",
+       "tog-enotifusertalkpages": "Pošalji mi imejl kada se promeni moja stranica za razgovor",
+       "tog-enotifminoredits": "Pošalji mi imejl i za manje izmene u stranicama i datotekama",
+       "tog-enotifrevealaddr": "Prikaži moju imejl adresu u porukama obaveštenja",
        "tog-shownumberswatching": "Prikaži broj korisnika koji nadgledaju",
        "tog-oldsig": "Tekući potpis:",
        "tog-fancysig": "Smatraj potpis kao vikitekst (bez samopovezivanja)",
@@ -61,7 +61,7 @@
        "tog-watchlisthideanons": "Sakrij izmene anonimnih korisnika sa spiska nadgledanja",
        "tog-watchlisthidepatrolled": "Sakrij patrolirane izmene sa spiska nadgledanja",
        "tog-watchlisthidecategorization": "Sakrij kategorizaciju stranica",
-       "tog-ccmeonemails": "Pošalji mi primerke e-poruka koje pošaljem drugim korisnicima",
+       "tog-ccmeonemails": "Pošalji mi kopije imejlova koje pošaljem drugim korisnicima",
        "tog-diffonly": "Ne prikazuj sadržaj stranice ispod razlika",
        "tog-showhiddencats": "Prikaži skrivene kategorije",
        "tog-norollbackdiff": "Izostavi razliku nakon izvršenog vraćanja",
        "qbfind": "Pronađi",
        "qbbrowse": "Potraži",
        "qbedit": "Uredi",
-       "qbpageoptions": "Postavke stranice",
+       "qbpageoptions": "Ova stranica",
        "qbmyoptions": "Moje stranice",
        "faq": "NPP",
        "faqpage": "Project:NPP",
        "translateinterface": "Da dodate ili promenite prevode za sve vikije, posetite [https://translatewiki.net/ Translejtviki], projekat za lokalizaciju Medijavikija.",
        "cascadeprotected": "Ova stranica je zaključana jer sadrži {{PLURAL:$1|sledeću stranicu koja je zaštićena|sledeće stranice koje su zaštićene}} „prenosivom“ zaštitom:\n$2",
        "namespaceprotected": "Nemate dozvolu da uređujete stranice u imenskom prostoru <strong>$1</strong>.",
-       "customcssprotected": "Nemate dozvolu da menjate ovu CSS stranicu jer sadrži lične postavke drugog korisnika.",
+       "customcssprotected": "Nemate dozvolu da menjate ovu CSS stranicu jer sadrži lična podešavanja drugog korisnika.",
        "customjsprotected": "Nemate dozvolu da menjate ovu stranicu javaskripta jer sadrži lične postavke drugog korisnika.",
        "mycustomcssprotected": "Nemate dozvolu za menjanje ove CSS stranice.",
        "mycustomjsprotected": "Nemate dozvolu za menjanje ove JavaScript stranice.",
        "userlogin": "Prijava/registracija",
        "userloginnocreate": "Prijava",
        "logout": "Odjava",
-       "userlogout": "Odjavi me",
+       "userlogout": "Odjava",
        "notloggedin": "Niste prijavljeni",
        "userlogin-noaccount": "Nemate nalog?",
        "userlogin-joinproject": "Otvorite ga",
        "userlogin-helplink2": "Pomoć pri prijavljivanju",
        "userlogin-loggedin": "Već ste prijavljeni kao {{GENDER:$1|$1}}.\nKoristite donji obrazac da biste se prijavili kao drugi korisnik.",
        "userlogin-createanother": "Otvori još jedan nalog",
-       "createacct-emailrequired": "Adresa e-pošte",
-       "createacct-emailoptional": "Adresa e-pošte (opciono)",
-       "createacct-email-ph": "Unesite vašu adresu e-pоšte",
-       "createacct-another-email-ph": "Unesite adresu e-pošte",
+       "createacct-emailrequired": "Imejl adresa",
+       "createacct-emailoptional": "Imejl adresa (opciono)",
+       "createacct-email-ph": "Unesite Vašu imejl adresu",
+       "createacct-another-email-ph": "Unesite imejl adresu",
        "createaccountmail": "Koristite privremenu, slučajno stvorenu lozinku i pošaljite na navedenu adresu elektronske pošte",
        "createacct-realname": "Pravo ime (opciono)",
        "createaccountreason": "Razlog:",
        "mailmypassword": "Resetuj lozinku",
        "passwordremindertitle": "{{SITENAME}} — privremena lozinka",
        "passwordremindertext": "Neko, verovatno vi, sa IP adrese $1 je zatražio novu lozinku na vikiju {{SITENAME}} ($4).\nStvorena je privremena lozinka za {{GENDER:$2|korisnika|korisnicu|korisnika}} $2 koja glasi $3.\nUkoliko je ovo vaš zahtev, sada se prijavite i postavite novu lozinku.\nPrivremena lozinka ističe za {{PLURAL:$5|jedan dan|$5 dana|$5 dana}}.\n\nAko je neko drugi zatražio promenu lozinke, ili ste se setili vaše lozinke i ne želite da je menjate, zanemarite ovu poruku.",
-       "noemail": "Ne postoji e-adresa za {{GENDER:$1|korisnika|korisnicu}} $1.",
-       "noemailcreate": "Morate navesti ispravnu e-adresu",
-       "passwordsent": "Nova lozinka je poslata na e-adresu {{GENDER:$1|korisnika|korisnice|korisnika}} $1.\nPrijavite se pošto je primite.",
+       "noemail": "Ne postoji imejl adresa za {{GENDER:$1|korisnika|korisnicu}} $1.",
+       "noemailcreate": "Morate navesti ispravnu imejl adresu.",
+       "passwordsent": "Nova lozinka je poslata na imejl adresu {{GENDER:$1|korisnika|korisnice|korisnika}} $1.\nPrijavite se pošto je primite.",
        "blocked-mailpassword": "Vašoj IP adresi je onemogućeno uređivanje stranica, kao i mogućnost zahtevanja nove lozinke.",
-       "eauthentsent": "Na navedenu e-adresu je poslat potvrdni kod.\nPre nego što pošaljemo daljnje poruke, pratite uputstva s e-pošte da biste potvrdili da ste vi otvorili nalog.",
+       "eauthentsent": "Na navedenu imejl adresu je poslat potvrdni kod.\nPre nego što pošaljemo daljnje poruke, pratite uputstva s imejla da biste potvrdili da ste Vi otvorili nalog.",
        "throttled-mailpassword": "Poruka za promenu lozinke je poslata u {{PLURAL:$1|1=poslednjih sat vremena|poslednja $1 sata|poslednjih $1 sati}}.\nDa bismo sprečili zloupotrebu, podsetnik šaljemo samo jednom u roku od {{PLURAL:$1|1=sat vremena|$1 sata|$1 sati}}.",
        "mailerror": "Greška pri slanju poruke: $1",
-       "acct_creation_throttle_hit": "Posetioci ovog vikija koji koriste vašu IP adresu su već otvorili {{PLURAL:$1|1=jedan nalog|$1 naloga|$1 naloga}} prethodni dan, što je najveći dozvoljeni broj u tom vremenskom periodu.\nZbog toga posetioci s ove IP adrese trenutno ne mogu otvoriti više naloga.",
-       "emailauthenticated": "Vaša e-adresa je potvrđena $2 u $3.",
-       "emailnotauthenticated": "Vaša e-adresa još nije potvrđena.\nPoruke neće biti poslate ni u jednom od sledećih slučajeva.",
-       "noemailprefs": "Unesite e-adresu kako bi ove mogućnosti radile.",
-       "emailconfirmlink": "Potvrdite svoju e-adresu",
-       "invalidemailaddress": "E-adresa ne može biti prihvaćena jer je neispravnog oblika.\nUnesite ispravnu adresu ili ostavite prazno polje.",
-       "cannotchangeemail": "Na ovom vikiju ne možete promeniti e-adresu naloga.",
-       "emaildisabled": "Ovaj sajt ne može da šalje e-poruke.",
+       "acct_creation_throttle_hit": "Posetioci ovog vikija koji koriste vašu IP adresu su već otvorili {{PLURAL:$1|1=jedan nalog|$1 naloga}} prethodni $2, što je najveći dozvoljeni broj u tom vremenskom periodu.\nZbog toga posetioci s ove IP adrese trenutno ne mogu otvoriti više naloga.",
+       "emailauthenticated": "Vaša imejl adresa je potvrđena $2 u $3.",
+       "emailnotauthenticated": "Vaša imejl adresa još nije potvrđena.\nImejl neće biti poslat ni u jednom od sledećih slučajeva.",
+       "noemailprefs": "Unesite imejl adresu kako bi ove mogućnosti radile.",
+       "emailconfirmlink": "Potvrdite svoju imejl adresu",
+       "invalidemailaddress": "Imejl adresa ne može biti prihvaćena jer je neispravnog oblika.\nUnesite ispravnu adresu ili ostavite prazno polje.",
+       "cannotchangeemail": "Na ovom vikiju ne možete promeniti imejl adresu naloga.",
+       "emaildisabled": "Ovaj sajt ne može da šalje imejlove.",
        "accountcreated": "Nalog je otvoren",
        "accountcreatedtext": "Korisnički nalog [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) je otvoren.",
        "createaccount-title": "Otvaranje korisničkog naloga za {{SITENAME}}",
-       "createaccount-text": "Neko je otvorio nalog s vašom e-adresom na {{SITENAME}} ($4) pod imenom $2 i lozinkom $3.\nPrijavite se i promenite svoju lozinku.\n\nAko je ovo greška, zanemarite ovu poruku.",
+       "createaccount-text": "Neko je otvorio nalog s vašom imejl adresom na {{SITENAME}} ($4) pod imenom $2 i lozinkom $3.\nPrijavite se i promenite svoju lozinku.\n\nAko je ovo greška, zanemarite ovu poruku.",
        "login-throttled": "Previše puta ste pokušali da se prijavite. \nMolimo vas da sačekate $1 pre nego što pokušate ponovo.",
        "login-abort-generic": "Neuspešna prijava – prekinuto",
        "login-migrated-generic": "Vaš nalog je migriran i vaše korisničko više ne postoji na ovom vikiju.",
        "pt-createaccount": "Otvori nalog",
        "pt-userlogout": "Odjavi me",
        "php-mail-error-unknown": "Nepoznata greška u funkciji PHP mail().",
-       "user-mail-no-addy": "Pokušali ste da pošaljete poruku bez e-adrese.",
+       "user-mail-no-addy": "Pokušali ste da pošaljete imejl bez imejl adrese.",
        "user-mail-no-body": "Pokušano slanje elektronske poruke s praznim ili nerazumno kratkim sadržajem.",
        "changepassword": "Promeni lozinku",
        "resetpass_announce": "Da biste završili prijavu, podesite novu lozinku ovde.",
        "resetpass_submit": "Postavi lozinku i prijavi me",
        "changepassword-success": "Vaša lozinka je uspešno promenjena.",
        "changepassword-throttled": "Previše puta ste pokušali da se prijavite.\nMolimo vas da sačekate $1 pre nego što pokušate ponovo.",
+       "botpasswords": "Lozinke botova",
        "botpasswords-label-cancel": "Otkaži",
        "botpasswords-label-delete": "Obriši",
        "resetpass_forbidden": "Lozinka ne može biti promenjena",
        "resetpass-submit-cancel": "Otkaži",
        "resetpass-wrong-oldpass": "Neispravna privremena ili tekuća lozinka.\nMožda ste već promenili lozinku ili ste zatražili novu privremenu lozinku.",
        "resetpass-recycled": "Uneli ste sadašnju lozinku, da biste resetovali lozinku morate uneti novu.",
-       "resetpass-temp-emailed": "Prijavili ste se sa privremenim kodom iz e-pošte.\nDa biste završili prijavljivanje morate postaviti novu lozinku ovde:",
+       "resetpass-temp-emailed": "Prijavili ste se sa privremenim kodom iz imejla.\nDa biste završili prijavljivanje morate postaviti novu lozinku ovde:",
        "resetpass-temp-password": "Privremena lozinka:",
        "resetpass-abort-generic": "Promenu lozinke je sprečio dodatak.",
        "resetpass-expired": "Vaša lozinka je istekla. Postavite novu lozinku da biste se prijavili.",
        "resetpass-expired-soft": "Vaša lozinka je istekla i morate postaviti novu. Postavite novu lozinku ili kliknite „{{int:authprovider-resetpass-skip-label}}“ da je postavite kasnije.",
        "resetpass-validity-soft": "Vaša lozinka nije valjana: $1\n\nMolimo izaberite novu ili kliknite „{{int:authprovider-resetpass-skip-label}}“ da resetujete kasnije.",
        "passwordreset": "Obnavljanje lozinke",
-       "passwordreset-text-one": "Popunite ovaj obrazac da biste dobili privremenu lozinku na e-poštu.",
-       "passwordreset-text-many": "{{PLURAL:$1|Ispunite jedno od polja kako biste dobili privremenu lozinku na e-poštu.}}",
+       "passwordreset-text-one": "Popunite ovaj obrazac da biste dobili privremenu lozinku na imejl.",
+       "passwordreset-text-many": "{{PLURAL:$1|Ispunite jedno od polja kako biste dobili privremenu lozinku na imejl.}}",
        "passwordreset-disabled": "Obnavljanje lozinke je onemogućeno na ovom vikiju.",
-       "passwordreset-emaildisabled": "E-pošta je onemogućena na ovom vikiju.",
+       "passwordreset-emaildisabled": "Imejl je onemogućen na ovom vikiju.",
        "passwordreset-username": "Korisničko ime:",
        "passwordreset-domain": "Domen:",
-       "passwordreset-capture": "Pogledati krajnju poruku?",
-       "passwordreset-capture-help": "Ako označite ovu kućicu, e-poruka s privremenom lozinkom će biti prikazana i poslata korisniku.",
-       "passwordreset-email": "E-adresa:",
+       "passwordreset-capture": "Pogledati krajnji imejl?",
+       "passwordreset-capture-help": "Ako označite ovo polje, imejl (s privremenom lozinkom) će biti prikazana i poslata korisniku.",
+       "passwordreset-email": "Imejl adresa:",
        "passwordreset-emailtitle": "Detalji naloga na vikiju {{SITENAME}}",
-       "passwordreset-emailtext-ip": "Neko, verovatno Vi, sa IP adrese $1 je zatražio novu lozinku na vikiju {{SITENAME}} ($4).\nSledeći {{PLURAL:$3|korisnički nalog je povezan|korisnički nalozi su povezani}} s ovom e-adresom:\n\n$2\n\n{{PLURAL:$3|Privremena lozinka ističe|Privremene lozinke ističu}} za {{PLURAL:$5|jedan dan|$5 dana}}.\nPrijavite se i izaberite novu lozinku. Ako je neko drugi zahtevao ovu radnju ili ste se setili lozinke i ne želite da je menjate, zanemarite ovu poruku i nastavite koristiti staru lozinku.",
-       "passwordreset-emailtext-user": "{{GENDER:$1|Korisnik je zatražio|Korisnica je zatražila}} podsetnik o podacima za prijavu na vikiju {{SITENAME}} ($4).\nSledeći {{PLURAL:$3|korisnički nalog je povezan|korisnički nalozi su povezani}} s ovom e-adresom:\n\n$2\n\n{{PLURAL:$3|Privremena lozinka ističe|Privremene lozinke ističu}} za {{PLURAL:$5|jedan dan|$5 dana}}.\nPrijavite se i izaberite novu lozinku. Ako je neko drugi zahtevao ovu radnju ili ste se setili lozinke i ne želite da je menjate, zanemarite ovu poruku.",
+       "passwordreset-emailtext-ip": "Neko (verovatno Vi, sa IP adrese $1) je zatražio novu lozinku na vikiju {{SITENAME}} ($4).\nSledeći {{PLURAL:$3|korisnički nalog je povezan|korisnički nalozi su povezani}} s ovom imejl adresom:\n\n$2\n\n{{PLURAL:$3|Privremena lozinka ističe|Privremene lozinke ističu}} za {{PLURAL:$5|jedan dan|$5 dana}}.\nPrijavite se i izaberite novu lozinku. Ako je neko drugi zahtevao ovu radnju ili ste se setili lozinke i ne želite da je menjate, zanemarite ovu poruku i nastavite koristiti staru lozinku.",
+       "passwordreset-emailtext-user": "{{GENDER:$1|Korisnik je zatražio|Korisnica je zatražila}} podsetnik o podacima za prijavu na vikiju {{SITENAME}} ($4).\nSledeći {{PLURAL:$3|korisnički nalog je povezan|korisnički nalozi su povezani}} s ovom imejl adresom:\n\n$2\n\n{{PLURAL:$3|Privremena lozinka ističe|Privremene lozinke ističu}} za {{PLURAL:$5|jedan dan|$5 dana}}.\nPrijavite se i izaberite novu lozinku. Ako je neko drugi zahtevao ovu radnju ili ste se setili lozinke i ne želite da je menjate, zanemarite ovu poruku.",
        "passwordreset-emailelement": "Korisničko ime: \n$1\n\nPrivremena lozinka: \n$2",
        "passwordreset-emailsentemail": "Podsetnik o lozinci je poslat na vašu adresu.",
        "passwordreset-emailsentusername": "Ako ste naveli imejl adresu prilikom registracije, biće poslat imejl za resetovanje lozinke.",
-       "changeemail": "Promeni ili ukloni e-adresu",
+       "changeemail": "Promeni ili ukloni imejl adresu",
        "changeemail-header": "Promenite e-adresu naloga",
        "changeemail-no-info": "Morate biti prijavljeni da biste pristupili ovoj stranici.",
-       "changeemail-oldemail": "Trenutna e-adresa:",
-       "changeemail-newemail": "Nova e-adresa:",
+       "changeemail-oldemail": "Trenutna imejl adresa:",
+       "changeemail-newemail": "Nova imejl adresa:",
        "changeemail-none": "(ništa)",
        "changeemail-password": "Vaša lozinka:",
-       "changeemail-submit": "Promeni",
+       "changeemail-submit": "Promeni imejl",
        "changeemail-throttled": "Previše puta ste pokušali da se prijavite.\nMolimo vas da sačekate $1 pre nego što pokušate ponovo.",
        "changeemail-nochange": "Unesite drugu imejl adresu.",
        "resettokens": "Resetovanje žetona",
        "summary-preview": "Pregled opisa:",
        "subject-preview": "Pregled tema:",
        "blockedtitle": "Korisnik je blokiran",
-       "blockedtext": "<strong>Vaše korisničko ime ili IP adresa je blokirana.</strong>\n\nBlokiranje je {{GENDER:$4|izvršio|izvršila}} $1.\nRazlog: <em>$2</em>.\n\n* Datum blokiranja: $8\n* Blokiranje ističe: $6\n* Ime korisnika: $7\n\nObratite se {{GENDER:$4|korisniku|korisnici}} $1 ili [[{{MediaWiki:Grouppage-sysop}}|administratoru]] da razjasnite stvar.\nNe možete koristiti mogućnost „Pošalji poruku ovom korisniku“ ako niste uneli ispravnu e-adresu u [[Special:Preferences|podešavanjima]].\nVaša blokirana IP adresa je $3, a ID blokiranja $5.\nNavedite sve podatke iznad pri stvaranju bilo kakvih upita.",
-       "autoblockedtext": "Vaša IP adresa je blokirana jer ju je upotrebljavao drugi korisnik, koga je {{GENDER:$4|blokirao|blokirala}} $1.\nRazlog:\n\n:<em>$2</em>\n\n* Datum blokiranja: $8\n* Blokiranje ističe: $6\n* Ime korisnika: $7\n\nObratite se {{GENDER:$4|korisniku|korisnici}} $1 ili [[{{MediaWiki:Grouppage-sysop}}|administratoru]] da razjasnite stvar.\n\nNe možete koristiti mogućnost „Pošalji poruku ovom korisniku“ ako niste uneli ispravnu e-adresu u [[Special:Preferences|podešavanjima]].\n\nVaša blokirana IP adresa je $3, a ID $5.\nNavedite sve podatke iznad pri stvaranju bilo kakvih upita.",
+       "blockedtext": "<strong>Vaše korisničko ime ili IP adresa je blokirana.</strong>\n\nBlokiranje je {{GENDER:$4|izvršio|izvršila}} $1.\nRazlog je <em>$2</em>.\n\n* Datum blokiranja: $8\n* Blokiranje ističe: $6\n* Ime korisnika: $7\n\nObratite se {{GENDER:$4|korisniku|korisnici}} $1 ili [[{{MediaWiki:Grouppage-sysop}}|administratoru]] da razjasnite stvar.\nNe možete koristiti mogućnost „Pošalji imejl ovom korisniku“ ako niste uneli ispravnu imejl adresu u [[Special:Preferences|podešavanjima]].\nVaša blokirana IP adresa je $3, a ID blokiranja $5.\nNavedite sve podatke iznad pri stvaranju bilo kakvih upita.",
+       "autoblockedtext": "Vaša IP adresa je blokirana jer ju je upotrebljavao drugi korisnik, koga je {{GENDER:$4|blokirao|blokirala}} $1.\nRazlog:\n\n:<em>$2</em>\n\n* Datum blokiranja: $8\n* Blokiranje ističe: $6\n* Ime korisnika: $7\n\nObratite se {{GENDER:$4|korisniku|korisnici}} $1 ili [[{{MediaWiki:Grouppage-sysop}}|administratoru]] da razjasnite stvar.\n\nNe možete koristiti mogućnost „Pošalji imejl ovom korisniku“ ako niste uneli ispravnu imejl adresu u [[Special:Preferences|podešavanjima]].\n\nVaša blokirana IP adresa je $3, a ID $5.\nNavedite sve podatke iznad pri stvaranju bilo kakvih upita.",
        "blockednoreason": "razlog nije naveden",
        "whitelistedittext": "Za uređivanje stranice je potrebno da budete $1.",
-       "confirmedittext": "Morate da potvrdite svoju e-adresu pre uređivanja stranica.\nPostavite i potvrdite adresu preko [[Special:Preferences|podešavanja]].",
+       "confirmedittext": "Morate da potvrdite svoju imejl adresu pre uređivanja stranica.\nPostavite i potvrdite imejl adresu preko [[Special:Preferences|podešavanja]].",
        "nosuchsectiontitle": "Ne mogu da pronađem odeljak",
        "nosuchsectiontext": "Pokušali ste da uredite odeljak koji ne postoji.\nMožda je premešten ili obrisan dok ste pregledali stranicu.",
        "loginreqtitle": "Potrebna je prijava",
        "revdelete-show-no-access": "Greška pri prikazivanju stavke od $1, $2: označena je kao „ograničena“.\nNemate pristup do nje.",
        "revdelete-modify-no-access": "Greška pri menjanju stavke od $1, $2: označena je kao „ograničena“.\nNemate pristup do nje.",
        "revdelete-modify-missing": "Greška pri menjanju IB stavke $1: ona ne postoji u bazi podataka.",
-       "revdelete-no-change": "'''Upozorenje:''' stavka od $1, $2 već poseduje zatražene postavke vidljivosti.",
+       "revdelete-no-change": "<strong>Upozorenje:</strong> stavka od $1, $2 već poseduje zatražena podešavanja vidljivosti.",
        "revdelete-concurrent-change": "Greška pri menjanju stavke od $1, $2: njeno stanje je u međuvremenu promenjeno od strane drugog korisnika.\nPogledajte istoriju.",
        "revdelete-only-restricted": "Greška pri sakrivanju stavke od $1, $2: ne možete sakriti stavke od administratora bez izbora drugih mogućnosti vidljivosti.",
        "revdelete-reason-dropdown": "*Uobičajeni razlozi za brisanje\n** Kršenje autorskog prava\n** Neprikladan komentar ili lični podaci\n** Neprikladno korisničko ime\n** Uvredljivi podaci",
        "searchprofile-advanced-tooltip": "Pretražite prilagođene imenske prostore",
        "search-result-size": "$1 ({{PLURAL:$2|1 reč|$2 reči|$2 reči}})",
        "search-result-category-size": "{{PLURAL:$1|1 član|$1 člana|$1 članova}}, ({{PLURAL:$2|1 potkategorija|$2 potkategorije|$2 potkategorija}}, {{PLURAL:$3|1 datoteka|$3 datoteke|$3 datoteka}})",
-       "search-redirect": "(preusmerenje $1)",
+       "search-redirect": "(preusmereno sa $1)",
        "search-section": "(odeljak $1)",
        "search-category": "(kategorija $1)",
        "search-file-match": "(podudara se sadržaj datoteke)",
        "prefs-watchlist-token": "Žeton spiska nadgledanja:",
        "prefs-misc": "Druga podešavanja",
        "prefs-resetpass": "Promeni lozinku",
-       "prefs-changeemail": "Promeni ili ukloni e-adresu",
-       "prefs-setemail": "Postavi e-adresu",
-       "prefs-email": "Postavke e-pošte",
+       "prefs-changeemail": "Promeni ili ukloni imejl adresu",
+       "prefs-setemail": "Postavi imejl adresu",
+       "prefs-email": "Postavke imejla",
        "prefs-rendering": "Izgled",
        "saveprefs": "Sačuvaj",
        "restoreprefs": "Vrati sve na podrazumevano (u svim odeljcima)",
        "timezoneregion-europe": "Evropa",
        "timezoneregion-indian": "Indijski okean",
        "timezoneregion-pacific": "Tihi okean",
-       "allowemail": "Omogući primanje e-poruka od drugih korisnika",
+       "allowemail": "Omogući primanje imejla od drugih korisnika",
        "prefs-searchoptions": "Pretraga",
        "prefs-namespaces": "Imenski prostori",
        "default": "podrazumevano",
        "prefs-custom-js": "Prilagođeni javaskript",
        "prefs-common-css-js": "Deljeni CSS/javaskript za sve teme:",
        "prefs-reset-intro": "Možete koristiti ovu stranicu da poništite svoje postavke na podrazumevane vrednosti.\nOva radnja se ne može vratiti.",
-       "prefs-emailconfirm-label": "Potvrda e-adrese:",
-       "youremail": "E-adresa:",
+       "prefs-emailconfirm-label": "Potvrda imejla:",
+       "youremail": "Imejl:",
        "username": "{{GENDER:$1|Korisničko ime}}:",
        "prefs-memberingroups": "{{PLURAL:$1|Grupa|Grupe}}:",
        "prefs-memberingroups-type": "$1",
        "gender-male": "On uređuje viki stranice",
        "gender-female": "Ona uređuje viki stranice",
        "prefs-help-gender": "Neobavezno: koristi se za ispravno obraćanje softvera korisnicima, zavisno od njihovog pola.\nOvaj podatak će biti javan.",
-       "email": "E-adresa",
+       "email": "Imejl",
        "prefs-help-realname": "Pravo ime nije obavezno.\nAko izaberete da ga unesete, ono će biti korišćeno za pripisivanje vašeg rada.",
-       "prefs-help-email": "E-adresa nije obavezna, ali je potrebna u slučaju da zaboravite lozinku.",
+       "prefs-help-email": "Imejl adresa nije obavezna, ali je potrebna u slučaju da zaboravite lozinku.",
        "prefs-help-email-others": "Možete je koristiti i da omogućite drugima da vas kontaktiraju preko korisničke stranice ili stranice za razgovor, bez otkrivanja svog identiteta.",
-       "prefs-help-email-required": "Potrebna je e-adresa.",
+       "prefs-help-email-required": "Potrebna je imejl adresa.",
        "prefs-info": "Osnovni podaci",
        "prefs-i18n": "Internacionalizacija",
        "prefs-signature": "Potpis",
        "right-move-categorypages": "premeštanje kategorija",
        "right-movefile": "premeštanje datoteka",
        "right-suppressredirect": "premeštanje stranica bez ostavljanja preusmerenja",
-       "right-upload": "otpremanje datoteka",
+       "right-upload": "Otpremanje datoteka",
        "right-reupload": "zamenjivanje postojećih datoteka",
        "right-reupload-own": "zamenjivanje sopstvenih datoteka",
        "right-reupload-shared": "menjanje datoteka na deljenom skladištu multimedije",
-       "right-upload_by_url": "otpremanje datoteka sa veb adrese",
+       "right-upload_by_url": "Otpremanje datoteka sa veb-adrese",
        "right-purge": "čišćenje keš memorije stranice bez potvrde",
        "right-autoconfirmed": "bez ograničavanja stavki za IP adrese",
        "right-bot": "smatranje izmena kao automatski proces",
        "right-viewsuppressed": "pregledanje izmena skrivenih od svih korisnika",
        "right-suppressionlog": "pregledanje privatnih dnevnika",
        "right-block": "blokiranje daljih izmena drugih korisnika",
-       "right-blockemail": "onemogućavanje korisnicima da šalju e-poruke",
+       "right-blockemail": "Blokiraj korisniku slanje imejla",
        "right-hideuser": "blokiranje korisničkog imena i njegovo sakrivanje od javnosti",
        "right-ipblock-exempt": "zaobilaženje blokiranja IP adrese, automatska blokiranja i blokiranja opsega",
        "right-unblockself": "deblokiranje samog sebe",
        "right-editmyuserjs": "uređivanje sopstvenih JavaScript datoteka",
        "right-viewmywatchlist": "vidi sopstveni spisak nadgledanja",
        "right-editmywatchlist": "uređivanje sopstvenog spiska nadgledanja; neke preduzete radnje će svejedno dodati stranice na spisak i bez ovog prava",
-       "right-viewmyprivateinfo": "vidite svoje lične podatke (npr. adresu e-pošte, pravo ime)",
-       "right-editmyprivateinfo": "uređivanje sopstvenih ličnih podataka (npr. adresu e-pošte, pravo ime)",
+       "right-viewmyprivateinfo": "Vidite svoje lične podatke (npr. imejl adresu, pravo ime)",
+       "right-editmyprivateinfo": "Уređivanje sopstvenih ličnih podataka (npr. imejl adresa, pravo ime)",
        "right-editmyoptions": "uređivanje sopstvenih podešavanja",
        "right-rollback": "brzo vraćanje izmena poslednjeg korisnika koji je menjao određenu stranicu",
        "right-markbotedits": "označavanje vraćenih izmena kao izmene bota",
        "right-userrights-interwiki": "uređivanje korisničkih prava na drugim vikijima",
        "right-siteadmin": "zaključavanje i otključavanje baze podataka",
        "right-override-export-depth": "izvoz stranica uključujući i povazene stranice do dubine od pet veza",
-       "right-sendemail": "slanje e-poruka drugim korisnicima",
+       "right-sendemail": "Pošalji imejl drugim korisnicima",
        "right-passwordreset": "pregledanje poruka za obnavljanje lozinke",
        "right-managechangetags": "pravljenje i (de)aktiviranje [[Special:Tags|oznaka]]",
        "grant-group-page-interaction": "Uređivanje stranica",
        "grant-editpage": "Uređivanje postojećih stranica",
        "grant-editprotected": "Uređivanje zaštićenih stranica",
        "grant-uploadeditmovefile": "Otpremanje, zamena i premeštanje datoteka",
-       "grant-uploadfile": "Slanje novih datoteka",
+       "grant-uploadfile": "Otpremanje novih datoteka",
        "newuserlogpage": "Dnevnik novih korisnika",
        "newuserlogpagetext": "Ovo je dnevnik novih korisnika.",
        "rightslog": "Dnevnik korisničkih prava",
        "action-move-rootuserpages": "premeštanje osnovnih korisničkih stranica",
        "action-move-categorypages": "premeštanje kategorija",
        "action-movefile": "premeštanje ove datoteke",
-       "action-upload": "slanje ove datoteke",
+       "action-upload": "otpremi ovu datoteku",
        "action-reupload": "zamenjivanje postojeće datoteke",
        "action-reupload-shared": "postavljanje ove datoteke na zajedničko skladište",
-       "action-upload_by_url": "slanje ove datoteke preko URL adrese",
+       "action-upload_by_url": "otpremanje ove datoteke preko veb-adrese",
        "action-writeapi": "pisanje API-ja",
        "action-delete": "brisanje ove stranice",
        "action-deleterevision": "brisanje ove izmene",
        "action-userrights": "uređivanje svih korisničkih prava",
        "action-userrights-interwiki": "uređivanje korisničkih prava na drugim vikijima",
        "action-siteadmin": "zaključavanje ili otključavanje baze podataka",
-       "action-sendemail": "slanje e-poruka",
+       "action-sendemail": "slanje imejlova",
        "action-editmywatchlist": "izmenu sopstvenog spisak nadgledanja",
        "action-viewmywatchlist": "pregled vašeg spisak nadgledanja",
        "action-viewmyprivateinfo": "pregledanje vaših ličnih podataka",
        "recentchanges-page-removed-from-category": "[[:$1]] je uklonjena iz kategorije",
        "recentchanges-page-removed-from-category-bundled": "[[:$1]] i još [[Special:WhatLinksHere/$1|{{PLURAL:$2|jedna stranica|$2 stranice}}]] su uklonjene iz kategorije",
        "autochange-username": "Medijaviki automatska izmena",
-       "upload": "Pošalji datoteku",
-       "uploadbtn": "Pošalji datoteku",
+       "upload": "Otpremi datoteku",
+       "uploadbtn": "Otpremi datoteku",
        "reuploaddesc": "Nazad na obrazac za otpremanje",
        "upload-tryagain": "Pošalji izmenjeni opis datoteke",
        "uploadnologin": "Niste prijavljeni",
-       "uploadnologintext": "Morate biti $1 da biste otpremali datoteke.",
+       "uploadnologintext": "$1 da biste otpremali datoteke.",
        "upload_directory_missing": "Fascikla za slanje ($1) nedostaje i server je ne može napraviti.",
        "upload_directory_read_only": "Server ne može da piše po fascikli za slanje ($1).",
        "uploaderror": "Greška pri otpremanju",
        "uploadwarning-text": "Izmenite opis datoteke i pokušajte ponovo.",
        "savefile": "Sačuvaj datoteku",
        "uploaddisabled": "Otpremanje je onemogućeno.",
-       "copyuploaddisabled": "Slanje putem URL adrese je onemogućeno.",
+       "copyuploaddisabled": "Otpremanje putem veb-adrese je onemogućeno.",
        "uploaddisabledtext": "Otpremanje datoteka je onemogućeno.",
-       "php-uploaddisabledtext": "Slanje datoteka je onemogućeno u PHP-u.\nProverite postavke file_uploads.",
+       "php-uploaddisabledtext": "Otpremanje datoteka je onemogućeno u PHP-u.\nProverite podešavanja file_uploads.",
        "uploadscripted": "Datoteka sadrži HTML ili skriptni kod koji može biti pogrešno protumačen od strane pregledača.",
        "uploadscriptednamespace": "Ova SVG datoteka sadrži pogrešan imenski prostor „$1“",
        "uploadvirus": "Datoteka sadrži virus!\nDetalji: $1",
        "destfilename": "Naziv:",
        "upload-maxfilesize": "Maksimalna veličina datoteke: $1",
        "upload-description": "Opis datoteke",
-       "upload-options": "Postavke slanja",
+       "upload-options": "Postavke otpremanja",
        "watchthisupload": "Nadgledaj ovu datoteku",
        "filewasdeleted": "Datoteka s ovim nazivom je ranije poslata, ali je obrisana.\nProverite $1 pre nego što nastavite s ponovnim slanjem.",
        "filename-bad-prefix": "Naziv datoteke koju šaljete počinje sa <strong>„$1“</strong>, a njega obično dodeljuju digitalni fotoaparati.\nIzaberite naziv datoteke koji opisuje njen sadržaj.",
        "upload-dialog-button-cancel": "Otkaži",
        "upload-dialog-button-done": "Gotovo",
        "upload-dialog-button-save": "Sačuvaj",
-       "upload-dialog-button-upload": "Pošalji",
+       "upload-dialog-button-upload": "Otpremi",
        "upload-form-label-infoform-title": "Detalji",
        "upload-form-label-infoform-name": "Ime",
        "upload-form-label-infoform-description": "Opis",
        "invalid-chunk-offset": "Neispravna polazna tačka",
        "img-auth-accessdenied": "Pristup je odbijen",
        "img-auth-nopathinfo": "Nedostaje PATH_INFO.\nVaš server nije podešen da prosleđuje ovakve podatke.\nMožda je zasnovan na CGI-ju koji ne podržava img_auth.\nPogledajte https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization?uselang=sr-ec.",
-       "img-auth-notindir": "Zahtevana putanja nije u podešenoj fascikli za slanje.",
+       "img-auth-notindir": "Zahtevana putanja nije u podešenoj fascikli za otpremanje.",
        "img-auth-badtitle": "Ne mogu da stvorim ispravan naslov za „$1“.",
        "img-auth-nologinnWL": "Niste prijavljeni i „$1“ nije na spisku dozvoljenih.",
        "img-auth-nofile": "Datoteka „$1“ ne postoji.",
        "http-bad-status": "Došlo je do problema tokom zahteva HTTP: $1 $2",
        "upload-curl-error6": "Ne mogu da pristupim adresi",
        "upload-curl-error6-text": "Ne mogu da pristupim navedenoj adresi.\nProverite da li je adresa ispravna i dostupna.",
-       "upload-curl-error28": "Slanje je isteklo",
+       "upload-curl-error28": "Otpremanje je isteklo",
        "upload-curl-error28-text": "Server ne odgovara na upit.\nProverite da li sajt radi, malo osačekajte i pokušajte ponovo.\nProbajte kasnije kada bude manje opterećenje.",
        "license": "Licenca:",
        "license-header": "Licenca:",
        "sharedupload-desc-create": "Ova datoteka se nalazi na $1 i može da se koristi na drugim projektima.\nNjen opis možete da izmenite na [$2 odgovarajućoj stranici].",
        "filepage-nofile": "Ne postoji datoteka s ovim nazivom.",
        "filepage-nofile-link": "Ne postoji datoteka s ovim nazivom, ali je možete [$1 poslati].",
-       "uploadnewversion-linktext": "Pošalji novu verziju ove datoteke",
+       "uploadnewversion-linktext": "Otpremi novu verziju ove datoteke",
        "shared-repo-from": "iz $1",
        "shared-repo": "zajedničko skladište",
        "shared-repo-name-wikimediacommons": "Vikimedijina ostava",
        "nopagetext": "Tražena stranica ne postoji.",
        "pager-newer-n": "{{PLURAL:$1|noviji 1|novija $1|novijih $1}}",
        "pager-older-n": "{{PLURAL:$1|stariji 1|starijih $1}}",
-       "suppress": "Nadzor",
+       "suppress": "Revizija",
        "querypage-disabled": "Ova posebna stranica je onemogućena radi poboljšanja performansi.",
        "apihelp": "API pomoć",
        "apihelp-no-such-module": "Modul „$1“ nije pronađen.",
        "activeusers-intro": "Ovo je spisak korisnika koji su bili aktivni {{PLURAL:$1|1=prethodni dan|u poslednja $1 dana|u poslednjih $1 dana}}.",
        "activeusers-count": "$1 {{PLURAL:$1|radnja|radnje|radnji}} {{PLURAL:$3|prethodni dan|u poslednja $3 dana|u poslednjih $3 dana}}",
        "activeusers-from": "Prikaži korisnike počev od:",
-       "activeusers-hidebots": "Sakrij botove",
-       "activeusers-hidesysops": "Sakrij administratore",
        "activeusers-noresult": "Korisnik nije pronađen.",
        "activeusers-submit": "Prikaži aktivne korisnike",
        "listgrouprights": "Prava korisničkih grupa",
        "trackingcategories-nodesc": "Opis nije dostupan.",
        "trackingcategories-disabled": "Kategorija je onemogućena",
        "mailnologin": "Nema adrese za slanje",
-       "mailnologintext": "Morate biti [[Special:UserLogin|prijavljeni]] i imati ispravnu e-adresu u [[Special:Preferences|podešavanjima]] da biste slali e-poruke drugim korisnicima.",
-       "emailuser": "Pošalji e-poruku",
-       "emailuser-title-target": "Slanje e-poruke {{GENDER:$1|korisniku|korisnici|korisniku}}",
-       "emailuser-title-notarget": "Slanje e-poruke korisniku",
-       "emailpagetext": "Možete da koristite donji obrazac da pošaljete e-poruku {{GENDER:$1|ovom korisniku|ovoj korisnici}}.\nE-adresa koju ste uneli u vašim [[Special:Preferences|podešavanjima]] će se prikazati u polju „Od“, tako da će primalac moći da vam odgovori direktno.",
-       "defemailsubject": "{{SITENAME}} — E-pošta od {{GENDER:$1|korisnika|korisnice}} $1",
-       "usermaildisabled": "Korisnička e-pošta je onemogućena",
-       "usermaildisabledtext": "Ne možete da šaljete e-poruke drugim korisnicima na ovom vikiju",
-       "noemailtitle": "Nema e-adrese",
-       "noemailtext": "Ovaj korisnik nije naveo ispravnu e-adresu.",
-       "nowikiemailtext": "Ovaj korisnik je odlučio da ne prima e-poruke od drugih korisnika.",
+       "mailnologintext": "Morate biti [[Special:UserLogin|prijavljeni]] i imati ispravnu imejl adresu u [[Special:Preferences|podešavanjima]] da biste slali imejlove drugim korisnicima.",
+       "emailuser": "Pošalji imejl",
+       "emailuser-title-target": "Slanje imejla {{GENDER:$1|korisniku|korisnici}}",
+       "emailuser-title-notarget": "Slanje imejla korisniku",
+       "emailpagetext": "Možete da koristite donji obrazac da pošaljete imejl {{GENDER:$1|ovom korisniku|ovoj korisnici}}.\nImejl koji ste uneli u vašim [[Special:Preferences|podešavanjima]] će se prikazati u polju „Od“, tako da će primalac moći da vam odgovori direktno.",
+       "defemailsubject": "{{SITENAME}} — Imejl od {{GENDER:$1|korisnika|korisnice}} „$1”",
+       "usermaildisabled": "Korisnički imejl je onemogućen",
+       "usermaildisabledtext": "Ne možete da šaljete imejlove drugim korisnicima na ovom vikiju",
+       "noemailtitle": "Nema imejl adrese",
+       "noemailtext": "Ovaj korisnik nije naveo ispravnu imejl adresu.",
+       "nowikiemailtext": "Ovaj korisnik je odlučio da ne prima imejlove od drugih korisnika.",
        "emailnotarget": "Nepostojeće ili neispravno korisničko ime primaoca.",
        "emailtarget": "Unos korisničkog imena primaoca",
        "emailusername": "Korisničko ime:",
        "emailusernamesubmit": "Pošalji",
-       "email-legend": "Slanje e-poruka drugom korisniku",
+       "email-legend": "Pošalji imejl drugom korisniku",
        "emailfrom": "Od:",
        "emailto": "Za:",
        "emailsubject": "Naslov:",
        "emailmessage": "Poruka:",
        "emailsend": "Pošalji",
-       "emailccme": "Pošalji mi kopiju poruke na moju e-poštu.",
+       "emailccme": "Pošalji mi kopiju poruke na moj imejl.",
        "emailccsubject": "Kopija vaše poruke korisniku $1: $2",
-       "emailsent": "Poruka je poslata",
-       "emailsenttext": "Vaša e-poruka je poslata.",
-       "emailuserfooter": "Ovu e-poruku je {{GENDER:$1|poslao|poslala}} $1 {{GENDER:$2|korisniku|korisnici}} $2 pomoću „{{int:emailuser}}“ s vikija {{SITENAME}}.",
+       "emailsent": "Imejl je poslat",
+       "emailsenttext": "Vaša imejl poruka je poslata.",
+       "emailuserfooter": "Ovaj imejl je {{GENDER:$1|poslao|poslala}} $1 {{GENDER:$2|korisniku|korisnici}} $2 pomoću „{{int:emailuser}}“ s vikija {{SITENAME}}.",
        "usermessage-summary": "Slanje sistemske poruke.",
        "usermessage-editor": "Uređivač sistemskih poruka",
        "usermessage-template": "MediaWiki:UserMessage",
        "notanarticle": "Nije stranica sa sadržajem",
        "notvisiblerev": "Izmena je obrisana",
        "watchlist-details": "Imate {{PLURAL:$1|$1 stranica|$1 stranice|$1 stranica}} na vašem spisku nadgledanja, ne računajući stranice za razgovor.",
-       "wlheader-enotif": "Obaveštenje e-porukom je omogućeno.",
+       "wlheader-enotif": "Obaveštenje imejlom je omogućeno.",
        "wlheader-showupdated": "Stranice koje su izmenjene otkad ste ih poslednji put posetili su '''podebljane'''.",
        "wlnote": "Ispod {{PLURAL:$1|je poslednja izmena|su poslednje <strong>$1</strong> izmene|je poslednjih <strong>$1</strong> izmena}} u {{PLURAL:$2|prethodnom satu|prethodna <strong>$2</strong> sata|prethodnih <strong>$2</strong> sati}}, zaključno sa $3, $4.",
        "wlshowlast": "Prikaži poslednjih $1 sati, $2 dana",
        "enotif_subject_created": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|napravio je|napravila je}} $2",
        "enotif_subject_moved": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|premestio je|premestila je}} $2",
        "enotif_subject_restored": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|vratio je|vratila je}} $2",
-       "enotif_subject_changed": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|promenio je|promenila je}} $2",
+       "enotif_subject_changed": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|promenio|promenila}} je $2",
        "enotif_body_intro_deleted": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|obrisao|obrisala}} je $2 dana $PAGEEDITDATE Pogledajte $3.",
        "enotif_body_intro_created": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|napravio|napravila}} je $2 dana $PAGEEDITDATE Trenutna izmena nalazi se na $3.",
        "enotif_body_intro_moved": "Stranicu $1 na {{SITENAME}} {{GENDER:$2|premestio|premestila}} je $2 dana $PAGEEDITDATE Trenutna izmena nalazi se na  $3.",
        "enotif_lastvisited": "Pogledajte $1 za sve izmene od vaše poslednje posete.",
        "enotif_lastdiff": "Pogledajte $1 da vidite ovu izmenu.",
        "enotif_anon_editor": "anoniman korisnik $1",
-       "enotif_body": "Poštovani $WATCHINGUSERNAME,\n \t\n$PAGEINTRO $NEWPAGE\n\nOpis: $PAGESUMMARY $PAGEMINOREDIT\n\nKontakt:\ne-pošta: $PAGEEDITOR_EMAIL\nviki: $PAGEEDITOR_WIKI\n\nNeće biti drugih obaveštenja u slučaju daljih izmena ukoliko ne posetite ovu stranicu kada ste prijavljeni.\nMožete i da poništite postavke obaveštenja za sve stranice u vašem spisku nadgledanja.\n\nSrdačan pozdrav, {{SITENAME}}\n\n--\nDa biste promenili postavke u vezi sa e-obaveštenjima, posetite\n{{canonicalurl:{{#special:Preferences}}}}\n\nDa biste promenili postavke u vezi sa spiskom nadgledanja, posetite\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nDa biste uklonili ovu stranicu sa spiska nadgledanja, posetite\n$UNWATCHURL\n\nPodrška i dalja pomoć:\n$HELPPAGE",
+       "enotif_body": "Poštovani $WATCHINGUSERNAME,\n \t\n$PAGEINTRO $NEWPAGE\n\nOpis: $PAGESUMMARY $PAGEMINOREDIT\n\nKontakt:\nmejl: $PAGEEDITOR_EMAIL\nviki: $PAGEEDITOR_WIKI\n\nNeće biti drugih obaveštenja u slučaju daljih izmena ukoliko ne posetite ovu stranicu kada ste prijavljeni.\nMožete i da poništite postavke obaveštenja za sve stranice u vašem spisku nadgledanja.\n\nSrdačan pozdrav, {{SITENAME}}\n\n--\nDa biste promenili postavke imejl obaveštenja, posetite\n{{canonicalurl:{{#special:Preferences}}}}\n\nDa biste promenili postavke spiska nadgledanja, posetite\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nDa biste uklonili ovu stranicu sa spiska nadgledanja, posetite\n$UNWATCHURL\n\nPodrška i dalja pomoć:\n$HELPPAGE",
        "created": "napravljena",
        "changed": "izmenjena",
        "deletepage": "Obriši stranicu",
        "protectedarticle": "je zaštitio „[[$1]]“",
        "modifiedarticleprotection": "promenjen stepen zaštite za „[[$1]]“",
        "unprotectedarticle": "je skinuo zaštitu sa stranice „[[$1]]“",
-       "movedarticleprotection": "je premestio postavke zaštite sa „[[$2]]“ na „[[$1]]“",
+       "movedarticleprotection": "je premestio podešavanja zaštite sa „[[$2]]“ na „[[$1]]“",
        "protect-title": "Stepen zaštite za „$1“",
        "protect-title-notallowed": "Pregled stepena zaštite za „$1“",
        "prot_1movedto2": "je premestio [[$1]] na [[$2]]",
        "restriction-edit": "uređivanje",
        "restriction-move": "premeštanje",
        "restriction-create": "pravljenje",
-       "restriction-upload": "slanje",
+       "restriction-upload": "otpremanje",
        "restriction-level-sysop": "potpuno zaštićeno",
        "restriction-level-autoconfirmed": "poluzaštićeno",
        "restriction-level-all": "svi nivoi",
        "sp-contributions-newbies-sub": "Za nove korisnike",
        "sp-contributions-newbies-title": "Doprinosi novih korisnika",
        "sp-contributions-blocklog": "dnevnik blokiranja",
-       "sp-contributions-deleted": "obrisani doprinosi",
+       "sp-contributions-deleted": "obrisani {{GENDER:$1|doprinosi}}",
        "sp-contributions-uploads": "otpremanja",
        "sp-contributions-logs": "dnevnici",
        "sp-contributions-talk": "razgovor",
        "ipbreason-dropdown": "*Najčešći razlozi za blokiranje\n** Unošenje lažnih informacija\n** Uklanjanje sadržaja sa stranica\n** Postavljanje veza do spoljašnjih sajtova\n** Unošenje besmislica u stranice\n** Nepristojno ponašanje\n** Upotreba više naloga\n** Neprihvatljivo korisničko ime",
        "ipb-hardblock": "Onemogući prijavljenim korisnicima da uređuju s ove IP adrese",
        "ipbcreateaccount": "Onemogući otvaranje naloga",
-       "ipbemailban": "Onemogući korisniku da šalje e-poruke",
+       "ipbemailban": "Spreči korisnika da šalje imejlove",
        "ipbenableautoblock": "Automatski blokiraj poslednju IP adresu ovog korisnika i sve daljnje adrese s kojih pokuša da uređuje",
        "ipbsubmit": "Blokiraj ovog korisnika",
        "ipbother": "Drugo vreme:",
        "anononlyblock": "samo anonimni",
        "noautoblockblock": "automatsko blokiranje je onemogućeno",
        "createaccountblock": "otvaranje naloga je onemogućeno",
-       "emailblock": "e-pošta je blokirana",
+       "emailblock": "imejl je onemogućen",
        "blocklist-nousertalk": "zabranjeno uređivanje sopstvene stranice za razgovor",
        "ipblocklist-empty": "Spisak blokiranja je prazan.",
        "ipblocklist-no-results": "Tražena IP adresa ili korisničko ime nije blokirano.",
        "unblocklink": "deblokiraj",
        "change-blocklink": "promeni blokiranje",
        "contribslink": "doprinosi",
-       "emaillink": "pošalji e-poruku",
+       "emaillink": "pošalji imejl",
        "autoblocker": "Automatski ste blokirani jer delite IP adresu s korisnikom/com [[User:$1|$1]].\nRazlog blokiranja: „$2“",
        "blocklogpage": "Dnevnik blokiranja",
        "blocklog-showlog": "{{GENDER:$1|Ovaj korisnik je ranije blokiran|Ova korisnica je ranije blokirana|Ovaj korisnik je ranije blokiran}}.\nIstorija blokiranja se nalazi ispod:",
        "block-log-flags-anononly": "samo anonimni korisnici",
        "block-log-flags-nocreate": "onemogućeno otvaranje naloga",
        "block-log-flags-noautoblock": "automatsko blokiranje je onemogućeno",
-       "block-log-flags-noemail": "e-pošta je blokirana",
+       "block-log-flags-noemail": "imejl je onemogućen",
        "block-log-flags-nousertalk": "zabranjeno uređivanje sopstvene stranice za razgovor",
        "block-log-flags-angry-autoblock": "prošireno automatsko blokiranje je omogućeno",
        "block-log-flags-hiddenname": "korisničko ime je sakriveno",
        "tooltip-search": "Pretraga",
        "tooltip-search-go": "Idite na stranicu s ovim imenom, ako postoji",
        "tooltip-search-fulltext": "Pretražite stranice s ovim tekstom",
-       "tooltip-p-logo": "Posetite naslovnu stranu",
-       "tooltip-n-mainpage": "Posetite naslovnu stranu",
-       "tooltip-n-mainpage-description": "Posetite naslovnu stranu",
+       "tooltip-p-logo": "Posetite glavnu stranu",
+       "tooltip-n-mainpage": "Posetite glavnu stranu",
+       "tooltip-n-mainpage-description": "Posetite glavnu stranu",
        "tooltip-n-portal": "O projektu, šta možete da radite i gde da pronađete stvari",
        "tooltip-n-currentevents": "Saznajte više o tekućim događajima",
        "tooltip-n-recentchanges": "Spisak skorašnjih izmena na vikiju",
        "tooltip-t-contributions": "Spisak doprinosa {{GENDER:$1|ovog korisnika|ove korisnice}}",
        "tooltip-t-emailuser": "Pošaljite imejl {{GENDER:$1|ovom korisniku|ovoj korisnici}}",
        "tooltip-t-info": "Više informacija o ovoj stranici",
-       "tooltip-t-upload": "Pošaljite datoteke",
+       "tooltip-t-upload": "Otpremi datoteke",
        "tooltip-t-specialpages": "Spisak svih posebnih stranica",
        "tooltip-t-print": "Verzija ove stranice za štampanje",
        "tooltip-t-permalink": "Stalna veza ka ovoj izmeni stranice",
        "lastmodifiedatby": "Ovu stranicu je poslednji put {{GENDER:$4|izmenio|izmenila|izmenio}} $3, $1 u $2.",
        "othercontribs": "Zasnovano na radu korisnika $1.",
        "others": "drugi",
-       "siteusers": "{{PLURAL:$2|korisnik|korisnici}} na projektu {{SITENAME}} $1",
+       "siteusers": "{{PLURAL:$2|1={{GENDER:$1|korisnik|korisnica}}|korisnici}} na projektu {{SITENAME}} $1",
        "anonusers": "{{PLURAL:$2|anoniman korisnik|anonimni korisnici}} na projektu {{SITENAME}} $1",
        "creditspage": "Autori stranice",
        "nocredits": "Ne postoje podaci o autoru ove stranice.",
        "pageinfo-robot-index": "Dozvoljeno",
        "pageinfo-robot-noindex": "Nije dozvoljeno",
        "pageinfo-watchers": "Broj nadgledača stranicе",
+       "pageinfo-visiting-watchers": "Broj nadgledača stranice koji su posjetili skorašnje izmjene",
        "pageinfo-few-watchers": "Manje od $1 {{PLURAL:$1|pratioca|pratilaca}}",
        "pageinfo-redirects-name": "Broj preusmerenja na ovu stranicu",
        "pageinfo-subpages-name": "Podstranice ove stranice",
        "exif-urgency-other": "Prilagođeni prioritet ($1)",
        "namespacesall": "svi",
        "monthsall": "sve",
-       "confirmemail": "Potvrda e-adrese",
-       "confirmemail_noemail": "Niste uneli ispravnu e-adresu u [[Special:Preferences|podešavanjima]].",
-       "confirmemail_text": "{{SITENAME}} zahteva da potvrdite e-adresu pre nego što počnete da koristite mogućnosti e-pošte.\nKliknite na dugme ispod za slanje poruke na vašu e-adresu.\nU poruci će se nalaziti veza s potvrdnim kodom;\nunesite je u pregledač da biste potvrdili da je vaša e-adresa ispravna.",
+       "confirmemail": "Potvrda imejl adrese",
+       "confirmemail_noemail": "Niste uneli ispravnu imejl adresu u [[Special:Preferences|podešavanjima]].",
+       "confirmemail_text": "{{SITENAME}} zahteva da potvrdite imejl adresu pre nego što počnete da koristite mogućnosti imejla.\nKliknite na dugme ispod za slanje poruke na vašu adresu.\nU poruci će se nalaziti veza s potvrdnim kodom;\nunesite je u pregledač da biste potvrdili da je vaša imejl adresa ispravna.",
        "confirmemail_pending": "Potvrdni kod vam je već poslat. Ako ste upravo otvorili nalog, onda verovatno treba da sačekate nekoliko minuta da pristigne, pre nego što ponovo zatražite novi kod.",
        "confirmemail_send": "Pošalji potvrdni kod",
        "confirmemail_sent": "Potvrdna poruka je poslata.",
-       "confirmemail_oncreate": "Poslat je potvrdni kod na vašu e-adresu.\nOvaj kod nije potreban za prijavljivanje, ali vam treba da biste uključili mogućnosti e-pošte na vikiju.",
-       "confirmemail_sendfailed": "{{SITENAME}} ne može da pošalje poruku.\nProverite da li je e-adresa pravilno napisana.\n\nGreška: $1",
+       "confirmemail_oncreate": "Poslat je potvrdni kod na vašu imejl adresu.\nOvaj kod nije potreban za prijavljivanje, ali vam treba da biste uključili mogućnosti imejla na vikiju.",
+       "confirmemail_sendfailed": "{{SITENAME}} ne može da pošalje imejl potvrdu.\nProverite da li je imejl adresa pravilno napisana.\n\nGreška: $1",
        "confirmemail_invalid": "Potvrdni kod je neispravan. Verovatno je istekao.",
-       "confirmemail_needlogin": "Morate biti $1 da biste potvrdili e-adresu.",
-       "confirmemail_success": "Vaša e-adresa je potvrđena.\nSada možete da se [[Special:UserLogin|prijavite]]. Želimo vam prijatan boravak na vikiju.",
-       "confirmemail_loggedin": "Vaša e-adresa je sada potvrđena.",
-       "confirmemail_subject": "{{SITENAME}} – potvrda e-adrese",
-       "confirmemail_body": "Neko, verovatno vi, sa IP adrese $1 je otvorio nalog „$2“ na vikiju {{SITENAME}}, navodeći ovu e-adresu.\n\nDa potvrdite da ovaj nalog stvarno pripada vama, kao i da\nomogućite mogućnosti e-pošte, otvorite ovu vezu u pregledaču:\n\n$3\n\nUkoliko niste otvorili nalog, pratite vezu\nispod kako biste prekinuli postupak upisa:\n\n$5\n\nOvaj potvrdni kod ističe $6 u $5.",
-       "confirmemail_body_changed": "Neko, verovatno vi, sa IP adrese $1 je promenio e-adresu naloga „$2“ u ovu adresu na vikiju {{SITENAME}}.\n\nDa biste potvrdili da ovaj nalog stvarno pripada vama i ponovo aktivirali mogućnosti e-pošte, otvorite sledeću vezu u pregledaču:\n\n$3\n\nAko nalog *ne* pripada vama, pratite sledeću vezu da otkažete potvrdu e-adrese:\n\n$5\n\nOvaj potvrdni kod ističe $6 u $7",
-       "confirmemail_body_set": "Neko, verovatno vi, sa IP adrese $1 je promenio e-adresu naloga „$2“ u ovu adresu na {{SITENAME}}.\n\nDa bismo potvrdili da ovaj nalog stvarno pripada vama i ponovo aktivirali mogućnosti e-pošte na {{SITENAME}}, otvorite sledeću vezu u pregledaču:\n\n$3\n\nAko nalog *ne* pripada vama, pratite sledeću vezu da otkažete potvrdu e-adrese:\n\n$5\n\nOvaj potvrdni kod ističe $4.",
-       "confirmemail_invalidated": "Potvrda e-pošte je otkazana",
-       "invalidateemail": "Otkazivanje potvrde e-pošte",
+       "confirmemail_needlogin": "Morate biti $1 da biste potvrdili imejl adresu.",
+       "confirmemail_success": "Vaša imejl adresa je potvrđena.\nSada možete da se [[Special:UserLogin|prijavite]] i uživate u vikiju.",
+       "confirmemail_loggedin": "Vaša imejl adresa je sada potvrđena.",
+       "confirmemail_subject": "{{SITENAME}} – potvrda imejl adrese",
+       "confirmemail_body": "Neko, verovatno vi, sa IP adrese $1,\notvorio je nalog „$2“ sa ovom imejl adresom na vikiju {{SITENAME}}.\n\nDa potvrdite da ovaj nalog stvarno pripada vama i da aktivirate\nmogućnosti imejla na vikiju {{SITENAME}}, otvorite ovu vezu u pregledaču:\n\n$3\n\nUkoliko nalog *ne* pripada vama, pratite vezu\nda otkažete potvrdu imejl adrese:\n\n$5\n\nOvaj potvrdni kod ističe u $4.",
+       "confirmemail_body_changed": "Neko, verovatno vi, sa IP adrese $1,\npromenio je imejl adresu naloga „$2“ u ovu adresu na vikiju {{SITENAME}}.\n\nDa biste potvrdili da ovaj nalog stvarno pripada vama i ponovo aktivirali mogućnosti imejla, otvorite sledeću vezu u pregledaču:\n\n$3\n\nAko nalog *ne* pripada vama, pratite sledeću vezu da otkažete potvrdu imejl adrese:\n\n$5\n\nOvaj potvrdni kod ističe $6 u $7",
+       "confirmemail_body_set": "Neko, verovatno vi, sa IP adrese $1,\npromenio je imejl adresu naloga „$2“ u ovu adresu na {{SITENAME}}.\n\nDa bismo potvrdili da ovaj nalog stvarno pripada vama i ponovo aktivirali\nmogućnosti imejla na {{SITENAME}}, otvorite sledeću vezu u pregledaču:\n\n$3\n\nAko nalog *ne* pripada vama, pratite sledeću vezu da otkažete potvrdu imejl adrese:\n\n$5\n\nOvaj potvrdni kod ističe $4.",
+       "confirmemail_invalidated": "Potvrda imejl adrese je otkazana",
+       "invalidateemail": "Otkazivanje potvrde imejla",
        "scarytranscludedisabled": "[Međuviki uključivanje šablona je onemogućeno]",
        "scarytranscludefailed": "[Dobavljanje šablona za $1 nije uspelo]",
        "scarytranscludefailed-httpstatus": "[Ne mogu da preuzmem šablon $1: HTTP $2]",
        "logentry-newusers-newusers": "$1 je {{GENDER:$2|otvorio|otvorila}} korisnički nalog",
        "logentry-newusers-create": "$1 je {{GENDER:$2|otvorio|otvorila}} korisnički nalog",
        "logentry-newusers-create2": "$1 je {{GENDER:$2|otvorio|otvorila}} korisnički nalog $3",
-       "logentry-newusers-byemail": "$1 je {{GENDER:$2|otvorio|otvorila}} korisnički nalog $3 i lozinka je poslata na e-poštu",
+       "logentry-newusers-byemail": "$1 je {{GENDER:$2|otvorio|otvorila}} korisnički nalog $3 i lozinka je poslata na imejl",
        "logentry-newusers-autocreate": "Korisnički nalog $1 je automatski {{GENDER:$2|otvoren}}",
        "logentry-protect-move_prot": "$1 je {{GENDER:$2|premestio|premestila}} postavke zaštite sa $4 na $3",
        "logentry-protect-unprotect": "$1 je {{GENDER:$2|skinuo|skinula}} zaštitu sa stranice $3",
        "feedback-cancel": "Otkaži",
        "feedback-close": "Urađeno",
        "feedback-external-bug-report-button": "Prijavi bag",
-       "feedback-error-title": "Greška",
        "feedback-error1": "Greška: neprepoznat rezultat od API-ja",
        "feedback-error2": "Greška: uređivanje nije uspelo",
        "feedback-error3": "Greška: nema odgovora od API-ja",
        "mediastatistics-header-total": "Sve datoteke",
        "json-error-syntax": "Greška u sintaksi",
        "headline-anchor-title": "Veza do ovog odeljka",
-       "special-characters-group-latin": "latinica",
+       "special-characters-group-latin": "Latinica",
        "special-characters-group-latinextended": "proširena latinica",
        "special-characters-group-ipa": "IPA",
        "special-characters-group-symbols": "Simboli",
        "mw-widgets-dateinput-placeholder-month": "GGGG-MM",
        "mw-widgets-titleinput-description-new-page": "stranica još uvek ne postoji",
        "mw-widgets-titleinput-description-redirect": "preusmerava na $1",
-       "randomrootpage": "Slučajna korenska stranica"
+       "randomrootpage": "Slučajna korenska stranica",
+       "log-action-filter-upload-upload": "Novo otpremanje",
+       "authmanager-email-label": "Imejl",
+       "authmanager-email-help": "Imejl adresa",
+       "changecredentials": "Promjena akreditiva"
 }
index 499ddeb..6b3bcec 100644 (file)
        "yourname": "Kebroikiman nen:",
        "yourpassword": "Psa wortu:",
        "yourpasswordagain": "Psa wortu ete wan leysi:",
-       "remembermypassword": "Tan memre mi kebroikiman nen nanga psa wortu (for a maximum of $1 {{PLURAL:$1|day|days}})",
        "yourdomainname": "Yu domein:",
        "login": "Psa kon",
        "nav-login-createaccount": "Psa kon / meki wan account",
        "template-semiprotected": "(sroto wan pisi)",
        "nocreatetext": "{{SITENAME}} puru den primisi fu meki nyun papira.\nYu kan go baka fu kenki papira di de kba, noso yu kan [[Special:UserLogin|psa kon noso meki wan account]].",
        "recreate-moveddeleted-warn": "'''Warskow: yu e meki wan papira, di ben puru fu dyaso kaba, baka.'''\n\nDenki fosi efu na wan bun sani fu meki a papira disi baka. A log buku fu puru sori dyaso gi yepi:",
-       "cantcreateaccounttitle": "Kan masyin ni skopu.",
        "viewpagelogs": "Luku a log buku fu a papira disi",
        "currentrev": "A versi disi",
        "revisionasof": "Versi tapu $1",
index 3853940..68b29f0 100644 (file)
        "yourname": "Benutsernoome:",
        "yourpassword": "Paaswoud:",
        "yourpasswordagain": "Paaswoud wierhoalje:",
-       "remembermypassword": "Ap dissen Computer duurhaft ounmälded blieuwe (Maximoal foar $1 {{PLURAL:$1|Dai|Deege}})",
        "yourdomainname": "Dien Domain:",
        "externaldberror": "Äntweeder deer lait n Failer bie ju externe Authentifizierenge foar, of du duurst din extern Benutzerkonto nit aktualisierje.",
        "login": "Anmäldje",
        "undo-failure": "Ju Annerenge kuud nit tourääch annerd wäide, deer ju betroffene Oudeelenge intwisken ferannerd wuude.",
        "undo-norev": "Ju Beoarbaidenge kuud nit räägels troald wäide, deer ju nit foarhounden is of läsked wuude.",
        "undo-summary": "Annerenge $1 fon [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskussion]]) wuude tourääch annerd.",
-       "cantcreateaccounttitle": "Benutserkonto kon nit moaked wäide",
        "cantcreateaccount-text": "Dät Moakjen fon n Benutserkonto fon ju IP-Adresse '''$1''' uut wuude fon [[User:$3|$3]] speerd.\n\nGruund fon ju Speere: ''$2''",
        "viewpagelogs": "Logbouke foar disse Siede anwiese",
        "nohistory": "Dät rakt neen fröiere Versione fon dissen Artikkel.",
        "activeusers-intro": "Dit is ne Lieste fon Benutsere, do binne {{PLURAL:$1|dän lääste Dai|do lääste $1 Deege}} Aktivitäte apwiese.",
        "activeusers-count": "$1 {{PLURAL:$1|Beoarbaidenge|Beoarbaidengen}} in do {{PLURAL:$3|lääste 24 Uuren|fergeene $3 Deege}}",
        "activeusers-from": "Wies Benutsere ounfangend mäd:",
-       "activeusers-hidebots": "Bots fersteete",
-       "activeusers-hidesysops": "Administratore fersteete",
        "activeusers-noresult": "Neen Benutsere fuunen.",
        "listgrouprights": "Benutsergruppen-Gjuchte",
        "listgrouprights-summary": "Dit is ne Lieste fon do in dissen Wiki definierde Benutsergruppen un do deermäd ferbuundene Gjuchte.\nInformatione uurhäär uur eenpelde Gjuchte konnen [[{{MediaWiki:Listgrouprights-helppage}}|hier]] fuunen wäide.",
        "htmlform-submit": "Uurdreege",
        "htmlform-reset": "Annerengen touräächtraale",
        "htmlform-selectorother-other": "Uur",
-       "sqlite-has-fts": "Version $1 mäd Unnerstutsenge foar ju Fultäkstsäike",
-       "sqlite-no-fts": "Version $1 sunner Unnerstutsenge foaar ju Fultäkstsäike",
        "revdelete-restricted": "Einskränkengen jäilde uk foar Administratore",
        "revdelete-unrestricted": "Ienskränkengen foar Administratore wächhoald",
        "rightsnone": "(-)",
index ed76949..f191865 100644 (file)
        "yourpasswordagain": "Ketik deui sandi anjeun",
        "createacct-yourpasswordagain": "Konfirmasi kecap sandi",
        "createacct-yourpasswordagain-ph": "Asupkeun deui kecap sandi",
-       "remembermypassword": "Apalkeun login kuring dina ieu komputer (pikeun paling lila $1 {{PLURAL:$1|poé|poé}})",
        "userlogin-remembermypassword": "Jaga ngarah angger asup log",
        "userlogin-signwithsecure": "Paké sambungan aman",
        "yourdomainname": "Domain anjeun",
        "passwordreset-emailtext-user": "Pamaké $1 di {{SITENAME}} ménta nyetél ulang sandi anjeun di {{SITENAME}} ($4). {{PLURAL:$3|Akun}} di handap tumali jeung alamat surélék ieu:\n\n$2\n\n{{PLURAL:$3|Ieu sandi saheulaanan}} bakal kadaluwarsa dina témpo {{PLURAL:$5|sapoé|$5 poé}}.\nAnjeun kudu asup sarta milih sandi anyar ayeuna. Lamun henteu rumasa nyieun ieu pamundut atawa lamun geus inget sandi asli sarta moal ngarobah deui, ieu talatah teu kudu dipaliré.",
        "passwordreset-emailelement": "Sandiasma: \n$1\n\nSandi saheulaanan: \n$2",
        "passwordreset-emailsentemail": "Surélék pikeun nyetél ulang kecap sandi geus dikirim.",
-       "passwordreset-emailsent-capture": "Surélék pikeun nyetél ulang kecap sandi geus dikirim, sakumaha ditémbongkeun di handap.",
-       "passwordreset-emailerror-capture": "Surélék pikeun nyetél ulang kecap sandi geus dijieun, sakumaha ditémbongkeun di handap, tapi gagal ngirim ka {{GENDER:$2|pamaké}}: $1",
        "changeemail": "Ganti alamat surélék",
        "changeemail-header": "Ganti alamat surélék akun",
        "changeemail-no-info": "Anjeun kudu asup log pikeun bisa muka ieu kaca sacara langsung.",
        "undo-norev": "Éditan ieu henteu bisa bolaykeun alatan kaca henteu kapanggih atawa geus dihapus.",
        "undo-summary": "←Ngabolaykeun révisi $1 ku [[Special:Contributions/$2|$2]] ([[User talk:$2|Obrolan]])",
        "undo-summary-username-hidden": "Bolaykeun révisi $1 ku pamaké nyumput",
-       "cantcreateaccounttitle": "Rekening teu bisa dijieun",
        "cantcreateaccount-text": "Nyieun rekening ti ieu alamat IP ('''$1''') dipeungpeuk ku [[User:$3|$3]].\n\nAlesanana $3 cenah ''$2''.",
        "cantcreateaccount-range-text": "Nyieun akun ti alamat IP dina rentang <strong>$1</strong>, kaasup alamat IP anjeun (<strong>$4</strong>), dipeungpeuk ku [[User:$3|$3]].\n\nAlesan $3 nyaéta <em>$2</em>",
        "viewpagelogs": "Tempo log kaca ieu",
        "activeusers-intro": "Ieu béréndélan kontributor anu geus ngoprék $1 {{PLURAL:$1|poé|poé}} panungtung.",
        "activeusers-count": "$1 {{PLURAL:$1|édit|édit}}an salila {{PLURAL:$3|poé|$3 poé}} panungtung",
        "activeusers-from": "Témbongkeun kontributor dimimitian ku:",
-       "activeusers-hidebots": "Sumputkeun bot",
-       "activeusers-hidesysops": "Sumputkeun kuncén",
        "activeusers-noresult": "Teu kapendak.",
        "listgrouprights": "Hak-hak grup pamaké",
        "listgrouprights-summary": "Ieu mangrupa daptar jumplukan pamaké anu aya di wiki ieu, kalawan daptar hak aksés maranéhanana.\nÉmbaran leuwih luyu ngeunaan hak pamaké bisa ditingali di [[{{MediaWiki:Listgrouprights-helppage}}|dieu]].",
index 868012a..4f49d5c 100644 (file)
        "eauthentsent": "Ett e-postmeddelande för bekräftelse har skickats till den angivna e-postadressen.\nInnan någon annan e-post kan skickas till kontot, måste du följa instruktionerna i e-postmeddelandet för att bekräfta att kontot verkligen är ditt.",
        "throttled-mailpassword": "En lösenordsåterställning har redan skickats för mindre än {{PLURAL:$1|en timme|$1 timmar}} sedan.\nFör att förhindra missbruk skickas bara en lösenordsåterställning per {{PLURAL:$1|timme|$1-timmarsperiod}}.",
        "mailerror": "Fel vid skickande av e-post: $1",
-       "acct_creation_throttle_hit": "Besökare till den här wikin som har använt din IP-adress har skapat {{PLURAL:$1|ett användarkonto|$1 användarkonton}} under det senaste dygnet, vilket är det maximalt tillåtna inom den tidsperioden.\nSom ett resultat kan besökare som använder den här IP-adressen inte skapa några fler användarkonton just nu.",
+       "acct_creation_throttle_hit": "Besökare till den här wikin som har använt din IP-adress har skapat {{PLURAL:$1|ett användarkonto|$1 användarkonton}} under det senaste $2, vilket är det maximalt tillåtna inom den tidsperioden.\nSom ett resultat kan besökare som använder den här IP-adressen inte skapa några fler användarkonton just nu.",
        "emailauthenticated": "Din e-postadress bekräftades den $2 kl. $3.",
        "emailnotauthenticated": "Din e-postadress är ännu inte bekräftad. Ingen e-post kommer att skickas vad gäller det följande funktionerna.",
        "noemailprefs": "Uppge en e-postadress i dina inställningar för att få dessa funktioner att fungera.",
        "passwordreset-nocaller": "En användare måste anges",
        "passwordreset-nosuchcaller": "Användare finns inte: $1",
        "passwordreset-ignored": "Lösenordsåterställningen hanterades inte. Kanske ingen leverantör har konfigurerats?",
-       "passwordreset-invalideamil": "Ogiltig e-postadress",
+       "passwordreset-invalidemail": "Ogiltig e-postadress",
        "passwordreset-nodata": "Varken ett användarnamn eller en e-postadress angavs",
        "changeemail": "Ändra eller ta bort e-postadress",
        "changeemail-header": "Fyll i detta formulär för att ändra din e-postadress. Om du vill ta bort en associerad e-postadress från ditt konto lämnar du fältet för ny e-postadress tomt när formuläret skickas in.",
        "searchprofile-advanced-tooltip": "Sök i vissa namnrymder",
        "search-result-size": "$1 ({{PLURAL:$2|1 ord|$2 ord}})",
        "search-result-category-size": "{{PLURAL:$1|1 medlem|$1 medlemmar}} ({{PLURAL:$2|1 underkategori|$2 underkategorier}}, {{PLURAL:$3|1 fil|$3 filer}})",
-       "search-redirect": "(omdirigering $1)",
+       "search-redirect": "(omdirigering från $1)",
        "search-section": "(avsnitt $1)",
        "search-category": "(kategorin $1)",
        "search-file-match": "(överensstämmer filens innehåll)",
        "grant-basic": "Grundläggande rättigheter",
        "grant-viewdeleted": "Visa raderade filer och sidor",
        "grant-viewmywatchlist": "Visa din bevakningslista",
+       "grant-viewrestrictedlogs": "Visa begränsade loggposter",
        "newuserlogpage": "Logg över nya användare",
        "newuserlogpagetext": "Detta är en logg över nya användarkonton.",
        "rightslog": "Användarrättighetslogg",
        "upload-dialog-disabled": "Filuppladdningar med denna dialogruta har inaktiverats på denna wiki.",
        "upload-dialog-title": "Ladda upp fil",
        "upload-dialog-button-cancel": "Avbryt",
+       "upload-dialog-button-back": "Tillbaka",
        "upload-dialog-button-done": "Klar",
        "upload-dialog-button-save": "Spara",
        "upload-dialog-button-upload": "Ladda upp",
        "apisandbox-results-fixtoken-fail": "Misslyckades att hämta nyckeln \"$1\".",
        "apisandbox-alert-page": "Fälten på denna sida är inte giltiga.",
        "apisandbox-alert-field": "Värdet i detta fält är inte giltigt.",
+       "apisandbox-continue": "Fortsätt",
+       "apisandbox-continue-clear": "Rensa",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} kommer att [https://www.mediawiki.org/wiki/API:Query#Continuing_queries fortsätta] den sista begäran; {{int:apisandbox-continue-clear}} kommer att rensa fortsättningsrelaterade parametrar.",
        "booksources": "Bokkällor",
        "booksources-search-legend": "Sök efter bokkällor",
        "booksources-search": "Sök",
        "booksources-text": "Nedan följer en lista över länkar till webbplatser som säljer nya och begagnade böcker, och som kanske har ytterligare information om de böcker du söker.",
        "booksources-invalid-isbn": "Det angivna ISBN-numret verkar inte vara giltigt. Kontrollera källan för eventuella fel.",
+       "magiclink-tracking-rfc": "Sidor som använder magiska RFC-länkar",
+       "magiclink-tracking-rfc-desc": "Denna sida använder magiska RFC-länkar. Se [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] om hur man migrerar.",
+       "magiclink-tracking-pmid": "Sidor som använder magiska PMID-länkar",
+       "magiclink-tracking-pmid-desc": "Denna sida använder magiska PMID-länkar. Se [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] om hur man migrerar.",
+       "magiclink-tracking-isbn": "Sidor som använder magiska ISBN-länkar",
+       "magiclink-tracking-isbn-desc": "Denna sida använder magiska ISBN-länkar. Se [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] om hur man migrerar.",
        "specialloguserlabel": "Utförare:",
        "speciallogtitlelabel": "Mål (titel eller {{ns:user}}:användarnamn för användare):",
        "log": "Loggar",
        "activeusers-intro": "Detta är en lista på användare som har haft någon form av aktivitet inom de senaste $1 {{PLURAL:$1|dygnet|dygnen}}.",
        "activeusers-count": "$1 {{PLURAL:$1|handling|handlingar}} {{PLURAL:$3|det senaste dygnet|de senaste $3 dygnen}}",
        "activeusers-from": "Visa användare från och med:",
-       "activeusers-hidebots": "Dölj botar",
-       "activeusers-hidesysops": "Dölj administratörer",
+       "activeusers-groups": "Visa användare som tillhör grupper:",
        "activeusers-noresult": "Inga användare funna.",
        "activeusers-submit": "Visa aktiva användare",
        "listgrouprights": "Behörigheter för användargrupper",
        "modifiedarticleprotection": "ändrade skyddsnivån för \"[[$1]]\"",
        "unprotectedarticle": "tog bort skrivskydd från \"[[$1]]\"",
        "movedarticleprotection": "flyttade skrivskyddsinställningar från \"[[$2]]\" till \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|Skyddad}} \"[[$1]]\"",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Ändrade skyddsnivå}} för \"[[$1]]\"",
+       "unprotectedarticle-comment": "{{GENDER:$2|Tog bort skydd}} från \"[[$1]]\"",
        "protect-title": "Ändra skrivskyddsnivå för \"$1\"",
        "protect-title-notallowed": "Visa skyddsnivån för \"$1\"",
        "prot_1movedto2": "[[$1]] flyttades till [[$2]]",
        "movelogpagetext": "Listan nedan visar sidor som flyttats.",
        "movesubpage": "{{PLURAL:$1|Undersida|Undersidor}}",
        "movesubpagetext": "Denna sida har $1 {{PLURAL:$1|undersida|undersidor}} som visas nedan.",
+       "movesubpagetalktext": "Den motsvarande diskussionssidan har $1 {{PLURAL:$1|undersida|undersidor}} som visas nedan.",
        "movenosubpage": "Denna sida har inga undersidor.",
        "movereason": "Anledning:",
        "revertmove": "återställ",
        "pageinfo-category-pages": "Antal sidor",
        "pageinfo-category-subcats": "Antal underkategorier",
        "pageinfo-category-files": "Antal filer",
+       "pageinfo-user-id": "Användar-ID",
        "markaspatrolleddiff": "Märk som patrullerad",
        "markaspatrolledtext": "Märk den här sidan som patrullerad",
        "markaspatrolledtext-file": "Märk denna filversion som patrullerad",
        "patrol-log-header": "Detta är en logg över patrullerade sidversioner.",
        "log-show-hide-patrol": "$1 patrulleringslogg",
        "log-show-hide-tag": "$1 märkeslogg",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Markera sidversionen $3 av $2 som patrullerad?",
        "deletedrevision": "Raderade gammal sidversion $1",
        "filedeleteerror-short": "Fel vid radering av fil: $1",
        "filedeleteerror-long": "Fel inträffade vid raderingen av filen:\n\n$1",
        "newimages-showbots": "Visa uppladdningar av botar",
        "newimages-hidepatrolled": "Dölj patrullerade uppladdningar",
        "noimages": "Ingenting att se.",
+       "gallery-slideshow-toggle": "Växla miniatyrer",
        "ilsubmit": "Sök",
        "bydate": "efter datum",
        "sp-newimages-showfrom": "Visa nya filer från och med kl. $2 den $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 ändringsmärken på dina ändringar.",
-       "tags-apply-blocked": "Du kan inte ange ändringsmärken med dina ändringar medans du är blockerad.",
+       "tags-apply-blocked": "Du kan inte ange ändringsmärken med dina ändringar när 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 märken från individuella sidversioner eller loggposter.",
        "htmlform-cloner-create": "Lägg till mer",
        "htmlform-cloner-delete": "Ta bort",
        "htmlform-cloner-required": "Det krävs minst ett värde.",
+       "htmlform-date-placeholder": "ÅÅÅÅ-MM-DD",
+       "htmlform-time-placeholder": "TT:MM:SS",
+       "htmlform-datetime-placeholder": "ÅÅÅÅ-MM-DD TT:MM:SS",
+       "htmlform-date-invalid": "Värdet du angav är inte ett igenkänt datum. Prova att använda formatet ÅÅÅÅ-MM-DD.",
+       "htmlform-time-invalid": "Värdet du angav är inte en igenkänd tid. Prova att använda formatet HH:MM:SS.",
+       "htmlform-datetime-invalid": "Värdet du angav är inte ett igenkänt datum och tid. Prova att använda formatet ÅÅÅÅ-MM-DD HH:MM:SS.",
+       "htmlform-date-toolow": "Värdet du angav är innan det tidigaste tillåtna datumet för $1.",
+       "htmlform-date-toohigh": "Värdet du angav är efter det senaste tillåtna datumet $1.",
+       "htmlform-time-toolow": "Värdet du angav är innan den tidigaste tillåtna tiden för $1.",
+       "htmlform-time-toohigh": "Värdet du angav är efter den senaste tillåtna tiden $1.",
+       "htmlform-datetime-toolow": "Värdet du angav är innan det tidigaste tillåtna datumet och tiden för $1.",
+       "htmlform-datetime-toohigh": "Värdet du angav är efter det senaste tillåtna datumet och tiden $1.",
        "htmlform-title-badnamespace": "[[:$1]] är inte i \"{{ns:$2}}\"-namnrymden.",
        "htmlform-title-not-creatable": "\"$1\" är inte en sidtitel som kan skapas",
        "htmlform-title-not-exists": "$1 finns inte.",
        "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-error-title": "Fel",
        "feedback-error1": "Fel: Okänt resultat från API",
        "feedback-error2": "Fel: Redigeringen misslyckades",
        "feedback-error3": "Fel: Inget svar från API",
        "feedback-thanks": "Tack! Din feedback har skickats till sidan \"[$2 $1]\".",
        "feedback-thanks-title": "Tack!",
        "feedback-useragent": "Användaragent:",
-       "searchsuggest-search": "Sök",
+       "searchsuggest-search": "Sök på {{SITENAME}}",
        "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.",
        "authmanager-authn-autocreate-failed": "Kunde inte skapa ett lokalt konto automatiskt: $1",
        "authmanager-change-not-supported": "De angivna inloggningsuppgifterna kan inte ändras, då ingenting kan använda dem.",
        "authmanager-create-disabled": "Kontoregistrering är inaktiverat.",
-       "authmanager-create-from-login": "Fyll i fälten nedan för att skapa ditt konto.",
+       "authmanager-create-from-login": "Fyll i fälten för att skapa ditt konto.",
        "authmanager-create-not-in-progress": "Skapande av konto pågår inte eller så har sessionsdata förlorats. Var god börja om från början igen.",
        "authmanager-create-no-primary": "De angivna inloggningsuppgifterna kunde inte användas för att skapa ett konto.",
        "authmanager-link-no-primary": "De angivna inloggningsuppgifterna kunde inte användas för att länka ett konto.",
        "unlinkaccounts-success": "Kontot avlänkades.",
        "authenticationdatachange-ignored": "Ändringen av autentiseringsdata hanterades inte. Kanske ingen tillhandahållare har konfigurerats?",
        "userjsispublic": "Observera: JavaScript-undersidor bör inte innehålla konfidentiella uppgifter eftersom de kan ses av andra användare.",
-       "usercssispublic": "Observera: CSS-undersidor bör inte innehålla konfidentiella uppgifter eftersom de kan ses av andra användare."
+       "usercssispublic": "Observera: CSS-undersidor bör inte innehålla konfidentiella uppgifter eftersom de kan ses av andra användare.",
+       "restrictionsfield-badip": "Ogiltig IP-adress eller intervall: $1",
+       "restrictionsfield-label": "Tillåtna IP-intervall:",
+       "restrictionsfield-help": "En IP-adress eller CIDR-intervall per rad. För att aktivera allting, använd<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Fel: $1",
+       "edit-error-long": "Fel:\n\n$1"
 }
index 6ab227a..44b15e8 100644 (file)
@@ -17,7 +17,8 @@
                        "Rich Farmbrough",
                        "Kipala",
                        "Kwisha",
-                       "Macofe"
+                       "Macofe",
+                       "Muddyb"
                ]
        },
        "tog-underline": "Wekea mstari viungo:",
        "yourpasswordagain": "Andika tena neno la siri",
        "createacct-yourpasswordagain": "Thibitisha neno la siri",
        "createacct-yourpasswordagain-ph": "Weka neno la siri tena",
-       "remembermypassword": "Kumbuka kuingia kwangu katika kivinjari hiki (kwa muda usiozidi {{PLURAL:$1|siku}} $1)",
        "userlogin-remembermypassword": "Niweke kama nimeingia",
        "userlogin-signwithsecure": "Tumia muunganisho salama",
        "yourdomainname": "Tovuti yako:",
        "passwordreset-emailtext-user": "Mtumiaji $1 kwenye {{SITENAME}} ameomba neno la siri la akaunti yako liwekwe upya katika {{SITENAME}} ($4). {{PLURAL:$3|Akaunti inayofuata imeunganishwa|Akaunti zinazofuata zimeunganishwa}} na anwani ya barua pepe hii:\n\n$2\n\n{{PLURAL:$3|Neno la siri hili litakwisha|Maneno ya siri haya yatakwisha}} baada ya siku {{PLURAL:$5|one day|$5 siku}}.\nTafadhali ingia sasa na uchague neno jipya la siri. Kama mtu mwingine ameomba hili, au ikiwa umekumbuka neno lako la siri na hutaki kulibadilisha tena, basi usijali ujumbe huu, na uendelee kutumia neno la siri lako la zamani.",
        "passwordreset-emailelement": "Jina la mtumiaji: \n$1\n\nNeno la siri la muda: \n$2",
        "passwordreset-emailsentemail": "Barua pepe ya ukumbusho wa neno la siri imetumwa.",
-       "passwordreset-emailsent-capture": "Barua pepe ya ukukumbusho wa neno la siri imetumwa, ambayo inaonekana hapo chini.",
-       "passwordreset-emailerror-capture": "Barua pepe ya ukukumbusho wa neno la siri imetengenezwa, ambayo inaonekana hapo chini, lakini kuituma kwa mtumiaji {{GENDER:$2|user}} kumeshindikana: $1",
        "changeemail": "Badilisha anwani ya barua pepe",
        "changeemail-header": "Badilisha anwani ya barua pepe ya akaunti yako",
        "changeemail-no-info": "Lazima uwe umeingia ili kuweza kutumia kurasa hii moja kwa moja.",
        "undo-nochange": "Hariri inaonekana kuwa tayari imerudishwa tena.",
        "undo-summary": "Tengua pitio $1 lililoandikwa na [[Special:Contributions/$2|$2]] ([[User talk:$2|Majadiliano]])",
        "undo-summary-username-hidden": "Tednua toleo $1 na mtumiaji aliyejificha",
-       "cantcreateaccounttitle": "Kushindwa kusajili akaunti",
        "cantcreateaccount-text": "Kusajili akaunti kwa kutumia anwani ya IP hii ('''$1''') imezuiwa na [[User:$3|$3]].\n\nSababu iliyotolewa na $3 ni ''$2''",
        "viewpagelogs": "Tazama kumbukumbu kwa ukurasa huu",
        "nohistory": "Hakuna historia ya kuhariri kwa ajili ya ukurasa huu.",
        "activeusers-intro": "Hii ni orodha ya watumiaji walioshughulika jambo fulani ndani ya siku $1 {{PLURAL:$1|iliyopita|zilizopita}}.",
        "activeusers-count": "{{PLURAL:$1|haririo|maharirio}} $1 katika siku $3 {{PLURAL:$3|iliyopita|zilizopita}}",
        "activeusers-from": "Onyesha watumiaji kuanzia:",
-       "activeusers-hidebots": "Ficha boti",
-       "activeusers-hidesysops": "Ficha wakabidhi",
        "activeusers-noresult": "Watumiaji hawakupatikana.",
        "listgrouprights": "Wezo za kundi za watumiaji",
        "listgrouprights-summary": "Inafuata orodha ya kundi za watumiaji wa wiki hii, pamoja na maelezo ya wezo zao za kushughulika mambo.\nLabda patakuwa na [[{{MediaWiki:Listgrouprights-helppage}}|maelezo mengine]] kuhusu wezo zingine.",
        "feedback-back": "Rudi",
        "feedback-cancel": "Batilisha",
        "feedback-close": "Tayari",
-       "feedback-error-title": "Kosa",
        "feedback-error1": "Hitilafu: Hatokeo ya API hayafahamiki",
        "feedback-error2": "Hitilafu: Hariri haikufaulu",
        "feedback-error3": "Hitilafu: API ya wiki haitoi majibu",
index 3685734..70344cf 100644 (file)
        "yourpasswordagain": "Naszkryflej ausdruk zaś",
        "createacct-yourpasswordagain": "Potwjyrdź hasło",
        "createacct-yourpasswordagain-ph": "Wszkryflej hasło jeszcze roz",
-       "remembermypassword": "Pamjyntej můj ausdruk na tym kůmputrze (nojdalij bez $1 {{PLURAL:$1|dźyń|dńůw}})",
        "userlogin-remembermypassword": "Ńy wylogůwywuj mje",
        "userlogin-signwithsecure": "Użyj bezpjecznygo połůnczyńa",
        "yourdomainname": "Twoja domyna",
        "listusersfrom": "Pokaž užytkowńikůw začynojůnc uod:",
        "listusers-submit": "Uobejrzij",
        "listusers-noresult": "Ńy znejdźůno žodnygo užytkowńika.",
-       "activeusers-hidebots": "Schrůń boty",
-       "activeusers-hidesysops": "Schrůń adminy",
        "activeusers-noresult": "Niy szło znŏjść żŏdnych używŏczōw",
        "listgrouprights": "Uprawńyńo grup użytkowńikůw",
        "listgrouprights-summary": "Půńiży znojdowo śe spis grup użytkowńikůw zdefińjowanych na tyj wiki, s wyszczygůlńyńym przidźelůnych im prow dostympu.\nSprowdź zajta [[{{MediaWiki:Listgrouprights-helppage}}|s dodatkowymi informacjami]] uo uprowńyńach użytkowńikůw.",
        "logentry-upload-upload": "$1 {{GENDER:$2|posłoł|posłała}} $3",
        "rightsnone": "podstawowo",
        "revdelete-summary": "uopis pomjyńań",
-       "searchsuggest-search": "Sznupej",
+       "searchsuggest-search": "Sznupej we {{SITENAME}}",
        "expand_templates_ok": "OK"
 }
index c065fce..7fd903d 100644 (file)
        "botpasswords-label-resetpassword": "கடவுச்சொலை மீளமை",
        "botpasswords-label-grants": "பொருந்தும் மானியங்கள்:",
        "botpasswords-help-grants": "ஒவ்வொரு மானியம் ஏற்கனவே உள்ள பயனர் கணக்குக்கு வரையறுக்கப்பட்ட பயனர் உரிமைகள் அணுக கொடுக்கிறது. மேலதிக விபரங்ளுக்கு [[சிறப்பு:ListGrants|மானியங்களின் அட்டவணையை]] பார்க்க.",
-       "botpasswords-label-restrictions": "பயன்பாட்டு வரையறைகள்:",
        "botpasswords-label-grants-column": "வழங்கப்பட்டது",
        "botpasswords-bad-appid": "\"$1\" என்ற தானியங்கி பெயர் பயன்படாதது.",
        "botpasswords-insert-failed": "\"$1\" என்ற தானியங்கி பெயரை இணைக்க முடியவில்லை. ஏற்கனவே இருக்குமோ?",
        "activeusers-intro": "கடைசி $1 {{PLURAL:$1|நாள்|நாட்கள்}} ஏதேனும் செயலை செய்த பயனர்களின் பட்டியல் இது.",
        "activeusers-count": "$1 {{PLURAL:$1|திருத்தம்|திருத்தங்கள்}} கடைசி {{PLURAL:$3|நாள்|$3 நாட்கள்}}",
        "activeusers-from": "பின்வரும் எழுத்துடன் தொடங்கும் பயனர்களைக் காட்டு:",
-       "activeusers-hidebots": "தானியங்கிகளை மறை",
-       "activeusers-hidesysops": "நிர்வாகிகளை மறை",
        "activeusers-noresult": "எந்தவொரு பயனர்களும் காணப்படவில்லை.",
        "activeusers-submit": "தொடர் பங்களிப்பாளர்களை காட்டு",
        "listgrouprights": "பயனர் குழு உரிமைகள்",
        "feedback-close": "முடிந்தது",
        "feedback-external-bug-report-button": "ஒரு தொழில்நுட்ப பணியைச் சமர்ப்பி",
        "feedback-dialog-title": "பின்னூட்டத்தை சமர்ப்பி",
-       "feedback-error-title": "பிழை",
        "feedback-error1": "பிழை: API லிருந்து அங்கீகரிக்கப்படாத முடிவு.",
        "feedback-error2": "பிழை: திருத்தல்  தோல்வியடைந்தது",
        "feedback-error3": "பிழை: API லிருந்து பதிற்குறிப்பு எதுவும் இல்லை.",
index 315a732..9277032 100644 (file)
        "passwordreset-username": "ಸದಸ್ಯೆರ್ನ ಪುದರ್:",
        "passwordreset-domain": "ಕ್ಷೇತ್ರೊ:",
        "passwordreset-email": "ಇ-ಅಂಚೆ ವಿಳಾಸೊ",
-       "passwordreset-invalideamil": "ಇಮೇಲ್ ಸರಿ ಇಜ್ಜಿ",
+       "passwordreset-invalidemail": "ಇಮೇಲ್ ಸರಿ ಇಜ್ಜಿ",
        "changeemail-oldemail": "ಇತ್ತೆತಾ ಈಮೇಲ್ ವಿಳಾಸೊ:",
        "changeemail-newemail": "ಪೊಸ ಇ-ಅಂಚೆ ವಿಳಾಸೊ:",
        "changeemail-none": "ಒವ್ವುಲಾ ಇಜ್ಜಿ",
        "searchprofile-everything-tooltip": "ಮಾತ ಮಾಹಿತಿಲೆನ್ ನಾಡ್‍ಲೆ (ಪಾತೆರದ ಪುಟೊಲ ಸೇರ್ದ್)",
        "searchprofile-advanced-tooltip": "ಬಳಕೆದ ನಾಮೊವರ್ಗೊಡು ನಾಡ್‍ಲೆ",
        "search-result-size": "$1 ({{PLURAL:$2|೧ ಪದೊ|$2 ಪದೊಕುಲು}})",
-       "search-redirect": "(ಪಿರ ನಿರ್ದೇಶನೊ $1)",
+       "search-redirect": "($1 ಡ್ದ್ ಪಿರ ನಿರ್ದೇಸನೊದ)",
        "search-section": "(ವಿಬಾಗೊ $1)",
        "search-suggest": "ಇಂದೆನ್ ನಾಡೊಂದುಲ್ಲರೆ: $1",
        "search-interwiki-caption": "ಬಳಗದ ಇತರ ಯೋಜನೆಲು",
        "logentry-move-move": "$1 {{GENDER:$2|ಜಾರಲೆ}} ಪುಟೊ $3 ಡ್ದ್ $4",
        "logentry-newusers-create": "ಬಳಕೆದಾರೆರೆ ಕಾತೆ $1 ನ್ನು {{GENDER:$2|ಸ್ರಿಸ್ಟಿ ಮಲ್ತಾಂಡ್}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|ಅಪ್ಲೋಡ್ ಮಲ್ತ್‌ದೆರ್}} $3",
-       "searchsuggest-search": "ನಾಡ್‍ಲೆ"
+       "searchsuggest-search": "{{SITENAME}}ನ್ ನಾಡ್‍ಲೆ"
 }
index b49742e..d33657c 100644 (file)
@@ -24,7 +24,8 @@
                        "아라",
                        "Macofe",
                        "Matma Rex",
-                       "WP MANIKHANTA"
+                       "WP MANIKHANTA",
+                       "SrihariThalla"
                ]
        },
        "tog-underline": "లంకె క్రీగీత:",
@@ -52,7 +53,7 @@
        "tog-enotifminoredits": "పేజీలు మరియు దస్త్రాలలో జరిగే చిన్న మార్పులకు కూడా నాకు ఈ-మెయిలును పంపు",
        "tog-enotifrevealaddr": "గమనింపు మెయిళ్ళలో నా ఈ-మెయిలు చిరునామాను చూపించు",
        "tog-shownumberswatching": "వీక్షకుల సంఖ్యను చూపు",
-       "tog-oldsig": "ప్రస్తుత సంతకం:",
+       "tog-oldsig": "à°®à±\80 à°ªà±\8dà°°à°¸à±\8dà°¤à±\81à°¤ à°¸à°\82à°¤à°\95à°\82:",
        "tog-fancysig": "సంతకాన్ని వికీపాఠ్యంగా తీసుకో (ఆటోమెటిక్‌ లింకు లేకుండా)",
        "tog-uselivepreview": "తాజా మునుజూపును వాడు",
        "tog-forceeditsummary": "దిద్దుబాటు సారాంశం ఖాళీగా ఉంటే ఆ విషయాన్ని నాకు సూచించు",
@@ -60,6 +61,7 @@
        "tog-watchlisthidebots": "బాట్లు చేసిన మార్పులను నా వీక్షణా జాబితాలో చూపించొద్దు",
        "tog-watchlisthideminor": "చిన్న మార్పులను నా వీక్షణా జాబితాలో చూపించొద్దు",
        "tog-watchlisthideliu": "లాగిన్ ఐన వాడుకరులు చేసే మార్పులను వీక్షణా జాబితాలో చూపించకు",
+       "tog-watchlistreloadautomatically": "ఫిల్టరు మారినప్పుడెల్లా వీక్షణ జాబితాను తిరిగి లోడు చెయ్యి (JavaScript అవసరం)",
        "tog-watchlisthideanons": "అజ్ఞాత వాడుకరుల మార్పులను వీక్షణా జాబితాలో చూపించకు",
        "tog-watchlisthidepatrolled": "నిఘా ఉన్న మార్పులను వీక్షణజాబితా నుంచి దాచిపెట్టు",
        "tog-watchlisthidecategorization": "పేజీ వర్గీకరణను దాచు",
        "newwindow": "(కొత్త కిటికీలో వస్తుంది)",
        "cancel": "రద్దుచేయి",
        "moredotdotdot": "ఇంకా...",
-       "morenotlisted": "à°\88 à°\9cాబితా à°¸à°\82à°ªà±\82à°°à±\8dà°£à°\82 à°\95ాదà±\81.",
+       "morenotlisted": "బహà±\81శా à°\88 à°\9cాబితా à°\85à°¸à°\82à°ªà±\82à°°à±\8dà°£à°\82.",
        "mypage": "పుట",
        "mytalk": "చర్చ",
        "anontalk": "చర్చ",
        "talk": "చర్చ",
        "views": "చూపులు",
        "toolbox": "పనిముట్లు",
+       "tool-link-userrights": "{{GENDER:$1|వాడుకరి}} గుంపులను మార్చు",
+       "tool-link-emailuser": "ఈ {{GENDER:$1|వాడుకరికి}} ఈమెయిలు పంపు",
        "userpage": "వాడుకరి పేజీని చూడండి",
        "projectpage": "ప్రాజెక్టు పేజీని చూడు",
        "imagepage": "ఫైలు పేజీని చూడండి",
        "mypreferencesprotected": "మీ అభీష్టాలను సవరించేందుకు మీకు అనుమతి లేదు.",
        "ns-specialprotected": "ప్రత్యేక పేజీలపై దిద్దుబాట్లు చేయలేరు.",
        "titleprotected": "[[User:$1|$1]] ఈ శీర్షికని సృష్టించకుండా ఇది సంరక్షించబడింది.\nఅందుకు ఇచ్చిన కారణం: <em>$2</em>.",
-       "filereadonlyerror": "à°«à±\88à°²à±\81 à°\96à°\9cానా \"$2\" à°°à±\80à°¡à±\8d-à°\93à°¨à±\8dà°²à±\80 à°¸à±\8dథితిలà±\8b à°\89à°\82à°¡à°\9fà°\82 à°\9aà±\87à°¤ \"$1\" à°«à±\88à°²à±\81à°²à±\8b à°®à°¾à°°à±\8dà°ªà±\81à°²à±\81 à°\9aà±\86à°¯à±\8dయలà±\87à°\95à°ªà±\8bయాà°\82.\n\nదానిà°\95à°¿ à°¤à°¾à°³à°\82 à°µà±\87సిన à°\85ధిà°\95ారి ఇచ్చిన వివరణ ఇది: \"$3\".",
+       "filereadonlyerror": "à°«à±\88à°²à±\81 à°\96à°\9cానా \"$2\" à°°à±\80à°¡à±\8d-à°\93à°¨à±\8dà°²à±\80 à°¸à±\8dథితిలà±\8b à°\89à°\82à°¡à°\9fà°\82 à°\9aà±\87à°¤ \"$1\" à°«à±\88à°²à±\81à°²à±\8b à°®à°¾à°°à±\8dà°ªà±\81à°²à±\81 à°\9aà±\86à°¯à±\8dయలà±\87à°\95à°ªà±\8bయాà°\82.\n\nదానిà°\95à°¿ à°¤à°¾à°³à°\82 à°µà±\87సిన à°¸à°¿à°¸à±\8dà°\9fà°®à±\81 à°¨à°¿à°°à±\8dవాహà°\95à±\81à°¡à±\81 ఇచ్చిన వివరణ ఇది: \"$3\".",
        "invalidtitle-knownnamespace": "పేరుబరి \"$2\", పాఠ్యము \"$3\" తో కూడిన ఈ శీర్షిక చెల్లనిది",
        "invalidtitle-unknownnamespace": "అపరిచితమైన పేరుబరి సంఖ్య \"$1\", పాఠ్యము \"$2\" తో కూడిన ఈ శీర్షిక చెల్లనిది",
        "exception-nologin": "లాగినై లేరు",
        "createacct-yourpasswordagain-ph": "సంకేతపదాన్ని మళ్ళీ ఇవ్వండి",
        "userlogin-remembermypassword": "నన్ను లాగిన్ చేసే ఉంచు",
        "userlogin-signwithsecure": "సురక్షిత కనెక్షను వాడు",
+       "cannotlogin-title": "లాగిన్ చెయ్యలేకున్నాం",
        "cannotloginnow-title": "ఇప్పుడు లాగిన్ అవలేరు",
        "cannotloginnow-text": "$1 ను వాడుతూండగా లాగౌట్ అవలేరు.",
+       "cannotcreateaccount-title": "ఖాతాలను సృష్టించలేము",
+       "cannotcreateaccount-text": "ఈ వికీలో నేరుగా ఖాతాలను సృష్టించడం సశక్తం చెయ్యలేదు.",
        "yourdomainname": "మీ డోమైను",
        "password-change-forbidden": "ఈ వికీలో మీరు సంకేతపదాలను మార్చలేరు.",
        "externaldberror": "డేటాబేసు అధీకరణలో లోపం జరిగింది లేదా మీ బయటి ఖాతాను తాజాకరించడానికి మీకు అనుమతి లేదు.",
        "eauthentsent": "ఇచ్చిన ఈ-మెయిలు అడ్రసుకు ధృవీకరణ మెయిలు పంపించాం.\nఇకపై మేము ఆ ఖాతాకు మెయిలు పంపాలంటే, ముందుగా మీరు ఆ మెయిల్లో సూచించినట్లుగా చేసి, ఈ చిరునామా మీదేనని ధృవీకరించాలి.",
        "throttled-mailpassword": "గడచిన {{PLURAL:$1|ఒక గంటలో|$1 గంటల్లో}} సంకేతపదం మార్చినట్లుగా ఒక మెయిలు పంపించివున్నాం.\nదుశ్చర్యలను నివారించేందుకు గాను, {{PLURAL:$1|ఒక గంటకు|$1 గంటలకు}} ఒక్కసారి మాత్రమే సంకేతపదం మార్పు మెయిలు పంపిస్తాము.",
        "mailerror": "మెయిలు పంపించడంలో లోపం: $1",
-       "acct_creation_throttle_hit": "మీ ఐపీ చిరునామా వాడుతున్న ఈ వికీ సందర్శకులు గత ఒక్క రోజులో {{PLURAL:$1|1 ఖాతాని|$1 ఖాతాలను}} సృష్టించారు, ఈ కాల వ్యవధిలో అది గరిష్ఠ పరిమితి.\nఅందువల్ల, ఈ ఐపీని వాడుతున్న సందర్శకులు ప్రస్తుతానికి ఇంక ఖాతాలని సృష్టించలేరు.",
+       "acct_creation_throttle_hit": "మీ ఐపీ చిరునామా వాడుతున్న ఈ వికీ సందర్శకులు గత $2 లో {{PLURAL:$1|1 ఖాతాను|$1 ఖాతాలను}} సృష్టించారు. ఈ కాల వ్యవధిలో అది గరిష్ఠ పరిమితి.\nఫలితంగా, ఈ ఐపీని వాడుతున్న సందర్శకులు ప్రస్తుతానికి ఇక ఖాతాలని సృష్టించలేరు.",
        "emailauthenticated": "మీ ఈ-మెయిలు చిరునామా $2న $3కి ధృవీకరింపబడింది.",
        "emailnotauthenticated": "మీ ఈ-మెయిలు చిరునామాను ఇంకా ధృవీకరించలేదు. \nకింద పేర్కొన్న అంశాలకు సంబంధించి ఎటువంటి ఈ-మెయిలునూ పంపించము.",
        "noemailprefs": "ఈ అంశాలు పని చెయ్యడానికి మీ అభిరుచుల్లో ఈమెయిలు చిరునామా ఇవ్వండి.",
        "botpasswords-label-delete": "తొలగించు",
        "botpasswords-label-resetpassword": "సంకేతపదాన్ని మార్చు",
        "botpasswords-label-grants": "వర్తించే గ్రాంట్లు:",
-       "botpasswords-label-restrictions": "వాడుక పరిమితులు:",
        "botpasswords-label-grants-column": "గ్రాంటు చేసాం",
        "botpasswords-bad-appid": "బాట్ పేరు \"$1\" సరైనది కాదు.",
        "botpasswords-insert-failed": "బాట్ పేరు \"$1\"ను చేర్చలేకపోయాం. దీన్ని ఇంతకు ముందే చేర్చారా ఏంటి?",
        "passwordreset-emailelement": "వాడుకరిపేరు: \n$1\n\nతాత్కాలిక సంకేతపదం: \n$2",
        "passwordreset-emailsentemail": "ఈ ఈమెయిలు చిరునామా మీ ఖాతాకు అనుసంధించి ఉంటే, సంకేతపదం మార్పు ఈమెయిలు పంపించబడుతుంది.",
        "passwordreset-emailsentusername": "ఈ వాడుకరిపేరుకు ఏదైనా ఈమెయిలు చిరునామా అనుసంధించి ఉంటే, సంకేతపదం మార్పు ఈమెయిలు పంపించబడుతుంది.",
-       "passwordreset-emailsent-capture2": "à°¸à°\82à°\95à±\87తపదà°\82 à°®à°¾à°°à±\8dà°ªà±\81 {{PLURAL:$1|à°\88à°®à±\86యిలà±\81à°¨à±\81|à°\88à°®à±\86యిళà±\8dళనà±\81}} à°ªà°\82పిà°\82à°\9aà°¾à°\82. {{PLURAL:$1|వాడà±\81à°\95à°°à°¿à°ªà±\87à°°à±\81, à°¸à°\82à°\95à±\87తపదానà±\8dని|వాడà±\81à°\95à°°à°¿à°ªà±\87à°°à±\8dà°²à±\81, à°¸à°\82à°\95à±\87తపదాల à°\9cాబితానà±\81}} à°\95à°¿à°\82à°¦ చూపించాం.",
-       "passwordreset-emailerror-capture2": "{{GENDER:$2|వాడà±\81à°\95à°°à°¿à°\95à°¿}} à°\88à°®à±\86యిలà±\81 à°ªà°\82పడà°\82 à°µà°¿à°«à°²à°®à±\88à°\82ది: $1 {{PLURAL:$3|వాడà±\81à°\95à°°à°¿à°ªà±\87à°°à±\81, à°¸à°\82à°\95à±\87తపదానà±\8dని|వాడà±\81à°\95à°°à°¿à°ªà±\87à°°à±\8dà°²à±\81, à°¸à°\82à°\95à±\87తపదాల à°\9cాబితానà±\81}} à°\95à°¿à°\82à°¦ చూపించాం.",
-       "passwordreset-invalideamil": "తప్పు ఈ-మెయిలు చిరునామా",
+       "passwordreset-emailsent-capture2": "à°¸à°\82à°\95à±\87తపదà°\82 à°®à°¾à°°à±\8dà°ªà±\81 {{PLURAL:$1|à°\88à°®à±\86యిలà±\81à°¨à±\81|à°\88à°®à±\86యిళà±\8dళనà±\81}} à°ªà°\82పిà°\82à°\9aà°¾à°\82. {{PLURAL:$1|వాడà±\81à°\95à°°à°¿à°ªà±\87à°°à±\81, à°¸à°\82à°\95à±\87తపదానà±\8dని|వాడà±\81à°\95à°°à°¿à°ªà±\87à°°à±\8dà°²à±\81, à°¸à°\82à°\95à±\87తపదాల à°\9cాబితానà±\81}} à°\87à°\95à±\8dà°\95à°¡ చూపించాం.",
+       "passwordreset-emailerror-capture2": "{{GENDER:$2|వాడà±\81à°\95à°°à°¿à°\95à°¿}} à°\88à°®à±\86యిలà±\81 à°ªà°\82పడà°\82 à°µà°¿à°«à°²à°®à±\88à°\82ది: $1 {{PLURAL:$3|వాడà±\81à°\95à°°à°¿à°ªà±\87à°°à±\81, à°¸à°\82à°\95à±\87తపదానà±\8dని|వాడà±\81à°\95à°°à°¿à°ªà±\87à°°à±\8dà°²à±\81, à°¸à°\82à°\95à±\87తపదాల à°\9cాబితానà±\81}} à°\87à°\95à±\8dà°\95à°¡ చూపించాం.",
+       "passwordreset-invalidemail": "తప్పు ఈ-మెయిలు చిరునామా",
        "passwordreset-nodata": "వాడుకరిపేరుగానీ, ఈ-మెయిలు చిరునామా గానీ ఇవ్వలేదు",
        "changeemail": "ఈ-మెయిలు చిరునామా మార్పు లేదా తొలగింపు",
        "changeemail-header": "మీ ఈ-మెయిల్ చిరునామాను మార్చుకునేందుకు ఈ ఫారమును నింపండి. అసలు మీ ఖాతాకు ఈ-మెయిలు చిరునామా దేన్నీ జోడించ వద్దనుకుంటే, కొత్త ఈ-మెయిలు చిరునామాను ఖాళీగా ఉంచి, ఫారాన్ని సమర్పించండి.",
        "searchprofile-advanced-tooltip": "కస్టం నేంస్పేసులలో వెదుకు",
        "search-result-size": "$1 ({{PLURAL:$2|1 పదం|$2 పదాలు}})",
        "search-result-category-size": "{{PLURAL:$1|1 సభ్యుడు|$1 సభ్యులు}} ({{PLURAL:$2|1 ఉవవర్గం|$2 ఉపవర్గాలు}}, {{PLURAL:$3|1 దస్త్రం|$3 దస్త్రాలు}})",
-       "search-redirect": "(దారిమార్పు $1)",
+       "search-redirect": "($1 నుండి దారిమార్పు)",
        "search-section": "(విభాగం $1)",
        "search-category": "(వర్గం $1)",
        "search-file-match": "(ఫైలు విషయంతో సరిపోలుతోంది)",
        "search-suggest": "మీరు అంటున్నది ఇదా: $1",
+       "search-rewritten": "$1 కు ఫలితాలు చూపిస్తున్నాం. లేదంటే $2 కోసం వెతకండి.",
        "search-interwiki-caption": "సోదర ప్రాజెక్టులు",
        "search-interwiki-default": "$1 నుండి ఫలితాలు:",
        "search-interwiki-more": "(మరిన్ని)",
        "badsig": "సంతకం చెల్లనిది.\nHTML ట్యాగులను ఒకసారి సరిచూసుకోండి.",
        "badsiglength": "మీ సంతకం చాలా పెద్దగా ఉంది.\nఇది తప్పనిసరిగా $1 {{PLURAL:$1|అక్షరం|అక్షరాల}} లోపులోనే ఉండాలి.",
        "yourgender": "మిమ్మల్ని మీరు ఎలా వర్ణించుకుంటారు?",
-       "gender-unknown": "సాఫà±\8dà°\9fà±\81à°µà±\87à°°à±\81 à°®à°¿à°®à±\8dమలà±\8dని à°\89à°²à±\8dà°²à±\87à°\96à°¿à°\82à°\9aà±\87 à°¸à°\82దరà±\8dà°­à°\82à°²à±\8b, à°µà±\80à°²à±\88à°¨à°\82తవరà°\95à±\81 à°²à°¿à°\82à°\97 à°¤à°\9fà°¸à±\8dథతనà±\81 à°\85వలà°\82à°¬ిస్తుంది",
+       "gender-unknown": "సాఫà±\8dà°\9fà±\81à°µà±\87à°°à±\81 à°®à°¿à°®à±\8dమలà±\8dని à°¸à°\82à°¬à±\8bధిà°\82à°\9aà±\87à°\9fà°ªà±\8dà°ªà±\81à°¡à±\81, à°µà±\80à°²à±\88à°¨à°\82తవరà°\95à±\81 à°²à°¿à°\82à°\97 à°¤à°\9fà°¸à±\8dథతనà±\81 à°ªà°¾à°\9fిస్తుంది",
        "gender-male": "అతను వికీ పేజీలను సరిదిద్దుతాడు",
        "gender-female": "ఆమె వికీ పేజీలను సరిదిద్దుతుంది",
        "prefs-help-gender": "ఈ అభిరుచిని అమర్చుకోవడం ఐచ్చికం.\nమిమ్మల్ని సంబోధించేప్పుడూ మిమ్మల్ని పేర్కొనేప్పుడూ వ్యాకరణపరంగా సరైన లింగాన్ని  వాడటానికి ఈ విలువ ఉపయోగపడుతుంది.\nఈ సమాచారం బహిరంగం.",
        "listusers": "వాడుకరుల జాబితా",
        "listusers-editsonly": "మార్పులు చేసిన వాడుకరులను మాత్రమే చూపించు",
        "listusers-creationsort": "చేరిన తేదీ క్రమంలో చూపించు",
-       "listusers-desc": "అవోహణ క్రమంలో పేర్చు",
+       "listusers-desc": "à°\85వరà±\8bహణ à°\95à±\8dà°°à°®à°\82à°²à±\8b à°ªà±\87à°°à±\8dà°\9aà±\81",
        "usereditcount": "$1 {{PLURAL:$1|మార్పు|మార్పులు}}",
        "usercreated": "$1 న $2కి {{GENDER:$3|చేరారు}}",
        "newpages": "కొత్త పేజీలు",
        "activeusers-intro": "ఇది గత $1 {{PLURAL:$1|రోజులో|రోజులలో}} ఏదైనా కార్యకలాపం చేసిన వాడుకరుల జాబితా.",
        "activeusers-count": "గడచిన {{PLURAL:$3|ఒక రోజు|$3 రోజుల}}లో $1 {{PLURAL:$1|చర్య|చర్యలు}}",
        "activeusers-from": "వాడుకరులను ఇక్కడ నుండి చూపించు:",
-       "activeusers-hidebots": "బాట్లను దాచు",
-       "activeusers-hidesysops": "నిర్వాహకులను దాచు",
        "activeusers-noresult": "వాడుకరులెవరూ లేరు.",
        "activeusers-submit": "చేతనంగా ఉన్న వాడుకరులను చూపించు",
        "listgrouprights": "వాడుకరి గుంపుల హక్కులు",
        "confirmemail_oncreate": "మీ ఈ-మెయిలు చిరునామాకి ఒక ధృవీకరణ సంకేతాన్ని పంపించాం.\nలోనికి ప్రవేశించేందుకు ఆ సంకేతం అవసరంలేదు, కానీ ఈ వికీలో ఈ-మెయిలు ఆధారిత సౌలభ్యాలను చేతనం చేసేముందు దాన్ని ఇవ్వవలసి ఉంటుంది.",
        "confirmemail_sendfailed": "{{SITENAME}} మీ  నిర్ధారణ మెయిలుని పంపలేకపోయింది.\nమీ ఈమెయిల్ చిరునామాలో తప్పులున్నాయేమో సరిచూసుకోండి.\n\nమెయిలరు ఇలా చెప్పింది: $1",
        "confirmemail_invalid": "ధృవీకరణ సంకేతం సరైనది కాదు. దానికి కాలం చెల్లి ఉండవచ్చు.",
-       "confirmemail_needlogin": "à°®à±\80 à°\88à°®à±\86యిలà±\81 à°\9aà°¿à°°à±\81నామాని à°¦à±\83వపరà°\9aà°\9fానిà°\95à°¿ à°®à±\80à°°à±\81 $1 à°\89à°\82డాలి.",
+       "confirmemail_needlogin": "à°®à±\80 à°\88à°®à±\86యిలà±\81 à°\9aà°¿à°°à±\81నామానà±\81 à°§à±\8dà°°à±\81à°µà±\80à°\95à°°à°¿à°\82à°\9aà±\87à°\82à°¦à±\81à°\95à±\81, $1.",
        "confirmemail_success": "మీ ఈ-మెయిలు చిరునామా ధృవీకరించబడింది.\nఇక [[Special:UserLogin|లోనికి ప్రవేశించి]] వికీని అస్వాదించండి.",
        "confirmemail_loggedin": "మీ ఈ-మెయిలు చిరునామా ఇప్పుడు రూఢి అయింది.",
        "confirmemail_subject": "{{SITENAME}} ఈ-మెయిలు చిరునామా ధృవీకరణ",
        "table_pager_empty": "ఫలితాలు లేవు",
        "autosumm-blank": "పేజీలోని విషయాన్నంతటినీ తీసేసారు.",
        "autosumm-replace": "పేజీని '$1' తో మారుస్తున్నాం",
-       "autoredircomment": "[[$1]]కు దారిమళ్ళించారు",
+       "autoredircomment": "పేజీని [[$1]] కు దారి మళ్ళించారు",
        "autosumm-new": "'$1' తో కొత్త పేజీని సృష్టించారు",
        "autosumm-newblank": "ఖాళీ పేజీని సృష్టించారు",
        "lag-warn-normal": "$1 {{PLURAL:$1|క్షణం|క్షణాల}} లోపు జరిగిన మార్పులు ఈ జాబితాలో కనిపించకపోవచ్చు.",
        "htmlform-cloner-create": "ఇంకా చేర్చు",
        "htmlform-cloner-delete": "తొలగించు",
        "htmlform-cloner-required": "కనీసం ఒక విలువు అయినా ఇవ్వాలి.",
-       "sqlite-has-fts": "$1 పూర్తి-పాఠ్య అన్వేషణ తోడ్పాటుతో",
-       "sqlite-no-fts": "$1 పూర్తి-పాఠ్య అన్వేషణ తోడ్పాటు లేకుండా",
        "logentry-delete-delete": "$1 $3 పేజీని {{GENDER:$2|తొలగించారు}}",
        "logentry-delete-restore": "పేజీ $3 ని $1 {{GENDER:$2|పునస్థాపించారు}}",
        "logentry-delete-event": "$3 లో {{PLURAL:$5|ఒక లాగ్ ఘటన|$5 లాగ్ ఘటనల}} యొక్క కన్పట్టటాన్ని (విజిబిలిటీ) $1 {{GENDER:$2|మార్చారు}}: $4",
        "feedback-close": "పూర్తయ్యింది",
        "feedback-dialog-title": "ప్రతిస్పందనను తెలియజేయండి",
        "feedback-dialog-intro": "మీ ప్రతిస్పందనను తెలియజేయడానికి ఈ తేలిక ఫారాన్ని వాడుకోవచ్చు. మీ వాడుకరి పేరుతో పాటు మీ వ్యాఖ్య \"$1\" పేజీకి చేర్చబడుతుంది.",
-       "feedback-error-title": "లోపం",
        "feedback-error1": "లోపం: API నుండి గుర్తుపట్టలేని ఫలితం",
        "feedback-error2": "దోషము: సవరణ విఫలమైంది",
        "feedback-error3": "లోపం: API నుండి ప్రతిస్పందన లేదు",
        "feedback-thanks": "కృతజ్ఞతలు! మీ ప్రతిస్పందనను “[$2 $1]” పేజీలో చేర్చాం.",
        "feedback-thanks-title": "కృతజ్ఞతలు!",
        "feedback-useragent": "వాడుకరి ఏజెంటు:",
-       "searchsuggest-search": "వెతుకు",
+       "searchsuggest-search": "{{SITENAME}}‌లో వెతకండి",
        "searchsuggest-containing": "కలిగియున్న...",
        "api-error-badaccess-groups": "ఈ వికీ లోనికి దస్త్రాలను ఎక్కించే అనుమతి మీకు లేదు.",
        "api-error-badtoken": "అంతర్గత లోపం: చెడు టోకెన్.",
index a224d42..15341c8 100644 (file)
        "nocreate-loggedin": "Ó la bele kria pájina foun.",
        "permissionserrorstext": "Ó la bele halo ne'e; {{PLURAL:$1|motivu|motivu sira}}:",
        "permissionserrorstext-withaction": "Ita la bele $2. {{PLURAL:$1|Razaun|Razaun sira}}:",
-       "cantcreateaccounttitle": "La bele registrar uza-na'in",
        "currentrev": "Versaun atuál",
        "revisionasof": "Versaun $1 nian",
        "revision-info": "Revisaun loron $4, tempu $5, husi $2",
        "linksearch-ns": "Espasu pájina nian:",
        "linksearch-ok": "Buka",
        "listusers-submit": "Hatudu",
-       "activeusers-hidebots": "Subar bot sira",
-       "activeusers-hidesysops": "Subar administradór sira",
        "listgrouprights-group": "Grupu",
        "listgrouprights-rights": "Priviléjiu",
        "listgrouprights-members": "(lista membru nian)",
index f7826ab..77ac744 100644 (file)
        "yourpasswordagain": "Калимаи убурро боз нависед",
        "createacct-yourpasswordagain": "Тасдиқи гузарвожа",
        "createacct-yourpasswordagain-ph": "Гузарвожаро бори дигар ворид кунед",
-       "remembermypassword": "Вуруди манро дар ин мурургар дар хотир нигоҳ дор (то ҳадди аксар $1 {{PLURAL:$1|рӯз|рӯз}})",
        "userlogin-remembermypassword": "Вурудшуда манро нигоҳ дор",
        "userlogin-signwithsecure": "Истифодаи пайвастшавии амн",
        "yourdomainname": "Домейни Шумо",
        "undo-success": "Ин вироиш метавонад ботил шавад. Лутфан муқоисаи зеринро барои таъйид кардани амалӣ худ, баррасӣ кунед, ва баъдан барои анҷом додани ботилкунии вироиш тағйироти зеринро захира кунед.",
        "undo-failure": "Ба иллати бархӯрдани вироишҳои дар миён омада, ин вироишро ботил наметавон кард.",
        "undo-summary": "Ботили нусхаи $1 аз тарафи [[Special:Contributions/$2|$2]] ([[User talk:$2|Баҳс]])",
-       "cantcreateaccounttitle": "Ҳисобе сохта наметавонам",
        "cantcreateaccount-text": "Имкони сохтани ҳисоби корбарӣ аз ин нишонаи IP ('''$1''') аз тарафи [[User:$3|$3]] баста шудааст.\n\nДалели $3 чунин аст ''$2''",
        "viewpagelogs": "Намоиши гузоришҳои марбута ба ин саҳифа",
        "nohistory": "Таърихи вироиш барои ин саҳифа вуҷуд надорад.",
index 6340644..a577ebe 100644 (file)
        "yourname": "Nomi korbar",
        "yourpassword": "Kalimai ubur\\parolь",
        "yourpasswordagain": "Kalimai uburro boz navised",
-       "remembermypassword": "Vurudi manro dar in mururgar dar xotir nigoh dor (to haddi aksar $1 {{PLURAL:$1|rūz|rūz}})",
        "yourdomainname": "Domejni Şumo",
        "externaldberror": "Xatoe dar irtibot bo pojgohi doda rux doda ast jo in ki şumo içozat ba rūzrasoniji hisobi beruniji xudro nadored.",
        "login": "Vurud",
        "undo-success": "In viroiş metavonad botil şavad. Lutfan muqoisai zerinro baroi ta'jid kardani amalī xud, barrasī kuned, va ba'dan baroi ançom dodani botilkuniji viroiş taƣjiroti zerinro zaxira kuned.",
        "undo-failure": "Ba illati barxūrdani viroişhoi dar mijon omada, in viroişro botil nametavon kard.",
        "undo-summary": "Botili nusxai $1 az tarafi [[Special:Contributions/$2|$2]] ([[User talk:$2|Bahs]])",
-       "cantcreateaccounttitle": "Hisobe soxta nametavonam",
        "cantcreateaccount-text": "Imkoni soxtani hisobi korbarī az in nişonai IP ('''$1''') az tarafi [[User:$3|$3]] basta şudaast.\n\nDaleli $3 cunin ast ''$2''",
        "viewpagelogs": "Namoişi guzorişhoi marbuta ba in sahifa",
        "nohistory": "Ta'rixi viroiş baroi in sahifa vuçud nadorad.",
index 656ea39..f9d5283 100644 (file)
        "yourpasswordagain": "พิมพ์รหัสผ่านอีกครั้ง:",
        "createacct-yourpasswordagain": "ยืนยันรหัสผ่าน",
        "createacct-yourpasswordagain-ph": "กรอกรหัสผ่านอีกครั้ง",
-       "remembermypassword": "จำการล็อกอินของฉันบนเบราเซอร์นี้ (นานสุด $1 วัน)",
        "userlogin-remembermypassword": "ให้ฉันอยู่ในระบบต่อ",
        "userlogin-signwithsecure": "ใช้การเชื่อมต่อที่ปลอดภัย",
        "cannotloginnow-title": "ไม่สามารถล็อกเอาต์ได้ขณะนี้",
        "activeusers-intro": "นี่คือรายการผู้ใช้ที่มีกิจกรรมใด ๆ ในช่วง $1 วันหลังสุด",
        "activeusers-count": "$1 ปฏิบัติการ{{PLURAL:$1|}} ในช่วง $3 วันหลังสุด",
        "activeusers-from": "แสดงผู้ใช้เริ่มจาก:",
-       "activeusers-hidebots": "ซ่อนบอต",
-       "activeusers-hidesysops": "ซ่อนผู้ดูแลระบบ",
        "activeusers-noresult": "ไม่พบผู้ใช้",
        "activeusers-submit": "แสดงผู้ใช้ที่ยังมีกิจกรรม",
        "listgrouprights": "สิทธิกลุ่มผู้ใช้",
        "htmlform-title-not-exists": "ไม่มี $1",
        "htmlform-user-not-exists": "ไม่มี <strong>$1</strong>",
        "htmlform-user-not-valid": "<strong>$1</strong> มิใช่ชื่อผู้ใช้ที่สมเหตุสมผล",
-       "sqlite-has-fts": "รุ่น $1 พร้อมการสนับสนุนการค้นหาข้อความแบบเต็ม",
-       "sqlite-no-fts": "รุ่น $1 โดยไม่มีการสนับสนุนการค้นหาข้อความแบบเต็ม",
        "logentry-delete-delete": "$1 ลบหน้า $3",
        "logentry-delete-restore": "$1 กู้คืนหน้า $3",
        "logentry-delete-event": "$1 เปลี่ยนทัศนวิสัยของ $5 รายการปูมใน $3: $4",
index 7ec316c..5d6b0b2 100644 (file)
        "yourname": "Ulanyjy adyňyz:",
        "yourpassword": "Parolyňyz:",
        "yourpasswordagain": "Paroly gaýtadan ýaz:",
-       "remembermypassword": "Sessiýamy şu kompýuterde ýatda sakla  (iň köp $1 {{PLURAL:$1|günläp|günläp}})",
        "yourdomainname": "Siziň domeniňiz:",
        "externaldberror": "Ýa tassyklama maglumat bazasynyň säwligi bar ýa-da öz ulanyjy hasabyňyzy täzelemegiňize rugsat berilmeýär.",
        "login": "Hasaba gir",
        "undo-failure": "Gapma-garşylykly aralyk özgerdişler zerarly bu özgerdişi yzyna alyp bolmaýar.",
        "undo-norev": "Özgerdişi yzyna alyp bolmaýar, sebäbi ol ýok ýa-da öçürilipdir.",
        "undo-summary": "$1 wersiýasy [[Special:Contributions/$2|$2]] ([[User talk:$2|Çekişme]]) tarapyndan yzyna alyndy.",
-       "cantcreateaccounttitle": "Hasap döredip bolmaýar",
        "cantcreateaccount-text": "Bu IP adresinden ('''$1''') ulanyjy hasaby döretmeklik [[User:$3|$3]] tarapyndan blokirlenipdir.\n\n$3 tarapyndan görkezilen sebäp: ''$2''",
        "viewpagelogs": "Bu sahypanyň gündeliklerini görkez",
        "nohistory": "Bu sahypanyň özgerdişler geçmişi ýok.",
        "activeusers-intro": "Bu sanawda soňky $1 {{PLURAL:$1|günüň|günüň}} dowamynda nähilidir bir iş geçiren ulanyjylar görkezilýär.",
        "activeusers-count": "Soňky {{PLURAL:$3|günde|$3 günde}} $1 sany {{PLURAL:$1|özgerdiş|özgerdiş}}",
        "activeusers-from": "Şunuň bilen başlaýan ulanyjylary görkez:",
-       "activeusers-hidebots": "Botlary gizle",
-       "activeusers-hidesysops": "Administratorlary gizle",
        "activeusers-noresult": "Ulanyjy tapylmady.",
        "listgrouprights": "Ulanyjy topary hukuklary",
        "listgrouprights-summary": "Aşakda şu wikide kesgitlenen ulanyjy toparlarynyň hem-de olaryň degişli ulanmak hukuklarynyň sanawy berilýär.\nŞahsy hukuklar barada [[{{MediaWiki:Listgrouprights-helppage}}|goşmaça maglumat]] bar bolup biler.",
        "htmlform-submit": "Tabşyr",
        "htmlform-reset": "Üýtgeşmeleri yzyna al",
        "htmlform-selectorother-other": "Başga",
-       "sqlite-has-fts": "$1 (doly tekstli gözleg goldawly)",
-       "sqlite-no-fts": "$1 (doly tekstli gözleg goldawsyz)",
        "revdelete-restricted": "administratorlara goýlan çäklendirmeler",
        "revdelete-unrestricted": "administratorlardan aýyrylan çäklendirmeler",
        "rightsnone": "(hiç biri)",
index 115d81d..405d823 100644 (file)
@@ -17,7 +17,8 @@
                        "Leeheonjin",
                        "Macofe",
                        "Matma Rex",
-                       "Stranger195"
+                       "Stranger195",
+                       "Emem.calist"
                ]
        },
        "tog-underline": "Pagsasalungguhit ng link:",
@@ -44,7 +45,7 @@
        "tog-enotifminoredits": "Padalhan din ako ng e-liham para sa mga maliliit na mga pagbabago ng mga pahina at mga talaksan",
        "tog-enotifrevealaddr": "Ipakita ang aking direksiyong e-liham sa loob ng mga e-liham ng pagpapahayag",
        "tog-shownumberswatching": "Ipakita ang bilang ng mga nagbabantay na tagagamit",
-       "tog-oldsig": "Umiiral na lagda:",
+       "tog-oldsig": "Ang iyong umiiral na lagda:",
        "tog-fancysig": "Ituring ang lagda bilang teksto ng wiki (walang automatikong pagkawing)",
        "tog-uselivepreview": "Gamitin ang buhay na paunang tingin",
        "tog-forceeditsummary": "Pagsabihan ako kapag nagpapasok ng walang-lamang buod ng pagbabago",
        "yourpasswordagain": "Password mo uli:",
        "createacct-yourpasswordagain": "Tiyakin ang password",
        "createacct-yourpasswordagain-ph": "Muling ilagay ang password",
-       "remembermypassword": "Tandaan ang paglagda ko sa kompyuter na ito (pinakamarami na ang $1 {{PLURAL:$1|araw|mga araw}})",
        "userlogin-remembermypassword": "Panatilihin akong naka-login",
        "userlogin-signwithsecure": "Gumamit ng ligtas na koneksyon",
        "yourdomainname": "Dominyo mo:",
        "resetpass_submit": "Itakda ang password at mag-login",
        "changepassword-success": "Matagumpay na nabago ang iyong password!",
        "changepassword-throttled": "Masyadong madami ang kamakailan lamang mong pagsubok sa pag-login.\nMaghintay po muna ng $1 bago subukan uli.",
+       "botpasswords-label-delete": "Burahin",
+       "botpasswords-label-resetpassword": "Itakdang-muli/baguhin ang hudyat (password)",
+       "botpasswords-label-grants-column": "Ipinagkaloob na",
        "resetpass_forbidden": "Hindi mababago ang mga password",
        "resetpass-no-info": "Nakalagda ka dapat para tuwirang mapuntahan ang pahina ito.",
        "resetpass-submit-loggedin": "Baguhin ang password",
        "passwordreset-emailtext-user": "Ang tagagamit na si $1 sa {{SITENAME}} ay humiling ng isang paalala ng iyong mga akawnt ng detalye para sa {{SITENAME}}\n($4). Ang sumusunod na pangtagagamit na {{PLURAL:$3|akawnt ay|mga akawnt ay}} may kaugnayan sa tirahang ito ng e-liham:\n\n$2\n\n{{PLURAL:$3|Ang pansamantalang hudyat na ito|Ang pansamantalang mga hudyat na ito}} mawawalan ng bias sa loob ng {{PLURAL:$5|isang araw|$5 mga araw}}.\nDapat kang lumagda at pumili ng isang hudyat ngayon. Kung ibang tao ang gumawa ng kahilingang ito, o kung naalala mo na ang iyong orihinal na hudyat, at hindi mo na nais palitan pa ito, maaari mong huwag nang pansinin ang mensaheng ito at magpatuloy sa paggamit ng iyong lumang hudyat.",
        "passwordreset-emailelement": "Pangalan ng tagagamit: \n$1\n\nPansamantalang password: \n$2",
        "passwordreset-emailsentemail": "Naipadala na ang isang e-liham na pampaalala.",
-       "passwordreset-emailsent-capture": "Naipadala na ang isang e-liham na paalala, na ipinapakita sa ibaba.",
-       "passwordreset-emailerror-capture": "Nalikha na ang isang e-liham na paalala, na ipinapakita sa ibaba, subalit nabigo ang pagpapadala sa tagagamit: $1",
        "changeemail": "Baguhin ang direksiyong e-liham",
        "changeemail-header": "Baguhin ang email address ng account",
        "changeemail-no-info": "Kailangan mong lumagda upang tuwirang mapuntahan ang pahinang ito.",
        "undo-failure": "Hindi matanggal ang pagbabago dahil sa magkakasalungat na panggitnang mga pagbabago.",
        "undo-norev": "Hindi matanggal ang pagbabago dahil hindi ito umiiral o nabura na.",
        "undo-summary": "Tanggalin ang pagbabagong $1 ni [[Special:Contributions/$2|$2]] ([[User talk:$2|Usapan]])",
-       "cantcreateaccounttitle": "Hindi malikha ang account",
        "cantcreateaccount-text": "Hinarang ni [[User:$3|$3]] ang paglikha ng acciybt mula sa IP address ('''$1''') na ito.\n\nAng dahilang ibinigay ni $3 ay ''$2''",
        "viewpagelogs": "Tingnan ang mga pagtatala para sa pahinang ito",
        "nohistory": "Walang kasaysayan ng pagbabago para sa pahinang ito.",
        "apisandbox-results": "Kinalabasan",
        "apisandbox-request-url-label": "Hilingin ang URL:",
        "apisandbox-request-time": "Oras ng paghiling: $1",
+       "apisandbox-continue": "Ipagpatuloy",
+       "apisandbox-continue-clear": "Burado",
        "booksources": "Mga mapagkukunang aklat",
        "booksources-search-legend": "Maghanap ng mapagkukunang aklat",
        "booksources-isbn": "ISBN:",
        "activeusers-intro": "Isa itong talaan ng mga tagagamit na nagkaroon ng ilang uri ng galaw sa loob ng huling $1 {{PLURAL:$1|araw|mga araw}}.",
        "activeusers-count": "$1 {{PLURAL:$1|pagbabago|mga pagbabago}} sa loob ng huling {{PLURAL:$3|araw|$3 mga araw}}",
        "activeusers-from": "Ipakita ang mga tagagamit simula sa:",
-       "activeusers-hidebots": "Itago ang mga bots",
-       "activeusers-hidesysops": "Itago ang mga tagapangasiwa",
        "activeusers-noresult": "Walang natagpuang mga tagagamit.",
        "listgrouprights": "Mga uri ng tagagamit",
        "listgrouprights-summary": "Ang sumusunod ay isang talaan ng mga pangkat ng tagagamit na binigyang kahulugang sa wiking ito, kasama ang kanilang mga kaugnay na mga karapatan.\nMaaaring may mga [[{{MediaWiki:Listgrouprights-helppage}}|karagdagang kabatiran]] tungkol sa bawat isang mga karapatan sa [[{{MediaWiki:Listgrouprights-helppage}}]].",
        "tags-create-submit": "Lumikha/Lumalang",
        "tags-activate-reason": "Dahilan:",
        "tags-deactivate-reason": "Dahilan:",
+       "tags-apply-blocked": "Hindi pwedeng i-apply ang mga tarheta (kasama ng pagbago) habang ikaw ay sinupalpal.",
        "comparepages": "Paghambingin ang mga pahina",
        "compare-page1": "Pahina 1",
        "compare-page2": "Pahina 2",
        "htmlform-reset": "Bawiin ang mga pagbabago",
        "htmlform-selectorother-other": "Iba pa",
        "htmlform-title-not-exists": "Hindi nairal ang $1.",
-       "sqlite-has-fts": "$1 na may suportang paghahanap ng buong teksto",
-       "sqlite-no-fts": "$1 na walang suporta ng paghahanap ng buong teksto",
        "logentry-delete-delete": "Binura ni $1 ang pahinang $3",
        "logentry-delete-restore": "Ibinalik ni $1 ang pahinang $3",
        "logentry-delete-event": "Binago ni $1 ang antas ng pagkanatatanaw ng {{PLURAL:$5|isang pangyayari sa talaan|$5 mga pangyayari sa talaan}} sa $3: $4",
        "feedback-external-bug-report-button": "Mag-habla ng teknikal na gawain",
        "feedback-dialog-title": "I-sumite ang katugunan",
        "feedback-dialog-intro": "Maaari mo nang gamitin ang madaling pormularyo na nasa ibaba upang i-sumite ang iyong katugunan. Madadagdag ang iyong komento sa pahinang $1, kasama ang iyong ngalan-tagagamit.",
-       "feedback-error-title": "Kamalian",
        "feedback-error1": "Kamalian: Hindi nakikilalang kinalabasan mula sa API",
        "feedback-error2": "Kamalian: Nabigo ang pagpatnugot",
        "feedback-error3": "Kamalian: Walang tugon mula sa API",
        "special-characters-group-khmer": "Khmer",
        "mw-widgets-dateinput-placeholder-day": "TTTT-BB-AA",
        "mw-widgets-dateinput-placeholder-month": "TTTT-BB",
-       "api-error-blacklisted": "Paki pumili ng isang naiibang mapaglarawang pamagat.",
-       "randomrootpage": "Alin mang pinag-ugatang/pinagmulang pahina"
+       "randomrootpage": "Alin mang pinag-ugatang/pinagmulang pahina",
+       "edit-error-long": "Mga kamalian:"
 }
index 6a78e81..b9f1bc2 100644 (file)
        "yourname": "Иштирокәкә ном:",
        "yourpassword": "Парол:",
        "yourpasswordagain": "Пароли сәнибәтон гырдә карде:",
-       "remembermypassword": "Мыни ым компутерәдә јодәдә огәт (максимум $1 {{PLURAL:$1|руж|руж}})",
        "login": "Ыштәни едаштеј",
        "nav-login-createaccount": "Ыштәни едаштеј / ыштәни ғејд кардовнијеј",
        "userlogin": "Ыштәни едаштеј / ыштәни ғејд кардовнијеј",
index dd64e03..812e34d 100644 (file)
        "yourname": "Hingoa ʻetita",
        "yourpassword": "Leatapu",
        "yourpasswordagain": "Toe ʻai leatapu",
-       "remembermypassword": "Manatuʻi au (for a maximum of $1 {{PLURAL:$1|day|days}})",
        "yourdomainname": "ho ngāueʻanga",
        "login": "Kau ki ai",
        "nav-login-createaccount": "Kau ki ai",
        "templatesusedpreview": "Ngaahi sīpinga ʻoku ngāueʻaki he vakaí ni:",
        "templatesusedsection": "Ngaahi sīpinga ʻoku ngāueʻaki he kongá ni:",
        "nocreatetext": "Naʻe fakangatangata ʻe he tuʻuʻangá ni ʻa e lava ke fakatupu ha peesi foʻou. ʻOku ke lava ke foki pea fatu ha peesi tuʻu, pe [[Special:UserLogin|kau-ki-ai, pe fakatupu ha tohi-kau-ki-ai]].",
-       "cantcreateaccounttitle": "ʻOku ʻikai lava fakatupu e tohi kau-ki-ai",
        "viewpagelogs": "Vakai ki he ngaahi tohinoa ʻo e pēsí ni",
        "nohistory": "ʻOku ʻikai ʻi ai ha hisitōlia fatu maʻa e kupú ni.",
        "currentrev": "Paaki taka",
index 0e572ce..abde066 100644 (file)
        "viewsource": "Lukim as tok",
        "yourname": "Yusanem:",
        "yourpassword": "Paswot:",
-       "remembermypassword": "Holim yusanem bilong mi long dispela komputa (holim pas longpela taim $1 {{PLURAL:$1|de|de}})",
        "login": "Log in",
        "userloginnocreate": "Log in",
        "logout": "Logaut",
index 80aca5a..cbf3596 100644 (file)
@@ -95,7 +95,7 @@
        "tog-hideminor": "Son değişiklikler sayfasında küçük değişiklikleri gizle",
        "tog-hidepatrolled": "Son değişikliklerde devriye görmüş değişiklikleri gizle",
        "tog-newpageshidepatrolled": "Yeni sayfalar listesinde, devriye görmüş sayfaları gizle",
-       "tog-hidecategorization": "Sayfa kategorilendirmesni gizle",
+       "tog-hidecategorization": "Sayfa kategorilendirmesini gizle",
        "tog-extendwatchlist": "İzleme listesini sadece en son değil, tüm değişiklikleri göstermek üzere genişlet",
        "tog-usenewrc": "Son değişiklikler sayfasındaki ve izleme listesindeki değişiklikleri sayfalara gruplandır",
        "tog-numberheadings": "Başlıkları otomatik numaralandır",
        "tog-enotifminoredits": "Sayfalardaki ve dosyalardaki küçük değişikliklerde de bana e-posta gönder",
        "tog-enotifrevealaddr": "Bildirim postalarında benim eposta adresimi açıkça göster",
        "tog-shownumberswatching": "İzleyen kullanıcı sayısını göster",
-       "tog-oldsig": "Mevcut imza:",
+       "tog-oldsig": "Mevcut imzanız:",
        "tog-fancysig": "İmzaya vikimetin muamelesi yap (otomatik bir bağlantı olmadan)",
        "tog-uselivepreview": "Canlı ön izlemeyi kullan",
        "tog-forceeditsummary": "Özeti boş bıraktığımda beni uyar",
        "tog-watchlistreloadautomatically": "Filtre değiştiğinde izleme listesini otomatik yenile (JavaScript gerekir)",
        "tog-watchlisthideanons": "İzleme listemde, anonim kullanıcılar tarafından yapılan değişiklikleri gizle",
        "tog-watchlisthidepatrolled": "İzleme listesinde, devriye görmüş değişiklikleri gizle",
-       "tog-watchlisthidecategorization": "Sayfa kategorilendirmesni gizle",
+       "tog-watchlisthidecategorization": "Sayfa kategorilendirmesini gizle",
        "tog-ccmeonemails": "Diğer kullanıcılara gönderdiğim e-postaların bir kopyasını bana da gönder",
        "tog-diffonly": "Sayfa içeriğini, sürüm farklarının altında gösterme",
        "tog-showhiddencats": "Gizli kategorileri göster",
        "tog-norollbackdiff": "Geri döndürme uygulandıktan sonra farkları gösterme",
        "tog-useeditwarning": "Yaptığım değişiklikleri kaydetmeden sayfayı kapatırken beni uyar",
-       "tog-prefershttps": "Oturum açarken her zaman güvenli bağlantı kullan",
+       "tog-prefershttps": "Oturum açarken her zaman güvenli bağlantı kullanın",
        "underline-always": "Daima",
        "underline-never": "Asla",
        "underline-default": "Tema ya da tarayıcı varsayılanı",
        "newwindow": "(yeni bir pencerede açılır)",
        "cancel": "İptal",
        "moredotdotdot": "Dahası...",
-       "morenotlisted": "Bu liste tam değildir.",
+       "morenotlisted": "Bu liste eksik olabilir.",
        "mypage": "Sayfa",
        "mytalk": "Mesaj",
        "anontalk": "Mesaj",
        "talk": "Tartışma",
        "views": "Görünümler",
        "toolbox": "Araçlar",
+       "tool-link-userrights": "{{GENDER:$1|Kullanıcı}} gruplarını değiştir",
+       "tool-link-emailuser": "Bu {{GENDER:$1|kullanıcıya}} e-posta gönder",
        "userpage": "Kullanıcı sayfasını görüntüle",
        "projectpage": "Proje sayfasını görüntüle",
        "imagepage": "Dosya sayfasını görüntüle",
        "databaseerror-query": "Sorgu: $1",
        "databaseerror-function": "Fonksiyon: $1",
        "databaseerror-error": "Hata: $1",
+       "transaction-duration-limit-exceeded": "Yüksek miktarda gecikme oluşacağından ve işlem süresi izin verilen $2 saniye sınırını aştığından ($1) bu işlem iptal edildi.\nEğer aynı anda birden fazla öge değiştiriyorsanız, bunun yerine küçük işlemler yapmayı deneyin.",
        "laggedslavemode": "<strong>Uyarı:</strong> Sayfa son güncellemeleri içermeyebilir.",
        "readonly": "Veritabanı koruma altına alındı",
        "enterlockreason": "Koruma için bir neden belirtin. Korumanın ne zaman kaldırılacağına dair tahmini bir tarih eklemeyi unutmayın.",
-       "readonlytext": "Veritabanı, muhtemelen olağan bakım/onarım çalışmaları sebebiyle, geçici olarak giriş ve değişiklik yapmaya kapatılmıştır. Çalışmaların ardından normale dönecektir.\n\nVeritabanını kilitleyen yöneticinin açıklaması şu şekilde: $1",
+       "readonlytext": "Veritabanı, muhtemelen olağan bakım/onarım çalışmaları sebebiyle, geçici olarak giriş ve değişiklik yapmaya kapatılmıştır. Çalışmaların ardından normale dönecektir.\n\nVeritabanını kilitleyen sistem yöneticisinin açıklaması şu şekilde: $1",
        "missing-article": "Veritabanında bulunması istenen \"$1\" $2 adlı sayfaya ait metin bulunamadı.\n\nBu durum, genellikle silinmiş bir sayfanın geçmiş bir sürümüne yönlendirilmekten kaynaklanır.\n\nEğer neden bu değilse yazılımda bir hata ile karşılaşmış olabilirsiniz.\nLütfen URL'yi not ederek bunu bir [[Special:ListUsers/sysop|hizmetliye]] iletin.",
        "missingarticle-rev": "(revizyon#: $1)",
        "missingarticle-diff": "(Fark: $1, $2)",
        "protectedinterface": "Bu sayfa yazılım için arayüz metni sağlamaktadır ve kötüye kullanımı önlemek için korumaya alınmıştır.\nBütün vikilere dair çeviri eklemek veya bunları değiştirmek için lütfen MediaWiki yerelleştirme projesi [https://translatewiki.net/ translatewiki.net]'i kullanın.",
        "editinginterface": "<strong>Uyarı:</strong> Yazılım için arayüz metni sağlayan bir sayfayı değiştiriyorsunuz.\nBu sayfada yapılacak değişiklikler diğer kullanıcıların vikilerindeki kullanıcı arayüzlerinin görünümünü de etkileyecektir.",
        "translateinterface": "Tüm vikilerde çeviri eklemek veya çevirileri değiştirmek için lütfen MediaWiki yerelleştirme projesini [https://translatewiki.net/] kullanın.",
-       "cascadeprotected": "Bu sayfa değişiklik yapılması engellenmiştir, çünkü  \"kademeli\" seçeneği aktif hale getirilerek koruma altına alınan {{PLURAL:$1|sayfada|sayfada}} kullanılmaktadır:\n$2",
+       "cascadeprotected": "Bu sayfa değişiklik yapılması engellenmiştir, çünkü  \"kademeli\" seçeneği aktif hale getirilerek koruma altına alınan {{PLURAL:$1|sayfada|sayfalarda}} kullanılmaktadır:\n$2",
        "namespaceprotected": "'''$1''' alandındaki sayfaları düzenlemeye izniniz bulunmamaktadır.",
        "customcssprotected": "Bu sayfayı değiştirmeye yetkiniz bulunmamaktadır, çünkü bu sayfa başka bir kullanıcının kişisel ayarlarını içermektedir.",
        "customjsprotected": "Bu Java Script sayfasını değiştirmeye yetkiniz bulunmamaktadır, çünkü bu sayfa başka bir kullanıcının kişisel ayarlarını içermektedir.",
        "mypreferencesprotected": "Tercihlerinizi düzenlemek için yetkiniz yok.",
        "ns-specialprotected": "{{ns:special}} alanadı içindeki sayfalar değiştirilemez.",
        "titleprotected": "[[User:$1|$1]] tarafından oluşturulması engellenmesi için bu sayfa koruma altına alınmıştır.\nVerilen sebep: <em>$2</em>.",
-       "filereadonlyerror": "\"$2\" dosya deposundaki \"$1\" dosyası salt okunur modda olduğundan dolayı değiştirmek için açılamıyor.\n\nKilitleyen hizmetlinin bu konudaki nedeni: \"$3\".",
+       "filereadonlyerror": "\"$2\" dosya deposundaki \"$1\" dosyası salt okunur modda olduğundan dolayı değiştirmek için açılamıyor.\n\nKilitleyen sistem yöneticisinin bu konudaki nedeni: \"$3\".",
        "invalidtitle-knownnamespace": "\"$2\" alan adı için \"$3\" metni geçersiz bir başlık",
        "invalidtitle-unknownnamespace": "Bilinmeyen $1 ad alanı sayısı ve geçersiz \"$2\" başlık",
        "exception-nologin": "Giriş yapılmamış",
        "createacct-yourpasswordagain-ph": "Parolayı yeniden girin",
        "userlogin-remembermypassword": "Oturumumu sürekli açık tut",
        "userlogin-signwithsecure": "Güvenli bağlantı kullanın",
+       "cannotlogin-title": "Şu an oturum açılamıyor",
+       "cannotlogin-text": "Oturum açmak mümkün değildir.",
        "cannotloginnow-title": "Şu an oturum açılamıyor",
        "cannotloginnow-text": "$1 kullanırken giriş yapmak mümkün değil.",
+       "cannotcreateaccount-title": "Hesap oluşturulamadı",
+       "cannotcreateaccount-text": "Doğrudan hesap oluşturma, bu wiki üzerinde etkin değil.",
        "yourdomainname": "Alan adınız:",
        "password-change-forbidden": "Bu vikide parolanızı değiştiremezsiniz.",
        "externaldberror": "Ya doğrulama veritabanı hatası var ya da kullanıcı hesabınızı güncellemeye yetkiniz yok.",
        "passwordreset-emailelement": "Kullanıcı adı: \n$1\n\nGeçici şifre: \n$2",
        "passwordreset-emailsentemail": "Eğer bu e-posta adresi hesabınızın bağlı olduğu adres ise, bir parola sıfırlama e-postası gönderilecektir.",
        "passwordreset-emailsentusername": "Eğer bu e-posta adresi hesabınızın bağlı olduğu adres ise, bir parola sıfırlama e-postası gönderilecektir.",
-       "passwordreset-invalideamil": "Geçersiz e-posta adresi",
+       "passwordreset-invalidemail": "Geçersiz e-posta adresi",
        "passwordreset-nodata": "Ne bir kullanıcı adı ne de bir e-posta adresi verildi.",
        "changeemail": "E-posta adresini değiştir veya çıkar",
        "changeemail-header": "E-posta adresinizi değiştirmek için bu formu doldurun. Eğer e-posta adresini hesabınızdan kaldırmak istiyorsanız formu gönderirken e-posta adresi bölümünü boş bırakın.",
        "upload-copy-upload-invalid-domain": "Kopya yüklemeler bu etki alanında mevcut değil.",
        "upload-dialog-title": "Dosya Yükle",
        "upload-dialog-button-cancel": "İptal",
+       "upload-dialog-button-back": "Geri",
        "upload-dialog-button-done": "Yapıldı",
        "upload-dialog-button-save": "Kaydet",
        "upload-dialog-button-upload": "Yükle",
        "apisandbox-retry": "Tekrar dene",
        "apisandbox-helpurls": "Yardım bağlantıları",
        "apisandbox-examples": "Örnekler",
+       "apisandbox-dynamic-parameters-add-label": "Parametre ekle:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Parametre adı",
        "apisandbox-results": "Sonuçlar",
        "apisandbox-request-url-label": "İstek URL:",
        "apisandbox-request-time": "İstek zamanı: $1",
+       "apisandbox-continue": "Devam et",
+       "apisandbox-continue-clear": "Temizle",
        "booksources": "Kaynak kitaplar",
        "booksources-search-legend": "Kitap kaynaklarını ara",
        "booksources-isbn": "ISBN:",
        "activeusers-intro": "Bu, son $1 {{PLURAL:$1|günde|günde}} bir çeşit etkinlik göstermiş kullanıcıların listesidir.",
        "activeusers-count": "Son {{PLURAL:$3|günde|$3 günde}} $1 {{PLURAL:$1|eylem|eylem}}",
        "activeusers-from": "Şununla başlayan kullanıcıları görüntüle:",
-       "activeusers-hidebots": "Botları gizle",
-       "activeusers-hidesysops": "Yöneticileri gizle",
        "activeusers-noresult": "Kullanıcı bulunamadı.",
        "listgrouprights": "Kullanıcı grubu hakları",
        "listgrouprights-summary": "Aşağıdaki bu vikide tanımlanan kullanıcı gruplarının, ilgili erişim haklarıyla birlikte listesidir.\nBireysel haklarla ilgili [[{{MediaWiki:Listgrouprights-helppage}}|daha fazla bilgi]] olabilir.",
        "wlnote": "$3 saat $4 itibariyle son {{PLURAL:$2|bir saatte|'''$2''' saatte}} yapılan {{PLURAL:$1|son değişiklik|son '''$1''' değişiklik}} aşağıdadır.",
        "wlshowlast": "Son $1 saati $2 günü göster",
        "watchlist-hide": "Gizle",
+       "watchlist-submit": "Göster",
        "wlshowtime": "Gösterilecek zaman aralığı:",
        "wlshowhideminor": "küçük değişiklikler",
        "wlshowhidebots": "botlar",
        "changecontentmodel-title-label": "Sayfa başlığı",
        "changecontentmodel-model-label": "Yeni içerik modeli",
        "changecontentmodel-reason-label": "Gerekçe:",
+       "changecontentmodel-submit": "Değiştir",
        "changecontentmodel-success-title": "İçerik modeli değiştirildi",
        "changecontentmodel-success-text": "İçerik türü [[:$1]] olarak değiştirildi.",
        "logentry-contentmodel-change-revertlink": "Eski haline döndür",
        "whatlinkshere-hidelinks": "Bağlantıları $1",
        "whatlinkshere-hideimages": "Dosya bağlantılarını $1",
        "whatlinkshere-filters": "Süzgeçler",
+       "whatlinkshere-submit": "Getir",
        "autoblockid": "Otomatik engelleme #$1",
        "block": "Kullanıcıyı engelle",
        "unblock": "Kullanıcının engelini kaldır",
        "pageinfo-article-id": "Sayfa ID",
        "pageinfo-language": "Sayfa içeriğinin dili",
        "pageinfo-content-model": "Sayfa içerik modeli",
+       "pageinfo-content-model-change": "değiştir",
        "pageinfo-robot-policy": "Robotlar tarafından endeksleniyor",
        "pageinfo-robot-index": "İzin verilmiş",
        "pageinfo-robot-noindex": "İzin verilmedi",
        "confirm-watch-top": "Bu sayfayı izleme listenize ekleyin",
        "confirm-unwatch-button": "TAMAM",
        "confirm-unwatch-top": "Bu sayfayı izleme listenizden çıkarın",
+       "confirm-rollback-button": "Tamam",
        "percent": "%$1",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← önceki sayfa",
        "htmlform-cloner-create": "Daha fazla ekle",
        "htmlform-cloner-delete": "Sil",
        "htmlform-cloner-required": "En az bir değer gereklidir.",
+       "htmlform-date-placeholder": "YYYY-AA-GG",
+       "htmlform-time-placeholder": "SS:DD:SS",
+       "htmlform-datetime-placeholder": "YYYY-AA-GG SS:DD:SS",
        "htmlform-title-not-creatable": "\"$1\"oluşturulabilir bir sayfa ismi değil.",
        "htmlform-title-not-exists": "$1 mevcut değil.",
        "htmlform-user-not-exists": "<strong>$1</strong> mevcut değil.",
        "feedback-external-bug-report-button": "Teknik hata raporu ilet",
        "feedback-dialog-title": "Geribildirim gönder",
        "feedback-dialog-intro": "Geribildirimde bulunmak için aşağıdaki basit formu kullanabilirsiniz. Yorumunuz kullanıcı adınızla beraber \"$1\" sayfasına eklenecektir.",
-       "feedback-error-title": "Hata",
        "feedback-error1": "Hata: Bilinmeyen API sonucu",
        "feedback-error2": "Hata: Düzenleme başarısız oldu",
        "feedback-error3": "Hata: API'den yanıt yok",
index 702c294..a32a979 100644 (file)
        "yourname": "Işme duHadomo:",
        "yourpassword": "Qliḍo:",
        "yourpasswordagain": "Naqla ḥreto kṭaw uQliḍo:",
-       "remembermypassword": "Dxar uQliḍayḍi buBrowser (buSowudo $1 {{PLURAL:$1|Yawmo|Yawme}})",
        "login": "3bar",
        "nav-login-createaccount": "3bar / Hway Hadomo",
        "userlogin": "3bar / Hway Hadomo",
index d41c469..6d971d5 100644 (file)
        "yourname": "Vito ra vutirhisi",
        "yourpassword": "Vito-mpfungulo:",
        "yourpasswordagain": "Thlela u hoxa ritompfungulo ra wena:",
-       "remembermypassword": "Tsundzuka ku nghena eka Khompuyuta leyi (kufikela eka $1 {{PLURAL:$1|siku|masiku}})",
        "login": "Pfula u nghena",
        "nav-login-createaccount": "Pfula unghena / Tumbuluxa akhawunti",
        "userlogin": "Pfula unghena / Tumbuluxa akhawunti",
index 5009a53..5ea66b8 100644 (file)
@@ -25,7 +25,8 @@
                        "Macofe",
                        "Selimcan",
                        "Исмаил Садуев",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Irus"
                ]
        },
        "tog-underline": "Сылтамаларның астына сызу:",
        "password-change-forbidden": "Сез бу викидә серсүзне үзгәртә алмыйсыз.",
        "externaldberror": "Тышкы мәгълүмат базасы ярдәмендә аутентификация үткәндә хата чыкты, яисә тышкы хисап язмагызга үзгәрешләр кертү хокукыгыз юк.",
        "login": "Керү",
+       "login-security": "Шәхесегезне раслагыз",
        "nav-login-createaccount": "Керү / теркәлү",
        "userlogin": "Керү / теркәлү",
        "userloginnocreate": "Керү",
        "minoredit": "Бу кече үзгәртү",
        "watchthis": "Бу битне күзәтү",
        "savearticle": "Битне саклау",
+       "savechanges": "Үзгәртүләрне саклау",
+       "publishpage": "Бит ясау",
+       "publishchanges": "Битне бастыру",
        "preview": "Алдан карау",
        "showpreview": "Алдан карау",
        "showdiff": "Кертелгән үзгәртүләр",
        "searchprofile-advanced-tooltip": "Бирелгән исемнәр мәйданында эзләү",
        "search-result-size": "$1 ({{PLURAL:$2|$2 сүз}})",
        "search-result-category-size": "$1 {{PLURAL:$1|әгъза}} ($2 {{PLURAL:$2|астөркем}}, $3 {{PLURAL:$3|файл}})",
-       "search-redirect": "(юнәлтү $1)",
+       "search-redirect": "($1 битеннән юнәлтү)",
        "search-section": "($1 бүлеге)",
        "search-category": "($1 категориясе)",
        "search-file-match": "(файл эчтәлеге белән туры килә)",
        "listusers-noresult": "Кулланучыларны табылмады.",
        "listusers-blocked": "(тыелган)",
        "activeusers": "Актив кулланучылар исемлеге",
-       "activeusers-hidebots": "Ботларны яшер",
-       "activeusers-hidesysops": "Идарәчеләрне яшер",
        "activeusers-noresult": "Кулланучылар табылмады.",
        "listgrouprights": "Кулланучы төркемнәренең хокуклары",
        "listgrouprights-key": "Легенда:\n* <span class=\"listgrouprights-granted\">Бирелгән хокуклар</span>\n* <span class=\"listgrouprights-revoked\">Алынган хокуклар</span>",
        "blocklogpage": "Тыю көндәлеге",
        "blocklogentry": "[[$1]] $2 вакытка тыелды $3",
        "unblocklogentry": "$1 кулланучысының тыелу вакыты бетте",
+       "block-log-flags-anononly": "аноним кулланучылар гына",
        "block-log-flags-nocreate": "яңа хисап язмасы теркәү тыелган",
        "block-log-flags-noemail": "хат җибәрү тыелган",
        "block-log-flags-hiddenname": "кулланучының исеме яшерелгән",
        "exif-copyrighted": "Автор хокуклары халәте:",
        "exif-copyrightowner": "Автор хокуклары иясе",
        "exif-usageterms": "Куллану шартлары",
-       "exif-orientation-1": "Ð\9dоÑ\80малÑ\8c",
+       "exif-orientation-1": "Ð\93адÓ\99Ñ\82и",
        "exif-orientation-3": "180° ка борылган",
        "exif-componentsconfiguration-0": "юк",
        "exif-exposureprogram-0": "Билгесез",
        "feedback-bugornote": "Әгәр дә сез техник проблеманы җентекләп тасвирларга әзер икәнсез, зинһар өчен, [$1 хата турында хәбәр итегез].\nБашка очракта сез түбәндәге гади форманы куллана аласыз. Сезнең шәрехләмә \"[$3 $2]\" сәхифәсенә сезнең кулланучы исеме һәм сез кулланган браузер исеме белән бергә өстәләчәк.",
        "feedback-cancel": "Баш тарту",
        "feedback-close": "Әзер",
-       "feedback-error-title": "Хата",
        "feedback-error1": "Хата. APIдан билгесез нәтиҗә",
        "feedback-error2": "Хата: төзәтү уңышсыз килеп чыкты",
        "feedback-error3": "Хата: APIдан җавап юк.",
        "feedback-submit": "Җибәрү",
        "feedback-thanks": "Рәхмәт! Сезнең фикер \"[$2 $1]\" сәхифәсенә куелды.",
        "feedback-thanks-title": "Рәхмәт!",
-       "searchsuggest-search": "Эзләү",
+       "searchsuggest-search": "{{SITENAME}} эчендә эзләү",
        "searchsuggest-containing": "эчтәлек...",
        "api-error-badaccess-groups": "Сезгә бу викигә файллар өстәү рөхсәт ителмәгән",
        "api-error-badtoken": "Эчке хата: дөрес булмаган токен.",
index 3b5ff02..8e77204 100644 (file)
        "yourpasswordagain": "Sersüzne qabat kertü:",
        "createacct-yourpasswordagain": "Sersüzegezne raslağız",
        "createacct-yourpasswordagain-ph": "Sersüzne yañadan kertegez",
-       "remembermypassword": "Xisap yazmamnı bu brauzerda saqlansın (iñ küp $1 {{PLURAL:$1|kön|kön|kön}}gä qädär)",
        "yourdomainname": "Sezneñ domenığız:",
        "externaldberror": "Tışqı mäğlümat bazası yärdämendä awtentifikatsiä ütkändä xata çıqtı, yäisä tışqı xisap yazmağızğa üzgäreşlär kertü xoquqığız yuq.",
        "login": "Kerü",
        "undo-failure": "Aralıqtağı üzgärtülär turı kilmäw säbäple, üzgärtüdän baş tartıp bulmıy.",
        "undo-norev": "Üzgärtü yuq yäisä ul beterelgän, şuña annan baş tartıp bulmıy.",
        "undo-summary": "[[Special:Contributions/$2|$2]] qullanuçısınıñ ([[User talk:$2|bäxäs]]) $1 üzgärtüennän baş tartu",
-       "cantcreateaccounttitle": "Xisap yazmasın tözep bulmıy",
        "cantcreateaccount-text": "Bu IP adresınnan (<b>$1</b>) xisap yazmaları tözü tıyıla. Tıyuçı: [[User:$3|$3]].\n\n$3 kürsätkän säbäp: ''$2''",
        "viewpagelogs": "Bu bitneñ köndäleklären qaraw",
        "nohistory": "Bu bitneñ üzgärtülär tarixı yuq.",
        "listusers-noresult": "Qullanuçılarnı tabılmadı.",
        "listusers-blocked": "(tıyılğan)",
        "activeusers": "Aktiv qullanuçılar isemlege",
-       "activeusers-hidebots": "Botlarnı yäşer",
-       "activeusers-hidesysops": "İdaräçelärne yäşer",
        "activeusers-noresult": "Qullanuçılar tabılmadı.",
        "listgrouprights": "Qullanuçı törkemnäreneñ xoquqları",
        "listgrouprights-group": "Törkem",
        "feedback-back": "Kire qaytu",
        "feedback-cancel": "Baş tartu",
        "feedback-close": "Yasaldı",
-       "feedback-error-title": "Xata",
        "feedback-message": "Xäbär:",
        "feedback-subject": "Tema:",
        "feedback-submit": "Cibärü",
index d2a098f..bac27db 100644 (file)
        "about": "Дугайында",
        "article": "Допчу арын",
        "newwindow": "(чаа көзенекке)",
-       "cancel": "ЫнÑ\87анмаÑ\81",
+       "cancel": "Ð\9eйÑ\82алал",
        "moredotdotdot": "Артык...",
        "mypage": "Арын",
        "mytalk": "Чугаа",
        "yourpassword": "Чажыт сөс",
        "userlogin-yourpassword": "Пароль",
        "yourpasswordagain": "Чажыт сөзүңерни катап бижиңер:",
-       "remembermypassword": "Мени бо компьютерде сактып алыры ($1 {{PLURAL:$1|1=хүн|хүн}}ге чедир)",
        "login": "Кирери",
        "nav-login-createaccount": "Кирери / бүрүткел бижикти чогаадыры",
        "userlogin": "Кирери / бүрүткел бижикти чогаадыры",
        "minoredit": "Бо эдилге бичии-дир",
        "watchthis": "Бо арынны хайгаараар",
        "savearticle": "Арынны шыгжаар",
+       "savechanges": "Өскертилгени шыгжаар",
        "preview": "Чижеглей көөрү",
        "showpreview": "Хынап көр",
-       "showdiff": "Кииртинген эдилгелер",
+       "showdiff": "Өскертилгени көргүзер",
        "anoneditwarning": "<strong> Кичээңгейлиг! </strong> Сайтта бүрүткеттинмээн-дир силер. Кандыг-даа бол эдилгелер киирер болзуңарза, IP-адрезиңер хөйге көскү болур. Сайтче <strong>[$1 кире бээр азы]</strong> азы <strong>[$2 бүрүткеттинип алыр] болзуңарза, эдилгелер силерниң адыңар-биле холбаалыг апаар, силерге өске-даа эптиг аргаларлыг тыптып кээр.",
        "missingcommenttext": "Тайылбырни адаанда чогаадыңар.",
        "summary-preview": "Түңнелдү чижеглей көөрү:",
        "editusergroup": "Ажыглакчының бөлгүмнерни өскертири",
        "editinguser": "Changing user rights of user '''[[User:$1|$1]]''' ([[User talk:$1|{{int:talkpagelinktext}}]]{{int:pipe-separator}}[[Special:Contributions/$1|{{int:contribslink}}]])",
        "userrights-editusergroup": "Ажыглакчының бөлгүмнерни өскертири",
-       "saveusergroups": "Ажыглакчының бөлгүмнерни шыгжаары",
+       "saveusergroups": "{{GENDER:$1|Ажыглакчының|Ажыглакчының}} бөлгүмнерин шыгжаар",
        "userrights-reason": "Чылдагаан:",
        "group": "Бөлгүм:",
        "group-user": "Ажыглакчылар",
        "rcshowhideminor-hide": "чажырар",
        "rcshowhidebots": "Роботтарны $1",
        "rcshowhidebots-show": "Көргүзер",
+       "rcshowhidebots-hide": "Чажырар",
        "rcshowhideliu": "бүрүткеттинген киржикчилер $1",
        "rcshowhideliu-show": "көргүзер",
        "rcshowhideliu-hide": "Чажырар",
        "linksearch-ok": "Дилээри",
        "linksearch-line": "$2-де бижиттинген $1 деп тускай айтыг",
        "listusers-submit": "Көргүзери",
-       "activeusers-hidebots": "Роботтарны чажырары",
-       "activeusers-hidesysops": "Эргелекчыларны чажырары",
        "listgrouprights-group": "Бөлүк",
        "listgrouprights-members": "(кежигүннүң даңзызы)",
        "emailuser": "Бо ажыглакчыга э-чагааны чорудаары",
        "feedback-cancel": "Соксаары",
        "feedback-message": "Чагаа:",
        "feedback-subject": "Кол сөс:",
-       "searchsuggest-search": "Дилээр",
+       "searchsuggest-search": "{{SITENAME}} иштинден дилээр",
        "duration-seconds": "$1 {{PLURAL:$1|секунда|секунда}}",
        "duration-minutes": "$1 {{PLURAL:$1|минут|минут}}",
        "duration-hours": "$1 {{PLURAL:$1|шак|шак}}",
index 7bff7f2..0f19d36 100644 (file)
@@ -6,26 +6,46 @@
                        "Udmwiki",
                        "ОйЛ",
                        "לערי ריינהארט",
-                       "TMg"
+                       "TMg",
+                       "AlnashPiyash2",
+                       "Irus",
+                       "Shklyaev",
+                       "Wadorgurt"
                ]
        },
-       "tog-underline": "Линкъёс ултӥз гожен сызоно",
-       "tog-hideminor": "Берпуметӥ тупатонъёслэн списоксэс ичи воштонъёстэк возьматыны",
-       "tog-hidepatrolled": "Берпуметӥ тупатонъёслэн списоксэс партрулировать каремын воштонъёстэк возьматыны",
-       "tog-newpageshidepatrolled": "Выль бамъёслэн списоксэс партрулировать каремын бамъёстэк возьматыны",
+       "tog-underline": "Чӧлсконъёсыз ултӥз гожен сызоно",
+       "tog-hideminor": "Выль тупатонъёслэн списоксэс ичи воштонъёстэк возьматыны",
+       "tog-hidepatrolled": "Выль тупатонъёслэн списоксэс эскерем воштонъёстэк возьматыны",
+       "tog-newpageshidepatrolled": "Выль бамъёслэн списоксэс эскерем бамъёстэк возьматыны",
+       "tog-hidecategorization": "Бамъёслэсь категоризацизэс ватыны",
        "tog-extendwatchlist": "Чаклан списокын вань тупатонъёсты возьматыны (озьытэк берпуметӥоссэс гинэ)",
        "tog-usenewrc": "Выль тупатонъёслэсь списоксэс умояллям сямен возьматыны (JavsScript кулэ)",
        "tog-numberheadings": "Заголовокъёсты автоматически нумеровать карыны",
-       "tog-showtoolbar": "Тупатон тӥрлыкъёслэн панельзэс возьматыны (JavaScript кулэ)",
+       "tog-showtoolbar": "Тупатон тӥрлыкъёслэн панельзэс возьматыны",
        "tog-editondblclick": "Бамъёсты шырлэсь зӥбонзэ кык пол зӥбыса тупатыны (JavaScript кулэ)",
        "tog-editsectiononrightclick": "Cекциолэсь заголовок вылазы шырлэн бур кнопкаеныз зӥбыса тупатонзэс лэзьыны (JavaScript кулэ)",
        "tog-watchcreations": "Мынэсьтым кылдытэм бамъёсме но ӝуткам файлъёсме чаклан списокам пыртыны",
        "tog-watchdefault": "Мынэсьтым тупатэм бамъёсме но файлъёсме чаклан списокам пыртыны",
        "tog-watchmoves": "Мынэсьтым мукет интые выжтэм бамъёсме но файлъёсме чаклан списокам пыртыны",
        "tog-watchdeletion": "Мынэсьтым ӵушыса быдтэм бамъёсме но файлъёсме чаклан списоке пыртыны",
+       "tog-watchuploads": "Мынам загрузить карем файлъёсме чаклан списоке пыртыны",
+       "tog-watchrollback": "Чаклан списоке пыртыны бамъёсыз, кудъёсаз мон откат лэсьтӥ",
        "tog-minordefault": "Вань воштонъёсты «ичи воштон» пусэн пусйыны",
        "tog-previewontop": "Утён азьвыл учконлэсь укнозэ тупатон укнолэсь азьвылгес возьматыны",
-       "tog-previewonfirst": "Бам нырысьсэ утиськыкуз уётн азьвыл учконэз возьматыны",
+       "tog-previewonfirst": "Тупатыны кутскыку возьматыны предпросмотрез",
+       "tog-enotifwatchlistpages": "Чаклан списокысь бамъёсыз но файлъёсыз тупатэм сярысь ивортыны электронной почта пыр",
+       "tog-enotifusertalkpages": "Вераськон бамез тупатон сярысь ивортыны электронной почта пыр",
+       "tog-enotifminoredits": "Ивортыны соку но, куке бамын яке файлын ичи воштон лэсьтэмын",
+       "tog-enotifrevealaddr": "Мынэсьтым почта адресме возьматыны ивортӥсь сообщениосын",
+       "tog-shownumberswatching": "Возьматыны викиавторъёслэсь лыдзэс, кудъёсыз бамез чаклан списоке пыртӥзы",
+       "tog-fancysig": "Подписьлэн аслам вики-разметкае (автоматической ӵӧлсконтэк)",
+       "tog-watchlisthideown": "Мынэсьтым тупатонъёсме чаклан списокысь ватыны",
+       "tog-watchlisthidebots": "Чаклан списокысь ватоно ботъёслэсь тупатэмзэс",
+       "tog-watchlisthideminor": "Чаклан списокысь ватоно ичи воштонъёсыз",
+       "tog-watchlisthideliu": "Авторизированной викиавторъёслэсь тупатэмъёссэс чаклан списокысь ватыны",
+       "tog-watchlisthidepatrolled": "Эскерем тупатонъёсыз чаклан списокысь ватыны",
+       "tog-watchlisthidecategorization": "Бамъёслэсь категоризацизэс ватыны",
+       "tog-showhiddencats": "Возьматоно ватэм категориосыз",
        "underline-always": "Котьку",
        "underline-never": "Ноку",
        "underline-default": "Браузерлэсь настройкаоссэ уже кутоно",
@@ -71,7 +91,7 @@
        "september-gen": "куарусёнэ",
        "october-gen": "коньывуонэ",
        "november-gen": "шуркынмонэ",
-       "december-gen": "толсурэ",
+       "december-gen": "толсуре",
        "jan": "тшт",
        "feb": "тпт",
        "mar": "южт",
        "oct": "квт",
        "nov": "шкт",
        "dec": "тст",
+       "january-date": "Толшор $1",
+       "february-date": "Тулыспал $1",
+       "march-date": "Южтолэзь $1",
+       "april-date": "Ожтолэзь $1",
+       "may-date": "Куартолэзь $1",
+       "june-date": "Инвожо $1",
+       "july-date": "Пӧсьтолэзь $1",
+       "august-date": "Гудырикошкон $1",
+       "september-date": "Куарусён $1",
+       "october-date": "Коньывуон $1",
+       "november-date": "Шуркынмон $1",
+       "december-date": "Толсур $1",
        "pagecategories": "{{PLURAL:$1|1=Категория|Категориос}}",
        "category_header": "«$1» категориысь бамъёс",
        "subcategories": "Подкатегориос",
        "category-empty": "''Та категориын али бамъёс но, файлъёс но ӧвӧл.''",
        "hidden-categories": "{{PLURAL:$1|1=Ватэм категория|Ватэм категориос}}",
        "hidden-category-category": "Ватэм категориос",
-       "category-subcat-count": "{{PLURAL:$2|1=Со категориын одӥг подкатегория гинэ.|Возьматэмын $1 подкатегория $2 пӧлысь.}}",
-       "category-subcat-count-limited": "Со категориын $1 подкатегория.",
-       "category-article-count": "{{PLURAL:$2|1=Со категориын одӥг бам гинэ.|Возьматэмын $1 бам $2 пӧлысь.}}",
-       "category-article-count-limited": "Со категориын $1 бам.",
-       "category-file-count": "{{PLURAL:$2|1=Со категориын одӥг файл гинэ.|Возьматэмын $1 файл $2 пӧлысь.}}",
-       "category-file-count-limited": "Со категориын $1 файл.",
+       "category-subcat-count": "{{PLURAL:$2|1=Со категориын одӥг подкатегория гинэ.|Возьматэмын $1 {{PLURAL:$1|подкатегория|подкатегориос}} $2 пӧлысь.}}",
+       "category-subcat-count-limited": "Со категориын {{PLURAL:$1|$1 подкатегория}}.",
+       "category-article-count": "{{PLURAL:$2|1=Со категориын одӥг бам гинэ.|Возьматэмын {{PLURAL:$1|$1 бам}} $2 пӧлысь.}}",
+       "category-article-count-limited": "Со категориын {{PLURAL:$1|$1 бам}}.",
+       "category-file-count": "{{PLURAL:$2|1=Со категориын одӥг файл гинэ.|Возьматэмын {{PLURAL:$1|$1 файл}} $2 пӧлысь.}}",
+       "category-file-count-limited": "Со категориын {{PLURAL:$1|$1 файл}}.",
        "listingcontinuesabbrev": "азьлань",
        "index-category": "Индексировать кароно бамъёс",
        "noindex-category": "Индексировать каронтэм бамъёс",
        "about": "Та сярысь",
        "article": "Статья",
-       "mypage": "Ас бам",
+       "newwindow": "(усьтӥськоз выль укноын)",
+       "cancel": "Берытсконо",
+       "mypage": "Бам",
        "mytalk": "Викиавтор сярысь вераськон",
-       "anontalk": "Со IP-адрес сярысь вераськон",
+       "anontalk": "Сярысь вераськон",
        "navigation": "Навигация",
+       "and": "&#32;но",
+       "qbfind": "Утчан",
+       "qbbrowse": "Учкыны",
+       "qbedit": "Тупатыны",
        "qbpageoptions": "Бамлэн настройкаосыз",
        "faq": "Юан-веран",
        "faqpage": "Project:Юан-веран",
+       "variants": "Вариантъёс",
+       "navigation-heading": "Навигация",
        "errorpagetitle": "Янгыш",
+       "returnto": "Берыктон борды бам $1.",
        "tagline": "{{SITENAME}}-ысь материал",
        "help": "Валэктонъёс",
        "search": "Утчан",
        "searchbutton": "Утчано",
+       "go": "Мыноно",
        "searcharticle": "Мыноно",
        "history": "Бамлэн историез",
        "history_short": "история",
+       "updatedmarker": "воштӥськемын мынам берпуметӥ пыраме бере",
        "printableversion": "Печатламон версия",
        "permalink": "Ӵапак та версиезлы линк",
        "print": "Печатлано",
+       "view": "Учкон",
+       "view-foreign": "$1 сайтын учконы",
        "edit": "тупатыны",
+       "create": "Кылдытоно",
+       "editthispage": "Та бамез тупатыны",
+       "create-this-page": "Та бамез кылдытыны",
        "delete": "Быдтыны",
+       "deletethispage": "Та бамез быдтыны",
+       "undeletethispage": "Та бамез быдтыны",
        "protect": "Утьыны",
+       "protect_change": "воштыны",
+       "protectthispage": "Та бамез утьыны",
+       "unprotect": "Утемез воштыны",
+       "unprotectthispage": "Та бамлэсь утемзэ воштыны",
+       "newpage": "Выль бам",
+       "talkpage": "Та бам сярысь вераськыны",
        "talkpagelinktext": "Вераськон",
+       "specialpage": "Ваньмыз панель",
+       "personaltools": "Нимаз тӥрлыке",
+       "articlepage": "Статьяез учкыны",
        "talk": "Вераськон",
+       "views": "Учконъёс",
        "toolbox": "Тӥрлык",
+       "userpage": "Викиавторлэсь бамзэ учкыны",
+       "templatepage": "Шаблонлэсь бамзэ учкыны",
+       "categorypage": "Категорилэсь бамзэ учкыны",
+       "viewtalkpage": "Вераськонэз учкыны",
+       "otherlanguages": "Мукет кылъёсын",
+       "redirectedfrom": "(Перенаправлять $1)",
+       "redirectpagesub": "Выжытон бам",
+       "redirectto": "Выжытон:",
+       "lastmodifiedat": "Та бамлэн берпуметӥ воштонэз: $2, $1.",
+       "protectedpage": "Утем бам",
+       "jumpto": "Выжон:",
        "jumptonavigation": "навигация",
        "jumptosearch": "утчан",
+       "pool-errorunknown": "Тодмотэм янгыш",
+       "aboutsite": "{{SITENAME}} сярысь",
+       "aboutpage": "Project:Описание",
+       "copyright": "Пуштрос $1 лицензияя луэ ярамон (мукетыз валэктэмын ӧвӧл дыръя).",
+       "copyrightpage": "{{ns:project}}:Автор праваос",
        "currentevents": "Выль иворъёс",
        "currentevents-url": "Project:Выль иворъёс",
+       "disclaimers": "Кыл кутыны пумит луон",
+       "disclaimerpage": "Project:Кыл кутыны пумит луон",
+       "edithelp": "Тупатонъя юрттэт",
+       "helppage-top-gethelp": "Юрттэт",
        "mainpage": "Кутскон бам",
        "mainpage-description": "Кутскон бам",
        "portal": "Сообщество",
        "portal-url": "Project:Портал сообщества",
+       "privacy": "Конфиденциальностья политика",
+       "privacypage": "Project:Конфиденциальностья политика",
+       "badaccess": "Янгышъёс юаське",
+       "badaccess-group0": "Быдэстэм ужез тонэ уг лэзьы, кин тонэ курозы.",
+       "badaccess-groups": "Ужъёсын но, кудаз тӥледыз курисько поциент {{PLURAL:$2|туркым|группа одӥг}}: $1.",
+       "versionrequired": "MediaWiki доллар кулэ версия $1",
+       "ok": "OK",
        "retrievedfrom": "«$1»-лэсь басьтэмын",
        "editsection": "тупатыны",
+       "editold": "тупатыны",
+       "viewsourceold": "кодзэ учкыны",
+       "editlink": "тупатыны",
+       "viewsourcelink": "кодзэ учкыны",
        "editsectionhint": "$1 секциез тупатоно",
+       "toc": "Пуштрос",
        "showtoc": "возьматоно",
        "hidetoc": "ватоно",
+       "collapsible-collapse": "ватоно",
+       "collapsible-expand": "возьматоно",
+       "confirmable-yes": "Мед",
+       "confirmable-no": "Ӧвӧл",
+       "viewdeleted": "Учкыны $1",
        "site-rss-feed": "$1 — RSS-лента",
        "site-atom-feed": "$1 — Atom-лента",
+       "page-atom-feed": "«$1» Атом-лента",
        "red-link-title": "$1 (со бам ӧвӧл на)",
+       "nstab-main": "Бам",
        "nstab-user": "Викиавтор",
+       "nstab-media": "Мультимедиа",
+       "nstab-special": "Ваньмыз панель",
+       "nstab-project": "Проект сярысь",
+       "nstab-image": "Файл",
        "nstab-mediawiki": "Ивортон",
+       "nstab-template": "Шаблон",
+       "nstab-help": "Валэктон",
+       "nstab-category": "Категория",
+       "mainpage-nstab": "Кутскон бам",
+       "error": "Янгыш",
+       "databaseerror-query": "Курон: $1",
+       "databaseerror-function": "Функция: $1",
+       "databaseerror-error": "Янгыш: $1",
        "viewsource": "Кодзэ учкыны",
-       "login": "Пырон",
+       "viewsource-title": "Кодзэ учкыны бам $1",
+       "actionthrottled": "Кекатыны ужъёс",
+       "actionthrottledtext": "Ужрадлэн ӟечлыкез злоупотребление-нюръяськон, та ужрад тӥ понна укыр трос поллы сюбегамын быдэстон вакчи дыр кусыпъёс, лимитъёс, та тӥляд но тубе.\nПожалуйста, кӧня ке минут ортчыса, нош ик утчасько.",
+       "protectedpagetext": "Та бамез утьыны луэ шуыса, яке мукет уже предотвращать редактировать карон.",
+       "viewsourcetext": "Та бамез учкыны быгатӥськоды тӥ но потон кӧчыро.",
+       "viewyourtext": "Ошмес но, тонэ учкыны быгатӥськоды кӧчырыны <strong>тон шонертон</strong> та бамам.",
+       "protectedinterface": "Та текст бам вайытиськом, та программаын вики интерфейсъёс, но дурбасьтэ, мед злоупотребление предотвращать.\nВика ватсаса, ваньзэ воштыны яке берыктон понна, пожалуйста, [https://translatewiki.net/ translatewiki.net] MediaWiki локализация проект.",
+       "editinginterface": "<strong>Юа:</strong> редактировать карыны бамзэ тон, программное обеспечение понна со интерфейс текстовые кылдытон понна кутыны.\nТа викилэн мукет бамаз луись туссэ воштон понна та интерфейсэз пользователь пользовательский педпал быгатонлыкъёссэс.",
+       "namespaceprotected": "Тон дорын редактировать карыны бам ӧвӧл юаське <кужмо>$1</strong> инты нимъёс.",
+       "exception-nologin": "Тон эн тусбуяськыны сӧзнэтэз",
+       "logouttext": "<strong>Тон али потэ.</strong>\n\nУчком, мар быгатозы бам куд-ог сямъёсты тӥледыз кадь возьматӥсько ке луысал, азьвыл сямен азьвыл системая пыртэмын, тон ӧд сузя, дыр кеш браузер.",
+       "welcomeuser": "Гажаса-а, $1!",
+       "welcomecreation-msg": "Тӥляд гожъямъёсты учётной кылдытэмын вал.\nТӥ быгатӥськоды воштэ {{SITENAME}} [[Special:Preferences|параметръёсты]] ке потэ тӥледлы.",
+       "yourname": "Пырон ним:",
+       "userlogin-yourname": "Пырон ним:",
+       "createacct-another-username-ph": "Учётной книга нимъёс пыртэмын",
+       "yourpassword": "Лушкемкыл:",
+       "userlogin-yourpassword": "Лушкемкыл",
+       "createacct-yourpasswordagain": "Пароль юнматэ",
+       "userlogin-remembermypassword": "Кылем сӧзнэтэз",
+       "cannotcreateaccount-title": "Уг быгатиськы гожъян кылдӥз учётной",
+       "yourdomainname": "Тӥ доменэн:",
+       "login": "Пырыны",
        "nav-login-createaccount": "Нимдэс вераны / Регистрациез ортчытыны",
-       "userlogin": "РегиÑ\81Ñ\82Ñ\80аÑ\86иез Ð¾Ñ\80Ñ\82Ñ\87Ñ\8bÑ\82Ñ\8bнÑ\8b Ñ\8fке Ð\92икипедие Ð¿Ñ\8bÑ\80ыны",
-       "userloginnocreate": "Пырон",
+       "userlogin": "Ð\9dимдÑ\8dÑ\81 Ð²ÐµÑ\80анÑ\8b / Ð ÐµÐ³Ð¸Ñ\81Ñ\82Ñ\80аÑ\86иез Ð¾Ñ\80Ñ\82Ñ\87Ñ\8bÑ\82ыны",
+       "userloginnocreate": "Пырыны",
        "logout": "Кошкыны",
-       "userlogout": "Кошкыны",
+       "userlogout": "Потыны",
+       "notloggedin": "Тон эн тусбуяськыны сӧзнэтэз",
+       "nologin": "Учётной книга ӧвӧл-а? $1.",
+       "nologinlink": "Выль вики-авторлэн регистрациез",
        "createaccount": "выль вики-авторлэн регистрациез",
+       "gotaccountlink": "Пырыны",
+       "userlogin-resetpassword-link": "Тӥлесьтыд парольдэс куштыны?",
+       "userlogin-helplink2": "Пыронъя юрттэт",
+       "createacct-emailrequired": "Электронной почталэн адресэз",
+       "createacct-emailoptional": "Электронной почтаезлэн адресэз (необязательное)",
+       "createaccountmail": "Адрес электронной почта огдырлы кутӥ вылын возьматэм образъёсыныз но соослэн случайной сгенерировать пароль ыстыны",
+       "createacct-submit": "Выль вики-авторлэн регистрациез",
+       "createacct-another-submit": "Выль вики-авторлэн регистрациез",
+       "loginerror": "Янгышъёс пырон",
+       "createacct-error": "Янгышъёс бордын учётной книга кылдытыны",
+       "createaccounterror": "Уг быгатиськы гожъян учётной кылдоз: $1",
+       "nocookiesnew": "Книга кылдытыны учётной пользователь вал, нош система тон уд пыры.\n{{SITENAME}} пользователь cookies пырон понна кутыны.\nDisconnect cookies тонэ дорам.\nПожалуйста, со гожтӥське, нош собере выльысь пырыны логин но пароль.",
+       "nocookieslogin": "{{SITENAME}} пользователь cookies пырон понна кутыны.\nDisconnect cookies тонэ дорам.\nПожалуйста, соосты утчано, выльысь гожтыны.",
+       "blocked-mailpassword": "Тон IP-адрес заблокировать-ысь редактировать карон. Злоупотребление предотвращение понна, та понна кутыны ӧз лэзиське пароль-ысь восстановление IP-адрес.",
+       "loginlanguagelabel": "Кыл: $1",
+       "pt-login": "Пырыны",
+       "pt-login-button": "Пырыны",
+       "pt-createaccount": "Выль вики-авторлэн регистрациез",
+       "pt-userlogout": "Потыны",
+       "oldpassword": "Вуж лушкемкыл:",
+       "newpassword": "Выль лушкемкыл:",
+       "passwordreset-username": "Пырон ним:",
+       "italic_sample": "Бекырес текст",
+       "italic_tip": "Бекырес текст",
+       "link_sample": "Чӧлсконлэн йыръянэз",
+       "link_tip": "Пуш чӧлскон",
+       "extlink_sample": "http://www.example.com чӧлсконлэн йыръянэз",
+       "extlink_tip": "Педпала чӧлскон (http:// префиксэз эн вунэтэ)",
+       "headline_sample": "Йыръян текст",
+       "headline_tip": "2-тӥ уровеньем йыръян",
+       "nowiki_sample": "Вики-пусъёсыз санэ басьтытэк кельтоно текстэз пуктэ татчы",
+       "nowiki_tip": "Вики-пусъёсыз лыдэ басьтоно ӧвӧл",
+       "image_tip": "Пыӵатэм файл",
+       "media_tip": "Файл чӧлскон",
+       "sig_tip": "Тӥляд гожтӥськонды но дыр пусъён",
+       "hr_tip": "Горизонтальной гож (эн пыртэ ӵем)",
        "summary": "Мар но малы тупатэмын? (вакчияк):",
        "minoredit": "Ичи воштон",
-       "noarticletext": "В настоящий момент текст на данной странице отсутствует.\nВы можете [[Special:Search/{{PAGENAME}}|найти упоминание данного названия]] на других страницах,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} найти соответствующие записи журналов],\nили '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} создать страницу с таким названием]'''</span>.",
+       "watchthis": "Та бамез чаклан списоке пыртыны",
+       "savearticle": "Бамез гожтоно",
+       "preview": "Бамез эскерон",
+       "showpreview": "Бамез эскерон",
+       "showdiff": "Пыртэм воштонъёс",
+       "blockedtitle": "Заблокировать пыриськисьёс",
+       "blockedtext": "<strong>Книгае яке учётной IP-адрес заблокирован.</strong>\n\nБлокировка администратор потӥз $1.\nВозьмалэ вуоно мугез: \"\"$2\"\".\n\n* Кутскон блокировка: $8\n* Блокировка ортчиз: $6\n* Блокировка меретъёсыз: $7\n\nБыгатӥськод-а тон герӟаськемын $1 яке мукет котькудӥныз [[{{MediaWiki:Grouppage-sysop}}|администраторъёс]], блокировка мед эскерозы.\nУчком, мар кутыны уг быгато функцизэс \"гожтэт\", ас ке [[Special:Preferences|настройка персональной]] зуркатӥсь яке электронной почтаезлэн адресэз эн чуртна уг корректный, яке гожтӥськод ке, гожтэт ыстон укшась блокировка алон.\nТон IP-адрес — $3, блокировка идентификаторлэн — $5.\nПожалуйста, аслэсьтым тодон-та вазиськонэз котьку возьмано.",
+       "autoblockedtext": "Тон IP-адрес, герӟет автоматически заблокирован а со, мар солэн кутыны луоно азьвыл кин ке но пырисьёс пӧлысь, заблокирован {{GENDER:$4|участник|куакеч}} $1. \nБлокировка возьмано луоз вуоно мугез:\n\n: \"$2\" - лы.\n\n* Кутскон блокировка: $8\n* Блокировка ортчиз: $6\n* Блокировка меретъёсыз: $7\n\nБыгатӥськод-а тон герӟаськемын $1 яке мукет котькудӥныз [[{{MediaWiki:Grouppage-sysop}}|администраторъёс]], блокировка мед эскерозы.\n\nУчком, мар кутыны уг быгато функцизэс \"гожтэт\", ас ке [[Special:Preferences|настройка персональной]] зуркатӥсь яке электронной почтаезлэн адресэз эн чуртна уг корректный, яке гожтӥськод ке, гожтэт ыстон укшась блокировка алон.\n\nТон IP-адрес — $3, блокировка идентификаторлэн — #$5.\nПожалуйста, аслэсьтым тодон-та вазиськонэз котьку возьмано.",
+       "blockednoreason": "мугезлы эн возьмалэ",
+       "whitelistedittext": "Тон кулэ $1 бам воштон понна.",
+       "loginreqtitle": "Авторизация кулэ",
+       "loginreqlink": "пырыны",
+       "loginreqpagetext": "Тон кулэ $1-ысь, сое мукет бамез учкыны шуыса.",
+       "newarticletext": "Тон бам ссылкаос вылэ выжыса, со кема уз улы.\nСоос мед кылдозы, текст бичась укноос, улазы интыяськемын (умой-умой см. [$1 бам справочной]).\nЯнгыш-а тон татын луысалыд ке, кнопказэ зӥбиз гинэ <strong>берлань</strong> асьтэлэсь браузеръёстэс.",
+       "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}}|сётэм йыръянъёс шедьто упоминание]] мукет бам вылын,\nяке <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} соответствующий журнал книгаез шедьтыны].</span> Тӥ дорын сётӥське юаськыны кылдӥз бам ӧвӧл.",
+       "blocked-notice-logextract": "Пользователь заблокирован сётӥз та учырлы.\nСправка понна радъяськылӥсь журнал блокировка лапег берпуметӥ гожтэт:",
+       "continue-editing": "Тупатъянэз азьланьтоно",
+       "editing": "Тупатон: $1",
+       "editingsection": "Тупатон: $1 (люкет)",
+       "template-protected": "(утемын)",
+       "template-semiprotected": "(полузащищенный)",
+       "nocreatetext": "Та сайтлэн бамаз выль сюбегатэм луонлыкъёсын кылдытон.\nТон улыса, берлань вуэ быгатэ бам отредактировать, [[Special:UserLogin|тусбуяськыны книгае яке выль система кылдыто учётной]].",
+       "nocreate-loggedin": "Тон доразы юаськыны кылдӥз выль бам ӧвӧл.",
+       "permissionserrors": "Янгышъёс юаське",
+       "permissionserrorstext": "Тон дорын разрешенизы ӧвӧлэн, тазэ лэсьтом шуыса, со понна вуоно {{PLURAL:$1|мугез}}:",
+       "permissionserrorstext-withaction": "Правоез ӧвӧл, тон дорын $2 тӥ {{PLURAL:$1/1=мугез вуоно|мугез вуоно}}:",
+       "content-model-wikitext": "викитекст",
+       "undo-summary": "Шонертон вошъян $1, лэсьтӥзы {{GENDER:$2|участник|куакеч}} [[Special:Contributions/$2|$2]] ([[User talk:$2|обс.]])",
+       "cantcreateaccount-text": "Та книгаез кылдытонлы учётной IP-адрес (<strong>$1</strong>) заблокировать луизы [[User:$3|$3]].\n\nМугез, вайиз $3 возьматэ <em>$2</em>",
+       "cantcreateaccount-range-text": "Учётной кылдытон - гожъян IP-адрес диапазонын <strong>$1</strong>, Тон пыриське со IP-адрес (<strong>$4</strong>), заблокировать луизы [[User:$3|$3]].\n\nМугез, вайиз $3 возьматэ <em>$2</em>",
+       "viewpagelogs": "Та бамлы журналъёсыз возьматыны",
+       "revisionasof": "Версия $1",
+       "previousrevision": "← Вужгем",
+       "cur": "али",
+       "last": "азьв.",
+       "history-show-deleted": "Ӵушылэмъёссэ гинэ",
+       "rev-showdeleted": "возьматоно",
+       "revdelete-show-file-submit": "да",
        "revdelete-radio-set": "Ватэм",
        "revdelete-radio-unset": "Адӟымон",
+       "revdelete-reason-dropdown": "*Вӧлскем палэнскон мугъёсты\n** Авторской правоосты тӥян\n** Яке кулэтэм информациез личной комментарий\n** Логин несоответствовать\n** Курла информациез Потенциально",
+       "history-title": "$1 — воштонъёслэн историзы",
+       "lineno": "$1-тӥ чур:",
+       "compareselectedversions": "Быръем версиосыз ӵошатыны",
+       "showhideselectedversions": "Возьматыны/ватыны быръем версиосыз",
+       "editundo": "берытсконо",
        "searchresults": "Шедьтэмын",
-       "search-result-size": "$1 кыл({{PLURAL:$2|1=1 word|$2 words}})",
+       "searchresults-title": "утчан \"$1\"",
+       "prevn": "{{PLURAL:$1|$1-лы}} берлань",
+       "nextn": "{{PLURAL:$1|$1-лы}} азьлань",
+       "shown-title": "Адӟытылоно $1 {{PLURAL:$1|шедьтэмез}} бамлы быдэ",
+       "viewprevnext": "Учкыны ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchprofile-articles": "Валтӥсь бамъёс",
+       "searchprofile-images": "Мультимедиа",
+       "searchprofile-everything": "Котькытын",
+       "searchprofile-advanced": "Паськытатэм",
+       "searchprofile-articles-tooltip": "$1 пушкын утчан",
+       "searchprofile-images-tooltip": "Файлъёсты утчан",
+       "searchprofile-everything-tooltip": "Вань бамъёсэтӥ утчан (вераськон бамъёсты пыртыса)",
+       "search-result-size": "$1 ({{PLURAL:$2|$2 кыл}})",
+       "search-redirect": "($1 бамысь ыстон)",
+       "search-interwiki-more": "(эшшо)",
+       "searchall": "Ваньзэ",
+       "search-nonefound": "Запрослы кельшись шедьтэмъёс ӧвӧл.",
+       "powersearch-toggleall": "Ваньзэ",
+       "powersearch-togglenone": "Номыре",
        "preferences": "настройкаос",
        "mypreferences": "Настройкаос",
        "prefs-watchlist": "Чаклан список",
+       "prefs-editing": "Тупатон",
+       "yourlanguage": "Интерфейслэн кылыз:",
+       "prefs-preview": "Бамез эскерон",
+       "editusergroup": "Группае {{GENDER:$1|пырись}} мукет",
+       "group-autoconfirmed": "Автоподтвержденный пыриськисьёс",
+       "group-bot": "Боты",
+       "group-sysop": "Администраторъёс",
+       "group-all": "(ваньзэ)",
+       "right-read": "лыдӟыны бам",
+       "right-edit": "правка бам",
+       "right-createpage": "бам кылдытон-а, уг-возьматэмзэ эскерон",
+       "right-createtalk": "создание бамлэн обсуждениосаз",
+       "right-createaccount": "выль книга кылдытон пыриськизы учётной",
+       "right-writeapi": "гожтэтъёсты кутон понна API",
+       "right-block": "мукет пыриськисьёслэсь курон-косон вылэ установкаосты редактировать",
+       "newuserlogpage": "Викиавторъёсыз регистрациосын журнал",
+       "action-read": "та лыдӟонъёс бам",
+       "action-edit": "та бамез редактировать",
+       "action-block": "пыриськисьёс та понна луонлыкъёссы сюбегам редактировать",
+       "enhancedrc-history": "история",
        "recentchanges": "Выль тупатонъёс",
+       "recentchanges-legend": "Выль тупатонъёслы настройкаос",
+       "recentchanges-label-newpage": "Та тупатонэн выль бам кылдӥз",
+       "recentchanges-label-minor": "Пичи воштон",
+       "recentchanges-label-bot": "Та тупатонэз кариз бот",
+       "recentchanges-label-unpatrolled": "Та тупатонэз нокин но ӧз эскеры на",
+       "recentchanges-label-plusminus": "Бамлэн быдӟалаез сомында байтъёслы воштӥськиз",
+       "recentchanges-legend-heading": "<strong>Легенда:</strong>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (озьы ик учке [[Special:NewPages|выль бамъёслы список]])",
+       "recentchanges-submit": "Возьматыны",
+       "rclistfrom": "$3 $2 но табере лэсьтэм воштонъёсыз возьматыны",
+       "rcshowhideminor": "$1 пичи тупатонъёсыз",
+       "rcshowhideminor-show": "Возьматыны",
+       "rcshowhideminor-hide": "Ватыны",
+       "rcshowhidebots": "$1 ботъёсыз",
+       "rcshowhidebots-show": "Возьматыны",
+       "rcshowhideliu": "$1 пырем викиавторъёсыз",
+       "rcshowhideliu-show": "Возьматыны",
+       "rcshowhideliu-hide": "Ватыны",
+       "rcshowhideanons": "$1 пырымтэ викиавторъёсыз",
+       "rcshowhideanons-show": "Возьматыны",
+       "rcshowhideanons-hide": "Ватыны",
+       "rcshowhidepatr-show": "Возьматыны",
+       "rcshowhidemine": "$1 аслэсьтым тупатонъёсме",
+       "rcshowhidemine-show": "Возьматыны",
+       "rcshowhidemine-hide": "Ватыны",
+       "rcshowhidecategorization-show": "Возьматыны",
+       "rcshowhidecategorization-hide": "Ватыны",
+       "rclinks": "Возьматыны $1 берло воштонэз $2 нуналскын<br />$3",
+       "diff": "пӧрт.",
        "hist": "история",
+       "hide": "Ватыны",
+       "show": "Возьматыны",
+       "minoreditletter": "п",
+       "newpageletter": "В",
+       "boteditletter": "б",
+       "rc-change-size-new": "Воштон бере быдӟала: $1 {{PLURAL:$1|байт}}",
+       "newsectionsummary": "/* $1 */ выль тема",
        "recentchangeslinked": "Герӟаськем тупатонъёс",
        "recentchangeslinked-feed": "Герӟаськем тупатонъёс",
        "recentchangeslinked-toolbox": "Герӟаськем тупатонъёс",
+       "recentchangeslinked-title": "«$1» ласянь герӟаськем тупатонъёс",
+       "recentchangeslinked-summary": "Татын алигес воштэм бамъёс адӟытэмын, кудъёссэ пусъем бам чӧлске (яке кудъёсыз пусъем категорие пыро).\n[[Special:Watchlist|Чаклан списокысьтыды]] бамъёс <strong>адӟиськытэмын</strong>.",
+       "recentchangeslinked-page": "Бамлэн нимыз:",
+       "recentchangeslinked-to": "Мыддоринтыны: та бамез чӧлскись бамъёсыз воштонъёсыз возьматыны",
        "upload": "Файл поныны",
+       "uploadnologin": "Тон эн тусбуяськыны сӧзнэтэз",
+       "uploadnologintext": "Тон кулэ $1, медаз загрузка файл сервер.",
+       "uploaddisabled": "Загрузка алӥзы",
+       "copyuploaddisabled": "Загрузка URL disconnect.",
+       "uploaddisabledtext": "Загрузка файл disconnect.",
+       "upload-dialog-button-cancel": "Берытсконо",
+       "nolicense": "Ӧвӧл",
+       "file-anchor-link": "Файл",
+       "filehist": "Файллэн историез",
+       "filehist-help": "Зӥбе дата/дыр шоры, кызьы файл со дырын адӟиськемез учкыны вылысь.",
+       "filehist-current": "алиез",
+       "filehist-datetime": "Дата/дыр",
+       "filehist-thumb": "Миниатюра",
+       "filehist-user": "Викиавтор",
+       "filehist-dimensions": "Быдӟала",
+       "filehist-comment": "Валэктон",
+       "imagelinks": "Файлэз уже кутон",
+       "linkstoimage": "{{PLURAL:$1|$1 бам}} та файлэз чӧлске:",
        "sharedupload": "Та файл — $1-ысь, сое мукет проектъёсын но уже кутыны луэ.",
+       "sharedupload-desc-here": "Та файл — $1-ысь, сое мукет проектъёсын но уже кутыны луэ.\n[$2 Файл гожъясь бамысьтыз] информация адӟытэмын улын.",
+       "upload-disallowed-here": "Тӥ та файлэз выльысь гожтыны уд быгатӥське.",
        "randompage": "Олокыӵе статья",
-       "nbytes": "$1 байт",
-       "move": "Мукет интые выжтыны",
+       "withoutinterwiki-submit": "Возьматыны",
+       "nbytes": "{{PLURAL:$1|$1 байт}}",
+       "prefixindex-submit": "Возьматыны",
+       "newpages": "Выль бамъёс",
+       "newpages-submit": "Возьматыны",
+       "move": "Нимзэ воштыны",
+       "log": "Журналъёс",
+       "logeventslist-submit": "Возьматыны",
+       "showhideselectedlogentries": "Возьматыны/ватыны быръем журналъёсысь гожъямъёсыз",
+       "checkbox-select": "Бырйыны: $1",
+       "checkbox-all": "Ваньзэ",
+       "checkbox-none": "Номыре",
+       "checkbox-invert": "Воштыны интыен",
+       "allpagessubmit": "Быдэстоно",
+       "categories-submit": "Возьматыны",
+       "sp-deletedcontributions-contribs": "тупатонъёсыз",
+       "listusers-submit": "Возьматыны",
+       "listusers-blocked": "(заблокировать{{GENDER:$1||а}})",
+       "listgrouprights": "Право группае пыриськисьёс",
+       "listgrouprights-summary": "Та группае пырисьёс возьматыны кулэ вики список улӥзы, право соответствующийгес солы возьматоно кариськиз. Оло, ас кожазы ватсаса ивортодэт улыны эрикрадэз сярысь.",
+       "listgrouprights-members": "(список пыриськисьёс)",
+       "emailuser": "Викиавторлы гожтэт",
        "emailmessage": "Ивортон:",
-       "watchlist": "Чаклано статьяос",
+       "watchlist": "Чаклан список",
        "mywatchlist": "Чаклан список",
        "watch": "Чаклано",
        "unwatch": "Чакламысь дугдыны",
-       "mycontris": "Мынам гожтэмъёсы",
-       "whatlinkshere": "Татчы линкъёс",
-       "movearticle": "Статьяез мукет интые выжтыны",
-       "move-watch": "Та бамез чаклан списоке пыртыны",
-       "delete_and_move": "Быдтыны но мукет интые выжтыны",
+       "watchlist-details": "Тӥляд чаклан списокады {{PLURAL:$1|$1 бам}}, вераськон бамъёсыз лыдӟытэк.",
+       "watchlist-submit": "Возьматыны",
+       "watchlist-options": "Чаклан списокез тупатыны",
+       "enotif_reset": "Вань бамъёсыз лыдӟем пусйыны",
+       "historyaction-submit": "Возьматыны",
+       "deletionlog": "палэнэ журнал",
+       "rollbacklink": "ӝог берыктыны",
+       "revertpage": "Откат шонертон [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]]) доры версия [[User:$1|$1]]",
+       "revertpage-nouser": "Откат шонертон (пыриськисьёс ватэм нимъёссы) доры версия {{GENDER:$1|[[User:$1|$1]]}}",
+       "restriction-edit": "Тупатон",
+       "undeletehistory": "Выльысь ке тон бамъёстэ, выльысь историяз луэм воштӥськонъёс вань.\nБӧрысь кылдӥзы выль бамъёс палэнэ кошконо луэ ке, сыӵе ик нимыз, историяз вошъяськонъёс предшествующий выльысь кылдозы.",
+       "undeletehistorynoadmin": "Статьяос палэнтэмын вал. Мугез но палэнэ список пыриды, со статьяе редактировать-озь палэнэгес, зӧк возьматэ. Текст статьяез удаленный администраторъёс гинэ учкыны быгатод.",
+       "invert": "Ватыны быръемез",
+       "blanknamespace": "(Валтӥсез)",
+       "contributions": "{{GENDER:$1|Викиавтор}} гожтэмъёсы",
+       "contributions-title": "$1 викиавтор гожтэмъёсы",
+       "mycontris": "Гожтэмъёс",
+       "nocontribs": "Критерии нокыӵе воштӥськонъёс та соответствующий шедьтыны уг луы.",
+       "sp-contributions-blocklog": "блокировка",
+       "sp-contributions-deleted": "шонертон палэнтыны {{GENDER:$1|участник|куакеч}}",
+       "sp-contributions-blocked-notice": "Пользователь заблокирован сётӥз та учырлы. Справка понна радъяськылӥсь журнал блокировка лапег берпуметӥ гожтэт:",
+       "sp-contributions-blocked-notice-anon": "Со ip-адрес вие заблокировать сётӥзы. Блокировка журналъёсты вайытэк улӥзы берпуметӥ книгаысь:",
+       "whatlinkshere": "Татчы чӧлсконъёс",
+       "block": "Блокировка пыриськисьёс",
+       "blockip": "Заблокировать пыриськисьёс",
+       "ipbreason-dropdown": "* Блокировка мугез кабес\n** Полы информациез оскизы\n** Вордскем палэнэ бам\n** Спам-сайтъя педпал чӧлскон\n** Текстлэсь визьем ватсан/жуг-жаг\n** Кышкытлыклэсь, пыриськыны уйиськон\n** Злоупотребление кӧня ке книга учётной\n** Пыриськисьёслэн нимъёссы пыриськисьёс",
+       "ipboptions": "2 час:2 hours,1 нуналлы:1 day,3 нуналлы:3 days,1 арняезлы:1 week,2 арняяз:2 weeks,1 толэзь:1 month,3 толэзь:3 months,6 толэзь:6 months,1 арлэн:1 year,бессрочно:infinite",
+       "unblocked": "$1 разблокировать",
+       "unblocked-id": "Блокировка $1 басьтоно луиз",
+       "blocklist-target": "Ужпумъёс",
+       "blocklist-reason": "Мугез",
+       "infiniteblock": "бессрочно",
+       "expiringblock": "йылпумъяськиз $1-ысь $2",
+       "anononlyblock": "аноним гинэ",
+       "noautoblockblock": "disconnect автоблокировка",
+       "createaccountblock": "гожъямъёстэс лэзьыны кылдытон учётной",
+       "emailblock": "лэзьымтэ гожтэт ыстон",
+       "blocklist-nousertalk": "тупатъяны ачиз уггес быгаты бамлэн обсуждениосаз",
+       "blocklink": "блокировать карыны",
+       "unblocklink": "разблокировать",
+       "change-blocklink": "блокировка воштыны",
+       "contribslink": "тупатонъёсыз",
+       "autoblocker": "Автоблокировка-со понна, мае тӥ IP-адрес кутыны али \"[[User:$1|$1]]\". \nБлокировка мугез $1: \"$2\"",
+       "blocklogentry": "заблокировать [[$1]] дыр $2 $3",
+       "reblock-logentry": "блокировка воштӥз [[$1]] дыр $2 $3",
+       "blocklogtext": "Блокировка но та журналлэн ужезлы разблокирование пользователь.\nЗаблокировать Автоматически IP-адрес уг возьма.\nПроизведениосыз печатласько эстониын [[Special:BlockList|сьӧд списокын]], бан список блокъёс лэсьтыны.",
+       "unblocklogentry": "разблокировать $1",
+       "block-log-flags-anononly": "пользователь гинэ нимтултэм",
+       "block-log-flags-nocreate": "регистрация учётной книгая ужъёсты быдэстон",
+       "block-log-flags-noemail": "лэзьымтэ гожтэт ыстон",
+       "block-log-flags-nousertalk": "тупатъяны ачиз уггес быгаты бамлэн обсуждениосаз",
+       "range_block_disabled": "Администратор диапазонэз блокировать али.",
+       "move-watch": "Чаклан списоке пыртоно инъет но валтӥсь бамъёсыз",
        "allmessagesname": "Ивортон",
+       "allmessages-filter-all": "Ваньзэ",
+       "thumbnail-more": "Будэтоно",
+       "tooltip-pt-login": "Татын системае пырыны луоно, нош одно ик ӧвӧл",
+       "tooltip-pt-createaccount": "Татын учётной записез лэсьтыны но системае пырыны луоно, нош одно ик ӧвӧл",
        "tooltip-ca-talk": "Бамлэн контентэз сярысь вераськон",
+       "tooltip-ca-edit": "Та бамез тупатъяно",
+       "tooltip-ca-addsection": "Выль люкет кылдытоно",
+       "tooltip-ca-viewsource": "Та бам воштонъёслэсь утемын.\nТӥ быгатӥськоды инъет текстсэ учкыны но кӧчырыны",
+       "tooltip-ca-history": "Бамлэн воштонъёсыныз журнал",
+       "tooltip-ca-watch": "Та бамез чаклан списокады пыртоно",
        "tooltip-search": "Утчано {{SITENAME}}",
+       "tooltip-search-go": "Выжоно сыӵе ик нимын баме",
+       "tooltip-search-fulltext": "Шедьтоно бамъёсыз, кудъёсаз пумиське пусъем текст",
+       "tooltip-p-logo": "Кутскон баме мыноно",
        "tooltip-n-mainpage": "Кутскон баме мыноно",
        "tooltip-n-mainpage-description": "Кутскон баме мыноно",
        "tooltip-n-portal": "Проект сярысь, мар карыны быгатоды, ужлы кулэ луэмзэ кытысь шедьтоно",
+       "tooltip-n-currentevents": "Выль иворъёс сярысь веранъёс",
        "tooltip-n-recentchanges": "Берпуметӥ тупатонъёслэн списоксы",
        "tooltip-n-randompage": "Олокыӵе бамез учконо",
+       "tooltip-n-help": "Юрттэт басьтымон инты",
        "tooltip-t-whatlinkshere": "Ваньмыз бамъёс, кудъёсаз та бамлы линксы вань",
+       "tooltip-t-recentchangeslinked": "Выль тупатонъёс бамъёсын, кудъёссэ та бам чӧлске",
+       "tooltip-feed-atom": "Та бамлэн Atom-е трансляциез",
+       "tooltip-t-upload": "Файл поныны",
        "tooltip-t-specialpages": "Специальной бамъёслэн списоксы",
+       "tooltip-t-print": "Та бамысь печатламон версия",
+       "tooltip-t-permalink": "Бамлэн та версияз ялан чӧлскон",
+       "tooltip-ca-nstab-main": "Валтӥсь бамез учконо",
+       "tooltip-ca-nstab-user": "Викиавторлэн бамез",
+       "tooltip-ca-nstab-special": "Та бам нимысьтыз, сое тупатон луонтэм",
+       "tooltip-ca-nstab-image": "Файллэн бамез",
+       "tooltip-ca-nstab-category": "Категорилэн бамез",
+       "tooltip-save": "Возьыны воштонъёстэс",
+       "tooltip-preview": "Воштонъёстэс эскерон. Тауна, бамез гожтонлэсь азьло учкелэ соосыз.",
+       "tooltip-diff": "Возьматыны воштонъёсыз, кудъёссэ тӥ текстэ пыртӥды.",
+       "tooltip-rollback": "Берло викиавторен лэсьтэм воштонъёсыз одӥг зӥбонэн палэнтыны",
+       "tooltip-summary": "Воштонъёсты сярысь вакчияк гожтэлэ",
+       "simpleantispam-label": "Анти-спам эскерон.\n<strong>Эн</strong> гожтэ татчы!",
+       "pageinfo-header-edits": "Воштонъёслэн историзы",
        "pageinfo-toolboxlink": "Бам сярысь тодэтъёс",
-       "specialpages": "Ваньмыз панельёс"
+       "file-info-size": "$1 × $2 пиксель, файллэн быдӟалаез: $3, MIME-тип: $4",
+       "show-big-image": "Инъет файл",
+       "show-big-image-preview": "Быдӟалаез та бамын: $1.",
+       "show-big-image-other": "Мукет {{PLURAL:$2|быдӟалаез|быдӟалаосыз}}: $1.",
+       "show-big-image-size": "$1 × $2 пиксель",
+       "metadata": "Метаданнойёс",
+       "metadata-help": "Файл пушкын информация вань на, кудзэ лыдпусо камераос яке сканеръёс файлэз кылдытыку огшоры ватсалляло.\nКылдытон бере файл воштӥськиз ке, куд-огез параметръёс воштэм суредлы ярантэм луыны быгато.",
+       "metadata-fields": "Суредысь метаданнойёслэн та списоке пыртэм полеоссы адӟытӥськозы суред бам вылын, метаданнойёслэн таблицазы бинемын дыръя.\nМукет полеоссы ватскозы.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "exif-xresolution": "Горизонтальной разрешение",
+       "exif-yresolution": "Вертикальной разрешение",
+       "exif-datetime": "Файлэз воштонлэн датаез но дырыз",
+       "exif-disclaimer": "Кыл кутыны пумит луон",
+       "namespacesall": "ваньзэ",
+       "monthsall": "ваньзэ",
+       "confirmrecreate-noreason": "{{GENDER:$1|Участник|Куакеч|}}&nbsp;[[User:$1|$1]] ([[User talk:$1|обс]]) {{GENDER:$1|палэнтыны|палэнтыны}} таиз бере бам, кызьы тон сое редактировать карыны кутскиз. Пожалуйста, подтвердите, мар тон малпаськод та бамез зэм но выльысь кылдозы.",
+       "confirm-watch-top": "Та бамез чаклан списокады пыртоно?",
+       "autosumm-new": "Выль бам: «$1»",
+       "version": "Версия",
+       "specialpages": "Ваньмыз панельёс",
+       "specialpages-group-login": "Тусбуяськыны / Гожтӥськоно",
+       "specialpages-group-users": "Пыриськисьёслэсь правооссэс но",
+       "tag-filter": "[[Special:Tags|Тэгъёсыз]] фильтр:",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|1=Метка|Меткаос}}]]: $2)",
+       "tags-title": "Меткаос",
+       "logentry-delete-delete": "$1 {{GENDER:$2|палэнтыны|палэнтыны}} бам $3",
+       "logentry-delete-restore": "$1 {{GENDER:$2|выльысь}} бам $3",
+       "logentry-newusers-create": "$1 нимо учётной запись {{GENDER:$2|кылдытэмын}} вал",
+       "searchsuggest-search": "Утчано {{SITENAME}}",
+       "searchsuggest-containing": "кудъёсаз вань...",
+       "api-error-autoblocked": "Тон IP-адрес заблокировать эрказ луи, малы ке шуоно со заблокировать пользователь кутыны луоз.",
+       "api-error-blocked": "Редактирование заблокировать вал тӥлесьтыд.",
+       "expand_templates_preview": "Эскерон",
+       "log-action-filter-all": "Ваньзэ"
 }
index f6381c2..edd0508 100644 (file)
        "yourpasswordagain": "پارولنى قايتا كىرگۈزۈڭ:",
        "createacct-yourpasswordagain": "پارولنى مۇقىملاشتۇرۇڭ",
        "createacct-yourpasswordagain-ph": "پارولنى قايتا كىرگۈزۈڭ",
-       "remembermypassword": "بۇ كومپيۇتېردا كىرگىنىمنى ئەستە ساقلا(ئەڭ ئۇزۇن بولغاندا $1 {{PLURAL:$1|كۈن|كۈن}})",
        "userlogin-remembermypassword": "مېنى ئەستە ساقلا",
        "userlogin-signwithsecure": "بىخەتەر ئۇلىنىشنى ئىشلەت",
        "yourdomainname": "دائىرە نامىڭىز:",
        "passwordreset-emailtext-user": "{{SITENAME}} دىكى ئىشلەتكۈچى $1 بېكەت {{SITENAME}} ($4) دىكى پارولىڭىزنى قايتا بېكىتىشنى ئىلتىماس قىلدى .\nتۆۋەندىكى ئىشلەتكۈچىنىڭ {{PLURAL:$3|ھېسابات|ھېسابات}}($4)ى مۇشۇ ئېلخەتكە باغلانغان:\n\n$2\n\n{{PLURAL:$3|بۇ ۋاقىتلىق پارول|بۇ ۋاقىتلىق پارول}} {{PLURAL:$5|بىر كۈن|$5 كۈن}}دە ۋاقتى ئۆتىدۇ. ئەگەر بۇ مەشغۇلاتنى سىز ئىلتىماس قىلغان بولسىڭىز، دەرھال تىزىمغا كىرىپ يېڭى پارولدىن بىرنى تاللاڭ.\nسىز بەلگىلىگەن يېڭى پارول {{PLURAL:$5|كۈن|$5 كۈن}}دە ۋاقتى توشىدۇ. ئەگەر باشقىلار ئىلتىماس قىلغان بولسا ياكى ئۆزىڭىز بەلگىلىگەن پارول ئېسىڭىزگە كېلىپ ئۇنى ئۆزگەرتمىسىڭىز، \nبۇ ئۇچۇرغا پەرۋا قىلماي ئۆزىڭىزنىڭ كونا پارولىنى ئىشلىتىۋېرىڭ.",
        "passwordreset-emailelement": "ئىشلەتكۈچى نامى: \n$1\n\nۋاقىتلىق پارول: \n$2",
        "passwordreset-emailsentemail": "پارولنى قايتا بېكىتىش ئېلخېتى يوللاندى.",
-       "passwordreset-emailsent-capture": "پارولنى قايتا بېكىتىش ئېلخېتى يوللاندى، تۆۋەندە كۆرسىتىلىدۇ.",
-       "passwordreset-emailerror-capture": "ھاسىل قىلىنغان پارولنى قايتا بېكىتىش ئېلخېتى تۆۋەندە كۆرسىتىلگەندەك ئەمما ئۇنى {{GENDER:$2|ئىشلەتكۈچى}}گە يوللىيالمىدى: $1",
        "changeemail": "ئېلخەت ئادرېس ئۆزگەرت",
        "changeemail-header": "ھېساباتنىڭ ئېلخەت ئادرېسىنى ئۆزگەرت",
        "changeemail-no-info": "سىز تىزىمغا كىرگەندىن كېيىن بىۋاسىتە بۇ بەتكە كىرىشىڭىز لازىم.",
        "undo-nochange": "بۇ قېتىملىق تەھرىرلەش ۋاز كېچىلدى.",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|مۇنازىرە]]) ئېلىپ بارغان تۈزىتىش $1",
        "undo-summary-username-hidden": "بىر يوشۇرۇن ئىشلەتكۈچى تەرىپىدىن يېنىۋېلىندى $1.",
-       "cantcreateaccounttitle": "ھېسابات قۇرالمىدى",
        "cantcreateaccount-text": "بۇ IP ئادرېستىن قۇرۇلغان ('''$1''')  ھېسابات [[User:$3|$3]] تەرىپىدىن چەكلەنگەن.\n\n$3 تەمىنلىگەن چەكلەش سەۋەبى ''$2''",
        "viewpagelogs": "بۇ بەتنىڭ خاتىرىسىنى كۆرسەت",
        "nohistory": "بۇ بەتنىڭ تەھرىرلەش خاتىرىسى يوق.",
        "activeusers-intro": "بۇ يېقىنقى $1 {{PLURAL:$1| كۈن|كۈن}}دىكى مەشغۇلات قىلغان ئىشلەتكۈچىلەر تىزىملىكى.",
        "activeusers-count": "يېقىنقى {{PLURAL:$3|كۈن|$3 كۈن}}دىكى {{PLURAL:$1|مەشغۇلات}} قېتىم سانى $1",
        "activeusers-from": "باشلانغان ئىشلەتكۈچىنى كۆرسەت:",
-       "activeusers-hidebots": "ماشىنا ئادەمنى يوشۇر",
-       "activeusers-hidesysops": "باشقۇرغۇچىنى يوشۇر",
        "activeusers-noresult": "ئىشلەتكۈچى تېپىلمىدى.",
        "listgrouprights": "ئىشلەتكۈچى گۇرۇپپا ھوقۇقى",
        "listgrouprights-summary": "تۆۋەندىكىسى بۇ wiki دا ئېنىقلىما بېرىلگەن ئىشلەتكۈچى ھوقۇق چېكى تىزىملىكى ۋە ئۇلارنىڭ زىيارەت ھوقۇق چېكى.\nتېخىمۇ كۆپ قىسمەن ھوقۇقنىڭ تەپسىلاتىنى [[{{MediaWiki:Listgrouprights-helppage}}|بۇ جاي]] دىن تاپالايسىز.",
        "htmlform-no": "ياق",
        "htmlform-yes": "ھەئە",
        "htmlform-chosen-placeholder": "بىرنى تاللاڭ",
-       "sqlite-has-fts": "$1 پۈتۈن تېكست ئىزدەشنى قوللايدۇ",
-       "sqlite-no-fts": "$1 پۈتۈن تېكست ئىزدەشنى قوللىمايدۇ",
        "logentry-delete-delete": "$1 $3 بەتنى {{GENDER:$2|ئۆچۈرىۋەتتى}}",
        "logentry-delete-restore": "$1 $3 بەتنى {{GENDER:$2|ئەسلىگە قايتۇردى}}",
        "logentry-delete-event": "$1 ئىشلەتكۈچى $3 دىكى {{PLURAL:$5|خاتىرە ھادىسە}}سىنىڭ كۆۈنۈشچانلىقىنى ئۆزگەرتتى: $4",
index 0dd4408..b68e6d2 100644 (file)
                        "Dars",
                        "Mix Gerder",
                        "E.belykh",
-                       "Visem"
+                       "Visem",
+                       "MMH",
+                       "Олександр",
+                       "Similartothissimilartothat"
                ]
        },
        "tog-underline": "Підкреслювання посилань:",
        "botpasswords-label-delete": "Видалити",
        "botpasswords-label-resetpassword": "Скинути пароль",
        "botpasswords-label-grants": "Придатні дозволи:",
-       "botpasswords-help-grants": "Ð\9aожен Ð´Ð¾Ð·Ð²Ñ\96л Ð´Ð°Ñ\94 Ð´Ð¾Ñ\81Ñ\82Ñ\83п Ð´Ð¾ Ð¿ÐµÑ\80елÑ\96Ñ\87ениÑ\85 Ð¿Ñ\80ав ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87а, Ñ\8fкÑ\96 Ð²Ð¶Ðµ Ñ\94 Ñ\83 Ð¾Ð±Ð»Ñ\96кового Ð·Ð°Ð¿Ð¸Ñ\81Ñ\83 ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87а. Див. [[Special:ListGrants|таблицю дозволів]] для отримання додаткової інформації.",
+       "botpasswords-help-grants": "Ð\94озволи Ð´Ð°Ñ\8eÑ\82Ñ\8c Ð´Ð¾Ñ\81Ñ\82Ñ\83п Ð´Ð¾ Ð¿Ñ\80ав, Ñ\8fкÑ\96 Ð²Ð¶Ðµ Ñ\94 Ñ\83 Ð\92аÑ\88ого Ð¾Ð±Ð»Ñ\96кового Ð·Ð°Ð¿Ð¸Ñ\81Ñ\83. Ð£Ð²Ñ\96мкненнÑ\8f Ð´Ð¾Ð·Ð²Ð¾Ð»Ñ\83 Ñ\82Ñ\83Ñ\82 Ð½Ðµ Ð½Ð°Ð´Ð°Ñ\81Ñ\82Ñ\8c Ð\92ам Ð´Ð¾Ñ\81Ñ\82Ñ\83пÑ\83 Ð´Ð¾ Ð±Ñ\83дÑ\8c\8fкиÑ\85 Ð¿Ñ\80ав, Ñ\8fкиÑ\85 Ð² Ñ\96нÑ\88омÑ\83 Ð²Ð¸Ð¿Ð°Ð´ÐºÑ\83 Ð½Ðµ Ð±Ñ\83ло Ð± Ñ\83 Ð\92аÑ\88ого Ð¾Ð±Ð»Ñ\96кового Ð·Ð°Ð¿Ð¸Ñ\81Ñ\83. Див. [[Special:ListGrants|таблицю дозволів]] для отримання додаткової інформації.",
        "botpasswords-label-grants-column": "Дозволено",
        "botpasswords-bad-appid": "Ім'я бота «$1» є недопустимим.",
        "botpasswords-insert-failed": "Не вдалось додати бота з іменем «$1». Можливо, він вже був доданий?",
        "passwordreset-nocaller": "Має бути надане джерело виклику",
        "passwordreset-nosuchcaller": "Джерело виклику не існує: $1",
        "passwordreset-ignored": "Скидання пароля не відбулося. Можливо, не було налашатовано надавача?",
-       "passwordreset-invalideamil": "Недійсна адреса електронної пошти",
+       "passwordreset-invalidemail": "Недійсна адреса електронної пошти",
        "passwordreset-nodata": "Не надано ні імені користувача, ні електронної адреси",
        "changeemail": "Змінити або вилучити адресу електронної пошти",
        "changeemail-header": "Заповніть цю форму, щоб змінити адресу електронної пошти. Якщо Ви хочете взагалі прибрати зв'язок свого облікового запису з адресою електронної пошти, при надсиланні форми залиште поле нової електронної адреси порожнім.",
        "italic_tip": "Курсив",
        "link_sample": "Назва посилання",
        "link_tip": "Внутрішнє посилання",
-       "extlink_sample": "назва посилання http://www.example.com",
+       "extlink_sample": "http://www.example.com назва посилання",
        "extlink_tip": "Зовнішнє посилання (не забудьте про префікс http://)",
        "headline_sample": "Текст заголовка",
        "headline_tip": "Заголовок 2-го рівня",
        "searchprofile-advanced-tooltip": "Шукати в заданих просторах назв",
        "search-result-size": "$1 ($2 {{PLURAL:$2|слово|слова|слів}})",
        "search-result-category-size": "{{PLURAL:$1|$1 елемент|$1 елементи|$1 елементів}} ({{PLURAL:$2|$2 підкатегорія|$2 підкатегорії|$2 підкатегорій}}, {{PLURAL:$3|$3 файл|$3 файли|$3 файлів}})",
-       "search-redirect": "(перенаправлення $1)",
+       "search-redirect": "(перенаправлення з $1)",
        "search-section": "(розділ $1)",
        "search-category": "(категорія $1)",
        "search-file-match": "(збігається із вмістом файлу)",
        "grant-basic": "Основні права",
        "grant-viewdeleted": "Перегляд видалених файлів і сторінок",
        "grant-viewmywatchlist": "Перегляд списку спостереження",
+       "grant-viewrestrictedlogs": "Показати записи журналу з обмеженим доступом",
        "newuserlogpage": "Журнал нових користувачів",
        "newuserlogpagetext": "Список нещодавно зареєстрованих користувачів.",
        "rightslog": "Журнал прав користувача",
        "upload-dialog-disabled": "Завантаження файлів з допомогою цього діалогового вікна відключені у цій вікі.",
        "upload-dialog-title": "Завантажити файл",
        "upload-dialog-button-cancel": "Скасувати",
+       "upload-dialog-button-back": "Назад",
        "upload-dialog-button-done": "Готово",
        "upload-dialog-button-save": "Зберегти",
        "upload-dialog-button-upload": "Завантажити",
        "apisandbox-results-fixtoken-fail": "Не вдалося викликати токен «$1».",
        "apisandbox-alert-page": "Поля на цій сторінці не є дійсними.",
        "apisandbox-alert-field": "Значення цього поля не є допустимим.",
+       "apisandbox-continue": "Продовжити",
+       "apisandbox-continue-clear": "Очистити",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries продовжить] останній запит; {{int:apisandbox-continue-clear}} очистить параметри, пов'язані з продовженням.",
+       "apisandbox-param-limit": "Введіть <kbd>max</kbd>, щоб використати максимальний ліміт.",
        "booksources": "Джерела книг",
        "booksources-search-legend": "Пошук інформації про книгу",
        "booksources-isbn": "ISBN:",
        "booksources-search": "Пошук",
        "booksources-text": "На цій сторінці наведено список посилань на сайти, де ви, можливо, знайдете додаткову інформацію про книгу. Це інтернет-магазини й системи пошуку в бібліотечних каталогах.",
        "booksources-invalid-isbn": "Вказаний номер ISBN, судячи з усього, містить помилку. Будь ласка, перевірте, що при перенесенні номера з першоджерела не виникло спотворень.",
+       "magiclink-tracking-rfc": "Сторінки, що використовують магічні посилання RFC",
+       "magiclink-tracking-rfc-desc": "Ця сторінка використовує магічні посилання RFC. Див. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] про те, як перенести.",
+       "magiclink-tracking-pmid": "Сторінки, що використовують магічні посилання PMID",
+       "magiclink-tracking-pmid-desc": "Ця сторінка використовує магічні посилання PMID. Див. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] про те, як перенести.",
+       "magiclink-tracking-isbn": "Сторінки, що використовують магічні посилання ISBN",
+       "magiclink-tracking-isbn-desc": "Ця сторінка використовує магічні посилання ISBN. Див. [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] про те, як перенести.",
        "specialloguserlabel": "Виконавець:",
        "speciallogtitlelabel": "Ціль (назва сторінки або {{ns:user}}:Ім'я_користувача):",
        "log": "Журнали",
        "activeusers-intro": "Це список користувачів, які здійснювали які-небудь дії за {{PLURAL:$1|останній $1 день|останні $1 дні|останні $1 днів}}.",
        "activeusers-count": "$1 {{PLURAL:$1|дія|дії|дій}} за {{PLURAL:$3|останній $3 день|останні $3 дні|останні $3 днів}}",
        "activeusers-from": "Показувати користувачів, починаючи з:",
-       "activeusers-hidebots": "Приховати ботів",
-       "activeusers-hidesysops": "Приховати адміністраторів",
+       "activeusers-groups": "Показувати користувачів, належних до груп:",
        "activeusers-noresult": "Не знайдено користувачів.",
        "activeusers-submit": "Показати активних користувачів",
        "listgrouprights": "Права груп користувачів",
        "modifiedarticleprotection": "змінено рівень захисту сторінки «[[$1]]»",
        "unprotectedarticle": "знято захист зі сторінки \"[[$1]]\"",
        "movedarticleprotection": "переніс налаштування захисту з «[[$2]]» на «[[$1]]»",
+       "protectedarticle-comment": "Захисти{{GENDER:$2|в|ла}} «[[$1]]»",
+       "modifiedarticleprotection-comment": "Зміни{{GENDER:$2|в|ла}} рівень захисту для \"[[$1]]\"",
+       "unprotectedarticle-comment": "Зня{{GENDER:$2|в|ла}} захист з \"[[$1]]\"",
        "protect-title": "Встановлення захисту для «$1»",
        "protect-title-notallowed": "Перегляд рівню захисту \"$1\"",
        "prot_1movedto2": "«[[$1]]» перейменована на «[[$2]]»",
        "movelogpagetext": "Далі подано список перейменованих сторінок.",
        "movesubpage": "{{PLURAL:$1|1=Підсторінка|Підсторінки}}",
        "movesubpagetext": "Ця сторінка має $1 {{PLURAL:$1|підсторінку|підсторінки|підсторінок}}.",
+       "movesubpagetalktext": "Відповідна сторінка обговорення має $1 {{PLURAL:$1|підсторінку, показану нижче|підсторінки, показані нижче|підсторінок, показаних нижче}}.",
        "movenosubpage": "Ця сторінка не має підсторінок.",
        "movereason": "Причина:",
        "revertmove": "скасувати перейменування",
        "pageinfo-category-pages": "Кількість сторінок",
        "pageinfo-category-subcats": "Кількість підкатегорій",
        "pageinfo-category-files": "Кількість файлів",
+       "pageinfo-user-id": "ID користувача",
        "markaspatrolleddiff": "Позначити як перевірену",
        "markaspatrolledtext": "Позначити цю сторінку як перевірену",
        "markaspatrolledtext-file": "Позначити цю версію файлу як відпатрульовану",
        "patrol-log-header": "Це журнал перевірених змін.",
        "log-show-hide-patrol": "$1 журнал патрулювання",
        "log-show-hide-tag": "$1 мітку журналу",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Позначити версію $3 сторінки $2 як відпатрульовану?",
        "deletedrevision": "Вилучена стара версія $1",
        "filedeleteerror-short": "Помилка вилучення файлу: $1",
        "filedeleteerror-long": "Під час вилучення файлу виникли помилки:\n\n$1",
        "newimages-showbots": "Показати завантаження ботами",
        "newimages-hidepatrolled": "Приховати відпатрульовані завантаження",
        "noimages": "Файли відсутні.",
+       "gallery-slideshow-toggle": "Перемикання мініатюр",
        "ilsubmit": "Шукати",
        "bydate": "за датою",
        "sp-newimages-showfrom": "Показати нові зображення, починаючи з $2, $1",
        "tags-deactivate": "вимкнути",
        "tags-hitcount": "$1 {{PLURAL:$1|зміна|зміни|змін}}",
        "tags-manage-no-permission": "У Вас нема дозволу керувати мітками змін.",
-       "tags-manage-blocked": "Не можна змінювати мітки під час блокування.",
+       "tags-manage-blocked": "Не можна змінювати теги, поки Вас заблоковано.",
        "tags-create-heading": "Створити нову мітку",
        "tags-create-explanation": "За замовчуванням, новостворені мітки будуть доступні для використання користувачами і ботами.",
        "tags-create-tag-name": "Назва мітки:",
        "tags-deactivate-not-allowed": "Неможливо вимкнути мітку «$1».",
        "tags-deactivate-submit": "Вимкнути",
        "tags-apply-no-permission": "Ви не маєте права міняти мітки вашого редагування.",
-       "tags-apply-blocked": "Ви не можете змінювати мітки редагувань, будучи заблокованим.",
+       "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-blocked": "Ви не можете додати чи видалити теги редагувань, поки Вас заблоковано.",
        "tags-update-add-not-allowed-one": "Мітку \"$1\" не можна додавати вручну.",
        "tags-update-add-not-allowed-multi": "{{PLURAL:$2|Таку мітку|Такі мітки}} не можна додавати вручну: $1",
        "tags-update-remove-not-allowed-one": "Мітку «$1» не дозволено вилучати.",
        "htmlform-cloner-create": "Додати більше",
        "htmlform-cloner-delete": "Вилучити",
        "htmlform-cloner-required": "Необхідно принаймні одне значення.",
+       "htmlform-date-placeholder": "РРРР-ММ-ДД",
+       "htmlform-time-placeholder": "ГГ:ХХ:СС",
+       "htmlform-datetime-placeholder": "РРРР-ММ-ДД ГГ:ХХ:СС",
+       "htmlform-date-invalid": "Введене Вами значення не розпізнається як дата. Спробуйте використати формат РРРР-ММ-ДД.",
+       "htmlform-time-invalid": "Введене Вами значення не розпізнається як час. Спробуйте використати формат ГГ:ХХ:СС.",
+       "htmlform-datetime-invalid": "Введене Вами значення не розпізнається як дата й час. Спробуйте використати формат РРРР-ММ-ДД ГГ:ХХ:СС.",
+       "htmlform-date-toolow": "Задане Вами значення — менше, ніж найраніша дозволена дата $1.",
+       "htmlform-date-toohigh": "Ви вказали значення після найпізнішої дозволеної дати: $1.",
+       "htmlform-time-toolow": "Ви вказали значення до найранішого дозволеного часу: $1",
+       "htmlform-time-toohigh": "Ви вказали значення після найпізнішого дозволеного часу: $1.",
+       "htmlform-datetime-toolow": "Ви вказали значення до найранішої дозволеної дати й часу: $1",
+       "htmlform-datetime-toohigh": "Ви вказали значення після найпізнішої дозволеної дати й часу: $1.",
        "htmlform-title-badnamespace": "[[:$1]] не в просторі назв «{{ns:$2}}».",
        "htmlform-title-not-creatable": "«$1» — назва сторінки, яку не можна створити",
        "htmlform-title-not-exists": "$1 не існує.",
        "feedback-external-bug-report-button": "Повідомити про технічну проблему",
        "feedback-dialog-title": "Надіслати відгук",
        "feedback-dialog-intro": "Для надсилання відгуку Ви можете скористатись простою формою внизу. Ваш коментар буде залишений на сторінці «$1», разом із Вашим іменем користувача (або IP-адресою).",
-       "feedback-error-title": "Помилка",
        "feedback-error1": "Помилка: Невідомий результаті API",
        "feedback-error2": "Помилка: Збій редагувань",
        "feedback-error3": "Помилка: Немає відповіді від API",
        "feedback-thanks": "Дякуємо! Ваші відгук розміщено на сторінці \"[$2 $1]\".",
        "feedback-thanks-title": "Дякуємо!",
        "feedback-useragent": "User Agent:",
-       "searchsuggest-search": "Пошук",
+       "searchsuggest-search": "Пошук {{GRAMMAR:locative|{{SITENAME}}}}",
        "searchsuggest-containing": "що містять...",
        "api-error-autoblocked": "Вашу IP-адресу було заблоковано автоматично, тому що її використовував заблокований користувач.",
        "api-error-badaccess-groups": "Вам не дозволено завантажувати файли до цього вікіпроекту.",
        "authmanager-authn-autocreate-failed": "Автоматичне створення локального облікового запису не вдалося: $1",
        "authmanager-change-not-supported": "Надані облікові дані не можуть бути змінені, оскільки їх нічого не буде використовувати.",
        "authmanager-create-disabled": "Створення облікових записів вимкнене.",
-       "authmanager-create-from-login": "Щоб Ñ\81Ñ\82воÑ\80иÑ\82и Ð¾Ð±Ð»Ñ\96ковий Ð·Ð°Ð¿Ð¸Ñ\81, Ð±Ñ\83дÑ\8c Ð»Ð°Ñ\81ка, Ð·Ð°Ð¿Ð¾Ð²Ð½Ñ\96Ñ\82Ñ\8c Ð¿Ð¾Ð»Ñ\8f Ð½Ð¸Ð¶Ñ\87е.",
+       "authmanager-create-from-login": "Щоб Ñ\81Ñ\82воÑ\80иÑ\82и Ð¾Ð±Ð»Ñ\96ковий Ð·Ð°Ð¿Ð¸Ñ\81, Ð±Ñ\83дÑ\8c Ð»Ð°Ñ\81ка, Ð·Ð°Ð¿Ð¾Ð²Ð½Ñ\96Ñ\82Ñ\8c Ð¿Ð¾Ð´Ð°Ð½Ñ\96 Ð¿Ð¾Ð»Ñ\8f.",
        "authmanager-create-not-in-progress": "Створення облікового запису не виконується або втрачено дані сесії. Будь ласка, почніть знову з самого початку.",
        "authmanager-create-no-primary": "Надані облікові дані не можуть бути використані для створення облікового запису.",
        "authmanager-link-no-primary": "Надані облікові дані не можуть бути використані для прив'язки облікового запису.",
        "usercssispublic": "Будь ласка, зверніть увагу: підсторінки CSS не повинні містити конфіденційних даних, бо їх можуть бачити інші користувачі.",
        "restrictionsfield-badip": "Недійсна IP-адреса або діапазон: $1",
        "restrictionsfield-label": "Дозволені діапазони IP-адрес:",
-       "restrictionsfield-help": "Одна IP-адреса або CIDR-діапазон на рядок. Щоб увімкнути все, використайте<br><code>0.0.0.0/0</code><br><code>::/0</code>"
+       "restrictionsfield-help": "Одна IP-адреса або CIDR-діапазон на рядок. Щоб увімкнути все, використайте<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "Помилка: $1",
+       "edit-error-long": "Помилки:\n\n$1"
 }
index 7c0b6c2..de2ee22 100644 (file)
        "category-subcat-count-limited": "اِس زمرہ میں درج ذیل {{PLURAL:$1|ذیلی زمرہ ہے|$1 ذیلی زمرہ جات ہیں}}۔",
        "category-article-count": "{{PLURAL:$2|اس زمرہ میں محض درج ذیل صفحہ موجود ہے۔|اس زمرہ کے کل $2 صفحات میں سے $1 {{PLURAL:$1|صفحہ|صفحات}} درج ذیل {{PLURAL:$1|ہے|ہیں}}}}۔",
        "category-article-count-limited": "درج ذیل {{PLURAL:$1|صفحہ|$1 صفحات}} اس زمرہ میں شامل {{PLURAL:$1|ہے|ہیں}}۔",
-       "category-file-count": "{{PLURAL:$2|اس Ø²Ù\85رÛ\81 Ù\85Û\8cÚº ØµØ±Ù\81 Ø¯Ø±Ø¬ Ø°Û\8cÙ\84 Ù\81ائÙ\84 Ù\85Ù\88جÙ\88د Û\81Û\92Û\94|اس Ø²Ù\85رÛ\81 Ú©Û\8c Ú©Ù\84 $2 Ù\81ائÙ\84Ù\88Úº Ù\85Û\8cÚº Ø³Û\92 $1 {{PLURAL:$1|Ù\81ائÙ\84\81ائÙ\84Û\8cÚº}} Ø¯Ø±Ø¬ ذیل {{PLURAL:$1|ہے|ہیں}}}}۔",
+       "category-file-count": "{{PLURAL:$2|اس Ø²Ù\85رÛ\81 Ù\85Û\8cÚº ØµØ±Ù\81 Ø¯Ø±Ø¬ Ø°Û\8cÙ\84 Ù\81ائÙ\84 Ù\85Ù\88جÙ\88د Û\81Û\92Û\94|اس Ø²Ù\85رÛ\81 Ú©Û\8c Ú©Ù\84 $2 Ù\81ائÙ\84Ù\88Úº Ù\85Û\8cÚº Ø³Û\92 $1 {{PLURAL:$1|Ù\81ائÙ\84\81ائÙ\84Û\8cÚº}} Ø­Ø³Ø¨ ذیل {{PLURAL:$1|ہے|ہیں}}}}۔",
        "category-file-count-limited": "درج ذیل {{PLURAL:$1|فائل|$1 فائلیں}} اس زمرہ میں شامل {{PLURAL:$1|ہے|ہیں}}۔",
        "listingcontinuesabbrev": "جاری۔",
        "index-category": "فہرست شدہ صفحات",
        "talk": "تبادلہٴ خیال",
        "views": "مشاہدات",
        "toolbox": "آلات",
-       "tool-link-userrights": "{{GENDER:$1|صارف}} کے گروہوں میں تبدیلی کریں",
+       "tool-link-userrights": "حلقہ ہائے {{GENDER:$1|صارف}} میں تبدیلی",
        "tool-link-emailuser": "اس {{GENDER:$1|صارف}} کو برقی خط لکھیں",
        "userpage": "صارف کا صفحہ دیکھیے",
        "projectpage": "منصوبہ کا صفحہ دیکھیے",
        "viewtalkpage": "تبادلۂ خیال دیکھیں",
        "otherlanguages": "دیگر زبانوں میں",
        "redirectedfrom": "($1 سے رجوع مکرر)",
-       "redirectpagesub": "لوٹایا گیا صفحہ",
+       "redirectpagesub": "رجوع مکرر",
        "redirectto": "رجوعِ مکرر از:",
        "lastmodifiedat": "اس صفحہ میں آخری بار مورخہ $1ء کو $2 بجے ترمیم کی گئی۔",
        "viewcount": "اِس صفحہ تک {{PLURAL:$1|ایک‌بار|$1 مرتبہ}} رسائی کی گئی",
        "editlink": "ترمیم",
        "viewsourcelink": "ماخذ دیکھیں",
        "editsectionhint": "ترمیم قطعہ: $1",
-       "toc": "Ù\85Ù\86درجات",
+       "toc": "Ù\81Û\81رست",
        "showtoc": "دکھائیں",
        "hidetoc": "چھپائیں",
        "collapsible-collapse": "خاتمے",
        "resetpass-expired": "آپ کے پاس ورد کی مدت ختم ہو چکی ہے۔ داخل ہونے کے لیے براہ کرم نیا پاس ورڈ بنائیں۔",
        "resetpass-expired-soft": "آپ کے پاس ورڈ کی مدت ختم ہو چکی ہے، لہذا اسے دوبارہ بنانے کی ضرورت ہے۔\nبراہ کرم نیا پاس ورڈ بنائیں، تاہم اگر مستقبل میں اس کی ترتیب نو مقصود ہو تو «{{int:authprovider-resetpass-skip-label}}» پر کلک کریں۔",
        "resetpass-validity-soft": "آپ کا پاس ورڈ درست نہیں: $1\n\nبراہ کرم نیا پاس ورڈ بنائیں، تاہم اگر مستقبل میں اس کی ترتیب نو مقصود ہو تو «{{int:authprovider-resetpass-skip-label}}» پر کلک کریں۔",
-       "passwordreset": "پارÙ\84Ù\81ظ Ú©Û\8c Ø¨Ø§Ø²ØªØ¹Û\8cÙ\86Û\8c",
+       "passwordreset": "پاس Ù\88رÚ\88 Ú©Û\8c ØªØ±ØªÛ\8cب Ù\86Ù\88",
        "passwordreset-text-one": "برقی خط کے ذریعہ عارضی پاس ورڈ حاصل کرنے کے لیے اس فارم کو پُر کریں۔",
        "passwordreset-text-many": "{{PLURAL:$1|برقی خط کے ذریعہ عارضی پاس ورڈ حاصل کرنے کے لیے کسی ایک خانے کو پُر کریں۔}}",
        "passwordreset-disabled": "اس ویکی پر پاس ورڈ کی ترتیب نو کی سہولت فعال نہیں ہے۔",
        "passwordreset-nocaller": "کالر کا فراہم کیا جانا لازمی ہے",
        "passwordreset-nosuchcaller": "کالر موجود نہیں: $1",
        "passwordreset-ignored": "پاس ورڈ کی ترتیب نو مکمل نہیں ہو سکی۔ شاید کوئی پرووائڈر فراہم نہیں کیا گیا؟",
-       "passwordreset-invalideamil": "نادرست برقی ڈاک پتا",
+       "passwordreset-invalidemail": "نادرست برقی ڈاک پتا",
        "passwordreset-nodata": "کوئی صارف نام اور نہ کوئی برقی ڈاک پتا فراہم کیا گیا",
-       "changeemail": "برقی ڈاک پتا تبدیل یا حذف کریں",
+       "changeemail": "برقی ڈاک پتے میں تبدیلی یا حذف شدگی",
        "changeemail-header": "اپنے برقی ڈاک پتے کو تبدیل کرنے کے لیے اس فارم کو پُر کریں۔ اگر آپ اپنے کھاتے سے منسلک کسی برقی ڈاک پتے کو ختم کرنا چاہتے ہیں تو فارم پُر کرنے کے دوران میں نئے برقی ڈاک پتے کا خانہ خالی چھوڑ دیں۔",
        "changeemail-no-info": "اِس صفحہ تک براہِ راست رسائی کیلئے آپ کو داخل ہونا پڑے گا۔",
        "changeemail-oldemail": "حالیہ برقی ڈاک پتہ:",
        "changeemail-submit": "برقی ڈاک تبدیل کریں",
        "changeemail-throttled": "آپ نے متعدد مرتبہ داخل ہونے کی کوشش کی ہے۔\nدوبارہ کوشش کرنے سے پہلے $1 انتظار فرمائیں۔",
        "changeemail-nochange": "براہ کرم کوئی دوسرا برقی ڈاک پتہ درج کریں۔",
-       "resettokens": "ٹوکنوں کو دوبارہ ترتیب دیں",
+       "resettokens": "ٹوکنوں کی ترتیب نو",
        "resettokens-no-tokens": "ترتیب نو کے لیے کوئی ٹوکن موجود نہیں۔",
        "resettokens-tokens": "ٹوکن:",
        "resettokens-token-label": "$1 (موجودہ قدر: $2)",
        "summary": "خلاصہ:",
        "subject": "عنوان:",
        "minoredit": "معمولی ترمیم",
-       "watchthis": "اس صفحہ کو زیر نظر کیحیے",
+       "watchthis": "اس صفحہ کو زیر نظر کریں",
        "savearticle": "محفوظ",
        "savechanges": "تبدیلیاں محفوظ کریں",
        "publishpage": "شائع کریں",
        "blocked-notice-logextract": "یہ صارف معطل ہے۔\nحوالہ کے لیے نوشتہ پابندی کا تازہ ترین اندراج ذیل میں دستیاب ہے:",
        "clearyourcache": "<strong>یاددہانی:</strong> محفوظ کرنے کے بعد ان تبدیلیوں کو دیکھنے کے لیے آپ کو اپنے براؤزر کا کیشے صاف کرنا ہوگا۔\n* '''فائرفاکس/ سفاری:''' جب ''Reload'' پر کلک کریں تو ''Shift'' دباکر رکھیں، یا ''Ctrl-F5'' یا ''Ctrl-R'' دبائیں (Mac پر ''R-⌘'')\n* '''گوگل کروم:''' ''Ctrl-Shift-R'' دبائیں (Mac پر ''Shift-R-⌘'')\n* '''انٹرنیٹ ایکسپلورر:''' جب ''Refresh'' پر کلک کریں تو ''Ctrl'' یا ''Ctrl-F5'' دبائیں\n* '''اوپیرا:'''  ''Tools → Preferences'' میں جائیں اور کیشے (cache) صاف کریں",
        "usercssyoucanpreview": "<strong>نکتہ:</strong> اپنی نئی سی ایس ایس کو جانچنے کے لیے اسے محفوظ کرنے سے قبل «{{int:showpreview}}» کی بٹن استعمال کریں۔",
-       "userjsyoucanpreview": "<strong>نکتہ:</strong> اپنی نئی جاوا اسکرپٹ کو جانچنے کے لیے اسے محفوظ کرنے سے قبل «{{int:showpreview}}» کی بٹن استعمال کریں۔",
+       "userjsyoucanpreview": "<strong>نکتہ:</strong>اپنی نئی جاوا اسکرپٹ کو  محفوظ کرنے سے قبل «{{int:showpreview}}» کی بٹن پر کلک کرکے جانچ لیں۔",
        "usercsspreview": "<strong>یاد رہے کہ اس وقت آپ اپنی سی ایس کی محض نمائش دیکھ رہے ہیں، یہ اب تک محفوظ نہیں ہوئی ہے!</strong>",
        "userjspreview": "<strong>یاد رہے کہ اس وقت آپ اپنی جاوا اسکرپٹ کی محض نمائش دیکھ/جانچ رہے ہیں، یہ اب تک محفوظ نہیں ہوئی ہے!</strong>",
        "sitecsspreview": "<strong>یاد رہے کہ اس وقت آپ اس سی ایس کی محض نمائش دیکھ رہے ہیں، یہ اب تک محفوظ نہیں ہوئی ہے!</strong>",
        "edit_form_incomplete": "<strong>خانہ ترمیم سے کچھ حصے سرور تک نہیں پہنچ سکے ہیں؛ براہ کرم اپنی ترامیم کو دوبارہ جانچ لیں کہ آیا وہ برقرار ہیں یا نہیں اور دوبارہ کوشش کریں۔</strong>",
        "editing": "آپ \"$1\" میں ترمیم کر رہے ہیں۔",
        "creating": "زیر تخلیق $1",
-       "editingsection": "$1 کے قطعہ کی ترمیم",
+       "editingsection": "«$1» کے قطعہ کی ترمیم",
        "editingcomment": "زیرترمیم $1 (نیا قطعہ)",
        "editconflict": "تنازعہ ترمیم:$1",
        "explainconflict": "آپکی تدوین شروع ہونے کے بعد شاید کسی نے یہ صفحہ تبدیل کردیا ہے.\nبالائی خانۂ متن میں صفحہ کا موجودہ مواد ہے.\nآپ کی تبدیلیاں نچلے متن خانہ میں دکھائی گئی ہیں.\nآپ کو اپنی تبدیلیاں موجودہ متن میں ضم کرنا ہوں گی.\n\"محفوظ\" کا بٹن ٹک کرنے سے '''صرف''' بالائی متن محفوظ ہوگا.",
        "prefswarning-warning": "ترجیحات میں آپ کی جانب سے کی جانے والی تبدیلیاں ابھی محفوظ نہیں ہوئی ہیں۔\nاگر آپ «$1» پر کلک کیے بغیر اس صفحہ کو چھوڑ دیں تو آپ کی تبدیلیاں محفوظ نہیں ہوگی۔",
        "prefs-tabs-navigation-hint": "نکتہ: مختلف خانوں میں جانے کے لیے آپ دائیں اور بائیں کی جہت نما کلیدیں استعمال کر سکتے ہیں۔",
        "userrights": "حقوقِ صارف کی نظامت",
-       "userrights-lookup-user": "گروہائے صارف کا انتظام",
+       "userrights-lookup-user": "حلقہ ہائے صارف کا انتظام",
        "userrights-user-editname": "کوئی اسم‌صارف داخل کیجئے:",
-       "editusergroup": "{{GENDER:$1|صارف}} کے گروہوں میں ترمیم کریں",
+       "editusergroup": "حلقہ ہائے {{GENDER:$1|صارف}} میں ترمیم کریں",
        "editinguser": "{{GENDER:$1|صارف}} <strong>[[User:$1|$1]]</strong> $2 کے اختیارات میں تبدیلی",
-       "userrights-editusergroup": "ترÙ\85Û\8cÙ\85 Ú¯Ø±Ù\88Û\81ائÛ\92 ØµØ§Ø±Ù\81",
-       "saveusergroups": "{{GENDER:$1|صارف}} کے گروہوں کو محفوظ کریں",
+       "userrights-editusergroup": "Ø­Ù\84Ù\82Û\81 Û\81ائÛ\92 ØµØ§Ø±Ù\81 Ù\85Û\8cÚº ØªØ±Ù\85Û\8cÙ\85 Ú©Ø±Û\8cÚº",
+       "saveusergroups": "حلقہ ہائے {{GENDER:$1|صارف}} کو محفوظ کریں",
        "userrights-groupsmember": "رکنِ:",
        "userrights-groupsmember-auto": "اعتباری صارف در",
-       "userrights-groups-help": "آپ ان گروہان میں تبدیلی کرسکتے ہیں جن سے صارف متعلق ہے: \n* نشان زد خانہ کا مطلب یہ ہے کہ صارف کا تعلق اس گروہ سے ہے۔ \n* غیر نشان زد خانہ کا مطلب یہ ہے کہ صارف کا تعلق اس گروہ سے نہیں ہے۔ \n* یہ * علامت اس بات کا اشارہ ہے کہ آپ اس گروہ کو نہیں ہٹا سکتے جسے ایک مرتبہ آپ نے شامل کردیا ہو، یا اس کے بر عکس۔",
+       "userrights-groups-help": "آپ ان حلقوں میں تبدیلی کرسکتے ہیں جن سے صارف متعلق ہے: \n* نشان زد خانہ کا مطلب یہ ہے کہ صارف کا تعلق اس گروہ سے ہے۔ \n* غیر نشان زد خانہ کا مطلب یہ ہے کہ صارف کا تعلق اس گروہ سے نہیں ہے۔ \n* یہ * علامت اس بات کا اشارہ ہے کہ آپ اس گروہ کو نہیں ہٹا سکتے جسے ایک مرتبہ آپ نے شامل کردیا ہو، یا اس کے بر عکس۔",
        "userrights-reason": "وجہ:",
        "userrights-no-interwiki": "دوسرے ویکیوں پر حقوقِ صارف میں ترمیم کی آپ کو اجازت نہیں ہے.",
        "userrights-nodatabase": "ڈیٹابیس $1 موجود نہیں یا مقامی نہیں۔",
        "userrights-unchangeable-col": "مجموعات جو آپ تبدیل نہیں کرسکتے",
        "userrights-conflict": "اختیارات کی تبدیلی میں تنازعہ! براہ کرم نظر ثانی کریں اور اپنی تبدیلیوں کی تصدیق کریں۔",
        "userrights-removed-self": "آپ نے اپنے اختیارات ختم کر لیے ہیں، چنانچہ اب یہ صفحہ آپ کی دسترس سے باہر ہو گیا ہے۔",
-       "group": "گروہ:",
+       "group": "حلقہ:",
        "group-user": "صارفین",
        "group-autoconfirmed": "خود توثیق شدہ صارفین",
        "group-bot": "روبالات",
        "uploaderror": "اپلوڈ کے دوران میں نقص",
        "upload-recreate-warning": "<strong>انتباہ: اس نام کی فائل حذف یا منتقل کر دی گئی ہے۔</strong>\n\nآسانی کے لیے ذیل میں اس صفحہ کا نوشتہ منتقلی و حذف شدگی درج ہے:",
        "uploadtext": "فائلیں اپلوڈ کرنے کے لیے درج ذیل فارم پُر کریں۔\n\n'''اطلاع''': اگر آپ اپنی فائل اپلوڈ کرتے وقت خلاصہ کے خانے میں درج ذیل دو باتوں کی وضاحت نہیں کریں گے تو اس فائل کو حذف کیا جاسکتا ہے:\n# فائل کا '''مـاخـذ''' ، یعنی:\n#*اگر یہ آپ نے خود تخلیق کی ہے تو اسے بیان کریں۔\n#*اگر یہ آن لائن دستیاب ہے تو اس سائٹ کا  '''ربط''' درج کریں۔\n#*اگر آپ نے اسے کسی دوسری زبان کے {{SITENAME}} سے لیا ہے تو اس کا نام تحریر کریں۔\n#صاحب حق طبع و نشر اور فائل کے اجازت نامہ کے بارے میں:\n#* فائل کے اجازت نامہ کے متعلق یہ درج کریں کہ اس کی موجودہ حیثیت کیا ہے۔\n#*اگر آپ خود اسکا حق طبع و نشر رکھتے ہیں تو آپ پر لازم ہے کہ آپ اسے [[دائرۂ عام]] (پبلک ڈومین) میں بھی شائع کریں۔\n\nجب کوئی صارف مستقل ایسی فائل اپلوڈ کرتا رہے جس کے اجازت نامہ کے بارے میں غلط بیانی کی گئی ہو یا وہ مستقل ایسی تصاویر اپلوڈ کرے جن کے بارے میں کوئی وضاحت موجود نہ ہو تو ایسی صورت میں اس صارف پر پابندی لگائے جانے کا قوی امکان موجود ہے۔\n\nفائل اپلوڈ کرنے کے لیے ذیل میں موجود فارم استعمال کریں، اگر آپ جملہ اپلوڈ کردہ تصاویر کو دیکھنا یا تلاش کرنا چاہتے ہیں تو [[Special:FileList|اس فہرست]] کو ملاحظہ فرمائیں۔ <br /> تمام اپلوڈ کردہ و حذف شدہ تصاویر کو [[Special:Log/upload|نوشتۂ منتقلی]] اور [[Special:Log/delete|نوشتہ حذف شدگی]] میں درج کر لیا جاتا ہے۔\n\nتصویر کی منتقلی کے بعد، اس کو کسی صفحہ پر رکھنے کیلیے مندرجہ ذیل طریقہ سے استعمال کریں۔\n\n'''<nowiki>[[تصویر:فائل کا نام|متبادل متن]]</nowiki>'''\n\n* فائل کا ربط درج کرنے کے لیے۔ '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>'''\n* فائل کا نام چھوٹے بڑے حروف کے معاملہ میں حساس ہے لہذا اگر اپلوڈ کرتے وقت فائل کا نام -- name:JPG  ہے اور آپ name:jpg یــا Name:jpg کا ربط درج کرتے ہیں تو ربط کام نہیں کرے گا۔",
-       "upload-permitted": "اجازت یافتہ فائلوں کی {{PLURAL:$2|قسم|قسمیں}}: $1",
+       "upload-permitted": "فائلوں کی اجازت یافتہ {{PLURAL:$2|قسم|قسمیں}}: $1",
        "upload-preferred": "ترجیحی فائلوں کی {{PLURAL:$2|قسم|قسمیں}}: $1",
        "upload-prohibited": "ممنوع فائلوں کی {{PLURAL:$2|قسم|قسمیں}}: $1",
        "uploadlogpage": "نوشتہ اپلوڈ",
        "filestatus": "کاپی رائٹ کی صورت حال:",
        "filesource": "ذرائع",
        "ignorewarning": "انتباہ نظر انداز کرتے ہوئے فائل کو بہرصورت محفوظ کر لیا جائے",
-       "ignorewarnings": "ہر انتباہ نظرانداز کردیا جاۓ۔",
+       "ignorewarnings": "تمام انتباہات کو نظر انداز کریں",
        "minlength1": "فائل کے ناموں میں کم از کم ایک حرف ہونا ضروری ہے۔",
        "illegalfilename": "اس فائل کے نام \"$1\" میں ایسے حروف موجود ہیں جو صفحہ کے عنوانات میں ممنوع ہیں۔\nبراہ کرم فائل کا نام تبدیل کرکے دوبارہ اپلوڈ کرنے کی کوشش کریں۔",
        "filename-toolong": "فائل کے نام 240 بائٹ سے زیادہ طویل نہ ہوں۔",
        "upload-maxfilesize": "فائل کا زیادہ سے زیادہ حجم: $1",
        "upload-description": "فائل کی وضاحت",
        "upload-options": "اپلوڈ کے اختیارات",
-       "watchthisupload": "یہ صفحہ زیر نظر کریں",
+       "watchthisupload": "اس فائل کو زیر نظر کریں",
        "upload-proto-error": "غلط پروٹوکول",
        "upload-file-error": "داخلی نقص",
        "upload-misc-error": "اپلوڈ کے دوران میں نامعلوم نقص",
        "upload-dialog-disabled": "اس ویکی پر اس ڈائیلاگ سے فائل اپ لوڈز غیر فعال ہیںَ",
        "upload-dialog-title": "فائل اپلوڈ کریں",
        "upload-dialog-button-cancel": "منسوخ",
+       "upload-dialog-button-back": "پیچھے جائیں",
        "upload-dialog-button-done": "مکمل",
        "upload-dialog-button-save": "محفوظ",
        "upload-dialog-button-upload": "اپلوڈ",
        "upload-curl-error6-text": "فراہم کردہ یوآرایل قابل رسائی نہیں ہے۔\nبراہ کرم اس یوآرایل کو دوبارہ جانچ لیں کہ آیا وہ درست ہے اور متعلقہ سائٹ فعال ہے یا نہیں۔",
        "upload-curl-error28": "اپلوڈ کی مہلت ختم",
        "upload-curl-error28-text": "یہ سائٹ جواب دینے میں بہت زیادہ وقت لے رہی ہے۔\nبراہ کرم اس سائٹ کو جانچ لیں کہ آیا وہ فعال ہے یا نہیں، اور کچھ دیر انتظار کرنے کے بعد دوبارہ کوشش کریں۔\nشاید آپ اسے کم مصروف وقت میں آزمانا چاہیں۔",
-       "license": "اجازہ:",
+       "license": "اجازت نامہ:",
        "license-header": "اجازہ کاری",
        "nolicense": "غیر منتخب",
        "licenses-edit": "اجازت نامہ کے اختیارات میں ترمیم کریں",
        "listduplicatedfiles": "مکررات کے ساتھ فائلوں کی فہرست",
        "listduplicatedfiles-summary": "اس صفحہ میں ان فائلوں کی فہرست موجود ہے جن کا حالیہ نسخہ کسی دوسری فائل کے تازہ ترین نسخہ کی نقل ہے۔ اس فہرست میں محض مقامی فائلیں درج کی گئی ہیں۔",
        "listduplicatedfiles-entry": "[[:File:$1|$1]] [[$3|{{PLURAL:$2|کی ایک نقل ہے|$2 نقلیں ہیں}}]]۔",
-       "unusedtemplates": "غیر استعمال شدہ سانچے",
+       "unusedtemplates": "غیر مستعمل سانچے",
        "unusedtemplatestext": "اس صفحہ میں {{ns:template}} نام فضا کے ان تمام صفحات کی فہرست درج ہے جو کسی دوسرے صفحہ میں شامل نہیں ہیں۔\nانہیں حذف کرنے سے قبل سانچوں سے مربوط دیگر صفحات کو جانچنا نہ بھولیں۔",
        "unusedtemplateswlh": "دیگر روابط",
        "randompage": "جستہ جستہ مطالعہ",
        "withoutinterwiki-summary": "درج ذیل صفحات دوسری زبان کے صفحات سے مربوط نہیں ہیں۔",
        "withoutinterwiki-legend": "سابقہ",
        "withoutinterwiki-submit": "دکھائیں",
-       "fewestrevisions": "کم نظرِ ثانی شدہ مضامین",
+       "fewestrevisions": "کم ترامیم کے حامل صفحات",
        "nbytes": "$1 {{PLURAL:$1|بائٹ}}",
        "ncategories": "{{PLURAL:$1|زمرہ|زمرہ جات}} $1",
        "ninterwikis": "$1 {{PLURAL:$1|بین الویکی ربط|بین الویکی روابط}}",
        "uncategorizedcategories": "بے زمرہ زمرہ جات",
        "uncategorizedimages": "بے زمرہ تصاویر",
        "uncategorizedtemplates": "غیر زمرہ بند سانچہ جات",
-       "unusedcategories": "غیر استعمال شدہ زمرہ جات",
-       "unusedimages": "غیر استعمال شدہ فائلیں",
+       "unusedcategories": "غیر مستعمل زمرہ جات",
+       "unusedimages": "غیر مستعمل فائلیں",
        "wantedcategories": "مطلوبہ زمرہ جات",
-       "wantedpages": "درخواست شدہ مضامین",
+       "wantedpages": "مطلوبہ مضامین",
        "wantedpages-summary": "ذیل میں ان غیر موجود صفحات کی فہرست ہے جن سے بہت سارے روابط مربوط ہیں، البتہ ان میں وہ صفحات شامل نہیں جن میں محض ان سے مربوط رجوع مکررات موجود ہیں۔ ان صفحوں کو دیکھنے کے لیے [[{{#special:BrokenRedirects}}|شکستہ روابط کی فہرست]] ملاحظہ فرمائیں۔",
        "wantedpages-badtitle": "نتائج میں نادرست عنوان: $1",
        "wantedfiles": "مطلوب تصاویر",
        "listusers-noresult": "یہ صارف نہیں ملا",
        "listusers-blocked": "(مسدود)",
        "activeusers": "متحرک صارفین کی فہرست",
-       "activeusers-intro": "ذیل میں ان صارفین کی فہرست ہے جو گزشتہ $1 {{PLURAL:$1|دن|دنوں}} میں کسی وقت فعال رہے ہوں۔",
+       "activeusers-intro": "ذیل میں ان صارفین کی فہرست ہے جو گزشتہ $1 {{PLURAL:$1|دن|دنوں}} میں کسی بھی قسم کی سرگرمی میں شریک رہے ہوں۔",
        "activeusers-count": "گزشتہ {{PLURAL:$3|دن|$3 دنوں}} میں $1 {{PLURAL:$1|اقدام|اقدامات}}",
        "activeusers-from": "اس حرف سے شروع ہونے والے صارفین کے نام دکھائیں:",
-       "activeusers-hidebots": "پوشیدہ خود کار صارف",
-       "activeusers-hidesysops": "پوشیدہ منتظمین",
        "activeusers-noresult": "یہ صارف نہیں مل سکا",
        "activeusers-submit": "فعال صارفین دکھائیں",
-       "listgrouprights": "صارÙ\81 Ú¯Ø±Ù\88Û\81Ù\88Úº کے اختیارات",
-       "listgrouprights-summary": "ذیل میں اس ویکی پر موجود صارف گروہوں کی فہرست درج ہے۔ اس میں دائیں جانب گروہ کا نام اور بائیں جانب متعلقہ گروہ کو حاصل شدہ اختیارات کی تفصیل بیان کی گئی ہے۔\nانفرادی اختیارات کے متعلق [[{{MediaWiki:Listgrouprights-helppage}}|اضافی معلومات یہاں]] دیکھی جا سکتی ہیں۔",
+       "listgrouprights": "Ø­Ù\84Ù\82Û\81 ØµØ§Ø±Ù\81Û\8cÙ\86 کے اختیارات",
+       "listgrouprights-summary": "ذیل میں اس ویکی پر موجود صارف حلقوں کی فہرست درج ہے۔ اس میں دائیں جانب حلقے کا نام اور بائیں جانب متعلقہ حلقے کو حاصل شدہ اختیارات کی تفصیل بیان کی گئی ہے۔\nانفرادی اختیارات کے متعلق [[{{MediaWiki:Listgrouprights-helppage}}|اضافی معلومات یہاں]] دیکھی جا سکتی ہیں۔",
        "listgrouprights-key": "عنوان:\n* <span class=\"listgrouprights-granted\">تفویض کردہ اختیارات</span>\n* <span class=\"listgrouprights-revoked\">منسوخ کردہ اختیارات</span>",
-       "listgrouprights-group": "گروہ",
+       "listgrouprights-group": "حلقہ",
        "listgrouprights-rights": "اختیارات",
-       "listgrouprights-helppage": "Help:اختیاراتِ گروہ",
+       "listgrouprights-helppage": "Help:اختیاراتِ حلقہ",
        "listgrouprights-members": "(اراکین کی فہرست)",
-       "listgrouprights-addgroup": "{{PLURAL:$2|اس گروہ|ان گروہوں}} میں شامل کرنے کا اختیار ہے: \n\n$1",
-       "listgrouprights-removegroup": "{{PLURAL:$2|اس گروہ|ان گروہوں}} سے ہٹانے کا اختیار ہے: \n\n$1",
-       "listgrouprights-addgroup-all": "تمام گروہوں کا ا ضافہ کریں",
-       "listgrouprights-removegroup-all": "تمام گروہوں کو ہٹانے کا اختیار ہے",
-       "listgrouprights-addgroup-self": "{{PLURAL:$2|اس گروہ|ان گروہوں}} میں از خود شامل ہونے کا اختیار ہے: \n\n$1",
-       "listgrouprights-removegroup-self": "{{PLURAL:$2|اس گروہ|ان گروہوں}} سے از خود نکلنے کا اختیار ہے: \n\n$1",
-       "listgrouprights-addgroup-self-all": "تمام گروہوں میں از خود شامل ہونے کا اختیار ہے",
-       "listgrouprights-removegroup-self-all": "تمام گروہوں سے از خود نکلنے کا اختیار ہے",
+       "listgrouprights-addgroup": "{{PLURAL:$2|اس حلقہ|ان حلقوں}} میں شامل کرنے کا اختیار ہے: \n\n$1",
+       "listgrouprights-removegroup": "{{PLURAL:$2|اس حلقہ|ان حلقوں}} سے ہٹانے کا اختیار ہے: \n\n$1",
+       "listgrouprights-addgroup-all": "تمام حلقوں کا ا ضافہ کریں",
+       "listgrouprights-removegroup-all": "تمام حلقوں کو ہٹانے کا اختیار ہے",
+       "listgrouprights-addgroup-self": "{{PLURAL:$2|اس حلقہ|ان حلقوں}} میں از خود شامل ہونے کا اختیار ہے: \n\n$1",
+       "listgrouprights-removegroup-self": "{{PLURAL:$2|اس حلقہ|ان حلقوں}} سے از خود نکلنے کا اختیار ہے: \n\n$1",
+       "listgrouprights-addgroup-self-all": "تمام حلقوں میں از خود شامل ہونے کا اختیار ہے",
+       "listgrouprights-removegroup-self-all": "تمام حلقوں سے از خود نکلنے کا اختیار ہے",
        "listgrouprights-namespaceprotection-header": "نام فضا پابندیاں",
        "listgrouprights-namespaceprotection-namespace": "فضائے نام",
        "listgrouprights-namespaceprotection-restrictedto": "ترمیم کی اجازت دینے والے اختیار(ات)",
        "contributions-title": "صارف $1 کی شراکتیں",
        "mycontris": "شراکتیں",
        "anoncontribs": "شراکتیں",
-       "contribsub2": "برائے {{GENDER:$3|$1}} ($2)",
+       "contribsub2": "{{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "«$1» کے نام سے صارف کھاتہ مندرج نہیں ہے۔",
        "nocontribs": "اس معیار کے مطابق کوئی ترمیم دستیاب نہیں ہوئی۔",
-       "uctop": "(موجودہ)",
+       "uctop": "(موجودہ نسخہ)",
        "month": "مہینہ (اور اُس سے قبل):",
        "year": "سال (اور اُس سے قبل):",
        "sp-contributions-newbies": "محض جدید صارفین کی شراکتیں دکھائیں",
        "sp-contributions-hideminor": "معمولی ترامیم چھپائیں",
        "sp-contributions-submit": "تلاش",
        "whatlinkshere": "مربوط صفحات",
-       "whatlinkshere-title": "\"$1\" سے مربوط صفحات",
+       "whatlinkshere-title": "«$1» سے مربوط صفحات",
        "whatlinkshere-page": "صفحہ:",
        "linkshere": "<strong>[[:$1]]</strong> سے درج ذیل صفحات مربوط ہیں:",
        "nolinkshere": "<strong>[[:$1]]</strong> سے کوئی صفحہ مربوط نہیں ہے۔",
        "whatlinkshere-next": "{{PLURAL:$1|اگلا|اگلے $1}}",
        "whatlinkshere-links": "→ روابط",
        "whatlinkshere-hideredirs": "رجوع مکررات $1",
-       "whatlinkshere-hidetrans": "$1 استعمالات",
+       "whatlinkshere-hidetrans": "استعمالات $1",
        "whatlinkshere-hidelinks": "روابط $1",
        "whatlinkshere-hideimages": "تصویر کے روابط $1",
        "whatlinkshere-filters": "مقطارات",
        "bad_image_list": "فارمیٹ درج ذیل ہے:\n\nمحض فہرست میں موجود مندرجات (* سے شروع ہونے والی سطریں) شامل سمجھے جائیں گے۔\nسطر میں پہلا ربط کسی خراب فائل کا ہونا لازمی ہے۔\nاُسی سطر کے بقیہ روابط کو مستثنیٰ سمجھا جائے گا، مثلاً وہ صفحات جن میں فائل سطر میں موجود ہوں۔",
        "metadata": "میٹا ڈیٹا",
        "metadata-help": "اِس فائل میں اِضافی معلومات شامل ہیں، جو شاید اُس ڈیجیٹل کیمرے یا سکینر سے آئی ہیں جس کے ذریعے یہ فائل بنائی گئی تھی۔\nاگر فائل اپنی اصل حالت میں نہ ہو تو کچھ معلومات ترمیم شدہ فائل کی مکمل طور پر عکاسی نہیں کر پائیں گی۔",
-       "metadata-expand": "تÙ\81صÛ\8cÙ\84Û\8c Ù\85عÙ\84Ù\88Ù\85ات دکھائیں",
-       "metadata-collapse": "Ø·Ù\88Û\8cÙ\84 ØªÙ\81اصÛ\8cÙ\84 Ú\86ھپاؤ",
+       "metadata-expand": "اضاÙ\81Û\8c ØªÙ\81صÛ\8cÙ\84ات دکھائیں",
+       "metadata-collapse": "اضاÙ\81Û\8c ØªÙ\81صÛ\8cÙ\84ات Ú\86ھپائÛ\8cÚº",
        "metadata-fields": "تصویر کے میٹاڈیٹا کے وہ خانے جو اس پیغام میں درج ہیں وہ تصویر کے صفحے پر شامل ہوتے ہیں نیز یہ اس وقت ظاہر ہوتے ہیں جب میٹاڈیٹا کو وسیع کیا جائے۔\nالبتہ دیگر خانے ابتدائی طور پر پوشیدہ ہوتے ہیں۔\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-imagewidth": "چوڑائی",
        "exif-imagelength": "لمبائی",
        "autosumm-blank": "تمام مندرجات حذف",
        "autosumm-replace": "\"$1\" سے مواد کی تبدیلی",
        "autoredircomment": "[[$1]] سے رجوع مکرر",
-       "autosumm-new": "نے «$1» مواد پر مشتمل نیا صفحہ بنایا",
+       "autosumm-new": "«$1» مواد پر مشتمل نیا صفحہ بنایا",
        "autosumm-newblank": "خالی صفحہ بنایا",
        "size-bytes": "$1 بائٹ",
        "size-kilobytes": "$1 کلوبائٹ",
        "blankpage": "خالی صفحہ",
        "intentionallyblankpage": "اس صفحہ کو دانستہ خالی چھوڑا گیا ہے۔",
        "external_image_whitelist": "#اس سطر کو ہو بہو ایسا ہی رہنے دیں<pre>\n#ذیل میں ریجیکس کی عبارتیں درج کریں (محض // کے درمیان)\n#ان عبارتوں کی بیرونی تصویروں کے روابط سے مطابقت کی جائے گی\n#جو مطابق ہو جائیں وہ تصویر کے طور پر نظر آئیں گے ورنہ محض تصویر کا ربط ظاہر ہوگا\n# علامت # سے شرع ہونے والی سطروں کو تبصرہ سمجھا جائے گا\n#چھوٹے بڑے حروف کو نظر انداز کیا جائے گا\n\nریجیکس کی تمام عبارتوں کو اس سطر کے اوپر رکھیں۔ اس سطر کو ہو بہو ایسا ہی رہنے دیں</pre>",
-       "tags": "تبدÛ\8cÙ\84Û\8c Ú©Û\92 Ø¯Ø±Ø³Øª ٹیگ",
+       "tags": "درست ØªØ¨Ø¯Û\8cÙ\84Û\8c Ú©Û\92 ٹیگ",
        "tag-filter": "مقطار [[Special:Tags|ٹیگ]]:",
        "tag-filter-submit": "مقطار",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ٹیگ}}]]: $2)",
        "htmlform-cloner-create": "مزید اضافہ کریں",
        "htmlform-cloner-delete": "حذف",
        "htmlform-cloner-required": "کم ازکم ایک قدر درکار ہے۔",
+       "htmlform-date-placeholder": "YYYY-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "YYYY-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "آپ کی درج کردہ قدر تسلیم شدہ تاریخ نہیں ہے۔ براہ کرم YYYY-MM-DD فارمیٹ استعمال کرنے کی کوشش کریں۔",
+       "htmlform-time-invalid": "آپ کی درج کردہ قدر تسلیم شدہ وقت نہیں ہے۔ براہ کرم HH:MM:SS فارمیٹ استعمال کرنے کی کوشش کریں۔",
+       "htmlform-datetime-invalid": "آپ کی درج کردہ قدر تسلیم شدہ تاریخ اور وقت نہیں ہے۔ براہ کرم YYYY-MM-DD HH:MM:SS فارمیٹ استعمال کرنے کی کوشش کریں۔",
        "htmlform-title-badnamespace": "[[:$1]] صفحہ \"{{ns:$2}}\" نام فضا میں موجود نہیں۔",
        "htmlform-title-not-creatable": "«$1» عنوان قابل تخلیق نہیں",
        "htmlform-title-not-exists": "$1 موجود نہیں ہے۔",
        "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 نے {{GENDER:$6|$3}} کی گروہی رکنیت از $4 تا $5 {{GENDER:$2|تبدیل کی}}",
-       "logentry-rights-rights-legacy": "$1 Ù\86Û\92 $3 Ú©Û\8c Ú¯Ø±Ù\88Û\81Û\8c Ø±Ù\88Ú©Ù\86Û\8cت کو {{GENDER:$2|تبدیل کیا}}",
+       "logentry-rights-rights": "$1 نے {{GENDER:$6|$3}} کا حلقہ صارف از $4 تا $5 {{GENDER:$2|تبدیل کی}}",
+       "logentry-rights-rights-legacy": "$1 Ù\86Û\92 $3 Ú©Û\92 Ø­Ù\84Ù\82Û\81 ØµØ§Ø±Ù\81 کو {{GENDER:$2|تبدیل کیا}}",
        "logentry-rights-autopromote": "$1 کو خودکار طور پر $4 سے $5 پر {{GENDER:$2|ترقی مل گئی}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|اپلوڈ}} $3",
        "logentry-upload-overwrite": "$1 نے $3 کا نیا نسخہ {{GENDER:$2|اپلوڈ کیا}}",
        "feedback-external-bug-report-button": "تکنیکی خامی کی اطلاع دیں",
        "feedback-dialog-title": "تبصرہ روانہ کریں",
        "feedback-dialog-intro": "اپنا تبصرہ شائع کرنے کے لیے ذیل میں موجود فارم کو استعمال کر سکتے ہیں۔ آپ کا تبصرہ آپ کے صارف نام کے ساتھ صفحہ «$1» میں شامل کر دیا جائے گا۔",
-       "feedback-error-title": "نقص",
        "feedback-error1": "نقص: اے پی آئی کی جانب سے غیر معروف نتیجہ",
        "feedback-error2": "نقص: ترمیم ناکام ہو گئی",
        "feedback-error3": "نقص: اے پی آئی سے کوئی جواب نہیں",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|بائٹ}}",
        "limitreport-expansiondepth": "توسیع کی بلند ترین گہرائی",
        "limitreport-expensivefunctioncount": "کثیر الاستعمال پارسر فنکشنوں کی تعداد",
-       "expandtemplates": "سانچے کو وسیع کریں",
+       "expandtemplates": "سانچوں کی توسیع",
        "expand_templates_intro": "اس خصوصی صفحہ میں ویکی کی عبارتوں کو اخذ کرکے ان میں موجود تمام مستعمل سانچوں کو کھولا جاتا ہے۔\nنیز اس صفحہ میں <code><nowiki>{{</nowiki>#language:…}}</code> جیسے پارسر فنکشنوں اور <code><nowiki>{{</nowiki>CURRENTDAY}}</code> جیسے متغیرات کی معاونت بھی رکھی گئی ہے۔\nدرحقیقت یہاں ہر چیز کو دوہرے محرابی قوسین میں کھول دیا جاتا ہے۔",
        "expand_templates_title": "اس عبارت کا عنوان، مثلاً {{FULLPAGENAME}} وغیرہ کے لیے:",
        "expand_templates_input": "ان پٹ متن:",
index 71b389f..99ab540 100644 (file)
                        "Arystanbek",
                        "6ahodir",
                        "Таржимон",
-                       "Ximik1991"
+                       "Ximik1991",
+                       "Bmansurov"
                ]
        },
-       "tog-underline": "Havolalarning tagiga chizish:",
+       "tog-underline": "Havolaning tagiga chizish:",
        "tog-hideminor": "Yangi oʻzgarishlar roʻyxatida kichik tahrirlarni yashirish",
        "tog-hidepatrolled": "Yangi oʻzgarishlar roʻyxatida tekshirilgan tahrirlarni yashirish",
        "tog-newpageshidepatrolled": "Yangi sahifalar roʻyxatidan tekshirilgan sahifalarni yashirish",
        "tog-diffonly": "Versiyalar taqqoslanayotganda, pastda sahifa matni koʻrsatilmasin",
        "tog-showhiddencats": "Yashirin turkumlarni koʻrsatish",
        "tog-norollbackdiff": "Tahrir qaytarilganda, versiyalar taqqosi koʻrsatilmasin",
-       "tog-useeditwarning": "Oʻzgarishlarni saqlamay sahifadan chiqib ketayotganim haqida ogohlantirish",
+       "tog-useeditwarning": "Oʻzgarishlarni saqlamay sahifadan chiqib ketayotganim haqida ogohlantir",
        "tog-prefershttps": "Doim himoyalangan holda kirish",
        "underline-always": "Har doim",
        "underline-never": "Hech qachon",
-       "underline-default": "Brauzer moslamari boʻyicha",
+       "underline-default": "Bezak mavzusi yoki brauzer andozasi boʻyicha",
        "editfont-style": "Tahrirlash maydonidagi shrift turi:",
-       "editfont-default": "Brauzer moslamari boʻyicha",
+       "editfont-default": "Brauzer andozasi boʻyicha",
        "editfont-monospace": "Teng enli shrift (Monospaced)",
        "editfont-sansserif": "Kertiksiz shrift (Sans-serif)",
        "editfont-serif": "Kertikli shrift (Serif)",
        "oct": "Okt",
        "nov": "Noy",
        "dec": "Dek",
-       "january-date": "Yanvar $1",
-       "february-date": "Fevral $1",
-       "march-date": "Mart $1",
-       "april-date": "Aprel $1",
-       "may-date": "$1-may",
-       "june-date": "Iyun $1",
-       "july-date": "Iyul $1",
+       "january-date": "$1 yanvar",
+       "february-date": "$1 fevral",
+       "march-date": "$1 mart",
+       "april-date": "$1 aprel",
+       "may-date": "$1 may",
+       "june-date": "$1 iyun",
+       "july-date": "$1 iyul",
        "august-date": "Avgust $1",
        "september-date": "Sentabr $1",
        "october-date": "Oktabr $1",
        "yourpasswordagain": "Maxfiy so‘zni qayta kiriting:",
        "createacct-yourpasswordagain": "Maxfiy soʻzni tasdiqlang",
        "createacct-yourpasswordagain-ph": "Maxfiy soʻzni yana bir bor kiriting",
-       "remembermypassword": "Hisob ma’lumotlarim ushbu brauzerda eslab qolinsin (ko‘pi bilan $1 {{PLURAL:$1|kunga|kunga}})",
        "userlogin-remembermypassword": "Kirgan deb esda saqla",
        "userlogin-signwithsecure": "Himoyalangan holda kirish",
        "yourdomainname": "Sizning domeningiz:",
        "listusers-blocked": "(chetlashtirilgan)",
        "activeusers": "Faol foydalanuvchilar roʻyxati",
        "activeusers-from": "Quyidagidan boshlanuvchi foydalanuvchilarni koʻrsatish:",
-       "activeusers-hidebots": "Botlarni yashirish",
-       "activeusers-hidesysops": "Maʼmurlarni yashirish",
        "activeusers-noresult": "Foydalanuvchilar topilmadi.",
        "listgrouprights": "Foydalanuvchilar guruhlari roʻyxati",
        "listgrouprights-summary": "Har bir viki-loyihada boʻlgani kabi, Oʻzbekcha Vikipediyada ham foydalanuvchilar bir nechta guruhlarga boʻlingan boʻlib, quyida ularning roʻyxati va tegishli huquqlari keltirilgan. Alohida huquqlar haqida [[{{MediaWiki:Listgrouprights-helppage}}|qoʻshimcha maʼlumotlar]] boʻlishi mumkin.",
index 42c3a28..9446b05 100644 (file)
@@ -88,7 +88,7 @@
        "march": "marso",
        "april": "avril",
        "may_long": "majo",
-       "june": "giugno",
+       "june": "zugno",
        "july": "lujo",
        "august": "agosto",
        "september": "setenbre",
        "march-gen": "marso",
        "april-gen": "avril",
        "may-gen": "majo",
-       "june-gen": "giugno",
+       "june-gen": "zugno",
        "july-gen": "lujo",
        "august-gen": "agosto",
        "september-gen": "setenbre",
        "yourpasswordagain": "De novo la password:",
        "createacct-yourpasswordagain": "Conferma la password",
        "createacct-yourpasswordagain-ph": "Inserissi da novo la password",
-       "remembermypassword": "Tiente in mente la password su sto conputer (par un massimo de $1 {{PLURAL:$1|zorno|zorni}})",
        "userlogin-remembermypassword": "Tienme colegà",
        "userlogin-signwithsecure": "Entra con na conesion segura",
        "yourdomainname": "Spesifegare el dominio",
        "newarticle": "(Novo)",
        "newarticletext": "Te ghe sì 'ndà drio a un colegamento a na pagina che no esiste gnancora.\nSe te voli crear sta pagina, taca scrìvar el testo in te la casèla qua soto\n(varda le [$1 pagine de ajuto] par saverghene de pì).\nSe te sì rivà qua par sbajo, basta che te struchi '''Indrìo''' sul to browser.",
        "anontalkpagetext": "----''Sta qua la xe la pagina de discussion de un utente anonimo che no'l se gà gnancora registrà o che no'l xe entrà col so nome utente.\nDe conseguenza xè necessario identificarlo tramite l'indirizo IP numerico.\nSto indirizo el pode èssar doparà da tanti utenti.\nSe te sì un utente anonimo e te ghè ricevù dei messagi che te secondo ti i gera par qualchedun altro, te podi [[Special:CreateAccount|registrarte]] o [[Special:UserLogin|entrar col to nome utente]] par evitar confusion con altri utenti anonimi in futuro.''",
-       "noarticletext": "In sto momento no ghe xe nissun testo su sta pagina.\nTe pol [[Special:Search/{{PAGENAME}}|sercar el titolo de sta pagina]] in altre pagine,\no <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} sercar in tei registri ligà a sta pagina] o se nò [{{fullurl:{{FULLPAGENAME}}|action=edit}} canbiar la pagina]</span>.",
+       "noarticletext": "In sto momento no ghe xe nissun testo su sta pagina.\nTe pol [[Special:Search/{{PAGENAME}}|sercar el titolo de sta pagina]] in altre pagine,\no <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} sercar in tei registri ligà a sta pagina] o se nò [{{fullurl:{{FULLPAGENAME}}|action=edit}} creàr la pagina]</span>.",
        "noarticletext-nopermission": "In sto momento no ghe xe nissun testo su sta pagina.\nTe pol [[Special:Search/{{PAGENAME}}|sercar sto titolo de pagina]] in altre pagine,\no <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} sercar in tei registri ligà a sta pagina]</span>, ma no te ghè el parmesso de crear sta pagina.",
        "missing-revision": "Ła revixion #$1 de ła pàjina \"{{FULLPAGENAME}}\" nó ła existe.",
        "userpage-userdoesnotexist": "L'account \"<nowiki>$1</nowiki>\" no'l corisponde mìa a un utente registrà. Verifica se te voli dal bon crear o modificar sta pagina.",
        "searchprofile-advanced-tooltip": "Serca nei namespace personalixài",
        "search-result-size": "$1 ({{PLURAL:$2|na parola|$2 parole}})",
        "search-result-category-size": "{{PLURAL:$1|1 utente|$1 utenti}} ({{PLURAL:$2|1 sotocategoria|$2 sotocategorie}}, {{PLURAL:$3|1 file|$3 file}})",
-       "search-redirect": "(redirect $1)",
+       "search-redirect": "(rimando da $1)",
        "search-section": "(sesion $1)",
        "search-category": "(categoria $1)",
        "search-suggest": "Sercavito forsi: $1",
        "activeusers-intro": "Sta qua xe la lista dei utenti che ga fato calcossa {{PLURAL:$1|sto ultimo zorno|sti ultimi $1 zorni}}.",
        "activeusers-count": "$1 {{PLURAL:$1|asion}} {{PLURAL:$3|inte'l ultimo xorno|inte i ultimi $3 xorni}}",
        "activeusers-from": "Fà védar i utenti a partir da:",
-       "activeusers-hidebots": "Scondi i bot",
-       "activeusers-hidesysops": "Scondi i aministradori",
        "activeusers-noresult": "Nissun utente catà.",
        "listgrouprights": "Diriti dei grupi utenti",
        "listgrouprights-summary": "Sta qua la xe na lista dei grupi de utenti definìi su sta wiki, coi diriti asocià a ognuno.\nSe pol consultar anca dele altre [[{{MediaWiki:Listgrouprights-helppage}}|informassion in pi]] sui diriti individuali.",
        "whatlinkshere-prev": "{{PLURAL:$1|quel prima|i $1 prima}}",
        "whatlinkshere-next": "{{PLURAL:$1|quel dopo|i $1 dopo}}",
        "whatlinkshere-links": "← colegamenti",
-       "whatlinkshere-hideredirs": "$1 rimandi",
+       "whatlinkshere-hideredirs": "$1 rimandi",
        "whatlinkshere-hidetrans": "$1 inclusion",
        "whatlinkshere-hidelinks": "$1 colegamenti",
        "whatlinkshere-hideimages": "$1 colegamenti da file",
        "htmlform-no": "No",
        "htmlform-yes": "Sì",
        "htmlform-chosen-placeholder": "Selessiona na opzione",
-       "sqlite-has-fts": "$1 con la possibilità de riserca completa nel testo",
-       "sqlite-no-fts": "$1 sensa la possibilità de riserca completa nel testo",
        "logentry-delete-delete": "$1 {{GENDER:$2|el|la}} ga scansełà ła pajina $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|el|la}} ga ripristinà \"$3\"",
        "logentry-delete-event": "$1 {{GENDER:$2|el|la}} ga canbià ła vixibiłità de {{PLURAL:$5|n'asion del registro|$5 asion del registro}} de \"$3\": $4",
        "feedback-bugornote": "Se se xe in grado de descrivare el problema tenico riscontrà in maniera precixa, [$1 segnałare el bug]. In alternadiva, se pol doparar el moduło senplifegà cuà soto. El comento inserio el sarà xontà a ła pàjina \"[$3 $2]\", insieme al propio nome utente.",
        "feedback-cancel": "Anuła",
        "feedback-close": "Fato",
-       "feedback-error-title": "Eròr",
        "feedback-error1": "Eror: Da ła API xe rivà un rexultà nó riconosùo",
        "feedback-error2": "Eror: Nó xe sta posibiłe exeguir ła modifega",
        "feedback-error3": "Errore: Nisuna risposta da ła API",
        "feedback-submit": "Manda",
        "feedback-thanks": "Grasie! El to feedback el xe sta publicà a ła pàjina \"[$2 $1]\".",
        "feedback-thanks-title": "Grassie!",
-       "searchsuggest-search": "Serca",
+       "searchsuggest-search": "Serca drento de {{SITENAME}}",
        "searchsuggest-containing": "che contien...",
        "api-error-badaccess-groups": "Nó te si autorixà a cargar documenti so sta wiki.",
        "api-error-badtoken": "Eror interno: token fałà.",
index 0fdce19..f22471c 100644 (file)
        "yourpasswordagain": "Kirjutagat peitsana udes:",
        "createacct-yourpasswordagain": "Peitsanan vahvištoituz",
        "createacct-yourpasswordagain-ph": "Kirjutagat peitsana toškerdan",
-       "remembermypassword": "Panda muštho minun tulendandmused neciš kompjuteras (enintään $1 {{PLURAL:$1|päivä|päivää}})",
        "userlogin-remembermypassword": "Jäda sistemha",
        "yourdomainname": "Teiden domen:",
        "password-change-forbidden": "Teile ei sa vajehtada peitsanad neciš vikiš.",
        "undo-failure": "Ei voi tühjištada redakcijad, sikš miše läbiredakcijad konfliktuidas.",
        "undo-norev": "Ei voi endištada lehtpol't, sikš miše mugošt lehtpol't ei ole vai se om jo čutud.",
        "undo-summary": "Tühjitadud toižetuz $1, kudamban tegi $2 (arutelu)",
-       "cantcreateaccounttitle": "Ei voi säta registracijad",
        "viewpagelogs": "Ozutada aigkirjad necen lehtpolen täht",
        "nohistory": "Necen lehtpolen täht ei ole toižetusiden aigkirjad.",
        "currentrev": "Nügüdläine versii",
        "listusers-blocked": "(blokiruidud)",
        "activeusers": "Aktivižiden kävutajiden nimikirjutez",
        "activeusers-from": "Oyutada kävutajid, augotaden necišpäi:",
-       "activeusers-hidebots": "Peitta botid",
-       "activeusers-hidesysops": "Peitta administratorid",
        "activeusers-noresult": "Kävutajad ei olgoi löutud.",
        "listgrouprights": "Kävutajiden gruppiden oiktused",
        "listgrouprights-group": "Grupp",
        "htmlform-reset": "Tühjitada toižetused",
        "htmlform-selectorother-other": "Toine",
        "htmlform-yes": "Ka",
-       "sqlite-has-fts": " $1 täuz'tekstaižen ecindan tügedamiženke",
-       "sqlite-no-fts": " $1 täuz'tekstaižen ecindan tügedamižeta",
        "revdelete-restricted": "kaidendused administratoriden täht",
        "revdelete-unrestricted": "kaidendused heittud administratoriden täht",
        "logentry-newusers-create": "{{GENDER:$2|tegihe}} $1-kävutajaks",
index 31b213f..fa1c73e 100644 (file)
@@ -62,7 +62,7 @@
        "tog-enotifminoredits": "Gửi thư cho tôi cả những thay đổi nhỏ trong trang và tập tin",
        "tog-enotifrevealaddr": "Hiện địa chỉ thư điện tử của tôi trong thư thông báo",
        "tog-shownumberswatching": "Hiển thị số người đang xem",
-       "tog-oldsig": "Chữ ký hiện tại:",
+       "tog-oldsig": "Chữ ký hiện tại của bạn:",
        "tog-fancysig": "Xem chữ ký là mã wiki (không có liên kết tự động)",
        "tog-uselivepreview": "Xem trước trực tiếp",
        "tog-forceeditsummary": "Nhắc tôi khi tôi quên tóm lược sửa đổi",
@@ -79,7 +79,7 @@
        "tog-showhiddencats": "Hiển thị thể loại ẩn",
        "tog-norollbackdiff": "Bỏ qua bản so sánh sau khi lùi sửa",
        "tog-useeditwarning": "Cảnh báo khi tôi thoát trang sửa đổi mà chưa lưu trang",
-       "tog-prefershttps": "Luôn kết nối an toàn khi đăng nhập",
+       "tog-prefershttps": "Luôn kết nối an toàn khi đã đăng nhập",
        "underline-always": "Luôn luôn",
        "underline-never": "Không bao giờ",
        "underline-default": "Mặc định của giao diện hoặc trình duyệt",
        "newwindow": "(mở cửa sổ mới)",
        "cancel": "Hủy bỏ",
        "moredotdotdot": "Thêm nữa…",
-       "morenotlisted": "Danh sách này không có đầy đủ.",
+       "morenotlisted": "Danh sách này có thể không đầy đủ.",
        "mypage": "Trang cá nhân",
        "mytalk": "Tin nhắn",
        "anontalk": "Thảo luận",
        "talk": "Thảo luận",
        "views": "Các hiển thị",
        "toolbox": "Công cụ",
+       "tool-link-userrights": "Thay đổi nhóm {{GENDER:$1}}người dùng",
+       "tool-link-emailuser": "Gửi thư cho {{GENDER:$1}}người dùng này",
        "userpage": "Xem trang thành viên",
        "projectpage": "Xem trang dự án",
        "imagepage": "Xem trang tập tin",
        "createacct-yourpasswordagain-ph": "Nhập mật khẩu lần nữa",
        "userlogin-remembermypassword": "Giữ trạng thái đăng nhập",
        "userlogin-signwithsecure": "Sử dụng kết nối an toàn",
+       "cannotlogin-title": "Không thể đăng nhập",
+       "cannotlogin-text": "Không thể nào đăng nhập.",
        "cannotloginnow-title": "Không thể đăng nhập lúc này",
        "cannotloginnow-text": "Không thể đăng nhập khi đang dùng $1.",
+       "cannotcreateaccount-title": "Không thể mở tài khoản",
+       "cannotcreateaccount-text": "Chức năng mở tài khoản trực tiếp không được kích hoạt tại wiki này.",
        "yourdomainname": "Tên miền của bạn:",
        "password-change-forbidden": "Bạn không thể đổi mật khẩu trên wiki này.",
        "externaldberror": "Có lỗi khi xác nhận cơ sở dữ liệu bên ngoài hoặc bạn không được phép cập nhật tài khoản bên ngoài.",
        "eauthentsent": "Thư xác nhận đã được gửi cho địa chỉ thư điện tử được chỉ định. Trước khi bạn có thể nhận thư, bạn cần thực hiện hướng dẫn trong thư để xác nhận tài khoản thuộc về bạn.",
        "throttled-mailpassword": "Mật khẩu đã được gửi đến cho bạn trong vòng {{PLURAL:$1|$1 giờ|$1 giờ}} đồng hồ trở lại. Để tránh lạm dụng, chỉ có thể gửi mật khẩu $1 giờ đồng hồ một lần.",
        "mailerror": "Lỗi gửi thư : $1",
-       "acct_creation_throttle_hit": "Ai đó cùng [[địa chỉ IP]] với bạn đã mở {{PLURAL:$1|một tài khoản|$1 tài khoản}} ở đây trong vòng 24 giờ. Vì quy định hạn chế số tài khoản mở trên một địa chỉ IP nên bạn hiện không thể mở thêm được nữa dùng địa chỉ IP này.",
+       "acct_creation_throttle_hit": "Ai đó cùng địa chỉ IP với bạn đã mở {{PLURAL:$1|một tài khoản|$1 tài khoản}} ở đây vào $2 qua. Vì quy định hạn chế số tài khoản mở trên một địa chỉ IP nên bạn hiện không thể mở thêm được nữa dùng địa chỉ IP này.",
        "emailauthenticated": "Địa chỉ thư điện tử của bạn được xác nhận vào lúc $3 $2.",
        "emailnotauthenticated": "Địa chỉ thư điện tử của bạn chưa được xác nhận. Các chức năng sau sẽ không gửi thư điện tử.",
        "noemailprefs": "Hãy ghi một địa chỉ thư điện tử trong tùy chọn cá nhân để có thể sử dụng tính năng này.",
        "botpasswords-label-resetpassword": "Đặt lại mật khẩu",
        "botpasswords-label-grants": "Các quyền có liên quan:",
        "botpasswords-help-grants": "Các lượt cấp phép cho phép truy cập các quyền người dùng mà một tài khoản đã có sẵn. Xem thêm thông tin trong [[Special:ListGrants|bảng cấp phép]].",
-       "botpasswords-label-restrictions": "Hạn chế sử dụng:",
        "botpasswords-label-grants-column": "Cấp quyền",
        "botpasswords-bad-appid": "Bot có tên \"$1\" không hợp lệ.",
        "botpasswords-insert-failed": "Không thể thêm tên bot \"$1\". Nó đã được thêm vào chưa?",
        "botpasswords-updated-body": "Đã cập nhật mật khẩu cho bot “$1” của người dùng “$2”.",
        "botpasswords-deleted-title": "Bot mật khẩu đã bị xóa",
        "botpasswords-deleted-body": "Đã xóa mật khẩu cho bot “$1” của người dùng “$2”.",
-       "botpasswords-newpassword": "Mật khẩu mới để đăng nhập như <strong>$1</strong> là <strong>$2</strong>. <em>Xin hãy ghi lại mật khẩu này để mai mốt tham khảo.</em>",
+       "botpasswords-newpassword": "Mật khẩu mới để đăng nhập như <strong>$1</strong> là <strong>$2</strong>. <em>Xin hãy ghi lại mật khẩu này để mai mốt tham khảo.</em> <br> (Các bot cũ cần tên đăng nhập khớp với tên người dùng cuối cùng có thể sử  dụng tên người dùng <strong>$3</strong> và mật khẩu <strong>$4</strong>.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider không có sẵn.",
        "botpasswords-restriction-failed": "Mật khẩu bot giới hạn ngăn chặn đăng nhập này.",
        "botpasswords-invalid-name": "Tên người dùng đã chỉ định không chứa dấu tách mật khẩu bot (\"$1\").",
        "passwordreset-nocaller": "Yêu cầu hàm gọi",
        "passwordreset-nosuchcaller": "Hàm gọi không tồn tại: $1",
        "passwordreset-ignored": "Tác vụ đặt lại mật khẩu không được xử lý. Có lẽ trình cung cấp chưa được cấu hình?",
-       "passwordreset-invalideamil": "Địa chỉ thư điện tử không hợp lệ",
+       "passwordreset-invalidemail": "Địa chỉ thư điện tử không hợp lệ",
        "passwordreset-nodata": "Cả tên người dùng và địa chỉ thư điện tử bị thiếu",
        "changeemail": "Đổi hoặc gỡ địa chỉ thư điện tử",
        "changeemail-header": "Điền biểu mẫu này để đổi địa chỉ thư điện tử của bạn. Nếu bạn muốn gỡ địa chỉ thư điện tử nào khỏi tài khoản của bạn, để trống hộp địa chỉ thư điện tử mới và lưu biểu mẫu.",
        "invalid-content-data": "Dữ liệu nội dung không hợp lệ",
        "content-not-allowed-here": "Không cho phép đưa nội dung “$1” vào trang [[$2]]",
        "editwarning-warning": "Rời khỏi trang này sẽ khiến bạn mất các sửa đổi đã thực hiện.\nNếu đã đăng nhập, bạn có thể tắt cảnh báo này tại mục “{{int:prefs-editing}}” trong tùy chọn cá nhân.",
+       "editpage-invalidcontentmodel-title": "Không hỗ trợ mô hình nội dung",
+       "editpage-invalidcontentmodel-text": "Mô hình nội dung “$1” không được hỗ trợ.",
        "editpage-notsupportedcontentformat-title": "Không hỗ trợ định dạng nội dung",
        "editpage-notsupportedcontentformat-text": "Kiểu nội dung $2 không hỗ trợ định dạng nội dung $1.",
        "content-model-wikitext": "mã wiki",
        "searchprofile-advanced-tooltip": "Tìm trong không gian tên tùy chọn",
        "search-result-size": "$1 ({{PLURAL:$2|1 từ|$2 từ}})",
        "search-result-category-size": "$1 trang thành viên ($2 thể loại con, $3 tập tin)",
-       "search-redirect": "(đổi hướng $1)",
+       "search-redirect": "(đổi hướng từ $1)",
        "search-section": "(đề mục $1)",
        "search-category": "(thể loại $1)",
        "search-file-match": "(khớp nội dung tập tin)",
        "group-bot": "Bot",
        "group-sysop": "Bảo quản viên",
        "group-bureaucrat": "Hành chính viên",
-       "group-suppress": "Giám sát viên",
+       "group-suppress": "Người xóa hẳn Flow",
        "group-all": "(tất cả)",
        "group-user-member": "{{GENDER:$1}}thành viên",
        "group-autoconfirmed-member": "{{GENDER:$1}}thành viên tự động xác nhận",
        "group-bot-member": "{{GENDER:$1}}bot",
        "group-sysop-member": "{{GENDER:$1}}bảo quản viên",
        "group-bureaucrat-member": "{{GENDER:$1}}hành chính viên",
-       "group-suppress-member": "{{GENDER:$1}}giám sát viên",
+       "group-suppress-member": "{{GENDER:$1}}người xóa hẳn Flow",
        "grouppage-user": "{{ns:project}}:Thành viên",
        "grouppage-autoconfirmed": "{{ns:project}}:Thành viên tự xác nhận",
        "grouppage-bot": "{{ns:project}}:Bot",
        "grouppage-sysop": "{{ns:project}}:Bảo quản viên",
        "grouppage-bureaucrat": "{{ns:project}}:Hành chính viên",
-       "grouppage-suppress": "{{ns:project}}:Đàn áp viên",
+       "grouppage-suppress": "{{ns:project}}:Người xóa hẳn Flow",
        "right-read": "Đọc trang",
        "right-edit": "Sửa trang",
        "right-createpage": "Tạo trang (không phải trang thảo luận)",
        "upload-dialog-disabled": "Chức năng tải lên tập tin qua hộp thoại này bị tắt trong wiki này.",
        "upload-dialog-title": "Tải tập tin lên",
        "upload-dialog-button-cancel": "Hủy bỏ",
+       "upload-dialog-button-back": "Quay lại",
        "upload-dialog-button-done": "Xong",
        "upload-dialog-button-save": "Lưu",
        "upload-dialog-button-upload": "Tải lên",
        "apisandbox-results-fixtoken-fail": "Thất bại khi lấy dấu hiệu “$1”.",
        "apisandbox-alert-page": "Các miền trên Trang này là không hợp lệ.",
        "apisandbox-alert-field": "Giá trị của miền này là không hợp lệ.",
+       "apisandbox-continue": "Tiếp tục",
+       "apisandbox-continue-clear": "Đặt lại",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} sẽ [https://www.mediawiki.org/wiki/API:Query#Continuing_queries tiếp tục] lời yêu cầu cuối cùng; {{int:apisandbox-continue-clear}} sẽ đặt lại các tham số có liên quan đến chức năng tiếp tục yêu cầu.",
        "booksources": "Nguồn sách",
        "booksources-search-legend": "Tìm kiếm nguồn sách",
        "booksources-search": "Tìm kiếm",
        "activeusers-intro": "Dánh sách này liệt kê các thành viên đã hoạt động cách nào đó trong $1 ngày qua.",
        "activeusers-count": "$1 tác vụ trong {{PLURAL:$3|ngày|$3 ngày}} qua",
        "activeusers-from": "Hiển thị thành viên bắt đầu từ:",
-       "activeusers-hidebots": "Ẩn robot",
-       "activeusers-hidesysops": "Ẩn bảo quản viên",
        "activeusers-noresult": "Không thấy thành viên.",
        "activeusers-submit": "Xem người dùng tích cực",
        "listgrouprights": "Nhóm thành viên",
        "pageinfo-article-id": "Mã số trang",
        "pageinfo-language": "Ngôn ngữ nội dung trang",
        "pageinfo-content-model": "Kiểu nội dung trang",
+       "pageinfo-content-model-change": "thay đổi",
        "pageinfo-robot-policy": "Ghi chỉ mục bởi robot",
        "pageinfo-robot-index": "Cho phép",
        "pageinfo-robot-noindex": "Không cho phép",
        "tag-filter": "Bộ lọc [[Special:Tags|thẻ]]:",
        "tag-filter-submit": "Bộ lọc",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1}}Thẻ]]: $2)",
+       "tag-mw-contentmodelchange": "thay đổi mô hình nội dung",
+       "tag-mw-contentmodelchange-description": "Sửa đổi [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel thay đổi mô hình nội dung] của trang",
        "tags-title": "Thẻ đánh dấu",
        "tags-intro": "Trang này liệt kê các thẻ đánh dấu mà phần mềm dùng nó để đánh dấu một sửa đổi, và ý nghĩa của nó.",
        "tags-tag": "Tên thẻ",
        "tags-actions-header": "Tác vụ",
        "tags-active-yes": "Kích hoạt",
        "tags-active-no": "Vô hiệu",
-       "tags-source-extension": "Xác định bởi một mở rộng",
+       "tags-source-extension": "Xác định bởi phần mềm",
        "tags-source-manual": "Áp dụng thủ công bởi người dùng và bot",
        "tags-source-none": "Không còn sử dụng",
        "tags-edit": "sửa",
        "htmlform-cloner-create": "Tiếp tục thêm",
        "htmlform-cloner-delete": "Loại bỏ",
        "htmlform-cloner-required": "Cần ít nhất một giá trị.",
+       "htmlform-date-placeholder": "YYYY-MM-DD (năm-tháng-ngày)",
+       "htmlform-time-placeholder": "HH:MM:SS (giờ:phút:giây)",
+       "htmlform-datetime-placeholder": "YYYY-MM-DD HH:MM:SS (năm-tháng-ngày giờ:phút:giây)",
+       "htmlform-date-invalid": "Giá trị bạn chỉ định không phải là một ngày được công nhận. Hãy thử sử dụng định dạng YYYY-MM-DD (năm-tháng-ngày).",
+       "htmlform-time-invalid": "Giá trị bạn chỉ định không phải là một giờ được công nhận. Hãy thử sử dụng định dạng HH:MM:SS (giờ:phút:giây).",
+       "htmlform-datetime-invalid": "Giá trị bạn chỉ định không phải là một ngày giờ được công nhận. Hãy thử sử dụng định dạng YYYY-MM-DD HH:MM:SS (năm-tháng-ngày giờ:phút:giây).",
+       "htmlform-date-toolow": "Giá trị bạn chỉ định là trước ngày được phép là $1.",
+       "htmlform-date-toohigh": "Giá trị bạn chỉ định là sau ngày được phép là $1.",
+       "htmlform-time-toolow": "Giá trị bạn chỉ định là trước giờ được phép là $1.",
+       "htmlform-time-toohigh": "Giá trị bạn chỉ định là sau giờ được phép là $1.",
+       "htmlform-datetime-toolow": "Giá trị bạn chỉ định là trước ngày giờ được phép là $1.",
+       "htmlform-datetime-toohigh": "Giá trị bạn chỉ định là sau ngày giờ được phép là $1.",
        "htmlform-title-badnamespace": "[[:$1]] không phải trong không gian tên “{{ns:$2}}”.",
        "htmlform-title-not-creatable": "Không cho phép tạo ra trang với tên “$1”",
        "htmlform-title-not-exists": "$1 không tồn tại.",
        "htmlform-user-not-exists": "<strong>$1</strong> không tồn tại.",
        "htmlform-user-not-valid": "<strong>$1</strong> không phải là tên người dùng.",
-       "sqlite-has-fts": "$1 với sự hỗ trợ tìm kiếm toàn văn",
-       "sqlite-no-fts": "$1 không có hỗ trợ tìm kiếm toàn văn",
        "logentry-delete-delete": "$1 {{GENDER:$2}}đã xóa trang “$3”",
        "logentry-delete-restore": "$1 {{GENDER:$2}}đã phục hồi trang “$3”",
        "logentry-delete-event": "$1 {{GENDER:$2}}đã thay đổi mức hiển thị của {{PLURAL:$5|một mục nhật trình|$5 mục nhật trình}} về $3: $4",
        "feedback-external-bug-report-button": "Tạo một công việc kỹ thuật",
        "feedback-dialog-title": "Gửi phản hồi",
        "feedback-dialog-intro": "Bạn có thể gửi phản hồi dễ dàng qua biểu mẫu bên dưới. Thông tin phản hồi của bạn sẽ được bổ sung vào trang “$1” cùng với tên người dùng của bạn.",
-       "feedback-error-title": "Lỗi",
        "feedback-error1": "Hủy bỏ",
        "feedback-error2": "Lỗi: Sửa đổi thất bại",
        "feedback-error3": "Lỗi: API không có phản ứng",
        "unlinkaccounts-success": "Đã gỡ liên kết tài khoản.",
        "authenticationdatachange-ignored": "Tác vụ thay đổi dữ liệu xác thực không được xử lý. Có lẽ nhà cung cấp chưa được cấu hình?",
        "userjsispublic": "Xin lưu ý: Các trang con JavaScript không nên chứa dữ liệu bí mật, vì những người dùng khác có thể xem các trang này.",
-       "usercssispublic": "Xin lưu ý: Các trang con CSS không nên chứa dữ liệu bí mật, vì những người dùng khác có thể xem các trang này."
+       "usercssispublic": "Xin lưu ý: Các trang con CSS không nên chứa dữ liệu bí mật, vì những người dùng khác có thể xem các trang này.",
+       "restrictionsfield-badip": "Địa chỉ hoặc dải IP không hợp lệ: $1.",
+       "restrictionsfield-label": "Các dải IP được cho phép:",
+       "restrictionsfield-help": "Mỗi dòng một địa chỉ IP hoặc dải CIDR. Để kích hoạt tất cả mọi địa chỉ IP, sử dụng<br><code>0.0.0.0/0</code><br><code>::/0</code>"
 }
index 0f2b80e..c4d76c3 100644 (file)
        "yourname": "Benudsârnôômâ",
        "yourpassword": "Bhaswôrd:",
        "yourpasswordagain": "Bassworrd widderhulln:",
-       "remembermypassword": "Miid den Brauser dauerhafd ogmeld bleim (maximal $1 {{PLURAL:$1|Dooch|Dooch}})",
        "login": "Ôômeldn",
        "nav-login-createaccount": "Oomeldn / Ghondoo ooleeng",
        "userlogin": "Ôômeldn / Als Bajdräächâr ajschrajm",
index 71f37b9..52d2d5b 100644 (file)
        "listusers-noresult": "Geban nonik petuvon.",
        "listusers-blocked": "(pebloköl)",
        "activeusers-count": "{{PLURAL:$1|dunot|dunots}} $1 ün {{PLURAL:$3|del lätik|dels lätik $3}}",
-       "activeusers-hidebots": "Klänedolöd elis bot",
-       "activeusers-hidesysops": "Klänedolöd guvanis",
        "activeusers-noresult": "Geban nonik petuvon.",
        "listgrouprights": "Gitäts gebanagrupa",
        "listgrouprights-summary": "Is palisedons gebanagrups in vük at dabinöls, sa gitäts tefik onsik.\nBa dabinons [[{{MediaWiki:Listgrouprights-helppage}}|nüns pluik]] tefü gebanagitäts patik.",
        "logentry-newusers-create": "Gebanakal: $1 pejafon",
        "rightsnone": "(nonik)",
        "revdelete-summary": "plän redakama",
-       "feedback-error-title": "Pöl",
        "feedback-subject": "Yegäd:",
        "searchsuggest-search": "Suk",
        "searchsuggest-containing": "ninädöl...",
index ef9200d..d1460b8 100644 (file)
        "yourname": "Cäüttijänimi:",
        "yourpassword": "Salasõna",
        "yourpasswordagain": "Tõissaga salain-sõna:",
-       "remembermypassword": "Mäleht minuu (enintään $1 {{PLURAL:$1|päivä|päivää}})",
        "login": "Cirjut süäme",
        "nav-login-createaccount": "Cirjut süäme vai registriiroit cäüttijässi",
        "userlogin": "Cirjut süäme",
index d11a639..84edb29 100644 (file)
        "nstab-template": "Näüdüs",
        "nstab-help": "Oppus",
        "nstab-category": "Katõgooria",
+       "mainpage-nstab": "Pääleht",
        "nosuchaction": "Säänest tallitust olõ-i.",
        "nosuchactiontext": "Seo aadrõsi manoq käüvä tallitus om viganõ.\nVõimalik, et sa kirotit aadrõsi võlssi vai pruugõt vigast linki.\nNiisama või taa ollaq {{SITENAME}} tarkvara viga.",
        "nosuchspecialpage": "Säänest tallituslehekülge olõ-i.",
        "yourpasswordagain": "Kirodaq viilkõrd salasõna",
        "createacct-yourpasswordagain": "Kinnüdäq uma salasõna",
        "createacct-yourpasswordagain-ph": "Kirodaq salasõna vahtsõst",
-       "remembermypassword": "Jätäq salasõna miilde (kooniq $1 {{PLURAL:$1|pääväs|pääväs}})",
        "userlogin-remembermypassword": "Jääq uma nimega sisse",
        "userlogin-signwithsecure": "Pruugiq kaidsõtut võrgoütistüst",
        "yourdomainname": "Võrgonimi",
        "undo-success": "Tagasivõtminõ läts' kõrda. Kaeq üle, kas taa om tuu, midä sa tetäq tahtsõt ja pästäq muutusõq.",
        "undo-failure": "Tagasivõtminõ lää-s kõrda samal aol tettüide muutmiisi vastaolo peräst. Võit muutusõq käsilde tagasi võttaq.",
        "undo-summary": "Tagasi võet muutminõ #$1, mink tekk' [[Special:Contributions/$2|$2]] ([[User talk:$2|Arotus]])",
-       "cantcreateaccounttitle": "Pruukjanime luuminõ lää-s kõrda",
        "cantcreateaccount-text": "Pruukjanime luuminõ taa puutri võrgoaadrõsi päält ('''$1''') om ärq keelet. Kiildjä: [[User:$3|$3]].\n\n$3 kirjäpant põhjus: ''$2''",
        "viewpagelogs": "Kaeq seo lehe muutmisnimekirjä.",
        "nohistory": "Seo leheküle pääl ei olõq vanõmbit kujjõ.",
        "searchprofile-advanced-tooltip": "Otsiq etteannõtuist nimeruumõst",
        "search-result-size": "$1 ({{PLURAL:$2|1 sõna|$2 sõnna}})",
        "search-result-category-size": "{{PLURAL:$1|1 lehekülg|$1 lehekülge}} ({{PLURAL:$2|1 alambkatõgooria|$2 alambkatõgooriat}}, {{PLURAL:$3|1 fail|$3 faili}})",
-       "search-redirect": "(ümbresaatminõ $1)",
+       "search-redirect": "(ümbresaatminõ lehelt $1)",
        "search-section": "(alljago $1)",
        "search-suggest": "Kas mõtlit: $1",
        "search-interwiki-caption": "Sõsarprojektiq",
        "contributions": "{{GENDER:$1|Pruukja}} toimõndusõq",
        "contributions-title": "Pruukja $1 toimõndusõq",
        "mycontris": "Hindä kirotusõq",
+       "anoncontribs": "Hindä kirotusõq",
        "contribsub2": "Pruukja {{GENDER:$3|$1}} ($2) toimõndusõq",
        "nocontribs": "Sääntsit muutmiisi es lövväq.",
        "uctop": "(parhillanõ)",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|kujo|kujjo}} lehest $2",
        "tooltip-pt-userpage": "Suq pruukjaleht",
        "tooltip-pt-anonuserpage": "Su puutri võrgoaadrõsi pruukjaleht",
-       "tooltip-pt-mytalk": "Mu arotusleht",
+       "tooltip-pt-mytalk": "{{GENDER:|Muq arotusleht}}",
        "tooltip-pt-anontalk": "Arotus taa puutri võrgoaadrõsi päält tettüisi toimõnduisi üle",
-       "tooltip-pt-preferences": "Mu säädmiseq",
+       "tooltip-pt-preferences": "{{GENDER:|Mu säädmiseq}}",
        "tooltip-pt-watchlist": "Nimekiri lehist, mil tahtnuq silmä pääl hoitaq",
        "tooltip-pt-mycontris": "Suq toimõnduisi nimekiri",
        "tooltip-pt-login": "Mineq nimega sisse vai tiiq hindäle pruukjanimi (soovitav).",
        "tooltip-pt-logout": "Mineq nime alt vällä",
        "tooltip-pt-createaccount": "Tuu olõ-õi joht kohustuslik, a sul tasos luvvaq konto ja nimega sisse minnäq.",
        "tooltip-ca-talk": "Arotus lehe sisu üle",
-       "tooltip-ca-edit": "Saa võit taad lehte toimõndaq.",
+       "tooltip-ca-edit": "Toimõndaq seod lehte",
        "tooltip-ca-addsection": "Tiiq vahtsõnõ alljago",
        "tooltip-ca-viewsource": "Taa om kaidsõt leht. Saat kaiaq õnnõ taa lättekuudi.",
        "tooltip-ca-history": "Taa lehe vanõmbaq kujoq.",
        "tooltip-t-recentchangeslinked": "Viimädseq muutmisõq lehile, mink pääle näüdätäs linkega seo lehe päält",
        "tooltip-feed-rss": "Taa lehe RSS-kujo",
        "tooltip-feed-atom": "Taa lehe Atom-kujo",
-       "tooltip-t-contributions": "Näütäq taa pruukja toimõnduisi nimekirjä",
+       "tooltip-t-contributions": "Näütäq {{GENDER:$1|seo pruukja}} toimõnduisi nimekirjä",
        "tooltip-t-emailuser": "Saadaq taalõ pruukjalõ e-kiri",
        "tooltip-t-upload": "Laadiq üles teedüstüid",
        "tooltip-t-specialpages": "Näütäq tallituslehekülgi",
        "tooltip-ca-nstab-main": "Näütäq sisulehekülge",
        "tooltip-ca-nstab-user": "Näütäq pruukjalehekülge",
        "tooltip-ca-nstab-media": "Näütäq meediälehekülge",
-       "tooltip-ca-nstab-special": "Taa om tallituslehekülg",
+       "tooltip-ca-nstab-special": "Seo om tallituslehekülg, seod saa-ai toimõndaq",
        "tooltip-ca-nstab-project": "Näütäq projektilehekülge",
        "tooltip-ca-nstab-image": "Näütäq teedüstü lehekülge",
        "tooltip-ca-nstab-mediawiki": "Näütäq tallitusteedüst",
        "spambot_username": "MediaWiki prahihäötäjä",
        "spam_reverting": "Tagasi pööret viimädse kujo pääle, koh olõ-i linke lehele $1",
        "spam_blanking": "Kõigin kujõn oll' linke lehele $1. Leht tühäs tett.",
-       "simpleantispam-label": "Rämpspostikontroll.\n'''ÄRQ''' täütkuq seod väljä!",
+       "simpleantispam-label": "Rämpspostikontroll.\n<strong>Ärq täütkuq</strong> seod väljä!",
        "pageinfo-toolboxlink": "Leheküle andmõq",
        "markaspatrolleddiff": "Märgiq ülekaetus",
        "markaspatrolledtext": "Märgiq toimõndus ülekaetus",
index 9937693..de1dd5f 100644 (file)
        "booksources": "Sourdants po les lives",
        "booksources-search-legend": "Cweri des sourdants po des lives",
        "booksources-search": "Cweri",
+       "booksources-invalid-isbn": "L'ISBN ki vos avoz scrît n' est nén bon; sayîz del raveuri, s' i vs plait",
+       "magiclink-tracking-pmid": "Pådje avou des hårdêyes otomatikes PMID",
+       "magiclink-tracking-isbn": "Pådjes avou des hårdêyes otomatikes ISBN",
+       "magiclink-tracking-isbn-desc": "So cisse pådje cial, gn a ene hårdêye otomatike ISBN. Loukîz so [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] po vey kimint aler dsu",
        "specialloguserlabel": "Fwait pa:",
        "speciallogtitlelabel": "Såme (tite ou uzeu):",
        "log": "Djournås",
        "listusers-submit": "Vey",
        "listusers-noresult": "Nol uzeu di trové.",
        "listusers-blocked": "({{GENDER:$1|bloké|blokêye}})",
-       "activeusers-hidebots": "Catchî les robots",
        "listgrouprights-members": "(djivêye des mimbes)",
        "mailnologin": "Nole adresse d' evoyeu",
        "mailnologintext": "Po-z evoyî èn emile a èn ôte uzeu i vs fåt esse [[Special:UserLogin|elodjî]] eyet aveur ene adresse emile d' evoyeu ki soeye valide dins vos [[Special:Preferences|preferinces]].",
index 9f36244..9a4f66e 100644 (file)
        "yourpasswordagain": "Utroha pagbutang an tigaman-han-pagsakob:",
        "createacct-yourpasswordagain": "Igkompirma an tigaman-pagsakob",
        "createacct-yourpasswordagain-ph": "Igbutang an tigaman-pagsakob utro",
-       "remembermypassword": "Hinumdumi an akon pan-sakob dinhi nga panngaykay ''(browser)'' (para ha pinakamaiha $1 {{PLURAL:$1|ka adlaw|ka mga adlaw}})",
        "userlogin-remembermypassword": "I-log-in la ako",
        "userlogin-signwithsecure": "Gamit hin koneksyon nga nakakasegurado",
        "cannotloginnow-title": "Diri nakakalog-in yana",
        "botpasswords-label-delete": "Paraa",
        "botpasswords-label-resetpassword": "Igreset an password",
        "botpasswords-label-grants": "Mga applicable grant",
-       "botpasswords-label-restrictions": "Mga gindidiri ha paggamit:",
        "botpasswords-label-grants-column": "Ginhatag",
        "botpasswords-bad-appid": "An ngaran han bot nga \"$1\" in diri puydi gamiton.",
        "botpasswords-insert-failed": "Pakyas han pagdugang han ngaran han bot nga \"$1\". Naidugang na ini?",
        "passwordreset-emailtext-ip": "Mayda gumaramit (bangin hi ikaw, tikang han IP adres nga $1) nga naghangyo hin reset han imo tigaman-pansulod han {{SITENAME}} ($4). An nasunod nga gumaramit {{PLURAL:$3|nga akawnt|nga mga akawnt}} nahanungod hini nga email nga adres: \n\n$2\n\n{{PLURAL:$3|Iní nga temporaryo nga tigaman-pansulod|Iní nga mga temporaryo nga tigaman-pansulod}} ma-waray bali hin {{PLURAL:$5|usa ka adlaw|$5 nga mga adlaw}}.\nAngay ka sumakob ngan pumílì hin bag-o nga tigaman-pansulod ha yanâ.  Kun mayda lain nga naghatag hini nga hangyo, o kun nahinumdoman mo an imo orihinal nga tigaman-pansulod, ngan nadírì ka na pagbalyo hiní, puyde mo pasagdan ini nga sumat ngan magpadayon hin paggamit han imo daan nga tigaman-pansulod.",
        "passwordreset-emailelement": "Agnay han gumaramit: \n$1\n\nTemporaryo nga tigaman han pagsakob: \n$2",
        "passwordreset-emailsentemail": "Kun inin nga email address in may pagkahisumpay ha imo account, papadangaton ka hin usa nga password reset email.",
-       "passwordreset-emailsent-capture": "Ginpadangat an password reset email, nga ginpakita ha ubos.",
-       "passwordreset-emailerror-capture": "Ginhimo an password reset email, kun diin nakikita ha ubos, pero pakyas an pagpadara ha  {{GENDER:$2|gumaramit}}: $1",
        "changeemail": "Igliwat o igtanggal an e-mail address",
        "changeemail-header": "Kompletoha ini nga form para masalyuan an imo email address. Kun karuyag nimo tanggalun an may pagkahisumpay han bisan ano nga email address tikang ha imo account, blankoha la an bag-o nga email address kun magsusumiti ka han form.",
-       "changeemail-passwordrequired": "Kinahanglan nim igbutang an imo password para igkompirma inin nga pagbag-o.",
        "changeemail-no-info": "Kinahanglanon mo mag-log-in para ka direkta makasakob hini nga pakli.",
        "changeemail-oldemail": "Yana nga e-mail address:",
        "changeemail-newemail": "Bag-o nga e-mail address:",
        "undo-norev": "An pagliwat in diri mapapawaray-buhat tungod waray ito dida o napara na.",
        "undo-summary": "Ginpawara-buhat an rebisyon nga $1 ni [[Special:Contributions/$2|$2]] ([[User talk:$2|himangrawi]])",
        "undo-summary-username-hidden": "Igpawara-an-ginbuhat nga rebisyon $1 han uska tago nga gumaramit",
-       "cantcreateaccounttitle": "Diri makakahimo hin akawnt",
        "cantcreateaccount-text": "An paghimo hin akawnt hini nga IP address  ('''$1''') in ginpugngan ni [[User:$3|$3]]. An rason nga ginhatag ni $3 in ''$2''",
        "viewpagelogs": "Kitaa an mga log para hini nga pakli",
        "nohistory": "Waray kaagi hin pagliwat hin nga pakli.",
        "listusers-blocked": "(ginpugngan)",
        "activeusers": "Taramdan hin mga gumaramit nga nanggigios",
        "activeusers-from": "Igpakita an mga gumaramit tikang ha:",
-       "activeusers-hidebots": "Igtago an mga bot",
-       "activeusers-hidesysops": "Igtago an mga magdudumara",
        "activeusers-noresult": "Waray gumaramit nga nahiagian.",
        "activeusers-submit": "Igpakita an mga gumaramit nga nangigios",
        "listgrouprights": "Mga katungod han grupo hin gumaramit",
        "feedback-back": "Balik",
        "feedback-cancel": "Pasagdi",
        "feedback-close": "Human na.",
-       "feedback-error-title": "Sayop",
        "feedback-error2": "Sayop: Pakyas an pagliwat",
        "feedback-message": "Mensahe:",
        "feedback-subject": "Himangrawon:",
index 575f5a9..dbee858 100644 (file)
        "yourpasswordagain": "Bindaatal sa baatujàll",
        "createacct-yourpasswordagain": "Dëggalal baatujàll bi",
        "createacct-yourpasswordagain-ph": "Duggalaatal baatujàll bi",
-       "remembermypassword": "Denc sama yëgley dukkukaay ci bii joowukaay (lu ëpp nag $1 {{PLURAL:$1|day|days}})",
        "userlogin-remembermypassword": "Wéyal dima jàppe gu dugg",
        "yourdomainname": "Sa barab",
        "externaldberror": "Njuumte judd na ci dàttub njoxe bi, walla day ni rekk amuloo sañ-sañu yeesal sa sàqum biti.",
        "undo-failure": "Neenalug coppite gi defuwul: man naa jur ab jàppante ci coppite yi ci diggante bi",
        "undo-norev": "Coppite gi manoo koo neenal ndaxte nekkul walla dañu koo far",
        "undo-summary": "Neenalug coppite $1 yu [[Special:Contributions/$2|$2]] ([[User talk:$2|waxtaan]])",
-       "cantcreateaccounttitle": "sag mbindu Manu la nekk .",
        "cantcreateaccount-text": "Sosum sàq mu bàyyikoo ci bii màkkaanu IP ('''$1''') dañ kaa téye [[User:$3|$3]].\n\nNgirtey téye gi $3 joxe, mooy ne: ''$2''.",
        "viewpagelogs": "Xool yéenekaayu xët wii",
        "nohistory": "Xët wii amulub jaar-jaar.",
        "searchprofile-everything-tooltip": "Seet fépp (ba ci xëti waxtaanuwaay yi)",
        "searchprofile-advanced-tooltip": "Seet ci barabi tur yi",
        "search-result-size": "$1 ({{PLURAL:$2|1 baat|$2 baat}})",
-       "search-redirect": "(jubluwaat bu jëm $1)",
+       "search-redirect": "(yoonalaat gu jëm $1)",
        "search-section": "(xaaj $1)",
        "search-suggest": "Xéj-na lii nga doon seet: $1",
        "search-interwiki-caption": "Sémbu niroowaale",
index e9877a5..5197c00 100644 (file)
        "yourpasswordagain": "密码再打一遍:",
        "createacct-yourpasswordagain": "确认密码",
        "createacct-yourpasswordagain-ph": "再打一遍密码",
-       "remembermypassword": "来箇只浏览器上记牢我个登录状态(顶长$1天)",
        "userlogin-remembermypassword": "记牢我个登录状态",
        "userlogin-signwithsecure": "用保险链接",
        "yourdomainname": "侬个域名:",
index 7dae096..c27fc60 100644 (file)
        "yourname": "Демнәчнә нерн:",
        "yourpassword": "Нууц үг:",
        "yourpasswordagain": "Нууц үг давтн:",
-       "remembermypassword": "Намаг эн тоолдврд тодлх ($1 {{PLURAL:$1|1=өдрт|өдрмүдт}} икәр биш)",
        "yourdomainname": "Тана домен:",
        "login": "Орлһн",
        "nav-login-createaccount": "Орх/бүрткгдх",
index d67a289..51150e4 100644 (file)
        "yourpasswordagain": "კჷნე გეკორობით პაროლი:",
        "createacct-yourpasswordagain": "დადასურით პაროლი",
        "createacct-yourpasswordagain-ph": "ხოლო ართშა გენშიონით პაროლი",
-       "remembermypassword": "ქჷგიშინი ჩქიმი მიშულა თე ბრაუზერს (მაქსიმუმ $1 დღას)",
        "userlogin-remembermypassword": "ქუდომტე მიშულირო",
        "userlogin-signwithsecure": "უსაფრთხო კავშირის გამოყენება",
        "yourdomainname": "თქვან დომენ",
        "passwordreset-emailtext-user": "მომხმარებელმა $1 პროექტიდან {{SITENAME}} მოითხოვა თქვენი \nპაროლის თავიდან დაყენება საიტისათვის {{SITENAME}} ($4).\n{{PLURAL:$3|შემდეგი ანგარიში მიბმულია|შემდეგი ანგარიშები მიბმულია}} ამ ელ.ფოსტის მისამართზე:\n\n$2\n\n{{PLURAL:$3|ეს დროებითი პაროლი|ეს დროებითი პაროლები}} იმოქმედებს {{PLURAL:$5|ერთი დღე|$5 დღე}}.\nთქვენ უნდა შეხვიდეთ სისტემაში და აირჩიოთ ახალი პაროლი.\nთუ თქვენ არ გაგიკეთებიათ აღნიშნული მოთხოვნა, ან გაიხსენეთ თქვენი პაროლი\nდა აღარ გსურთ მისი შეცვლა, მაშინ შეგიძლიათ იგნორირება გაუკეთოთ ამ შეტყობინებას\nდა გააგრძელოთ თქვენი ძველი პაროლის გამოყენება.",
        "passwordreset-emailelement": "მომხმარებლის სახელი: \n$1\n\nდროებითი პაროლი: \n$2",
        "passwordreset-emailsentemail": "პაროლის თავიდან დასაყენებელი ელ.ფოსტა გაიგზავნა.",
-       "passwordreset-emailsent-capture": "ქვემოთ ნაჩვენები პაროლის თავიდან დასაყენებელი წერილი გაიგზავნა.",
-       "passwordreset-emailerror-capture": "ქვემოთ მოცემულია შექმნილი პაროლის დასაყენებელი წერილი, რომლის გაგზავნაც {{GENDER:$2|მომხმარებელთან}} ვერ მოხერხდა: $1 გამო",
        "changeemail": "გენშიონით თქვანი ელ. ფოსტაშ ოწურაფუ",
        "changeemail-header": "შეავსეთ ეს ფორმა თქვენი ელ-ფოსტის მისამართის შესაცვლელად. თქვენი პაროლის შეყვანა დაგჭირდებათ ამ ცვლილების დასადასტურებლად.",
        "changeemail-no-info": "კონკრეტულად ამ გვერდთან სამუშაოდ თქვენ უნდა წარადგინოთ თავი სისტემისადმი.",
        "undo-norev": "რედაქტირება ვერ გაუქმდება რადგანაც არ არსებობს ან წაშლილი იქნა.",
        "undo-nochange": "როგორც ჩანს, რედაქტირება უკვე გაუქმდა.",
        "undo-summary": "[[Special:Contributions/$2|$2-ის]]([[User talk:$2|განხილვა]]) ცვლილებების გაუქმება (№$1)",
-       "cantcreateaccounttitle": "ანგარიშის შექმნა ვერ ხერხდება",
        "cantcreateaccount-text": "ამ IP-მისამართიდან აიკრძალა (<strong>$1</strong>) მომხმარებელ [[User:$3|$3]]-ის მიერ.\n\n$3-მა მიუთითა შემდეგი მიზეზი: <em>$2</em>",
        "viewpagelogs": "თე ხასჷლაშო ორეგისტრაციე ჟურნალეფიშ ძირაფა",
        "nohistory": "ამ გვერდს განხილვის გვერდი ცარიელი აქვს.",
        "feedback-external-bug-report-button": "ტექნიკური დავალების გაგზავნა",
        "feedback-dialog-title": "გამოხმაურების გაგზავნა",
        "feedback-dialog-intro": "თქვენ შეგიძლიათ ისარგებლოთ ქვემოთ არსებული მარტივი ფორმით, რათა დატოვოთ თქვენი გამოძახილი. კომენტარები თქვენ მომხმარებლის სახელთან ერთად დამატებული იქნება \"$1\" გვერდზე",
-       "feedback-error-title": "ჩილათა",
        "feedback-error1": "შეცდომა. API-ს მოულოდნელი რეზულტატი",
        "feedback-error2": "შეცდომა: რედაქტირება ვერ განხორციელდა",
        "feedback-error3": "შეცდომა. არ არის API-ს პასუხი",
index d2f0247..8a9f6f1 100644 (file)
        "passwordreset-emailsentusername": "טאמער איז פאראן אן ע־פאסט אדרעס פארקניפט מיט דעם באניצער־נאמען, וועט מען שיקן א פאסווארט צוריקשטעלן ע-פּאָסט.",
        "passwordreset-nocaller": "מען דארף פֿארזארגן א רופֿער",
        "passwordreset-nosuchcaller": "רופֿער איז נישט פֿאראן: $1",
-       "passwordreset-invalideamil": "אומגילטיקער ע־פאסט אדרעס",
+       "passwordreset-invalidemail": "אומגילטיקער ע־פאסט אדרעס",
        "changeemail": "ענדערן אדער אראפנעמען ע-פּאָסט אַדרעס",
        "changeemail-header": "דערגאַנצט די פֿאָרעם צו ענדערן אייער ע-פּאָסט אַדרעס .\nטאמער ווילט איר אראפנעמען די צוארדנונג פון איינעם פון אייערע ע־פאסט אדרעסן פו אייער קאנטע, לאזט ליידיג דעם נייעם ע־פאסט אדרעס ווען איר גיט איין די פֿארעם.",
        "changeemail-no-info": "איר דאַרפֿט זיין אַרײַנלאגירט צוצוקומען גלײַך צו דעם דאָזיגן בלאַט.",
        "activeusers-intro": "דאָס איז א ליסטע פֿון באַניצער וואָס זענען געווען אַקטיוו אינערהאָלב  $1 {{PLURAL:$1|דעם לעצטן טאָג|די לעצטע $1 טעג}}.",
        "activeusers-count": "$1 {{PLURAL:$1|פעולה|פעולות}} אין  {{PLURAL:$3|דעם לעצטן טאָג|די לעצטע $3 טעג}}",
        "activeusers-from": "ווײַזן באַניצער אָנהייבנדיג פון:",
-       "activeusers-hidebots": "באַהאַלטן באטן",
-       "activeusers-hidesysops": "באַהאַלטן סיסאפן",
        "activeusers-noresult": "קיין באניצער נישט געטראפֿן.",
        "activeusers-submit": "ווייזן טעטיגע באניצער",
        "listgrouprights": "באַניצער גרופע רעכטן",
index 73f4629..ec49fc8 100644 (file)
        "yourpasswordagain": "Kọ ọ̀rọ̀ìpamọ́ lẹ́ẹ̀kansí:",
        "createacct-yourpasswordagain": "Ẹ ṣe ìfidájú ọ̀rọ̀ìpamọ́",
        "createacct-yourpasswordagain-ph": "Ẹ kọ ọ̀rọ̀ìpamọ́ lẹ́ẹ̀kan síi",
-       "remembermypassword": "Ṣè'rántí ìwọlé mi lórí kọ̀mpútà yìí (fún ó pẹ́ jù {{PLURAL:$1|ọjọ́|ọjọ́}} $1)",
        "userlogin-remembermypassword": "Fi mí sí ìwọlé",
        "userlogin-signwithsecure": "Lo ìsopọ̀ ẹ̀rọ tó ní àbò",
        "yourdomainname": "Domain yín:",
        "activeusers-intro": "Èyí ni àtòjọ àwọn oníṣe tí wọ́n ní irú àgbéṣe kan láàrin {{PLURAL:$1|ọjọ́|ọjọ́}} $1 sẹ́yìn.",
        "activeusers-count": "{{PLURAL:$1|Àtúnṣe|Àwọn àtúnṣe}} $1 ní {{PLURAL:$3|ọjọ́|ọjọ́}} $3 sẹ́yìn",
        "activeusers-from": "Ìfihàn àwọn oníṣe nípa bíbẹ̀rẹ̀ láti:",
-       "activeusers-hidebots": "Ìbòmọ́lẹ̀ àwọn bọt",
-       "activeusers-hidesysops": "Ìbòmọ́lẹ̀ àwọn olùmójútó",
        "activeusers-noresult": "Kò rí oníṣe kankan.",
        "listgrouprights": "Àwọn ẹ̀tọ́ ẹgbẹ́ oníṣe",
        "listgrouprights-summary": "Nísàlẹ̀ ni àtòjọ àwọn ẹgbẹ́ oníṣe tó nítumọ̀ lórí wiki yìí, pẹ̀lú àwọn ẹ̀tọ́ lílò wọn.\nÓ ṣe é ṣe kí [[{{MediaWiki:Listgrouprights-helppage}}|ẹ̀kúnrẹ́rẹ́]] ó wà nípa ẹ̀tọ́ kọ̀ọ̀kan.",
        "movelogpagetext": "Nísàlẹ̀ ni àtòjọ gbogbo àwọn ìyípòdà ojúewé.",
        "movesubpage": "{{PLURAL:$1|Ojúewé abẹ́|Àwọn ojúewé abẹ́}}",
        "movesubpagetext": "Ojúewé yìí ní {{PLURAL:$1|ojúewé abẹ́|àwọn ojúewé abẹ́}} $1 tó hàn nísàlẹ̀.",
+       "movesubpagetalktext": "Ojúewé ọ̀rọ̀ rẹ̀ ní {{PLURAL:$1|ojúewé abẹ́|àwọn ojúewé abẹ́}} $1 tó hàn nísàlẹ̀.",
        "movenosubpage": "Ojúewé yìí kò ní àwọn abẹ́ojúewé.",
        "movereason": "Ìdíẹ̀:",
        "revertmove": "dápadà",
        "htmlform-submit": "Fúnsílẹ̀",
        "htmlform-reset": "Ìdápadà àwọn àtúnṣe",
        "htmlform-selectorother-other": "Òmíràn",
-       "sqlite-has-fts": "$1 pẹ̀lú àtìlẹ́yìn àwárí ìkọ̀rọ̀ kíkún",
-       "sqlite-no-fts": "$1 láìní àtìlẹ́yìn àwárí ìkọ̀rọ̀ kíkún",
        "logentry-delete-delete": "$1 pa ojúewé $3 rẹ́",
        "logentry-delete-restore": "$1 dá ojúewé $3 padà",
        "logentry-delete-event": "$1 ṣe àyípadà ìhànsí {{PLURAL:$5|ìṣẹ̀lẹ̀ àkọọ́lẹ̀ kan|àwọn ìṣẹ̀lẹ̀ àkọọ́lẹ̀ $5}} lórí $3: $4",
        "special-characters-group-gujarati": "Gujarati",
        "special-characters-group-thai": "Thai",
        "special-characters-group-lao": "Lao",
-       "special-characters-group-khmer": "Khmer"
+       "special-characters-group-khmer": "Khmer",
+       "edit-error-short": "Àṣìṣe: $1",
+       "edit-error-long": "Àwọn àsìṣe:\n\n\n$1"
 }
index 84ec923..f225126 100644 (file)
@@ -27,7 +27,8 @@
                        "CRCHF",
                        "Shinjiman",
                        "Macofe",
-                       "Jdforrester"
+                       "Jdforrester",
+                       "Tungakl"
                ]
        },
        "tog-underline": "連結加底線:",
        "activeusers-intro": "呢個係響最近$1日之內有一啲動作嘅用戶名單。",
        "activeusers-count": "響{{PLURAL:$3|$3日}}之內嘅$1次{{PLURAL:$1|編輯}}",
        "activeusers-from": "顯示用戶開始於:",
-       "activeusers-hidebots": "隱藏機械人",
-       "activeusers-hidesysops": "隱藏管理員",
        "activeusers-noresult": "搵唔到用戶。",
        "activeusers-submit": "顯示活躍用戶",
        "listgrouprights": "用戶組權限",
        "htmlform-chosen-placeholder": "揀個選項",
        "htmlform-cloner-create": "加多啲",
        "htmlform-cloner-delete": "拎走",
-       "sqlite-has-fts": "$1 有全文搜尋支援",
-       "sqlite-no-fts": "$1 冇全文搜尋支援",
        "logentry-delete-delete": "$1 刪咗頁 $3",
        "revdelete-restricted": "已經應用限制到操作員",
        "revdelete-unrestricted": "已經拎走對於操作員嘅限制",
        "feedback-back": "返轉頭",
        "feedback-cancel": "取消",
        "feedback-close": "搞掂",
-       "feedback-error-title": "出錯",
        "feedback-message": "信息:",
        "feedback-subject": "主旨:",
        "feedback-submit": "遞交",
        "feedback-thanks-title": "多謝!",
-       "searchsuggest-search": "搵",
+       "searchsuggest-search": "搵{{SITENAME}}",
        "searchsuggest-containing": "名單傳送緊...",
        "api-error-unclassified": "發生未知嘅錯誤。",
        "api-error-unknown-code": "未知嘅出錯:$1。",
index b3838a7..9a3a44f 100644 (file)
        "yourpassword": "Wachtwoôrd",
        "userlogin-yourpassword": "Wachtwoôrd",
        "yourpasswordagain": "Heef je wachtwoôrd opnieuw in:",
-       "remembermypassword": "Anmeldhehevens ontouwen (maximaal $1 {{PLURAL:$1|dag|daege}})",
        "yourdomainname": "Je domein:",
        "externaldberror": "Der is een fout opetreeën bie 't anmelden bie de database of je ei hin toestemmieng jen externe gebruker bie te werken.",
        "login": "Anmelden",
        "undo-success": "Ieronder sti de tekst wirin a de wiezigieng onedaene is emikt. Controleer voe 't opslaene of a 't resultaot ewenst is.",
        "undo-failure": "De wiezigieng kan nie onhedaen emikt worn vanwehe aore striedihe wiezigiengen.",
        "undo-summary": "Versie $1 van [[Special:Contributions/$2|$2]] ([[User talk:$2|overleg]]) onedaen emikt.",
-       "cantcreateaccounttitle": "Anmaeken gebruker mislukt.",
        "cantcreateaccount-text": "'t Anmaeken van gebrukers van dit IP-adres (<b>$1</b>) is eblokkeerd deur [[User:$3|$3]].\n\nDe deur $3 opeheven reeën is ''$2''",
        "viewpagelogs": "Bekiek de logboeken vò deêze bladzie",
        "nohistory": "Deêze pagina is nie bewerkt.",
index 3798d91..33aa12a 100644 (file)
@@ -92,7 +92,8 @@
                        "Cosine02",
                        "Arthur2e5",
                        "Myy730",
-                       "SolidBlock"
+                       "SolidBlock",
+                       "D41D8CD98F"
                ]
        },
        "tog-underline": "链接下划线:",
        "namespaces": "命名空间",
        "variants": "变种",
        "navigation-heading": "导航菜单",
-       "errorpagetitle": "出错",
+       "errorpagetitle": "错误",
        "returnto": "返回至$1。",
        "tagline": "来自{{SITENAME}}",
        "help": "帮助",
        "nosuchactiontext": "URL指定的操作无效。您可能输入了错误的URL地址,或是点击了错误的链接。这也可能表明{{SITENAME}}使用的软件存在漏洞。",
        "nosuchspecialpage": "此特殊页面不存在",
        "nospecialpagetext": "<strong>您请求了一个无效的特殊页面。</strong>\n\n有效的特殊页面的列表可以在[[Special:SpecialPages|{{int:specialpages}}]]找到。",
-       "error": "出错",
+       "error": "错误",
        "databaseerror": "数据库错误",
        "databaseerror-text": "出现数据库查询错误。这可能表示软件中存在漏洞。",
        "databaseerror-textcl": "出现数据库查询错误。",
        "unexpected": "非正常值:“$1”=“$2”。",
        "formerror": "错误:无法提交表单",
        "badarticleerror": "无法在此页进行该操作。",
-       "cannotdelete": "无法删除页面或文件“$1”。\n它可能已被其他人删除了。",
+       "cannotdelete": "无法删除页面或文件“$1”。它可能已被其他人删除了。",
        "cannotdelete-title": "无法删除页面“$1”",
        "delete-hook-aborted": "删除被扩展钩子取消。钩子并没有给出解释。",
-       "no-null-revision": "无法创建对\"$1\"页面新的空白版本",
+       "no-null-revision": "无法创建对“$1”页面新的空白版本",
        "badtitle": "错误标题",
        "badtitletext": "您请求了个无效、不存在或者跨语言或跨wiki链接标题错误的页面。它可能包含一个或多个不能用于标题的字符。",
        "title-invalid-empty": "请求的页面标题为空,或只包含名字空间名称。",
        "userlogin-createanother": "创建另一个账户",
        "createacct-emailrequired": "电子邮件地址",
        "createacct-emailoptional": "电子邮件地址(可选)",
-       "createacct-email-ph": "请输入的电子邮件地址",
+       "createacct-email-ph": "请输入的电子邮件地址",
        "createacct-another-email-ph": "输入电子邮件地址",
        "createaccountmail": "使用一个临时的随机密码并将其发送到指定的电子邮件地址中",
        "createaccountmail-help": "可被用于为另一个人创建账户而不需要得知密码。",
        "botpasswords-label-delete": "删除",
        "botpasswords-label-resetpassword": "重置密码",
        "botpasswords-label-grants": "应用授权:",
-       "botpasswords-help-grants": "æ¯\8f个æ\8e\88æ\9d\83å°\86ä¼\9aèµ\8bäº\88被å\88\97å\87ºã\80\81ä¸\94ç\94¨æ\88·è´¦æ\88·å·²æ\8b¥æ\9c\89权限的访问权。参见[[Special:ListGrants|授权表]]以获取更多信息。",
+       "botpasswords-help-grants": "æ\8e\88æ\9d\83å\85\81许对æ\82¨ç\9a\84ç\94¨æ\88·è´¦æ\88·å·²æ\8c\81æ\9c\89ç\9a\84æ\9d\83é\99\90è¿\9bè¡\8c访é\97®ã\80\82å\9c¨æ­¤å\90¯ç\94¨æ\8e\88æ\9d\83并ä¸\8dä¼\9aæ\8f\90ä¾\9bæ\82¨æ ¹æ\9c¬ä¸\8dä¼\9aæ\8b¥æ\9c\89ç\9a\84权限的访问权。参见[[Special:ListGrants|授权表]]以获取更多信息。",
        "botpasswords-label-grants-column": "已授权",
        "botpasswords-bad-appid": "机器人名“$1”无效。",
        "botpasswords-insert-failed": "无法添加机器人名“$1”。它是否已添加?",
        "resetpass-temp-emailed": "您通过一个暂时电子邮件发送的代码登录。要完成登录,您必须在此设置一个新密码:",
        "resetpass-temp-password": "临时密码:",
        "resetpass-abort-generic": "密码更改已经被扩展程序中止。",
-       "resetpass-expired": "的密码已经到期。请设置新登录密码。",
+       "resetpass-expired": "的密码已经到期。请设置新登录密码。",
        "resetpass-expired-soft": "您的密码已经到期,需要重置。请现在更换新密码,或单击“{{int:authprovider-resetpass-skip-label}}”以稍后重置。",
        "resetpass-validity-soft": "您的密码无效:$1\n\n请选择一个新密码,或单击“{{int:authprovider-resetpass-skip-label}}”以稍后重置。",
        "passwordreset": "重置密码",
-       "passwordreset-text-one": "请输入你要重置的用户名。",
+       "passwordreset-text-one": "请完成此表单来通过电子邮件接收临时密码。",
        "passwordreset-text-many": "{{PLURAL:$1|在此键入您希望接收临时密码的邮件地址。}}",
        "passwordreset-disabled": "此Wiki已经禁用密码重置。",
        "passwordreset-emaildisabled": "此Wiki上无法使用邮件功能。",
        "passwordreset-nocaller": "必须提供一个调用方",
        "passwordreset-nosuchcaller": "调用方不存在:$1",
        "passwordreset-ignored": "密码重置没有处理。也许没有配置提供者?",
-       "passwordreset-invalideamil": "无效的电子邮件地址",
+       "passwordreset-invalidemail": "无效的电子邮件地址",
        "passwordreset-nodata": "用户名和电子邮件地址均未提供",
        "changeemail": "更改或移除电子邮件地址",
        "changeemail-header": "完成此表格以更改您的电子邮件地址。如果您希望从您的账户中移除任何关联的电子邮件地址,请在提交表格时将新电子邮件地址留空。",
        "anoneditwarning": "<strong>警告:</strong>您没有登录。如果您做出任意编辑,您的IP地址将会公开可见。如果您<strong>[$1 登录]</strong>或<strong>[$2 创建]</strong>一个账户,您的编辑将归属于您的用户名,且将享受其他好处。",
        "anonpreviewwarning": "<em>您没有登录。保存将您的IP地址记录至此页面的编辑历史中。</em>",
        "missingsummary": "<strong>提示:</strong>您没有提供编辑摘要。如果您再次点击“{{int:savearticle}}”,您的编辑将不带摘要保存。",
-       "selfredirect": "<strong>警告:</strong>您正在将此页面重定向至它自己。您可能指定了错误的重定向目标,或者您正在编辑错误的页面。如果您再次点击“{{int:savearticle}}”,重定向将无论如何被创建。",
+       "selfredirect": "<strong>警告:</strong>您正在将此页面重定向至它自己。您可能指定了错误的重定向目标,或者您正在编辑错误的页面。如果您再次点击“{{int:savearticle}}”,重定向仍将被创建。",
        "missingcommenttext": "请在下面输入评论。",
        "missingcommentheader": "<strong>提示:</strong>您还没有为此评论提供一个标题。如果您再次点击“{{int:savearticle}}”,您的编辑将不带标题保存。",
        "summary-preview": "摘要预览:",
        "searchprofile-advanced-tooltip": "在自定义名字空间中搜索",
        "search-result-size": "$1($2个字)",
        "search-result-category-size": "$1个成员($2个子分类,$3个文件)",
-       "search-redirect": "(重定向自“$1”)",
+       "search-redirect": "(重定向自$1)",
        "search-section": "(“$1”章节)",
        "search-category": "(分类$1)",
        "search-file-match": "(匹配文件内容)",
        "grant-basic": "基本权限",
        "grant-viewdeleted": "查看已删除文件和页面",
        "grant-viewmywatchlist": "查看您的监视列表",
+       "grant-viewrestrictedlogs": "查看受限制的日志记录",
        "newuserlogpage": "用户创建日志",
        "newuserlogpagetext": "这是用户创建的日志。",
        "rightslog": "用户权限日志",
        "upload-dialog-disabled": "使用此对话框的文件上传在此wiki已禁用。",
        "upload-dialog-title": "上传文件",
        "upload-dialog-button-cancel": "取消",
+       "upload-dialog-button-back": "返回",
        "upload-dialog-button-done": "完成",
        "upload-dialog-button-save": "保存",
        "upload-dialog-button-upload": "上传",
        "uploadstash-summary": "这个页面提供已经上传(或者上传中)但未发布到wiki之文件存取。这些文件除了上传的用户之外不会被其他人可见。",
        "uploadstash-clear": "清除贮藏文件",
        "uploadstash-nofiles": "您没有被隐藏的文件。",
-       "uploadstash-badtoken": "执行对应操作失败。可能是因为您的编辑凭证已过期。请重试。",
+       "uploadstash-badtoken": "执行对应操作失败,可能是因为您的编辑凭据已过期。请重试。",
        "uploadstash-errclear": "清除文件失败。",
        "uploadstash-refresh": "更新文件列表",
        "uploadstash-thumbnail": "显示缩略图",
        "apisandbox-results-fixtoken-fail": "检索“$1”令牌失败。",
        "apisandbox-alert-page": "此页面上的字段无效。",
        "apisandbox-alert-field": "此字段的值无效。",
+       "apisandbox-continue": "继续",
+       "apisandbox-continue-clear": "清除",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}}将[https://www.mediawiki.org/wiki/API:Query#Continuing_queries 继续]上次请求;{{int:apisandbox-continue-clear}}将清除继续相关的参数。",
+       "apisandbox-param-limit": "输入<kbd>max</kbd>以使用最大限制。",
        "booksources": "网络书源",
        "booksources-search-legend": "搜索图书来源",
        "booksources-isbn": "ISBN:",
        "booksources-search": "搜索",
        "booksources-text": "下面是销售新书和二手书的其他网站的链接的列表,也可能有关于你正在寻找的图书的更多信息:",
        "booksources-invalid-isbn": "提供的ISBN号码并不正确,请检查原始复制来源号码是否有误。",
+       "magiclink-tracking-rfc": "使用RFC魔术链接的页面",
+       "magiclink-tracking-rfc-desc": "此页面使用RFC魔术链接。参见[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org]以获取有关如何迁移的信息。",
+       "magiclink-tracking-pmid": "使用PMID魔术链接的页面",
+       "magiclink-tracking-pmid-desc": "此页面使用PMID魔术链接。参见[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org]以获取有关如何迁移的信息。",
+       "magiclink-tracking-isbn": "使用ISBN魔术链接的页面",
+       "magiclink-tracking-isbn-desc": "此页面使用ISBN魔术链接。参见[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org]以获取有关如何迁移的信息。",
        "specialloguserlabel": "执行者:",
        "speciallogtitlelabel": "目标(标题,或对于用户使用{{ns:user}}:用户名):",
        "log": "日志",
        "activeusers-intro": "这是在过去$1{{PLURAL:$1|天}}有过某种活动的用户的列表。",
        "activeusers-count": "过去$3天有$1次操作",
        "activeusers-from": "显示用户开始于:",
-       "activeusers-hidebots": "隐藏机器人",
-       "activeusers-hidesysops": "隐藏管理员",
+       "activeusers-groups": "显示属于用户组的用户:",
        "activeusers-noresult": "找不到用户。",
        "activeusers-submit": "显示活跃用户",
        "listgrouprights": "用户组权限",
        "modifiedarticleprotection": "更改“[[$1]]”的保护等级",
        "unprotectedarticle": "移除页面“[[$1]]”的保护",
        "movedarticleprotection": "移动保护设置自“[[$2]]”至“[[$1]]”",
+       "protectedarticle-comment": "{{GENDER:$2|已保护}}“[[$1]]”",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|已更改}}“[[$1]]”的保护等级",
+       "unprotectedarticle-comment": "已从“[[$1]]”{{GENDER:$2|移除保护}}",
        "protect-title": "更改“$1”的保护等级",
        "protect-title-notallowed": "查看“$1”的保护等级",
        "prot_1movedto2": "[[$1]]移动至[[$2]]",
        "viewdeletedpage": "查看被删页面",
        "undeletepagetext": "以下{{PLURAL:$1|页面|$1个页面}}已被删除,但依然在归档中并可以被恢复。归档可能会被定时清理。",
        "undelete-fieldset-title": "还原版本",
-       "undeleteextrahelp": "要恢复该页面的整个历史记录时,不选中任何复选框直接点击'''''{{int:undeletebtn}}'''''。要选择性地恢复部分版本时,请选中相应版本前的复选框再点击'''''{{int:undeletebtn}}'''''。",
+       "undeleteextrahelp": "要恢复该页面的整个历史记录时,不选中任何复选框直接点击<strong><em>{{int:undeletebtn}}</em></strong>。要选择性地恢复部分版本时,请选中相应版本前的复选框再点击<strong><em>{{int:undeletebtn}}</em></strong>。",
        "undeleterevisions": "$1个{{PLURAL:$1|修订版本}}已删除",
        "undeletehistory": "如果您恢复了该页面,所有版本都会被恢复到版本历史中。如果本页删除后有一个同名的新页面建立,被恢复的版本将会出现在先前的历史中。",
        "undeleterevdel": "如果把最新版本部分删除,反删除将会无法进行。如果遇到这种情况,您必须反选或反隐藏最新已删除的版本。",
        "unlockdbtext": "解锁数据库将会恢复所有用户编辑页面、修改参数、编辑监视列表以及其他需要更改数据库的操作。请确认您的决定。",
        "lockconfirm": "是,我的确想要锁定数据库。",
        "unlockconfirm": "是,我的确想要解锁数据库。",
-       "lockbtn": "数据库锁定",
+       "lockbtn": "锁定数据库",
        "unlockbtn": "解锁数据库",
        "locknoconfirm": "您没有勾选确认框。",
        "lockdbsuccesssub": "数据库锁定成功",
        "lockedbyandtime": "(由 {{GENDER:$1|$1}} 于$2 $3执行)",
        "move-page": "移动$1",
        "move-page-legend": "移动页面",
-       "movepagetext": "您可以使用下面的表单来重命名一个页面,同时将其版本历史移动到新页面。同时老的条目将会被重定向到新条目。您可以自动地将重定向更新到原条目。如果您不选择这样做的话,请检查[[Special:DoubleRedirects|双重]]或[[Special:BrokenRedirects|损坏重定向]]链接。您有责任确保链接会被正确指向他们应该被指向的地方。\n\n注意:即使新条目已经有对应页面,此页面也<strong>不会</strong>被移动,除非新页面无任何编辑历史或是重定向页。这意味着您可在误操作后将页面移回原处,同时,您也无法覆盖现有页面。\n\n<strong>注意:</strong>对这样一个经常被访问的页面而言这可能是一个重大且唐突的更改;请在行动前先了解您的修改可能带来的一切后果。",
+       "movepagetext": "您可以使用下面的表单来重命名一个页面,同时将其所有版本历史移动到新页面。旧标题将会被重定向到新标题。您可以自动更新链接至原标题的重定向。如果您不选择这样做的话,请检查[[Special:DoubleRedirects|双重]]或[[Special:BrokenRedirects|损坏重定向]]链接。您有责任确保链接会被正确指向他们应该被指向的地方。\n\n注意:如果已存在使用新标题的页面,此页面将<strong>不会</strong>被移动,除非新页面是重定向,并且没有过去的编辑历史。这意味着您可在误操作后将页面移回原处,同时,您无法覆盖现有页面。\n\n<strong>注意:</strong>对这样一个经常被访问的页面而言这可能是一个重大且唐突的更改;请在行动前先了解您的修改可能带来的一切后果。",
        "movepagetext-noredirectfixer": "用下面的表单来重命名一个页面,并将其版本历史同时移动到新页面。老的页面将成为新页面的重定向页。请检查[[Special:DoubleRedirects|双重重定向]]或[[Special:BrokenRedirects|损坏重定向]]链接。您应当负责确定所有链接依然会链到指定的页面。\n\n注意如果新页面已经有内容的话,页面将<strong>不会</strong>被移动,除非新页面无内容或是重定向页,而且没有版本历史。这意味着您再必要时可以在移动到新页面后再移回老的页面,同时您也无法覆盖现有页面。\n\n<strong>注意:</strong>对一个经常被访问的页面而言这可能是一个重大与唐突的更改;请在行动前先确定您了解其所可能带来的后果。",
        "movepagetalktext": "如果您勾选此框,相关联的讨论页将被自动移动到新的标题,除非这里已经有了一个非空讨论页。\n\n在这种情况下,如有需要,您将不得不手动移动或合并页面。",
        "moveuserpage-warning": "'''警告:'''你将移动一个用户页面。请注意,只有该页面会被移动,该用户''不''会被更名。",
        "movelogpagetext": "下面是所有页面移动的列表。",
        "movesubpage": "{{PLURAL:$1|子页面}}",
        "movesubpagetext": "该页面有$1个子页面在下面展示。",
+       "movesubpagetalktext": "相应讨论页有$1个{{PLURAL:$1|子页面}}在下面展示。",
        "movenosubpage": "这个页面没有子页面。",
        "movereason": "原因:",
        "revertmove": "恢复",
        "pageinfo-category-pages": "页面数",
        "pageinfo-category-subcats": "子分类数",
        "pageinfo-category-files": "文件数",
+       "pageinfo-user-id": "用户ID",
        "markaspatrolleddiff": "标记为已巡查",
        "markaspatrolledtext": "标记此页面为已巡查",
        "markaspatrolledtext-file": "将此文件版本标记为已巡查",
        "patrol-log-header": "这是已巡查版本的日志。",
        "log-show-hide-patrol": "$1巡查纪录",
        "log-show-hide-tag": "$1标签日志",
+       "confirm-markpatrolled-button": "确定",
+       "confirm-markpatrolled-top": "将$2的修订版本$3标记为已巡查么?",
        "deletedrevision": "已删除旧版本$1",
        "filedeleteerror-short": "删除文件发生错误:$1",
        "filedeleteerror-long": "删除文件时出错:\n\n$1",
        "newimages-showbots": "显示机器人上传",
        "newimages-hidepatrolled": "隐藏已巡查的上传",
        "noimages": "无可查看文件。",
+       "gallery-slideshow-toggle": "开启/关闭缩略图",
        "ilsubmit": "搜索",
        "bydate": "按日期",
        "sp-newimages-showfrom": "从$1 $2开始显示新文件",
        "confirmemail_success": "您的邮箱已经被确认。您现在可以[[Special:UserLogin|登录]]并使用此网站了。",
        "confirmemail_loggedin": "你的电子邮件地址现在已经确认。",
        "confirmemail_subject": "{{SITENAME}}电子邮件地址确认",
-       "confirmemail_body": "来自IP地址$1的用户(可能是您)在{{SITENAME}}上创建了账户“$2”,并提交了您\n的电子邮箱地址。\n\n请确认这个账户是属于您的,并同时激活在{{SITENAME}}上的电子邮件功能。请在浏\n览器中打开下面的链接:\n\n$3\n\n如果您*未曾*注册账户,请打开下面的链接去取消电子邮件确认:\n\n$5\n\n确认码会在$4过期。",
+       "confirmemail_body": "来自IP地址$1的用户(可能是您)在{{SITENAME}}上创建了账户“$2”,并提交了您的电子邮箱地址。\n\n请确认这个账户是属于您的,并同时激活在{{SITENAME}}上的电子邮件功能。请在浏览器中打开下面的链接:\n\n$3\n\n如果您*未曾*注册账户,请打开下面的链接去取消电子邮件确认:\n\n$5\n\n确认码会在$4过期。",
        "confirmemail_body_changed": "拥有IP地址$1的用户(可能是您)在{{SITENAME}}更改了账户“$2”的电子邮箱地址。\n\n要确认此账户确实属于您并同时激活在{{SITENAME}}的电子邮件功能,请在浏览器中打开下面的链接:\n\n$3\n\n如果这个账户*不是*属于您的,请打开下面的链接去取消电子邮件确认:\n\n$5\n\n确认码会在$4过期。",
-       "confirmemail_body_set": "拥有IP地址$1的用户(可能是您)在{{SITENAME}}将账户“$2”的电子邮箱地址设置为这个电子邮件地址。\n\n请确认这个账户是属于您的,并同时激活在{{SITENAME}}上的电子邮件功能。请\n在浏览器中打开下面的链接:\n\n$3\n\n如果这个账户*不是*属于您的,请打开下面的链接去取消电子邮件确认:\n\n$5\n\n确认码会在$4过期。",
+       "confirmemail_body_set": "拥有IP地址$1的用户(可能是您)在{{SITENAME}}将账户“$2”的电子邮箱地址设置为这个电子邮件地址。\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}}注册的电子邮件地址已被移除",
        "notificationemail_body_changed": "来自IP地址$1的人(可能是您)在{{SITENAME}}上更改了账户“$2”的电子邮件地址至“$3”。\n\n如果这不是您,请立即联系一位网站管理员。",
        "notificationemail_body_removed": "来自IP地址$1的人(可能是您)在{{SITENAME}}上移除了账户“$2”的电子邮件地址。\n\n如果这不是您,请立即联系一位网站管理员。",
-       "scarytranscludedisabled": "[跨网站的编码转换不可用]",
+       "scarytranscludedisabled": "[跨wiki嵌入功能被禁用]",
        "scarytranscludefailed": "[提取$1失败]",
        "scarytranscludefailed-httpstatus": "[模板$1读取失败:HTTP $2]",
        "scarytranscludetoolong": "[URL过长]",
        "confirmrecreate-noreason": "用户 [[User:$1|$1]]([[User talk:$1|talk]]) 在您开始编辑之后{{GENDER:$1|删除}}此页面。请确认您确实要重新创建此页面。",
        "recreate": "重新创建",
        "confirm_purge_button": "确定",
-       "confirm-purge-top": "要清除此页面的缓存吗?",
+       "confirm-purge-top": "要清除此页面的缓存吗",
        "confirm-purge-bottom": "清除页面数据会清除缓存并强制显示最近的版本。",
        "confirm-watch-button": "确定",
        "confirm-watch-top": "将此页添加到您的监视列表吗?",
        "confirm-rollback-button": "确定",
        "confirm-rollback-top": "回退此页面的编辑么?",
        "semicolon-separator": ";",
-       "comma-separator": "",
+       "comma-separator": "",
        "colon-separator": ":",
        "pipe-separator": "&#32;|&#32;",
        "word-separator": "",
        "tags-deactivate": "取消激活",
        "tags-hitcount": "$1个更改",
        "tags-manage-no-permission": "您没有权限管理更改标签。",
-       "tags-manage-blocked": "不能在被封禁的情况下管理更改标签。",
+       "tags-manage-blocked": "{{GENDER:$1|您}}不能在被封禁的情况下管理更改标签。",
        "tags-create-heading": "创建一个新标签",
        "tags-create-explanation": "默认情况下,新创建的标签将可供用户和机器人使用。",
        "tags-create-tag-name": "标签名称:",
        "tags-deactivate-not-allowed": "无法取消激活标签“$1”。",
        "tags-deactivate-submit": "取消激活",
        "tags-apply-no-permission": "您并无权限连带您的更改一起应用更改标签。",
-       "tags-apply-blocked": "不能在被封禁的情况下应用更改标签到您的更改中。",
+       "tags-apply-blocked": "{{GENDER:$1|您}}不能在被封禁的情况下应用更改标签到您的更改中。",
        "tags-apply-not-allowed-one": "标签“$1”不允许手动应用。",
        "tags-apply-not-allowed-multi": "以下{{PLURAL:$2|标签}}不允许手动应用:$1",
        "tags-update-no-permission": "您并无权限从个别修订或日志记录中添加或移除更改标签。",
-       "tags-update-blocked": "不能在被封禁的情况下添加或移除更改标签。",
+       "tags-update-blocked": "{{GENDER:$1|您}}不能在被封禁的情况下添加或移除更改标签。",
        "tags-update-add-not-allowed-one": "标签“$1”不被允许手动添加。",
        "tags-update-add-not-allowed-multi": "以下{{PLURAL:$2|标签}}不被允许手动添加:$1",
        "tags-update-remove-not-allowed-one": "标签“$1”不被允许移除。",
        "htmlform-select-badoption": "您指定的值不是有效选项。",
        "htmlform-int-invalid": "您指定的值不是整数。",
        "htmlform-float-invalid": "您指定的值不是数字。",
-       "htmlform-int-toolow": "您指定的值小于最小值$1",
+       "htmlform-int-toolow": "您指定的值小于最小值$1",
        "htmlform-int-toohigh": "您指定的值大于最大值$1",
        "htmlform-required": "本值必填",
        "htmlform-submit": "提交",
        "htmlform-cloner-create": "添加更多",
        "htmlform-cloner-delete": "移除",
        "htmlform-cloner-required": "至少一个值是必需的。",
+       "htmlform-date-placeholder": "YYYY-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "YYYY-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "您指定的值不是可识别的日期。尝试使用YYYY-MM-DD格式。",
+       "htmlform-time-invalid": "您指定的值不是可识别的时间。尝试使用HH:MM:SS格式。",
+       "htmlform-datetime-invalid": "您指定的值不是可识别的日期和时间。尝试使用YYYY-MM-DD HH:MM:SS格式。",
+       "htmlform-date-toolow": "您指定的值在$1的最早允许日期之前。",
+       "htmlform-date-toohigh": "您指定的值在$1的最晚允许日期之后。",
+       "htmlform-time-toolow": "您指定的值在$1的最早允许时间之前。",
+       "htmlform-time-toohigh": "您指定的值在$1的最晚允许时间之后。",
+       "htmlform-datetime-toolow": "您指定的值在$1的最早允许日期和时间之前。",
+       "htmlform-datetime-toohigh": "您指定的值在$1的最晚允许日期和时间之后。",
        "htmlform-title-badnamespace": "[[:$1]]不在“{{ns:$2}}”名字空间中。",
        "htmlform-title-not-creatable": "“$1”不是一个可创建的页面标题",
        "htmlform-title-not-exists": "$1不存在",
        "feedback-external-bug-report-button": "提交技术报告",
        "feedback-dialog-title": "发送反馈",
        "feedback-dialog-intro": "您可以使用下面的简便表格提交您的反馈。您的评论将连同您的用户名一起加入至页面“$1”。",
-       "feedback-error-title": "错误",
        "feedback-error1": "错误:从API返回无法识别的结果",
        "feedback-error2": "错误:编辑失败",
        "feedback-error3": "错误:API没有响应",
        "feedback-thanks": "谢谢!您的反馈已发布至页面“[$2 $1]”。",
        "feedback-thanks-title": "谢谢您!",
        "feedback-useragent": "用户代理:",
-       "searchsuggest-search": "搜索",
+       "searchsuggest-search": "搜索{{SITENAME}}",
        "searchsuggest-containing": "含有...",
        "api-error-autoblocked": "您的IP地址已被自动封禁,因为它曾被一位已封禁用户使用。",
        "api-error-badaccess-groups": "您没有将文件上传到此 wiki 的权限。",
        "authmanager-authn-not-in-progress": "身份验证尚未进行,或会话数据丢失。请从头重新开始。",
        "authmanager-authn-no-primary": "提供的凭据不能被认证。",
        "authmanager-authn-no-local-user": "提供的证书没有与该wiki上的任何用户相关联。",
-       "authmanager-authn-no-local-user-link": "提供的证书有效,但没有与该wiki上的任何用户相关联。请通过不同方式登录,或创建一个新用户,然后您将拥有一个把您之前的证书链接到对应账户的选项。",
+       "authmanager-authn-no-local-user-link": "提供的凭据有效,但没有与该wiki上的任何用户相关联。请通过不同方式登录,或创建一个新用户,然后您将拥有一个把您之前的凭据链接到对应账户的选项。",
        "authmanager-authn-autocreate-failed": "所有账户的自动创建失败:$1",
-       "authmanager-change-not-supported": "提供的证书不能被更改,因为没有东西会使用它们。",
+       "authmanager-change-not-supported": "提供的凭据不能被更改,因为没有东西会使用它们。",
        "authmanager-create-disabled": "账户创建已停用。",
-       "authmanager-create-from-login": "要创建您的账户,请填写下方的字段。",
+       "authmanager-create-from-login": "要创建您的账户,请填写字段。",
        "authmanager-create-not-in-progress": "账户创建尚未进行,或会话数据丢失。请从头重新开始。",
-       "authmanager-create-no-primary": "提供的证书不能用于账户创建。",
+       "authmanager-create-no-primary": "提供的凭据不能用于账户创建。",
        "authmanager-link-no-primary": "提供的证书不能用于账户链接。",
        "authmanager-link-not-in-progress": "账户链接尚未进行,或会话数据丢失。请从头重新开始。",
        "authmanager-authplugin-setpass-failed-title": "密码更改失败",
        "authpage-cannot-link-continue": "无法继续账户链接。您的会话大概已超时。",
        "cannotauth-not-allowed-title": "权限被拒绝",
        "cannotauth-not-allowed": "您不被允许使用此页面",
-       "changecredentials": "更改证书",
-       "changecredentials-submit": "更改证书",
-       "changecredentials-invalidsubpage": "$1不是有效的证书类型。",
+       "changecredentials": "更改凭据",
+       "changecredentials-submit": "更改凭据",
+       "changecredentials-invalidsubpage": "$1不是有效的凭据类型。",
        "changecredentials-success": "您的证书已被更改。",
-       "removecredentials": "移除证书",
+       "removecredentials": "移除凭据",
        "removecredentials-submit": "移除证书",
-       "removecredentials-invalidsubpage": "$1不是有效的证书类型。",
+       "removecredentials-invalidsubpage": "$1不是有效的凭据类型。",
        "removecredentials-success": "您的证书已被移除。",
-       "credentialsform-provider": "证书类型:",
+       "credentialsform-provider": "凭据类型:",
        "credentialsform-account": "帐户名称:",
        "cannotlink-no-provider-title": "没有可链接账户",
        "cannotlink-no-provider": "没有可链接账户。",
        "usercssispublic": "请注意:CSS子页面不应包含机密数据,因为它们可以被其他用户查看。",
        "restrictionsfield-badip": "无效的IP地址或段:$1",
        "restrictionsfield-label": "允许的IP段:",
-       "restrictionsfield-help": "每行一个IP地址或CIDR段。要启用所有,可使用<br><code>0.0.0.0/0</code><br><code>::/0</code>"
+       "restrictionsfield-help": "每行一个IP地址或CIDR段。要启用所有,可使用<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "错误:$1",
+       "edit-error-long": "错误:\n\n$1"
 }
index 0f38d8e..ee7ce7c 100644 (file)
@@ -75,7 +75,8 @@
                        "Kly",
                        "Cosine02",
                        "一個正常人",
-                       "Wehwei"
+                       "Wehwei",
+                       "1233thehongkonger"
                ]
        },
        "tog-underline": "底線標示連結:",
        "tog-enotifminoredits": "當頁面與檔案有小修訂時,傳送電子郵件通知我",
        "tog-enotifrevealaddr": "在通知郵件中顯示我的電子郵件地址",
        "tog-shownumberswatching": "顯示監視使用者數量",
-       "tog-oldsig": "現有簽名:",
+       "tog-oldsig": "您現有的簽名:",
        "tog-fancysig": "將簽名視為 Wikitext 語言 (不自動產生連結)",
        "tog-uselivepreview": "使用即時預覽",
        "tog-forceeditsummary": "未填寫編輯摘要時提示我",
        "tog-showhiddencats": "顯示隱藏分類",
        "tog-norollbackdiff": "執行還原後略過差異比對",
        "tog-useeditwarning": "未儲存離開編輯頁面時警告我",
-       "tog-prefershttps": "登入時始終使用安全連線",
+       "tog-prefershttps": "永遠使用安全連線來登入",
        "underline-always": "永遠使用",
        "underline-never": "永不使用",
        "underline-default": "依外觀或瀏覽器預設值",
        "newwindow": "(以新視窗開啟)",
        "cancel": "取消",
        "moredotdotdot": "更多...",
-       "morenotlisted": "此清單尚未讀取完畢。",
+       "morenotlisted": "這可能只是部份清單。",
        "mypage": "頁面",
        "mytalk": "對話",
        "anontalk": "對話",
        "talk": "討論",
        "views": "檢視",
        "toolbox": "工具",
+       "tool-link-userrights": "更改{{GENDER:$1|使用者}}群組",
+       "tool-link-emailuser": "寄信給這位{{GENDER:$1|使用者}}",
        "userpage": "檢視使用者頁面",
        "projectpage": "檢視專案頁面",
        "imagepage": "檢視檔案頁面",
        "currentevents-url": "Project:Current events",
        "disclaimers": "免責聲明",
        "disclaimerpage": "Project:一般免責聲明",
-       "edithelp": "編輯説明",
-       "helppage-top-gethelp": "説明",
+       "edithelp": "編輯說明",
+       "helppage-top-gethelp": "說明",
        "mainpage": "首頁",
        "mainpage-description": "首頁",
        "policy-url": "Project:Policy",
        "cannotloginnow-title": "現在無法登入",
        "cannotloginnow-text": "使用 $1 時無法登入。",
        "cannotcreateaccount-title": "無法建立帳號",
+       "cannotcreateaccount-text": "此 wiki 未開啟直接建立帳號的功能。",
        "yourdomainname": "您的網域:",
        "password-change-forbidden": "您不可變更此 Wiki 上的密碼。",
        "externaldberror": "這可能是由於資料庫驗證錯誤,或是不允許您更新外部帳號。",
        "eauthentsent": "已寄出一封確認信到您所設定的電子郵件地址。\n在未收到其它電子郵件前,您必須先依照郵件中的指示,確認這個帳號確實是您本人。",
        "throttled-mailpassword": "密碼重設的電子郵件已經在最近 $1 小時內寄出。\n為防止濫用,$1 小時內只能寄出一次密碼重設信件。",
        "mailerror": "傳送電子郵件錯誤:$1",
-       "acct_creation_throttle_hit": "使用您目前的 IP 位址的訪客在最近一天建立了 {{PLURAL:$1|1 個帳號|$1 個帳號}},已超出系統允許的上限。\n因此,目前無法讓使用此 IP 位址的訪客建立帳號。",
+       "acct_creation_throttle_hit": "使用您目前 IP 位址到 wiki 的訪客在最近 $2 建立了 {{PLURAL:$1|1 個帳號|$1 個帳號}},已超出了期間允許的上限。\n因此,目前無法讓使用此 IP 位址的訪客建立任何帳號。",
        "emailauthenticated": "您的電子郵件地址已於 $2 $3 確認。",
        "emailnotauthenticated": "您的電子郵件地址尚未確認,\n尚不會寄出以下功能的電子郵件給您。",
        "noemailprefs": "在您的偏好設定中設定電子郵件地址,讓您可以使用這些功能。",
        "botpasswords-label-resetpassword": "重設密碼",
        "botpasswords-label-grants": "適用的權限:",
        "botpasswords-help-grants": "每個授權會給予擁有該授權的使用者帳號列於該授權清單的使用者權限。 請參考 [[Special:ListGrants|授權表]] 取得更多資訊。",
-       "botpasswords-label-restrictions": "使用限制:",
        "botpasswords-label-grants-column": "已授權",
        "botpasswords-bad-appid": "機器人名稱 \"$1\" 無效。",
        "botpasswords-insert-failed": "新增機器人名稱 \"$1\" 失敗,是否已新增過?",
        "botpasswords-updated-body": "使用者''$2\"所擁有的機器人\"$1\"之密碼已更新。",
        "botpasswords-deleted-title": "已刪除機器人密碼",
        "botpasswords-deleted-body": "使用者''$2\"所擁有的機器人\"$1\"之密碼已刪除。",
-       "botpasswords-newpassword": "用來登入 <strong>$1</strong> 的新密碼為 <strong>$2</strong>。 <em>請記錄此密碼以供未來參考使用。</em>",
+       "botpasswords-newpassword": "用來登入 <strong>$1</strong> 的新密碼為 <strong>$2</strong>。 <em>請記錄此密碼以供未來參考使用。</em> <br> (較舊的機器人的登入名稱需與最終使用者名稱相同,您也可使用 <strong>$3</strong> 做為使用者名稱 <strong>$4</strong> 做為密碼。)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider 無法使用。",
        "botpasswords-restriction-failed": "機器人密碼限制已拒絕此次登入。",
        "botpasswords-invalid-name": "指定的使用者名稱未包含機器人密碼分隔字元 (\"$1\")。",
        "passwordreset-emailelement": "使用者名稱:\n$1\n\n臨時密碼:\n$2",
        "passwordreset-emailsentemail": "若此確實為您帳號所登記的電子郵件地址,將會寄出重設密碼的信件給您。",
        "passwordreset-emailsentusername": "若此確實為您使用者名稱所登記的電子郵件地址,將會寄出重設密碼的信件給您。",
-       "passwordreset-emailsent-capture2": "密碼重設{{PLURAL:$1|郵件|郵件}}已寄出,{{PLURAL:$1|使用者名稱與密碼|使用者名稱與密碼}}如下顯示。",
-       "passwordreset-emailerror-capture2": "寄發電子郵件給{{GENDER:$2|使用者}}失敗:$1,{{PLURAL:$3|使用者名稱與密碼|使用者名稱與密碼}}如下顯示。",
+       "passwordreset-emailsent-capture2": "密碼重設{{PLURAL:$1|郵件|郵件}}已寄出,{{PLURAL:$1|使用者名稱與密碼|使用者名稱與密碼清單}}如下顯示。",
+       "passwordreset-emailerror-capture2": "寄發電子郵件給{{GENDER:$2|使用者}}失敗:$1,{{PLURAL:$3|使用者名稱與密碼|使用者名稱與密碼清單}}如下顯示。",
        "passwordreset-nocaller": "必須提供 caller",
        "passwordreset-nosuchcaller": "Caller 不存在:$1",
        "passwordreset-ignored": "未處理密碼重設動作,可能尚未設定提供者?",
-       "passwordreset-invalideamil": "無效的電子郵件地址",
+       "passwordreset-invalidemail": "無效的電子郵件地址",
        "passwordreset-nodata": "未提供使用者名稱或是電子郵件地址",
        "changeemail": "變更或移除電子郵件地址",
        "changeemail-header": "請填寫此表單來變更您的電子郵件地址,若您想要移除您帳號所連結的所有電子郵件地址,請於新電子郵件地址欄位留空。",
        "accmailtitle": "密碼已寄出",
        "accmailtext": "[[User talk:$1|$1]] 的隨機密碼已經寄送至 $2,可登入後至 <em>[[Special:ChangePassword|變更密碼]] 頁面更改</em>。",
        "newarticle": "(新)",
-       "newarticletext": "您正連結至一頁不存在頁面。\n要建立該頁面,請在下方的編輯方塊中輸入內容 (詳情請參考 [$1 明頁面]) 。\n如果您是不小心來到此頁面,請點選瀏覽器的 <strong>返回</strong> 按鈕。",
+       "newarticletext": "您正連結至一頁不存在頁面。\n要建立該頁面,請在下方的編輯方塊中輸入內容 (詳情請參考 [$1 使用說明頁面]) 。\n如果您是不小心來到此頁面,請點選瀏覽器的 <strong>返回</strong> 按鈕。",
        "anontalkpagetext": "----\n<em>此討論頁面是給尚未建立帳號的匿名使用者使用</em>\n因此我們必須使用 IP 位址來辨識身份,但相同的 IP 位址可能由許多不同的使用者所共用。\n如果您是匿名使用者並且覺得評論的內容與您無關,請 [[Special:CreateAccount|建立新帳號]] 或 [[Special:UserLogin|登入]] 避免與其他匿名使用者混淆。",
        "noarticletext": "此頁面目前沒有內容,您可以在其它頁面中[[Special:Search/{{PAGENAME}}|搜尋此頁面標題]]、<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜尋相關日誌]或[{{fullurl:{{FULLPAGENAME}}|action=edit}} 建立此頁]</span>。",
        "noarticletext-nopermission": "此頁面目前沒有內容,\n您可以在其它頁面中 [[Special:Search/{{PAGENAME}}|搜尋此頁面標題]],或 <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜尋相關日誌]</span>,但您沒有權限建立此頁面。",
        "invalid-content-data": "內容資料無效",
        "content-not-allowed-here": "頁面 [[$2]] 不允許使用 \"$1\" 語法內容",
        "editwarning-warning": "離開此頁面可能會令您遺失之前所作的所有更改。\n若您已經登入,您可在偏好設定的 \"{{int:prefs-editing}}\" 項目關閉此警告。",
+       "editpage-invalidcontentmodel-title": "不支援的內容模型",
+       "editpage-invalidcontentmodel-text": "不支援內容模型 \"$1\"。",
        "editpage-notsupportedcontentformat-title": "不支援此內容格式",
        "editpage-notsupportedcontentformat-text": "內容語法 $2 不支援使用 $1 格式的內容。",
        "content-model-wikitext": "Wikitext",
        "grant-basic": "基本權限",
        "grant-viewdeleted": "檢視已刪除的檔案及頁面",
        "grant-viewmywatchlist": "檢視您的監視清單",
+       "grant-viewrestrictedlogs": "檢視已限制的日誌項目",
        "newuserlogpage": "建立使用者日誌",
        "newuserlogpagetext": "此為建立使用者的日誌。",
        "rightslog": "使用者權限日誌",
        "upload-dialog-disabled": "此 wiki 已關閉使用此對話框上傳檔案的功能。",
        "upload-dialog-title": "上傳檔案",
        "upload-dialog-button-cancel": "取消",
+       "upload-dialog-button-back": "返回",
        "upload-dialog-button-done": "完成",
        "upload-dialog-button-save": "儲存",
        "upload-dialog-button-upload": "上傳",
        "uploadstash-errclear": "清除檔案失敗。",
        "uploadstash-refresh": "更新檔案清單",
        "uploadstash-thumbnail": "檢視縮圖",
+       "uploadstash-exception": "無法儲存上傳到儲藏庫 ($1): \"$2\"。",
        "invalid-chunk-offset": "無效區塊位置",
        "img-auth-accessdenied": "拒絕存取",
        "img-auth-nopathinfo": "缺少 PATH_INFO 參數。\n您安裝的伺服器未傳遞此資訊,\n您可能使用 CGI 為基礎的伺服器,且不支援 img_auth 功能。\n請參考 https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization。",
        "apisandbox-results-fixtoken-fail": "取得 \"$1\" 密鑰失敗。",
        "apisandbox-alert-page": "此頁面上的欄位無效。",
        "apisandbox-alert-field": "此欄位的值無效。",
+       "apisandbox-continue": "繼續",
+       "apisandbox-continue-clear": "清除",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} 會 [https://www.mediawiki.org/wiki/API:Query#Continuing_queries 繼續] 最後的請求,{{int:apisandbox-continue-clear}} 則會清除繼續相關的參數。",
        "booksources": "圖書資源",
        "booksources-search-legend": "尋找圖書資源",
        "booksources-isbn": "國際標準書號:",
        "activeusers-intro": "此清單為最近 $1 天有活動的使用者。",
        "activeusers-count": "最近 $3 天內有 $1 次動作",
        "activeusers-from": "顯示使用者開始自:",
-       "activeusers-hidebots": "隱藏機器人",
-       "activeusers-hidesysops": "隱藏管理員",
+       "activeusers-groups": "顯示屬於以下群組的使用者:",
        "activeusers-noresult": "查無使用者。",
        "activeusers-submit": "顯示活動中的使用者",
        "listgrouprights": "使用者群組權限",
        "movelogpagetext": "以下是所有移動頁面的動作記錄清單。",
        "movesubpage": "{{PLURAL:$1|子頁面}}",
        "movesubpagetext": "此頁面有 $1 個子頁面如下所示。",
+       "movesubpagetalktext": "對應的對話頁有以下 $1 頁{{PLURAL:$1|子頁面|子頁面}}。",
        "movenosubpage": "此頁面沒有任何子頁面。",
        "movereason": "原因",
        "revertmove": "還原",
        "pageinfo-category-pages": "頁面數量",
        "pageinfo-category-subcats": "子分類數量",
        "pageinfo-category-files": "檔案數量",
+       "pageinfo-user-id": "使用者 ID",
        "markaspatrolleddiff": "標記為已巡查",
        "markaspatrolledtext": "標記此頁面為已巡查",
        "markaspatrolledtext-file": "標記此檔案版本為己巡查",
        "patrol-log-header": "這是已巡查的修訂版本的日誌。",
        "log-show-hide-patrol": "$1 巡查日誌",
        "log-show-hide-tag": "$1 標籤日誌",
+       "confirm-markpatrolled-button": "確定",
        "deletedrevision": "已刪除舊修訂 $1",
        "filedeleteerror-short": "刪除檔案發生錯誤:$1",
        "filedeleteerror-long": "刪除檔案時發生錯誤:\n\n$1",
        "newimages-showbots": "顯示由機器人上傳的檔案",
        "newimages-hidepatrolled": "隱藏己巡查上傳",
        "noimages": "無任何圖片。",
+       "gallery-slideshow-toggle": "切換縮圖",
        "ilsubmit": "搜尋",
        "bydate": "依日期",
        "sp-newimages-showfrom": "顯示自 $1 $2 以來的新檔案",
        "confirm-rollback-button": "確定",
        "confirm-rollback-top": "還原編輯到此頁面?",
        "semicolon-separator": ";",
-       "comma-separator": "",
+       "comma-separator": "",
        "colon-separator": ":",
        "word-separator": "",
        "parentheses": " ($1)",
        "version-poweredby-translators": " translatewiki.net 翻譯人員",
        "version-credits-summary": "我們感謝以下人士為 [[Special:Version|MediaWiki]] 作出的貢獻。",
        "version-license-info": "MediaWiki 為自由軟體;您可依據自由軟體基金會所發表的 GNU 通用公共授權條款規定,將本程式重新發佈與/或修改;無論您依據的是本授權條款的第二版或 (您可自行選擇) 之後的任何版本。\n\n本程式發佈的目的是希望可以提供幫助,但不負任何擔保責任;亦無隱含對適售性或 特定用途的適用性的情形擔保。詳情請參照 GNU 通用公共授權。\n\n您應已隨本程式收到 [{{SERVER}}{{SCRIPTPATH}}/COPYING GNU 通用公共授權條款的副本];如果沒有,請寄信通知自由軟體基金會,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA,或 [//www.gnu.org/licenses/old-licenses/gpl-2.0.html 線上閱讀]。",
-       "version-software": "已安裝的軟體",
+       "version-software": "已安裝的軟體",
        "version-software-product": "產品",
        "version-software-version": "版本",
        "version-entrypoints": "入口 URL",
        "tag-filter": "[[Special:Tags|標籤]]搜尋:",
        "tag-filter-submit": "搜尋",
        "tag-list-wrapper": "([[Special:Tags|$1 個標籤]]:$2)",
+       "tag-mw-contentmodelchange": "內容模型變更",
+       "tag-mw-contentmodelchange-description": "編輯 [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel 更改頁面的內容模型]。",
        "tags-title": "標籤",
        "tags-intro": "此頁面列出所有可用來標示編輯內容的標籤以及這些標籤所代表的意思。",
        "tags-tag": "標籤名稱",
        "htmlform-cloner-create": "新增更多",
        "htmlform-cloner-delete": "移除",
        "htmlform-cloner-required": "至少必須填寫一筆資料。",
+       "htmlform-date-placeholder": "YYYY-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "YYYY-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "您指定的值不是一個可以辨識的日期,請嘗試使用 YYYY-MM-DD 格式。",
+       "htmlform-time-invalid": "您指定的值不是一個可以辨識的時間,請嘗試使用 HH:MM:SS 格式。",
+       "htmlform-datetime-invalid": "您指定的值不是一個可以辨識的日期及時間,請嘗試使用 YYYY-MM-DD HH:MM:SS 格式。",
+       "htmlform-date-toolow": "您指定的值在允許的日期 $1 之前。",
+       "htmlform-date-toohigh": "您指定的值在允許的日期 $1 之後。",
+       "htmlform-time-toolow": "您指定的值在最早允許的時間 $1 之前。",
+       "htmlform-time-toohigh": "您指定的值在最後允許的時間 $1 之後。",
+       "htmlform-datetime-toolow": "您指定的值在最早允許的日期及時間 $1 之前。",
+       "htmlform-datetime-toohigh": "您指定的值在最後允許的日期及時間 $1 之後。",
        "htmlform-title-badnamespace": "[[:$1]] 不在 \"{{ns:$2}}\" 命名空間中。",
        "htmlform-title-not-creatable": "\"$1\" 並非可用來建立頁面的標題",
        "htmlform-title-not-exists": "$1 並不存在。",
        "feedback-external-bug-report-button": "回報技術問題",
        "feedback-dialog-title": "送出意見回饋",
        "feedback-dialog-intro": "您可以使用以下簡易表單傳送您的意見回饋。您的意見將會使用您的使用者名稱新增至頁面 \"$1\"。",
-       "feedback-error-title": "錯誤",
        "feedback-error1": "錯誤:無法識別 API 回傳的結果",
        "feedback-error2": "錯誤:編輯失敗",
        "feedback-error3": "錯誤:API 沒有回應",
        "feedback-thanks": "感謝!您的意見回饋已發佈到頁面 \"[$2 $1]\"。",
        "feedback-thanks-title": "感謝您!",
        "feedback-useragent": "使用者代理:",
-       "searchsuggest-search": "搜尋",
+       "searchsuggest-search": "搜尋 {{SITENAME}}",
        "searchsuggest-containing": "包含...",
        "api-error-autoblocked": "您的IP位址已經被自動封禁,因為它曾經被一名已封禁的使用者使用過。",
        "api-error-badaccess-groups": "您沒有權限在此 Wiki 上傳檔案。",
        "unlinkaccounts-success": "已取消連結帳號。",
        "authenticationdatachange-ignored": "認証資料變更未被處理,可能未設定提供者?",
        "userjsispublic": "請注意:JavaScript 子頁面可被其他使用者檢視,不應包含憑証資料。",
-       "usercssispublic": "請注意:CSS 子頁面可被其他使用者檢視,不應包含憑証資料。"
+       "usercssispublic": "請注意:CSS 子頁面可被其他使用者檢視,不應包含憑証資料。",
+       "restrictionsfield-badip": "無效的 IP 位址或範圍:$1",
+       "restrictionsfield-label": "允許的 IP 範圍:",
+       "restrictionsfield-help": "一個 IP 位址或 CIDR 範圍一行,要開啟所有範圍可使用 <br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "edit-error-short": "錯誤:$1",
+       "edit-error-long": "錯誤:\n\n$1"
 }
index 5bc3590..59b4f65 100644 (file)
@@ -49,3 +49,125 @@ $digitTransformTable = [
 
 $digitGroupingPattern = "##,##,###";
 
+$specialPageAliases = [
+       'Activeusers'               => [ 'সক্রিয়_ব্যবহারকারী' ],
+       'Allmessages'               => [ 'সব_বার্তা' ],
+       'AllMyUploads'              => [ 'আমার_সব_আপলোড', 'আমার_সব_ফাইল' ],
+       'Allpages'                  => [ 'সব_পাতা', 'সব_পৃষ্ঠা', 'সব_পাতাসমূহ' ],
+       'ApiHelp'                   => [ 'এপিআই_সাহায্য' ],
+       'ApiSandbox'                => [ 'এপিআই_খেলাঘর' ],
+       'Ancientpages'              => [ 'পুরানো_পাতা', 'পুরানো_পৃষ্ঠা' ],
+       'Badtitle'                  => [ 'ত্রুটিযুক্ত_শিরোনাম' ],
+       'Blankpage'                 => [ 'খালি_পাতা', 'খালি_পৃষ্ঠা' ],
+       'Block'                     => [ 'বাধাদান', 'আইপি_বাধাদান', 'ব্যবহারকারী_বাধাদান' ],
+       'Booksources'               => [ 'বইয়ের_উৎস' ],
+       'BotPasswords'              => [ 'বট_পাসওয়ার্ড' ],
+       'BrokenRedirects'           => [ 'ভাঙ্গা_পুনর্নির্দেশ' ],
+       'Categories'                => [ 'বিষয়শ্রেণী' ],
+       'ChangeContentModel'        => [ 'বিষয়বস্তুর_মডেল_পরিবর্তন' ],
+       'ChangeCredentials'         => [ 'পরিচয়পত্র_পরিবর্তন' ],
+       'ChangeEmail'               => [ 'ইমেইল_পরিবর্তন' ],
+       'ChangePassword'            => [ 'পাসওয়ার্ড_পরিবর্তন', 'পাসপরিবর্তন', 'পাসওয়ার্ডপরিবর্তন' ],
+       'ComparePages'              => [ 'পাতার_তুলনা', 'পৃষ্ঠার_তুলনা' ],
+       'Confirmemail'              => [ 'ইমেইল_নিশ্চিতকরণ' ],
+       'Contributions'             => [ 'অবদান', 'অবদানসমূহ' ],
+       'CreateAccount'             => [ 'অ্যাকাউন্ট_তৈরি' ],
+       'Deadendpages'              => [ 'সংযোগহীন_পাতা', 'সংযোগহীন_পৃষ্ঠা' ],
+       'DeletedContributions'      => [ 'অপসারিত_অবদান' ],
+       'Diff'                      => [ 'পার্থক্য' ],
+       'DoubleRedirects'           => [ 'দ্বৈত_পুনর্নির্দেশ', 'দুইবার_করা_পুনর্নির্দেশ' ],
+       'EditTags'                  => [ 'ট্যাগ_সম্পাদনা' ],
+       'EditWatchlist'             => [ 'নজরতালিকা_সম্পাদনা' ],
+       'Emailuser'                 => [ 'ইমেইল_প্রেরণ', 'ইমেইল' ],
+       'ExpandTemplates'           => [ 'টেমপ্লেট_সম্প্রসারণ' ],
+       'Export'                    => [ 'রপ্তানি' ],
+       'Fewestrevisions'           => [ 'কমসংখ্যক_সংশোধন' ],
+       'FileDuplicateSearch'       => [ 'সদৃশ_ফাইল_অনুসন্ধান' ],
+       'Filepath'                  => [ 'ফাইলের_পথ' ],
+       'Import'                    => [ 'আমদানি' ],
+       'Invalidateemail'           => [ 'অবৈধ_ইমেইল' ],
+       'JavaScriptTest'            => [ 'জাভাস্ক্রিপ্ট_পরীক্ষা' ],
+       'BlockList'                 => [ 'বাধার_তালিকা', 'বাধার_তালিকাসমূহ', 'আইপি_বাধার_তালিকা' ],
+       'LinkSearch'                => [ 'সংযোগ_অনুসন্ধান' ],
+       'LinkAccounts'              => [ 'অ্যাকাউন্টের_তালিকা' ],
+       'Listadmins'                => [ 'প্রশাসকের_তালিকা' ],
+       'Listbots'                  => [ 'বটের_তালিকা' ],
+       'Listfiles'                 => [ 'ফাইলের_তালিকা', 'চিত্রের_তালিকা', 'ছবির_তালিকা' ],
+       'Listgrouprights'           => [ 'দলগত_অধিকারের_তালিকা', 'ব্যবহারকারীর_দলগত_অধিকার' ],
+       'Listgrants'                => [ 'অনুদানের_তালিকা', 'গ্র্যান্টের_তালিকা' ],
+       'Listredirects'             => [ 'পুনর্নির্দেশের_তালিকা', 'পুনঃনির্দেশের_তালিকা' ],
+       'ListDuplicatedFiles'       => [ 'সদৃশ_ফাইলের_তালিকা', 'অনুরূপ_ফাইলের_তালিকা' ],
+       'Listusers'                 => [ 'ব্যবহারকারীর_তালিকা', 'ব্যবহারকারী_তালিকা' ],
+       'Lockdb'                    => [ 'ডাটাবেস_অবরোধ', 'লকডিবি' ],
+       'Log'                       => [ 'লগ', 'লগসমূহ' ],
+       'Lonelypages'               => [ 'পিতৃহীন_পাতা', 'পিতৃহীন_পাতাসমূহ' ],
+       'Longpages'                 => [ 'দীর্ঘ_পাতাসমূহ' ],
+       'MediaStatistics'           => [ 'মিডিয়া_পরিসংখ্যান' ],
+       'MergeHistory'              => [ 'ইতিহাস_একত্রীকরণ' ],
+       'MIMEsearch'                => [ 'এমআইএমই_অনুসন্ধান' ],
+       'Mostcategories'            => [ 'সর্বাধিক_বিষয়শ্রেণীসমৃদ্ধ' ],
+       'Mostimages'                => [ 'সর্বাধিক_ফাইল', 'বেশী_ছবি' ],
+       'Mostinterwikis'            => [ 'সর্বাধিক_আন্তঃউইকি' ],
+       'Mostlinked'                => [ 'সর্বাধিক_সংযুক্ত_পাতা' ],
+       'Mostlinkedcategories'      => [ 'সর্বাধিক_সংযুক্ত_বিষয়শ্রেণী', 'সর্বাধিক_ব্যবহৃত_বিষয়শ্রেণী', 'সর্বাধিক_সংযুক্ত_বিষয়শ্রেণীসমূহ' ],
+       'Mostlinkedtemplates'       => [ 'সর্বাধিক_সংযুক্ত_টেমপ্লট', 'সর্বাধিক_সংযুক্ত_টেমপ্লটসমূহ', 'সর্বাধিক_ব্যবহৃত_টেমপ্লেট' ],
+       'Mostrevisions'             => [ 'সর্বাধিক_সংশোধন' ],
+       'Movepage'                  => [ 'পাতা_স্থানান্তর' ],
+       'Mycontributions'           => [ 'আমার_অবদান' ],
+       'MyLanguage'                => [ 'আমার_ভাষা' ],
+       'Mypage'                    => [ 'আমার_পাতা' ],
+       'Mytalk'                    => [ 'আমার_আলাপ' ],
+       'Myuploads'                 => [ 'আমার_আপলোড', 'আমার_ফাইল' ],
+       'Newimages'                 => [ 'নতুন_চিত্রসমূহ', 'নতুন_ছবিসমূহ' ],
+       'Newpages'                  => [ 'নতুন_পাতাসমূহ' ],
+       'PagesWithProp'             => [ 'বৈশিষ্ট্যযুক্ত_পাতা', 'বৈশিষ্ট্যযুক্ত_পৃষ্ঠা' ],
+       'PageLanguage'              => [ 'পাতার_ভাষা' ],
+       'PasswordReset'             => [ 'পাসওয়ার্ড_পুনঃস্থাপন' ],
+       'PermanentLink'             => [ 'স্থায়ী_সংযোগ', 'স্থায়ী_লিঙ্ক' ],
+       'Preferences'               => [ 'পছন্দসমূহ', 'আমার_পছন্দ' ],
+       'Prefixindex'               => [ 'উপসর্গ' ],
+       'Protectedpages'            => [ 'সুরক্ষিত_পাতা' ],
+       'Protectedtitles'           => [ 'সুরক্ষিত_শিরোনাম' ],
+       'Randompage'                => [ 'অজানা_পাতা', 'অজানা_যেকোন_পাতা' ],
+       'RandomInCategory'          => [ 'অজানা_বিষয়শ্রেণী' ],
+       'Randomredirect'            => [ 'অজানা_পুনর্নির্দেশ' ],
+       'Randomrootpage'            => [ 'অজানা_মূল_পাতা' ],
+       'Recentchanges'             => [ 'সাম্প্রতিক_পরিবর্তনসমূহ', 'সাম্প্রতিক_পরিবর্তন' ],
+       'Recentchangeslinked'       => [ 'সংযুক্ত_সাম্প্রতিক_পরিবর্তন', 'সংযুক্ত_সাম্প্রতিক_পরিবর্তনসমূহ', 'সম্পর্কিত_পরিবর্তন' ],
+       'Redirect'                  => [ 'পুনর্নির্দেশ' ],
+       'RemoveCredentials'         => [ 'পরিচয়পত্র_অপসারণ' ],
+       'ResetTokens'               => [ 'টোকেন_পরিবর্তন' ],
+       'Revisiondelete'            => [ 'অপসারিত_ইতিহাস' ],
+       'RunJobs'                   => [ 'রানজব' ],
+       'Search'                    => [ 'অনুসন্ধান' ],
+       'Shortpages'                => [ 'সংক্ষিপ্ত_পাতাসমূহ' ],
+       'Specialpages'              => [ 'বিশেষ_পাতাসমূহ' ],
+       'Statistics'                => [ 'পরিসংখ্যান' ],
+       'Tags'                      => [ 'ট্যাগ' ],
+       'TrackingCategories'        => [ 'বিষয়শ্রেণীসমূহ_অনুসরণ' ],
+       'Unblock'                   => [ 'বাধা_তোলা', 'বাধা_অপসারণ' ],
+       'Uncategorizedcategories'   => [ 'বিষয়শ্রেণীবিহীন_বিষয়শ্রেণী' ],
+       'Uncategorizedimages'       => [ 'বিষয়শ্রেণীবিহীন_চিত্র', 'বিষয়শ্রেণীবিহীন_ছবি' ],
+       'Uncategorizedpages'        => [ 'বিষয়শ্রেণীবিহীন_পাতা' ],
+       'Uncategorizedtemplates'    => [ 'বিষয়শ্রেণীবিহীন_টেমপ্লেট' ],
+       'Undelete'                  => [ 'পুনরুদ্ধার' ],
+       'UnlinkAccounts'            => [ 'অসংযুক্ত_অ্যাকাউন্ট' ],
+       'Unlockdb'                  => [ 'ডাটাবেস_মুক্তি', 'আনলকডিবি' ],
+       'Unusedcategories'          => [ 'অব্যবহৃত_বিষয়শ্রেণী' ],
+       'Unusedimages'              => [ 'অব্যবহৃত_চিত্র', 'অব্যবহৃত_ছবি' ],
+       'Unusedtemplates'           => [ 'অব্যবহৃত_টেমপ্লেট' ],
+       'Unwatchedpages'            => [ 'নজরহীন_পাতা', 'নজরে_না_রাখা_পাতা' ],
+       'Upload'                    => [ 'আপলোড' ],
+       'UploadStash'               => [ 'স্টাশ_আপলোড' ],
+       'Userlogin'                 => [ 'ব্যবহারকারী_প্রবেশ', 'প্রবেশ' ],
+       'Userlogout'                => [ 'ব্যবহারকারী_প্রস্থান', 'প্রস্থান' ],
+       'Userrights'                => [ 'ব্যবহারকারী_অধিকার', 'ব্যবহারকারীর_অধিকার' ],
+       'Version'                   => [ 'সংস্করণ' ],
+       'Wantedcategories'          => [ 'আবশ্যিক_বিষয়শ্রেণীসমূহ' ],
+       'Wantedfiles'               => [ 'আবশ্যিক_ফাইলসমূহ' ],
+       'Wantedpages'               => [ 'আবশ্যিক_পাতাসমূহ', 'ভাঙ্গা_লিংকসমূহ' ],
+       'Wantedtemplates'           => [ 'আবশ্যিক_টেমপ্লেটসমূহ' ],
+       'Watchlist'                 => [ 'নজরতালিকা' ],
+       'Whatlinkshere'             => [ 'সংযোগকারী_পৃষ্ঠাসমূহ' ],
+       'Withoutinterwiki'          => [ 'আন্তঃউইকিহীন' ],
+];
index 9d8b1bd..6d875ae 100644 (file)
@@ -19,8 +19,8 @@ $namespaceNames = [
        NS_PROJECT_TALK     => '$1討論',
        NS_FILE             => '文件',
        NS_FILE_TALK        => '文件討論',
-       NS_MEDIAWIKI        => '媒體維基',
-       NS_MEDIAWIKI_TALK   => '媒體維基討論',
+       NS_MEDIAWIKI        => 'MediaWiki',
+       NS_MEDIAWIKI_TALK   => 'MediaWiki討論',
        NS_TEMPLATE         => '模板',
        NS_TEMPLATE_TALK    => '模板討論',
        NS_HELP             => '幫助',
index 108f777..5d846ea 100644 (file)
@@ -7,11 +7,11 @@
  * @file
  *
  * @author Akoppad
- * @author Ashwath Mattur <ashwatham@gmail.com> http://en.wikipedia.org/wiki/User:Ashwatham
+ * @author Ashwath Mattur <ashwatham@gmail.com> https://en.wikipedia.org/wiki/User:Ashwatham
  * @author Dimension10
  * @author Dipin
  * @author HPN
- * @author Hari Prasad Nadig <hpnadig@gmail.com> http://en.wikipedia.org/wiki/User:Hpnadig
+ * @author Hari Prasad Nadig <hpnadig@gmail.com> https://en.wikipedia.org/wiki/User:Hpnadig
  * @author Kaganer
  * @author Ktkaushik
  * @author M G Harish
diff --git a/languages/messages/MessagesKrl.php b/languages/messages/MessagesKrl.php
new file mode 100644 (file)
index 0000000..b991899
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+/** Karelian (Karlaj)
+ *
+ * To improve a translation please visit https://translatewiki.net
+ *
+ * @ingroup Language
+ * @file
+ *
+ */
+
+$fallback = 'fi'; // T137415
index b8ae8d7..5ceafd1 100644 (file)
@@ -38,8 +38,8 @@
  * @license http://www.gnu.org/copyleft/fdl.html GNU Free Documentation License
  * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
  *
- * @see http://meta.wikimedia.org/w/index.php?title=LanguageNn.php&action=history
- * @see http://nn.wikipedia.org/w/index.php?title=Brukar:Dittaeva/LanguageNn.php&action=history
+ * @see https://meta.wikimedia.org/w/index.php?title=LanguageNn.php&action=history
+ * @see https://nn.wikipedia.org/w/index.php?title=Brukar:Dittaeva/LanguageNn.php&action=history
  */
 
 $datePreferences = [
index ba3d364..14f5b6f 100644 (file)
 
 $fallback = 'ru';
 
+$namespaceNames = [
+       NS_MEDIA            => 'Medii',
+       NS_SPECIAL          => 'Erikoine',
+       NS_TALK             => 'Pagin',
+       NS_USER             => 'Käyttäi',
+       NS_USER_TALK        => 'Käyttäi_pagin',
+       NS_PROJECT_TALK     => '$1_pagin',
+       NS_FILE             => 'Failu',
+       NS_FILE_TALK        => 'Failu_pagin',
+       NS_MEDIAWIKI        => 'MediiWiki',
+       NS_MEDIAWIKI_TALK   => 'MediiWiki_pagin',
+       NS_TEMPLATE         => 'Šablonu',
+       NS_TEMPLATE_TALK    => 'Šablonu_pagin',
+       NS_HELP             => 'Abu',
+       NS_HELP_TALK        => 'Abu_pagin',
+       NS_CATEGORY         => 'Kategourii',
+       NS_CATEGORY_TALK    => 'Kategourii_pagin',
+];
+
 $linkTrail = '/^([a-zčČšŠžŽäÄöÖ]+)(.*)$/sDu';
 
index 2d04f63..40dc198 100644 (file)
@@ -138,6 +138,8 @@ $datePreferenceMigrationMap = [
        'short tdmy',
 ];
 
+$defaultDateFormat = 'dmy';
+
 $dateFormats = [
        /*
        'Default',
index c832237..974771f 100644 (file)
--- a/load.php
+++ b/load.php
@@ -23,6 +23,7 @@
  */
 
 use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
 
 // This endpoint is supposed to be independent of request cookies and other
 // details of the session. Enforce this constraint with respect to session use.
@@ -35,6 +36,12 @@ if ( !$wgRequest->checkUrlExtension() ) {
        return;
 }
 
+// Don't initialise ChronologyProtector from object cache, and
+// don't wait for unrelated MediaWiki writes when querying ResourceLoader.
+MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->setRequestInfo( [
+       'ChronologyProtection' => 'false',
+] );
+
 // Set up ResourceLoader
 $resourceLoader = new ResourceLoader(
        ConfigFactory::getDefaultInstance()->makeConfig( 'main' ),
index 0c89c05..7e9220c 100644 (file)
@@ -4,10 +4,10 @@
 # doxygen (www.doxygen.org) for MediaWiki.
 #
 # Some placeholders have been added for MediaWiki usage:
-# {{OUTPUT_DIRECTORY}}
-# {{CURRENT_VERSION}}
-# {{STRIP_FROM_PATH}}
-# {{INPUT}}
+# OUTPUT_DIRECTORY = {{OUTPUT_DIRECTORY}}
+# CURRENT_VERSION  = {{CURRENT_VERSION}}
+# STRIP_FROM_PATH  = {{STRIP_FROM_PATH}}
+# INPUT            = {{INPUT}}
 #
 # To generate documentation run: php mwdocgen.php --no-extensions
 
index e1a4dc6..552bec0 100644 (file)
@@ -104,7 +104,7 @@ abstract class Maintenance {
 
        /**
         * Used by getDB() / setDB()
-        * @var IDatabase
+        * @var Database
         */
        private $mDb = null;
 
@@ -459,7 +459,6 @@ abstract class Maintenance {
         * Add the default parameters to the scripts
         */
        protected function addDefaultParams() {
-
                # Generic (non script dependant) options:
 
                $this->addOption( 'help', 'Display this help message', false, false, 'h' );
@@ -546,7 +545,6 @@ abstract class Maintenance {
                                . "for this script to run: $joined. Please enable them and then try again.";
                        $this->error( $msg, 1 );
                }
-
        }
 
        /**
@@ -726,6 +724,7 @@ abstract class Maintenance {
 
                if ( is_array( $wgProfiler ) && isset( $wgProfiler['class'] ) ) {
                        $class = $wgProfiler['class'];
+                       /** @var Profiler $profiler */
                        $profiler = new $class(
                                [ 'sampling' => 1, 'output' => [ $output ] ]
                                        + $wgProfiler
@@ -1182,6 +1181,7 @@ abstract class Maintenance {
                $this->beginTransaction( $dbw, __METHOD__ );
 
                # Get "active" text records from the revisions table
+               $cur = [];
                $this->output( 'Searching for active text records in revisions table...' );
                $res = $dbw->select( 'revision', 'rev_text_id', [], __METHOD__, [ 'DISTINCT' ] );
                foreach ( $res as $row ) {
@@ -1316,7 +1316,7 @@ abstract class Maintenance {
 
        /**
         * Lock the search index
-        * @param DatabaseBase &$db
+        * @param Database &$db
         */
        private function lockSearchindex( $db ) {
                $write = [ 'searchindex' ];
@@ -1334,7 +1334,7 @@ abstract class Maintenance {
 
        /**
         * Unlock the tables
-        * @param DatabaseBase &$db
+        * @param Database &$db
         */
        private function unlockSearchindex( $db ) {
                $db->unlockTables( __CLASS__ . '::' . __METHOD__ );
@@ -1343,7 +1343,7 @@ abstract class Maintenance {
        /**
         * Unlock and lock again
         * Since the lock is low-priority, queued reads will be able to complete
-        * @param DatabaseBase &$db
+        * @param Database &$db
         */
        private function relockSearchindex( $db ) {
                $this->unlockSearchindex( $db );
@@ -1354,7 +1354,7 @@ abstract class Maintenance {
         * Perform a search index update with locking
         * @param int $maxLockTime The maximum time to keep the search index locked.
         * @param string $callback The function that will update the function.
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @param array $results
         */
        public function updateSearchIndex( $maxLockTime, $callback, $dbw, $results ) {
@@ -1390,7 +1390,7 @@ abstract class Maintenance {
 
        /**
         * Update the searchindex table for a given pageid
-        * @param DatabaseBase $dbw A database write handle
+        * @param Database $dbw A database write handle
         * @param int $pageId The page ID to update.
         * @return null|string
         */
@@ -1500,6 +1500,36 @@ abstract class Maintenance {
                return fgets( STDIN, 1024 );
        }
 
+       /**
+        * Get the terminal size as a two-element array where the first element
+        * is the width (number of columns) and the second element is the height
+        * (number of rows).
+        *
+        * @return array
+        */
+       public static function getTermSize() {
+               $default = [ 80, 50 ];
+               if ( wfIsWindows() ) {
+                       return $default;
+               }
+               // It's possible to get the screen size with VT-100 terminal escapes,
+               // but reading the responses is not possible without setting raw mode
+               // (unless you want to require the user to press enter), and that
+               // requires an ioctl(), which we can't do. So we have to shell out to
+               // something that can do the relevant syscalls. There are a few
+               // options. Linux and Mac OS X both have "stty size" which does the
+               // job directly.
+               $retval = false;
+               $size = wfShellExec( 'stty size', $retval );
+               if ( $retval !== 0 ) {
+                       return $default;
+               }
+               if ( !preg_match( '/^(\d+) (\d+)$/', $size, $m ) ) {
+                       return $default;
+               }
+               return [ intval( $m[2] ), intval( $m[1] ) ];
+       }
+
        /**
         * Call this to set up the autoloader to allow classes to be used from the
         * tests directory.
diff --git a/maintenance/addRFCandPMIDInterwiki.php b/maintenance/addRFCandPMIDInterwiki.php
new file mode 100644 (file)
index 0000000..2262338
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+/**
+ * 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
+ */
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Run automatically with update.php
+ *
+ * - Changes "rfc" URL to use tools.ietf.org domain
+ * - Adds "pmid" interwiki
+ *
+ * @since 1.28
+ */
+class AddRFCAndPMIDInterwiki extends LoggedUpdateMaintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription( 'Add RFC and PMID to the interwiki database table' );
+       }
+
+       protected function getUpdateKey() {
+               return __CLASS__;
+       }
+
+       protected function updateSkippedMessage() {
+               return 'RFC and PMID already added to interwiki database table';
+       }
+
+       protected function doDBUpdates() {
+               $interwikiCache = $this->getConfig()->get( 'InterwikiCache' );
+               // Using something other than the database,
+               if ( $interwikiCache !== false ) {
+                       return true;
+               }
+               $dbw = $this->getDB( DB_MASTER );
+               $rfc = $dbw->selectField(
+                       'interwiki',
+                       'iw_url',
+                       [ 'iw_prefix' => 'rfc' ],
+                       __METHOD__
+               );
+
+               // Old pre-1.28 default value, or not set at all
+               if ( $rfc === false || $rfc === 'http://www.rfc-editor.org/rfc/rfc$1.txt' ) {
+                       $dbw->replace(
+                               'interwiki',
+                               [ 'iw_prefix' ],
+                               [
+                                       'iw_prefix' => 'rfc',
+                                       'iw_url' => 'https://tools.ietf.org/html/rfc$1',
+                                       'iw_api' => '',
+                                       'iw_wikiid' => '',
+                                       'iw_local' => 0,
+                               ],
+                               __METHOD__
+                       );
+               }
+
+               $dbw->insert(
+                       'interwiki',
+                       [
+                               'iw_prefix' => 'pmid',
+                               'iw_url' => 'https://www.ncbi.nlm.nih.gov/pubmed/$1?dopt=Abstract',
+                               'iw_api' => '',
+                               'iw_wikiid' => '',
+                               'iw_local' => 0,
+                       ],
+                       __METHOD__,
+                       // If there's already a pmid interwiki link, don't
+                       // overwrite it
+                       [ 'IGNORE' ]
+               );
+
+               return true;
+       }
+}
+
+$maintClass = 'AddRFCAndPMIDInterwiki';
+require_once RUN_MAINTENANCE_IF_MAIN;
diff --git a/maintenance/archives/patch-change_tag-ct_id.sql b/maintenance/archives/patch-change_tag-ct_id.sql
new file mode 100644 (file)
index 0000000..7b986d6
--- /dev/null
@@ -0,0 +1,5 @@
+-- Primary key in change_tag table
+
+ALTER TABLE /*$wgDBprefix*/change_tag
+       ADD COLUMN ct_id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
+       ADD PRIMARY KEY (ct_id);
index 87b8c2f..b0f9ece 100644 (file)
@@ -6,12 +6,12 @@ ALTER TABLE /*$wgDBprefix*/image ADD (
   img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
 
   -- major part of a MIME media type as defined by IANA
-  -- see http://www.iana.org/assignments/media-types/
+  -- see https://www.iana.org/assignments/media-types/
   img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart") NOT NULL default "unknown",
 
   -- minor part of a MIME media type as defined by IANA
   -- the minor parts are not required to adher to any standard
   -- but should be consistent throughout the database
-  -- see http://www.iana.org/assignments/media-types/
+  -- see https://www.iana.org/assignments/media-types/
   img_minor_mime varbinary(32) NOT NULL default "unknown"
 );
diff --git a/maintenance/archives/patch-rc_ip_modify.sql b/maintenance/archives/patch-rc_ip_modify.sql
new file mode 100644 (file)
index 0000000..e889b5c
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE /*_*/recentchanges MODIFY COLUMN rc_ip varbinary(40) NOT NULL default '';
diff --git a/maintenance/archives/patch-tag_summary-ts_id.sql b/maintenance/archives/patch-tag_summary-ts_id.sql
new file mode 100644 (file)
index 0000000..66fa72e
--- /dev/null
@@ -0,0 +1,5 @@
+-- Primary key in tag_summary table
+
+ALTER TABLE /*$wgDBprefix*/tag_summary
+       ADD COLUMN ts_id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
+       ADD PRIMARY KEY (ts_id);
index cf5a19c..0beff7c 100644 (file)
@@ -32,7 +32,7 @@ require __DIR__ . '/../commandLine.inc';
 class UpdateLogging {
 
        /**
-        * @var DatabaseBase
+        * @var Database
         */
        public $dbw;
        public $batchSize = 1000;
index e9cdb58..2a8d79a 100644 (file)
@@ -69,7 +69,7 @@ class BenchmarkDeleteTruncate extends Benchmarker {
        }
 
        /**
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @return void
         */
        private function insertData( $dbw ) {
@@ -82,7 +82,7 @@ class BenchmarkDeleteTruncate extends Benchmarker {
        }
 
        /**
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @return void
         */
        private function delete( $dbw ) {
@@ -90,7 +90,7 @@ class BenchmarkDeleteTruncate extends Benchmarker {
        }
 
        /**
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @return void
         */
        private function truncate( $dbw ) {
index 9ec61dc..b504bde 100644 (file)
@@ -34,11 +34,7 @@ class CheckComposerLockUpToDate extends Maintenance {
                $lock = new ComposerLock( $lockLocation );
                $json = new ComposerJson( $jsonLocation );
 
-               if ( $lock->getHash() === $json->getHash() ) {
-                       $this->output( "Your composer.lock file is up to date with current dependencies!\n" );
-                       return;
-               }
-               // Out of date, lets figure out which dependencies are old
+               // Check all the dependencies to see if any are old
                $found = false;
                $installed = $lock->getInstalledDependencies();
                foreach ( $json->getRequiredDependencies() as $name => $version ) {
@@ -61,12 +57,9 @@ class CheckComposerLockUpToDate extends Maintenance {
                                1
                        );
                } else {
-                       // The hash is the entire composer.json file,
-                       // so it can be updated without any of the dependencies changing
                        // We couldn't find any out-of-date dependencies, so assume everything is ok!
                        $this->output( "Your composer.lock file is up to date with current dependencies!\n" );
                }
-
        }
 }
 
index cd7a842..95bbe3d 100644 (file)
@@ -47,7 +47,7 @@ class UploadStashCleanup extends Maintenance {
                $repo = RepoGroup::singleton()->getLocalRepo();
                $tempRepo = $repo->getTempRepo();
 
-               $dbr = $repo->getSlaveDB();
+               $dbr = $repo->getReplicaDB();
 
                // how far back should this look for files to delete?
                $cutoff = time() - $wgUploadStashMaxAge;
index 14557f4..b8001a4 100644 (file)
@@ -74,7 +74,7 @@ class ConvertUserOptions extends Maintenance {
 
        /**
         * @param ResultWrapper $res
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @return null|int
         */
        function convertOptionBatch( $res, $dbw ) {
index f13dd93..388ad8a 100644 (file)
@@ -109,7 +109,6 @@ class GenerateCommonPassword extends Maintenance {
                } catch ( \Cdb\Exception $e ) {
                        $this->error( "Error writing cdb file: " . $e->getMessage(), 2 );
                }
-
        }
 }
 
index 507a494..df496d4 100644 (file)
@@ -83,7 +83,7 @@ class DeleteOrphanedRevisions extends Maintenance {
         * Do this inside a transaction
         *
         * @param array $id Array of revision id values
-        * @param DatabaseBase $dbw DatabaseBase class (needs to be a master)
+        * @param Database $dbw Database class (needs to be a master)
         */
        private function deleteRevs( $id, &$dbw ) {
                if ( !is_array( $id ) ) {
index 97c8954..77b0e61 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /**
  * Router for the php cli-server built-in webserver.
- * http://www.php.net/manual/en/features.commandline.webserver.php
+ * https://secure.php.net/manual/en/features.commandline.webserver.php
  *
  * 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
@@ -63,7 +63,8 @@ if ( $ext == 'php' || $ext == 'php5' ) {
        return true;
 }
 $mime = false;
-$lines = explode( "\n", file_get_contents( "includes/mime.types" ) );
+// Borrow mime type file from MimeAnalyzer
+$lines = explode( "\n", file_get_contents( "includes/libs/mime/mime.types" ) );
 foreach ( $lines as $line ) {
        $exts = explode( " ", $line );
        $mime = array_shift( $exts );
index 60b24a2..f3561b5 100644 (file)
@@ -25,6 +25,7 @@
  * @file
  * @ingroup Maintenance
  */
+use MediaWiki\MediaWikiServices;
 
 if ( !defined( 'RUN_MAINTENANCE_IF_MAIN' ) ) {
        echo "This file must be included after Maintenance.php\n";
@@ -113,12 +114,13 @@ $maintenance->execute();
 $maintenance->globals();
 
 // Perform deferred updates.
+$lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+$lbFactory->commitMasterChanges( $maintClass );
 DeferredUpdates::doUpdates();
 
 // log profiling info
 wfLogProfilingData();
 
 // Commit and close up!
-$factory = wfGetLBFactory();
-$factory->commitMasterChanges( 'doMaintenance' );
-$factory->shutdown( $factory::SHUTDOWN_NO_CHRONPROT );
+$lbFactory->commitMasterChanges( 'doMaintenance' );
+$lbFactory->shutdown( $lbFactory::SHUTDOWN_NO_CHRONPROT );
index 31272bc..9f983c1 100644 (file)
@@ -117,7 +117,7 @@ abstract class DumpIterator extends Maintenance {
        /**
         * Callback function for each revision, child classes should override
         * processRevision instead.
-        * @param DatabaseBase $rev
+        * @param Database $rev
         */
        public function handleRevision( $rev ) {
                $title = $rev->getTitle();
index d0bda4e..d8661c1 100644 (file)
@@ -86,7 +86,7 @@ class TextPassDumper extends BackupDumper {
        protected $checkpointFiles = [];
 
        /**
-        * @var DatabaseBase
+        * @var Database
         */
        protected $db;
 
index 2ed1efa..9dee6e5 100644 (file)
@@ -71,7 +71,7 @@ class FetchText extends Maintenance {
 
        /**
         * May throw a database error if, say, the server dies during query.
-        * @param DatabaseBase $db
+        * @param Database $db
         * @param int $id The old_id
         * @return string
         */
index c91d824..f6e65f9 100644 (file)
@@ -8,7 +8,7 @@
  * - hooks names in code are the first parameter of wfRunHooks.
  *
  * if --online option is passed, the script will compare the hooks in the code
- * with the ones at http://www.mediawiki.org/wiki/Manual:Hooks
+ * with the ones at https://www.mediawiki.org/wiki/Manual:Hooks
  *
  * Any instance of wfRunHooks that doesn't meet these parameters will be noted.
  *
index c06a72e..7979e7d 100644 (file)
@@ -36,7 +36,7 @@ class FindMissingFiles extends Maintenance {
                $lastName = $this->getOption( 'start', '' );
 
                $repo = RepoGroup::singleton()->getLocalRepo();
-               $dbr = $repo->getSlaveDB();
+               $dbr = $repo->getReplicaDB();
                $be = $repo->getBackend();
 
                $mtime1 = $dbr->timestampOrNull( $this->getOption( 'mtimeafter', null ) );
index abd170b..5980631 100644 (file)
@@ -75,7 +75,7 @@ class FindOrphanedFiles extends Maintenance {
                        return;
                }
 
-               $dbr = $repo->getSlaveDB();
+               $dbr = $repo->getReplicaDB();
 
                $curNames = [];
                $oldNames = [];
index c2c6958..677bfa2 100644 (file)
@@ -23,6 +23,8 @@
 
 require_once __DIR__ . '/Maintenance.php';
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Maintenance script that displays replication lag times.
  *
@@ -32,27 +34,35 @@ class GetLagTimes extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->addDescription( 'Dump replication lag times' );
+               $this->addOption( 'report', "Report the lag values to StatsD" );
        }
 
        public function execute() {
-               $lb = wfGetLB();
+               $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+               $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
 
-               if ( $lb->getServerCount() == 1 ) {
-                       $this->error( "This script dumps replication lag times, but you don't seem to have\n"
-                               . "a multi-host db server configuration." );
-               } else {
+               $lbs = $lbFactory->getAllMainLBs() + $lbFactory->getAllExternalLBs();
+               foreach ( $lbs as $cluster => $lb ) {
+                       if ( $lb->getServerCount() <= 1 ) {
+                               continue;
+                       }
                        $lags = $lb->getLagTimes();
-                       foreach ( $lags as $n => $lag ) {
-                               $host = $lb->getServerName( $n );
+                       foreach ( $lags as $serverIndex => $lag ) {
+                               $host = $lb->getServerName( $serverIndex );
                                if ( IP::isValid( $host ) ) {
                                        $ip = $host;
                                        $host = gethostbyaddr( $host );
                                } else {
                                        $ip = gethostbyname( $host );
                                }
+
                                $starLen = min( intval( $lag ), 40 );
                                $stars = str_repeat( '*', $starLen );
                                $this->output( sprintf( "%10s %20s %3d %s\n", $ip, $host, $lag, $stars ) );
+
+                               if ( $this->hasOption( 'report' ) ) {
+                                       $stats->gauge( "loadbalancer.lag.$cluster.$host", $lag );
+                               }
                        }
                }
        }
index b1e0fa4..fa8bf3b 100644 (file)
@@ -7,7 +7,6 @@ c2find|http://c2.com/cgi/wiki?FindPage&value=$1|0|
 cache|http://www.google.com/search?q=cache:$1|0|
 commons|https://commons.wikimedia.org/wiki/$1|0|https://commons.wikimedia.org/w/api.php
 dictionary|http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query=$1|0|
-docbook|http://wiki.docbook.org/$1|0|
 doi|http://dx.doi.org/$1|0|
 drumcorpswiki|http://www.drumcorpswiki.com/$1|0|http://drumcorpswiki.com/api.php
 dwjwiki|http://www.suberic.net/cgi-bin/dwj/wiki.cgi?$1|0|
@@ -16,22 +15,18 @@ emacswiki|http://www.emacswiki.org/cgi-bin/wiki.pl?$1|0|
 foldoc|http://foldoc.org/?$1|0|
 foxwiki|http://fox.wikis.com/wc.dll?Wiki~$1|0|
 freebsdman|http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=$1|0|
-gej|http://www.esperanto.de/dej.malnova/aktivikio.pl?$1|0|
 gentoo-wiki|http://gentoo-wiki.com/$1|0|
 google|http://www.google.com/search?q=$1|0|
 googlegroups|http://groups.google.com/groups?q=$1|0|
 hammondwiki|http://www.dairiki.org/HammondWiki/$1|0|
 hrwiki|http://www.hrwiki.org/wiki/$1|0|http://www.hrwiki.org/w/api.php
 imdb|http://www.imdb.com/find?q=$1&tt=on|0|
-jargonfile|http://sunir.org/apps/meta.pl?wiki=JargonFile&redirect=$1|0|
 kmwiki|http://kmwiki.wikispaces.com/$1|0|
 linuxwiki|http://linuxwiki.de/$1|0|
 lojban|http://mw.lojban.org/papri/$1|0|
 lqwiki|http://wiki.linuxquestions.org/wiki/$1|0|
-lugkr|http://www.lug-kr.de/wiki/$1|0|
 meatball|http://www.usemod.com/cgi-bin/mb.pl?$1|0|
 mediawikiwiki|https://www.mediawiki.org/wiki/$1|0|https://www.mediawiki.org/w/api.php
-mediazilla|https://bugzilla.wikimedia.org/$1|0|
 memoryalpha|http://en.memory-alpha.org/wiki/$1|0|http://en.memory-alpha.org/api.php
 metawiki|http://sunir.org/apps/meta.pl?$1|0|
 metawikimedia|https://meta.wikimedia.org/wiki/$1|0|https://meta.wikimedia.org/w/api.php
@@ -39,25 +34,21 @@ mozillawiki|http://wiki.mozilla.org/$1|0|https://wiki.mozilla.org/api.php
 mw|https://www.mediawiki.org/wiki/$1|0|https://www.mediawiki.org/w/api.php
 oeis|http://oeis.org/$1|0|
 openwiki|http://openwiki.com/ow.asp?$1|0|
-ppr|http://c2.com/cgi/wiki?$1|0|
+pmid|https://www.ncbi.nlm.nih.gov/pubmed/$1?dopt=Abstract|0|
 pythoninfo|http://wiki.python.org/moin/$1|0|
-rfc|http://www.rfc-editor.org/rfc/rfc$1.txt|0|
+rfc|https://tools.ietf.org/html/rfc$1|0|
 s23wiki|http://s23.org/wiki/$1|0|http://s23.org/w/api.php
 seattlewireless|http://seattlewireless.net/$1|0|
 senseislibrary|http://senseis.xmp.net/?$1|0|
 shoutwiki|http://www.shoutwiki.com/wiki/$1|0|http://www.shoutwiki.com/w/api.php
-sourcewatch|http://www.sourcewatch.org/index.php?title=$1|0|http://www.sourcewatch.org/api.php
 squeak|http://wiki.squeak.org/squeak/$1|0|
-tejo|http://www.tejo.org/vikio/$1|0|
 tmbw|http://www.tmbw.net/wiki/$1|0|http://tmbw.net/wiki/api.php
 tmnet|http://www.technomanifestos.net/?$1|0|
 theopedia|http://www.theopedia.com/$1|0|
 twiki|http://twiki.org/cgi-bin/view/$1|0|
-uea|http://uea.org/vikio/index.php/$1|0|http://uea.org/vikio/api.php
 uncyclopedia|http://en.uncyclopedia.co/wiki/$1|0|http://en.uncyclopedia.co/w/api.php
 unreal|http://wiki.beyondunreal.com/$1|0|http://wiki.beyondunreal.com/w/api.php
 usemod|http://www.usemod.com/cgi-bin/wiki.pl?$1|0|
-webseitzwiki|http://webseitz.fluxent.com/wiki/$1|0|
 wiki|http://c2.com/cgi/wiki?$1|0|
 wikia|http://www.wikia.com/wiki/$1|0|
 wikibooks|https://en.wikibooks.org/wiki/$1|0|https://en.wikibooks.org/w/api.php
index b7d1a84..adb6cd1 100644 (file)
@@ -9,7 +9,6 @@ REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local,iw_api) VALUES
 ('cache','http://www.google.com/search?q=cache:$1',0,''),
 ('commons','https://commons.wikimedia.org/wiki/$1',0,'https://commons.wikimedia.org/w/api.php'),
 ('dictionary','http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query=$1',0,''),
-('docbook','http://wiki.docbook.org/$1',0,''),
 ('doi','http://dx.doi.org/$1',0,''),
 ('drumcorpswiki','http://www.drumcorpswiki.com/$1',0,'http://drumcorpswiki.com/api.php'),
 ('dwjwiki','http://www.suberic.net/cgi-bin/dwj/wiki.cgi?$1',0,''),
@@ -18,22 +17,18 @@ REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local,iw_api) VALUES
 ('foldoc','http://foldoc.org/?$1',0,''),
 ('foxwiki','http://fox.wikis.com/wc.dll?Wiki~$1',0,''),
 ('freebsdman','http://www.FreeBSD.org/cgi/man.cgi?apropos=1&query=$1',0,''),
-('gej','http://www.esperanto.de/dej.malnova/aktivikio.pl?$1',0,''),
 ('gentoo-wiki','http://gentoo-wiki.com/$1',0,''),
 ('google','http://www.google.com/search?q=$1',0,''),
 ('googlegroups','http://groups.google.com/groups?q=$1',0,''),
 ('hammondwiki','http://www.dairiki.org/HammondWiki/$1',0,''),
 ('hrwiki','http://www.hrwiki.org/wiki/$1',0,'http://www.hrwiki.org/w/api.php'),
 ('imdb','http://www.imdb.com/find?q=$1&tt=on',0,''),
-('jargonfile','http://sunir.org/apps/meta.pl?wiki=JargonFile&redirect=$1',0,''),
 ('kmwiki','http://kmwiki.wikispaces.com/$1',0,''),
 ('linuxwiki','http://linuxwiki.de/$1',0,''),
 ('lojban','http://www.lojban.org/tiki/tiki-index.php?page=$1',0,''),
 ('lqwiki','http://wiki.linuxquestions.org/wiki/$1',0,''),
-('lugkr','http://www.lug-kr.de/wiki/$1',0,''),
 ('meatball','http://www.usemod.com/cgi-bin/mb.pl?$1',0,''),
 ('mediawikiwiki','https://www.mediawiki.org/wiki/$1',0,'https://www.mediawiki.org/w/api.php'),
-('mediazilla','https://bugzilla.wikimedia.org/$1',0,''),
 ('memoryalpha','http://en.memory-alpha.org/wiki/$1',0,'http://en.memory-alpha.org/api.php'),
 ('metawiki','http://sunir.org/apps/meta.pl?$1',0,''),
 ('metawikimedia','https://meta.wikimedia.org/wiki/$1',0,'https://meta.wikimedia.org/w/api.php'),
@@ -41,25 +36,21 @@ REPLACE INTO /*$wgDBprefix*/interwiki (iw_prefix,iw_url,iw_local,iw_api) VALUES
 ('mw','https://www.mediawiki.org/wiki/$1',0,'https://www.mediawiki.org/w/api.php'),
 ('oeis','http://oeis.org/$1',0,''),
 ('openwiki','http://openwiki.com/ow.asp?$1',0,''),
-('ppr','http://c2.com/cgi/wiki?$1',0,''),
+('pmid', 'https://www.ncbi.nlm.nih.gov/pubmed/$1?dopt=Abstract',0,''),
 ('pythoninfo','http://wiki.python.org/moin/$1',0,''),
-('rfc','http://www.rfc-editor.org/rfc/rfc$1.txt',0,''),
+('rfc','https://tools.ietf.org/html/rfc$1',0,''),
 ('s23wiki','http://s23.org/wiki/$1',0,'http://s23.org/w/api.php'),
 ('seattlewireless','http://seattlewireless.net/$1',0,''),
 ('senseislibrary','http://senseis.xmp.net/?$1',0,''),
 ('shoutwiki','http://www.shoutwiki.com/wiki/$1',0,'http://www.shoutwiki.com/w/api.php'),
-('sourcewatch','http://www.sourcewatch.org/index.php?title=$1',0,'http://www.sourcewatch.org/api.php'),
 ('squeak','http://wiki.squeak.org/squeak/$1',0,''),
-('tejo','http://www.tejo.org/vikio/$1',0,''),
 ('tmbw','http://www.tmbw.net/wiki/$1',0,'http://tmbw.net/wiki/api.php'),
 ('tmnet','http://www.technomanifestos.net/?$1',0,''),
 ('theopedia','http://www.theopedia.com/$1',0,''),
 ('twiki','http://twiki.org/cgi-bin/view/$1',0,''),
-('uea','http://uea.org/vikio/index.php/$1',0,'http://uea.org/vikio/api.php'),
 ('uncyclopedia','http://en.uncyclopedia.co/wiki/$1',0,'http://en.uncyclopedia.co/w/api.php'),
 ('unreal','http://wiki.beyondunreal.com/$1',0,'http://wiki.beyondunreal.com/w/api.php'),
 ('usemod','http://www.usemod.com/cgi-bin/wiki.pl?$1',0,''),
-('webseitzwiki','http://webseitz.fluxent.com/wiki/$1',0,''),
 ('wiki','http://c2.com/cgi/wiki?$1',0,''),
 ('wikia','http://www.wikia.com/wiki/$1',0,''),
 ('wikibooks','https://en.wikibooks.org/wiki/$1',0,'https://en.wikibooks.org/w/api.php'),
index 068ee8c..aad85da 100644 (file)
@@ -6,7 +6,6 @@
                                "name": "Base",
                                "classes": [
                                        "mw",
-                                       "mw.Map",
                                        "mw.Message",
                                        "mw.loader",
                                        "mw.loader.store",
index 1613111..85b1f92 100644 (file)
@@ -38,6 +38,6 @@
  */
 
 /**
- * Source: <http://api.qunitjs.com/>
+ * Source: <https://api.qunitjs.com/>
  * @class QUnit
  */
index 9d92794..fa2bd54 100644 (file)
@@ -48,7 +48,6 @@ class DatabaseLag extends Maintenance {
                        echo "\n";
 
                        while ( 1 ) {
-                               $lb->clearLagTimeCache();
                                $lags = $lb->getLagTimes();
                                unset( $lags[0] );
                                echo gmdate( 'H:i:s' ) . ' ';
index 5bdc8a7..bb1f3d2 100644 (file)
@@ -31,7 +31,7 @@ require_once __DIR__ . '/../Maintenance.php';
 class Digit2Html extends Maintenance {
 
        # A list of unicode numerals is available at:
-       # http://www.fileformat.info/info/unicode/category/Nd/list.htm
+       # https://www.fileformat.info/info/unicode/category/Nd/list.htm
        private $mLangs = [
                'Ar', 'As', 'Bh', 'Bo', 'Dz',
                'Fa', 'Gu', 'Hi', 'Km', 'Kn',
diff --git a/maintenance/mssql/archives/patch-change_tag-ct_id.sql b/maintenance/mssql/archives/patch-change_tag-ct_id.sql
new file mode 100644 (file)
index 0000000..94cb9d1
--- /dev/null
@@ -0,0 +1,4 @@
+-- Primary key in change_tag table
+
+ALTER TABLE /*_*/change_tag ADD ct_id INT IDENTITY;
+ALTER TABLE /*_*/change_tag ADD CONSTRAINT pk_change_tag PRIMARY KEY(ct_id)
diff --git a/maintenance/mssql/archives/patch-tag_summary-ts_id.sql b/maintenance/mssql/archives/patch-tag_summary-ts_id.sql
new file mode 100644 (file)
index 0000000..d62bd35
--- /dev/null
@@ -0,0 +1,4 @@
+-- Primary key in tag_summary table
+
+ALTER TABLE /*_*/tag_summary ADD ts_id INT IDENTITY;
+ALTER TABLE /*_*/tag_summary ADD CONSTRAINT pk_tag_summary PRIMARY KEY(ts_id)
index ea087a6..256ee36 100644 (file)
@@ -577,13 +577,13 @@ CREATE TABLE /*_*/image (
   img_media_type varchar(16) default null,
 
   -- major part of a MIME media type as defined by IANA
-  -- see http://www.iana.org/assignments/media-types/
+  -- see https://www.iana.org/assignments/media-types/
   img_major_mime varchar(16) not null default 'unknown',
 
   -- minor part of a MIME media type as defined by IANA
   -- the minor parts are not required to adher to any standard
   -- but should be consistent throughout the database
-  -- see http://www.iana.org/assignments/media-types/
+  -- see https://www.iana.org/assignments/media-types/
   img_minor_mime nvarchar(100) NOT NULL default 'unknown',
 
   -- Description field as entered by the uploader.
@@ -1193,6 +1193,7 @@ CREATE TABLE /*_*/updatelog (
 
 -- A table to track tags for revisions, logs and recent changes.
 CREATE TABLE /*_*/change_tag (
+  ct_id int NOT NULL PRIMARY KEY IDENTITY,
   -- RCID for the change
   ct_rc_id int NULL REFERENCES /*_*/recentchanges(rc_id),
   -- LOGID for the change
@@ -1215,6 +1216,7 @@ CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_i
 -- Rollup table to pull a LIST of tags simply without ugly GROUP_CONCAT
 -- that only works on MySQL 4.1+
 CREATE TABLE /*_*/tag_summary (
+  ts_id int NOT NULL PRIMARY KEY IDENTITY,
   -- RCID for the change
   ts_rc_id int NULL REFERENCES /*_*/recentchanges(rc_id),
   -- LOGID for the change
index ed63c5c..07aa282 100644 (file)
@@ -5,7 +5,7 @@
  * Should be set in Doxygen INPUT_FILTER as "php mwdoc-filter.php"
  *
  * Based on
- * <http://virtualtee.blogspot.co.uk/2012/03/tip-for-using-doxygen-for-php-code.html>
+ * <https://virtualtee.blogspot.co.uk/2012/03/tip-for-using-doxygen-for-php-code.html>
  *
  * Improved to resolve various bugs and better MediaWiki PHPDoc conventions:
  *
@@ -16,7 +16,7 @@
  * - Strip the text after @var from the output to avoid Doxygen warnings aboug bogus
  *   symbols being documented but not declared or defined.
  *
- * Copyright (C) 2012 Tamas Imrei <tamas.imrei@gmail.com> http://virtualtee.blogspot.com/
+ * Copyright (C) 2012 Tamas Imrei <tamas.imrei@gmail.com> https://virtualtee.blogspot.com/
  * Copyright (C) 2015 Timo Tijhof
  *
  * Permission is hereby granted, free of charge, to any person obtaining
index 506bc9c..b705500 100644 (file)
@@ -37,7 +37,7 @@ require_once __DIR__ . '/Maintenance.php';
 class NamespaceConflictChecker extends Maintenance {
 
        /**
-        * @var DatabaseBase
+        * @var Database
         */
        protected $db;
 
diff --git a/maintenance/oracle/archives/patch-change_tag-ct_id.sql b/maintenance/oracle/archives/patch-change_tag-ct_id.sql
new file mode 100644 (file)
index 0000000..6672872
--- /dev/null
@@ -0,0 +1,6 @@
+define mw_prefix='{$wgDBprefix}';
+
+ALTER TABLE &mw_prefix.change_tag ADD (
+ct_id NUMBER NOT NULL,
+);
+ALTER TABLE &mw_prefix.change_tag ADD CONSTRAINT &mw_prefix.change_tag_pk PRIMARY KEY (ct_id);
diff --git a/maintenance/oracle/archives/patch-tag_summary-ts_id.sql b/maintenance/oracle/archives/patch-tag_summary-ts_id.sql
new file mode 100644 (file)
index 0000000..91c3338
--- /dev/null
@@ -0,0 +1,6 @@
+define mw_prefix='{$wgDBprefix}';
+
+ALTER TABLE &mw_prefix.tag_summary ADD (
+ts_id NUMBER NOT NULL,
+);
+ALTER TABLE &mw_prefix.tag_summary ADD CONSTRAINT &mw_prefix.tag_summary_pk PRIMARY KEY (ts_id);
index d9369c9..616b401 100644 (file)
@@ -616,23 +616,27 @@ CREATE TABLE &mw_prefix.updatelog (
 ALTER TABLE &mw_prefix.updatelog ADD CONSTRAINT &mw_prefix.updatelog_pk PRIMARY KEY (ul_key);
 
 CREATE TABLE &mw_prefix.change_tag (
+  ct_id NUMBER NOT NULL,
   ct_rc_id NUMBER NULL,
   ct_log_id NUMBER NULL,
   ct_rev_id NUMBER NULL,
   ct_tag VARCHAR2(255) NOT NULL,
   ct_params BLOB NULL
 );
+ALTER TABLE &mw_prefix.change_tag ADD CONSTRAINT &mw_prefix.change_tag_pk PRIMARY KEY (ct_id);
 CREATE UNIQUE INDEX &mw_prefix.change_tag_u01 ON &mw_prefix.change_tag (ct_rc_id,ct_tag);
 CREATE UNIQUE INDEX &mw_prefix.change_tag_u02 ON &mw_prefix.change_tag (ct_log_id,ct_tag);
 CREATE UNIQUE INDEX &mw_prefix.change_tag_u03 ON &mw_prefix.change_tag (ct_rev_id,ct_tag);
 CREATE INDEX &mw_prefix.change_tag_i01 ON &mw_prefix.change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
 
 CREATE TABLE &mw_prefix.tag_summary (
+  ts_id NUMBER NOT NULL,
   ts_rc_id NUMBER NULL,
   ts_log_id NUMBER NULL,
   ts_rev_id NUMBER NULL,
   ts_tags BLOB NOT NULL
 );
+ALTER TABLE &mw_prefix.tag_summary ADD CONSTRAINT &mw_prefix.tag_summary_pk PRIMARY KEY (ts_id);
 CREATE UNIQUE INDEX &mw_prefix.tag_summary_u01 ON &mw_prefix.tag_summary (ts_rc_id);
 CREATE UNIQUE INDEX &mw_prefix.tag_summary_u02 ON &mw_prefix.tag_summary (ts_log_id);
 CREATE UNIQUE INDEX &mw_prefix.tag_summary_u03 ON &mw_prefix.tag_summary (ts_rev_id);
index 7b8f2cd..e4f3e91 100644 (file)
@@ -56,7 +56,7 @@ class Orphans extends Maintenance {
 
        /**
         * Lock the appropriate tables for the script
-        * @param DatabaseBase $db
+        * @param Database $db
         * @param string $extraTable The name of any extra tables to lock (eg: text)
         */
        private function lockTables( $db, $extraTable = [] ) {
index 401ef12..c6bd794 100644 (file)
@@ -57,7 +57,7 @@ class PopulateContentModel extends Maintenance {
                }
        }
 
-       private function updatePageRows( DatabaseBase $dbw, $pageIds, $model ) {
+       private function updatePageRows( Database $dbw, $pageIds, $model ) {
                $count = count( $pageIds );
                $this->output( "Setting $count rows to $model..." );
                $dbw->update(
@@ -70,7 +70,7 @@ class PopulateContentModel extends Maintenance {
                $this->output( "done.\n" );
        }
 
-       protected function populatePage( DatabaseBase $dbw, $ns ) {
+       protected function populatePage( Database $dbw, $ns ) {
                $toSave = [];
                $lastId = 0;
                $nsCondition = $ns === 'all' ? [] : [ 'page_namespace' => $ns ];
@@ -102,7 +102,7 @@ class PopulateContentModel extends Maintenance {
                }
        }
 
-       private function updateRevisionOrArchiveRows( DatabaseBase $dbw, $ids, $model, $table ) {
+       private function updateRevisionOrArchiveRows( Database $dbw, $ids, $model, $table ) {
                $prefix = $table === 'archive' ? 'ar' : 'rev';
                $model_column = "{$prefix}_content_model";
                $format_column = "{$prefix}_content_format";
@@ -120,7 +120,7 @@ class PopulateContentModel extends Maintenance {
                $this->output( "done.\n" );
        }
 
-       protected function populateRevisionOrArchive( DatabaseBase $dbw, $table, $ns ) {
+       protected function populateRevisionOrArchive( Database $dbw, $table, $ns ) {
                $prefix = $table === 'archive' ? 'ar' : 'rev';
                $model_column = "{$prefix}_content_model";
                $format_column = "{$prefix}_content_format";
index 05098ac..ac87cf3 100644 (file)
@@ -83,7 +83,7 @@ class PopulateRecentChangesSource extends LoggedUpdateMaintenance {
                return __CLASS__;
        }
 
-       protected function buildUpdateCondition( DatabaseBase $dbw ) {
+       protected function buildUpdateCondition( Database $dbw ) {
                $rcNew = $dbw->addQuotes( RC_NEW );
                $rcSrcNew = $dbw->addQuotes( RecentChange::SRC_NEW );
                $rcEdit = $dbw->addQuotes( RC_EDIT );
index 95c87c0..2273761 100644 (file)
@@ -25,6 +25,8 @@ DROP SEQUENCE IF EXISTS category_cat_id_seq CASCADE;
 DROP SEQUENCE IF EXISTS archive_ar_id_seq CASCADE;
 DROP SEQUENCE IF EXISTS externallinks_el_id_seq CASCADE;
 DROP SEQUENCE IF EXISTS sites_site_id_seq CASCADE;
+DROP SEQUENCE IF EXISTS change_tag_ct_id_seq CASCADE;
+DROP SEQUENCE IF EXISTS tag_summary_ts_id_seq CASCADE;
 DROP FUNCTION IF EXISTS page_deleted() CASCADE;
 DROP FUNCTION IF EXISTS ts2_page_title() CASCADE;
 DROP FUNCTION IF EXISTS ts2_page_text() CASCADE;
@@ -653,7 +655,9 @@ CREATE TABLE category (
 CREATE UNIQUE INDEX category_title ON category(cat_title);
 CREATE INDEX category_pages ON category(cat_pages);
 
+CREATE SEQUENCE change_tag_ct_id_seq;
 CREATE TABLE change_tag (
+  ct_id      INTEGER  NOT NULL  PRIMARY KEY DEFAULT nextval('change_tag_ct_id_seq'),
   ct_rc_id   INTEGER      NULL,
   ct_log_id  INTEGER      NULL,
   ct_rev_id  INTEGER      NULL,
@@ -665,11 +669,13 @@ CREATE UNIQUE INDEX change_tag_log_tag ON change_tag(ct_log_id,ct_tag);
 CREATE UNIQUE INDEX change_tag_rev_tag ON change_tag(ct_rev_id,ct_tag);
 CREATE INDEX change_tag_tag_id ON change_tag(ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
 
+CREATE SEQUENCE tag_summary_ts_id_seq;
 CREATE TABLE tag_summary (
-  ts_rc_id   INTEGER     NULL,
-  ts_log_id  INTEGER     NULL,
-  ts_rev_id  INTEGER     NULL,
-  ts_tags    TEXT    NOT NULL
+  ts_id      INTEGER  NOT NULL  PRIMARY KEY DEFAULT nextval('tag_summary_ts_id_seq'),
+  ts_rc_id   INTEGER      NULL,
+  ts_log_id  INTEGER      NULL,
+  ts_rev_id  INTEGER      NULL,
+  ts_tags    TEXT     NOT NULL
 );
 CREATE UNIQUE INDEX tag_summary_rc_id ON tag_summary(ts_rc_id);
 CREATE UNIQUE INDEX tag_summary_log_id ON tag_summary(ts_log_id);
index 615d1fe..3c0fc7e 100644 (file)
@@ -210,7 +210,7 @@ class PurgeChangedFiles extends Maintenance {
        }
 
        protected function purgeFromArchiveTable( LocalRepo $repo, LocalFile $file ) {
-               $dbr = $repo->getSlaveDB();
+               $dbr = $repo->getReplicaDB();
                $res = $dbr->select(
                        'filearchive',
                        [ 'fa_archive_name' ],
index 5d085a8..e00a55d 100644 (file)
@@ -32,6 +32,8 @@ require __DIR__ . '/Maintenance.php';
 class PurgeParserCache extends Maintenance {
        public $lastProgress;
 
+       private $usleep = 0;
+
        function __construct() {
                parent::__construct();
                $this->addDescription( "Remove old objects from the parser cache. " .
@@ -39,36 +41,44 @@ class PurgeParserCache extends Maintenance {
                $this->addOption( 'expiredate', 'Delete objects expiring before this date.', false, true );
                $this->addOption(
                        'age',
-                       'Delete objects created more than this many seconds ago, assuming $wgParserCacheExpireTime ' .
-                               'has been consistent.',
-                       false, true );
+                       'Delete objects created more than this many seconds ago, assuming ' .
+                               '$wgParserCacheExpireTime has remained consistent.',
+                       false,
+                       true );
+               $this->addOption( 'msleep', 'Milliseconds to sleep between purge chunks', false, true );
        }
 
        function execute() {
+               global $wgParserCacheExpireTime;
+
                $inputDate = $this->getOption( 'expiredate' );
                $inputAge = $this->getOption( 'age' );
                if ( $inputDate !== null ) {
                        $date = wfTimestamp( TS_MW, strtotime( $inputDate ) );
                } elseif ( $inputAge !== null ) {
-                       global $wgParserCacheExpireTime;
                        $date = wfTimestamp( TS_MW, time() + $wgParserCacheExpireTime - intval( $inputAge ) );
                } else {
                        $this->error( "Must specify either --expiredate or --age", 1 );
+                       return;
                }
+               $this->usleep = 1e3 * $this->getOption( 'msleep', 0 );
 
                $english = Language::factory( 'en' );
-               $this->output( "Deleting objects expiring before " . $english->timeanddate( $date ) . "\n" );
+               $this->output( "Deleting objects expiring before " .
+                       $english->timeanddate( $date ) . "\n" );
 
                $pc = wfGetParserCacheStorage();
-               $success = $pc->deleteObjectsExpiringBefore( $date, [ $this, 'showProgress' ] );
+               $success = $pc->deleteObjectsExpiringBefore( $date, [ $this, 'showProgressAndWait' ] );
                if ( !$success ) {
                        $this->error( "\nCannot purge this kind of parser cache.", 1 );
                }
-               $this->showProgress( 100 );
+               $this->showProgressAndWait( 100 );
                $this->output( "\nDone\n" );
        }
 
-       function showProgress( $percent ) {
+       public function showProgressAndWait( $percent ) {
+               usleep( $this->usleep ); // avoid lag; T150124
+
                $percentString = sprintf( "%.2f", $percent );
                if ( $percentString === $this->lastProgress ) {
                        return;
index 3157186..6aa1f37 100644 (file)
@@ -40,7 +40,7 @@ require_once __DIR__ . '/Maintenance.php';
 class ImageBuilder extends Maintenance {
 
        /**
-        * @var DatabaseBase
+        * @var Database
         */
        protected $dbw;
 
index b9c797d..48602de 100644 (file)
@@ -112,7 +112,7 @@ class RebuildLocalisationCache extends Maintenance {
 
                        if ( $pid === 0 ) {
                                // Child, reseed because there is no bug in PHP:
-                               // http://bugs.php.net/bug.php?id=42465
+                               // https://bugs.php.net/bug.php?id=42465
                                mt_srand( getmypid() );
 
                                $this->doRebuild( $codes, $lc, $force );
index ec99d84..37636c8 100644 (file)
@@ -36,7 +36,7 @@ class RebuildTextIndex extends Maintenance {
        const RTI_CHUNK_SIZE = 500;
 
        /**
-        * @var DatabaseBase
+        * @var Database
         */
        private $db;
 
index aea966f..df4ce56 100644 (file)
@@ -37,7 +37,7 @@ require_once __DIR__ . '/Maintenance.php';
 class RefreshImageMetadata extends Maintenance {
 
        /**
-        * @var DatabaseBase
+        * @var Database
         */
        protected $dbw;
 
@@ -197,7 +197,7 @@ class RefreshImageMetadata extends Maintenance {
        }
 
        /**
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @return array
         */
        function getConditions( $dbw ) {
index a5e7a2f..f8eedb3 100644 (file)
@@ -34,26 +34,74 @@ class BatchedQueryRunner extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->addDescription(
-                       "Run a query repeatedly until it affects 0 rows, and wait for replica DBs in between.\n" .
-                               "NOTE: You need to set a LIMIT clause yourself." );
+                       "Run an update query on all rows of a table. " .
+                       "Waits for replicas at appropriate intervals." );
+               $this->addOption( 'table', 'The table name', true, true );
+               $this->addOption( 'set', 'The SET clause', true, true );
+               $this->addOption( 'where', 'The WHERE clause', false, true );
+               $this->addOption( 'key', 'A column name, the values of which are unique', true, true );
+               $this->addOption( 'batch-size', 'The batch size (default 1000)', false, true );
+               $this->addOption( 'db', 'The database name, or omit to use the current wiki.', false, true );
        }
 
        public function execute() {
-               if ( !$this->hasArg() ) {
-                       $this->error( "No query specified. Specify the query as a command line parameter.", true );
+               $table = $this->getOption( 'table' );
+               $key = $this->getOption( 'key' );
+               $set = $this->getOption( 'set' );
+               $where = $this->getOption( 'where', null );
+               $where = $where === null ? [] : [ $where ];
+               $batchSize = $this->getOption( 'batch-size', 1000 );
+
+               $dbName = $this->getOption( 'db', null );
+               if ( $dbName === null ) {
+                       $dbw = $this->getDB( DB_MASTER );
+               } else {
+                       $lbf = MediaWiki\MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+                       $lb = $lbf->getMainLB( $dbName );
+                       $dbw = $lb->getConnection( DB_MASTER, [], $dbName );
                }
 
-               $query = $this->getArg();
+               $selectConds = $where;
+               $prevEnd = false;
+
                $n = 1;
-               $dbw = $this->getDB( DB_MASTER );
                do {
                        $this->output( "Batch $n: " );
                        $n++;
+
+                       // Note that the update conditions do not rely on atomicity of the
+                       // SELECT query in order to guarantee that all rows are updated. The
+                       // results of the SELECT are merely a partitioning hint. Simultaneous
+                       // updates merely result in the wrong number of rows being updated
+                       // in a batch.
+
+                       $res = $dbw->select( $table, $key, $selectConds, __METHOD__,
+                               [ 'ORDER BY' => $key, 'LIMIT' => $batchSize ] );
+                       if ( $res->numRows() ) {
+                               $res->seek( $res->numRows() - 1 );
+                               $row = $res->fetchObject();
+                               $end = $dbw->addQuotes( $row->$key );
+                               $selectConds = array_merge( $where, [ "$key > $end" ] );
+                               $updateConds = array_merge( $where, [ "$key <= $end" ] );
+                       } else {
+                               $updateConds = $where;
+                       }
+                       if ( $prevEnd !== false ) {
+                               $updateConds = array_merge( [ "$key > $prevEnd" ], $updateConds );
+                       }
+
+                       $query = "UPDATE " . $dbw->tableName( $table ) .
+                               " SET " . $set .
+                               " WHERE " . $dbw->makeList( $updateConds, IDatabase::LIST_AND );
+
                        $dbw->query( $query, __METHOD__ );
+
+                       $prevEnd = $end;
+
                        $affected = $dbw->affectedRows();
-                       $this->output( "$affected rows\n" );
+                       $this->output( "$affected rows affected\n" );
                        wfWaitForSlaves();
-               } while ( $affected > 0 );
+               } while ( $res->numRows() );
        }
 
        public function getDbType() {
index a9a982c..cc976ed 100644 (file)
@@ -91,7 +91,7 @@ class MwSql extends Maintenance {
                                $this->error( "Unable to open input file", true );
                        }
 
-                       $error = $db->sourceStream( $file, false, [ $this, 'sqlPrintResult' ] );
+                       $error = $db->sourceStream( $file, null, [ $this, 'sqlPrintResult' ] );
                        if ( $error !== true ) {
                                $this->error( $error, true );
                        } else {
diff --git a/maintenance/sqlite/archives/patch-change_tag-ct_id.sql b/maintenance/sqlite/archives/patch-change_tag-ct_id.sql
new file mode 100644 (file)
index 0000000..1c01094
--- /dev/null
@@ -0,0 +1,25 @@
+DROP TABLE IF EXISTS /*_*/change_tag_tmp;
+
+CREATE TABLE /*$wgDBprefix*/change_tag_tmp (
+  ct_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  ct_rc_id int NULL,
+  ct_log_id int NULL,
+  ct_rev_id int NULL,
+  ct_tag varchar(255) NOT NULL,
+  ct_params blob NULL
+);
+
+INSERT OR IGNORE INTO /*_*/change_tag_tmp (
+    ct_rc_id, ct_log_id, ct_rev_id, ct_tag, ct_params )
+    SELECT
+    ct_rc_id, ct_log_id, ct_rev_id, ct_tag, ct_params
+    FROM /*_*/change_tag;
+
+DROP TABLE /*_*/change_tag;
+
+ALTER TABLE /*_*/change_tag_tmp RENAME TO /*_*/change_tag;
+
+CREATE UNIQUE INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag (ct_rc_id,ct_tag);
+CREATE UNIQUE INDEX /*i*/change_tag_log_tag ON /*_*/change_tag (ct_log_id,ct_tag);
+CREATE UNIQUE INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag (ct_rev_id,ct_tag);
+CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
diff --git a/maintenance/sqlite/archives/patch-tag_summary-ts_id.sql b/maintenance/sqlite/archives/patch-tag_summary-ts_id.sql
new file mode 100644 (file)
index 0000000..b6a1202
--- /dev/null
@@ -0,0 +1,23 @@
+DROP TABLE IF EXISTS /*_*/tag_summary_tmp;
+
+CREATE TABLE /*$wgDBprefix*/tag_summary_tmp (
+  ts_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  ts_rc_id int NULL,
+  ts_log_id int NULL,
+  ts_rev_id int NULL,
+  ts_tags blob NOT NULL
+);
+
+INSERT OR IGNORE INTO /*_*/tag_summary_tmp (
+    ts_rc_id, ts_log_id, ts_rev_id, ts_tags )
+    SELECT
+    ts_rc_id, ts_log_id, ts_rev_id, ts_tags
+    FROM /*_*/tag_summary;
+
+DROP TABLE /*_*/tag_summary;
+
+ALTER TABLE /*_*/tag_summary_tmp RENAME TO /*_*/tag_summary;
+
+CREATE UNIQUE INDEX /*i*/tag_summary_rc_id ON /*_*/tag_summary (ts_rc_id);
+CREATE UNIQUE INDEX /*i*/tag_summary_log_id ON /*_*/tag_summary (ts_log_id);
+CREATE UNIQUE INDEX /*i*/tag_summary_rev_id ON /*_*/tag_summary (ts_rev_id);
index 2a37094..38cdfcf 100644 (file)
@@ -1,6 +1,6 @@
 -- Patch that introduces fulltext search capabilities to SQLite schema
 -- Requires that SQLite must be compiled with FTS3 module (comes with core amalgamation).
--- See http://sqlite.org/fts3.html for details of syntax.
+-- See https://sqlite.org/fts3.html for details of syntax.
 -- Will fail if FTS3 is not present,
 DROP TABLE IF EXISTS /*_*/searchindex;
 CREATE VIRTUAL TABLE /*_*/searchindex USING FTS3(
@@ -15,4 +15,4 @@ CREATE VIRTUAL TABLE /*_*/searchindex USING FTS3(
   si_text
 );
 
-INSERT INTO /*_*/updatelog (ul_key) VALUES ('fts3');
\ No newline at end of file
+INSERT INTO /*_*/updatelog (ul_key) VALUES ('fts3');
index a0efcb8..c5dd53b 100644 (file)
@@ -640,7 +640,7 @@ class RecompressTracked {
        /**
         * Gets a DB master connection for the given external cluster name
         * @param string $cluster
-        * @return DatabaseBase
+        * @return Database
         */
        function getExtDB( $cluster ) {
                $lb = wfGetLBFactory()->getExternalLB( $cluster );
index b5c14e3..cf60d89 100644 (file)
@@ -861,14 +861,14 @@ CREATE TABLE /*_*/image (
   img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
 
   -- major part of a MIME media type as defined by IANA
-  -- see http://www.iana.org/assignments/media-types/
+  -- see https://www.iana.org/assignments/media-types/
   -- for "chemical" cf. http://dx.doi.org/10.1021/ci9803233 by the ACS
   img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
 
   -- minor part of a MIME media type as defined by IANA
   -- the minor parts are not required to adher to any standard
   -- but should be consistent throughout the database
-  -- see http://www.iana.org/assignments/media-types/
+  -- see https://www.iana.org/assignments/media-types/
   img_minor_mime varbinary(100) NOT NULL default "unknown",
 
   -- Description field as entered by the uploader.
@@ -1472,6 +1472,7 @@ CREATE TABLE /*_*/updatelog (
 
 -- A table to track tags for revisions, logs and recent changes.
 CREATE TABLE /*_*/change_tag (
+  ct_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
   -- RCID for the change
   ct_rc_id int NULL,
   -- LOGID for the change
@@ -1494,6 +1495,7 @@ CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_i
 -- Rollup table to pull a LIST of tags simply without ugly GROUP_CONCAT
 -- that only works on MySQL 4.1+
 CREATE TABLE /*_*/tag_summary (
+  ts_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
   -- RCID for the change
   ts_rc_id int NULL,
   -- LOGID for the change
index b96e7eb..a672e29 100755 (executable)
@@ -145,6 +145,7 @@ class UpdateMediaWiki extends Maintenance {
 
                $this->output( "Going to run database updates for " . wfWikiID() . "\n" );
                if ( $db->getType() === 'sqlite' ) {
+                       /** @var Database|DatabaseSqlite $db */
                        $this->output( "Using SQLite file: '{$db->getDbFilePath()}'\n" );
                }
                $this->output( "Depending on the size of your database this may take a while!\n" );
index e754e3c..e70a176 100644 (file)
@@ -242,7 +242,7 @@ TEXT
         * Return an SQL expression selecting rows which sort above the given row,
         * assuming an ordering of cl_collation, cl_to, cl_type, cl_from
         * @param stdClass $row
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @return string
         */
        function getBatchCondition( $row, $dbw ) {
diff --git a/maintenance/updateCredits.php b/maintenance/updateCredits.php
new file mode 100644 (file)
index 0000000..a43e0ba
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Update the CREDITS list by merging in the list of git commit authors.
+ *
+ * The contents of the existing contributors list will be preserved. If a name
+ * needs to be removed for some reason that must be done manually before or
+ * after running this script.
+ *
+ * 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
+ */
+
+if ( PHP_SAPI != 'cli' ) {
+       die( "This script can only be run from the command line.\n" );
+}
+
+chdir( dirname( __DIR__ ) );
+
+$CREDITS = 'CREDITS';
+$START_CONTRIBUTORS = '<!-- BEGIN CONTRIBUTOR LIST -->';
+$END_CONTRIBUTORS = '<!-- END CONTRIBUTOR LIST -->';
+
+$inHeader = true;
+$inFooter = false;
+$header = [];
+$contributors = [];
+$footer = [];
+
+$lines = explode( "\n", file_get_contents( $CREDITS ) );
+foreach ( $lines as $line ) {
+       if ( $inHeader ) {
+               $header[] = $line;
+               $inHeader = $line !== $START_CONTRIBUTORS;
+       } elseif ( $inFooter ) {
+               $footer[] = $line;
+       } elseif ( $line == $END_CONTRIBUTORS ) {
+               $inFooter = true;
+               $footer[] = $line;
+       } else {
+               $name = substr( $line, 2 );
+               $contributors[$name] = true;
+       }
+}
+unset( $lines );
+
+$lines = explode( "\n", shell_exec( 'git log --format="%aN"' ) );
+foreach ( $lines as $line ) {
+       if ( empty( $line ) )  {
+               continue;
+       }
+       if ( substr( $line, 0, 5 ) === '[BOT]' ) {
+               continue;
+       }
+       $contributors[$line] = true;
+}
+
+$contributors = array_keys( $contributors );
+$collator = Collator::create( 'uca-default-u-kn' );
+$collator->sort( $contributors );
+array_walk( $contributors, function ( &$v, $k ) {
+       $v = "* {$v}";
+} );
+
+file_put_contents( $CREDITS,
+       implode( "\n", array_merge( $header, $contributors, $footer ) ) );
index bd34a50..b9baf8c 100644 (file)
@@ -2,14 +2,21 @@
 
 require_once __DIR__ . '/Maintenance.php';
 
+use Composer\Spdx\SpdxLicenses;
+use JsonSchema\Validator;
+
 class ValidateRegistrationFile extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->addArg( 'path', 'Path to extension.json/skin.json file.', true );
        }
        public function execute() {
-               if ( !class_exists( 'JsonSchema\Validato' ) ) {
+               if ( !class_exists( Validator::class ) ) {
                        $this->error( 'The JsonSchema library cannot be found, please install it through composer.', 1 );
+               } elseif ( !class_exists( SpdxLicenses::class ) ) {
+                       $this->error(
+                               'The spdx-licenses library cannot be found, please install it through composer.', 1
+                       );
                }
 
                $path = $this->getArg( 0 );
@@ -38,14 +45,29 @@ class ValidateRegistrationFile extends Maintenance {
                        $this->output( "Warning: $path is using a deprecated schema, and should be updated to "
                                . ExtensionRegistry::MANIFEST_VERSION . "\n" );
                }
-               $validator = new JsonSchema\Validator;
-               $validator->check( $data, (object) [ '$ref' => 'file://' . $schemaPath ] );
-               if ( $validator->isValid() ) {
+
+               $licenseError = false;
+               // Check if it's a string, if not, schema validation will display an error
+               if ( isset( $data->{'license-name'} ) && is_string( $data->{'license-name'} ) ) {
+                       $licenses = new SpdxLicenses();
+                       $valid = $licenses->validate( $data->{'license-name'} );
+                       if ( !$valid ) {
+                               $licenseError = '[license-name] Invalid SPDX license identifier, '
+                                       . 'see <https://spdx.org/licenses/>';
+                       }
+               }
+
+               $validator = new Validator;
+               $validator->check( $data, (object)[ '$ref' => 'file://' . $schemaPath ] );
+               if ( $validator->isValid() && !$licenseError ) {
                        $this->output( "$path validates against the version $version schema!\n" );
                } else {
                        foreach ( $validator->getErrors() as $error ) {
                                $this->output( "[{$error['property']}] {$error['message']}\n" );
                        }
+                       if ( $licenseError ) {
+                               $this->output( "$licenseError\n" );
+                       }
                        $this->error( "$path does not validate.", 1 );
                }
        }
index 2ce19e5..0a859c0 100644 (file)
@@ -113,6 +113,7 @@ class WrapOldPasswords extends Maintenance {
                        }
 
                        $this->commitTransaction( $dbw, __METHOD__ );
+                       LBFactory::waitForReplication();
 
                        // Clear memcached so old passwords are wiped out
                        foreach ( $updateUsers as $user ) {
index 3b75c3a..0e841f8 100644 (file)
@@ -6,12 +6,12 @@
     "postdoc": "grunt copy:jsduck"
   },
   "devDependencies": {
+    "eslint-config-wikimedia": "0.3.0",
     "grunt": "1.0.1",
     "grunt-banana-checker": "0.5.0",
     "grunt-contrib-copy": "1.0.0",
-    "grunt-contrib-jshint": "1.0.0",
     "grunt-contrib-watch": "1.0.0",
-    "grunt-jscs": "2.8.0",
+    "grunt-eslint": "19.0.0",
     "grunt-jsonlint": "1.0.7",
     "grunt-karma": "2.0.0",
     "grunt-stylelint": "0.6.0",
index b81fbde..1dfafc7 100644 (file)
@@ -1020,7 +1020,6 @@ return [
                        'feedback-cancel',
                        'feedback-close',
                        'feedback-dialog-title',
-                       'feedback-error-title',
                        'feedback-error1',
                        'feedback-error2',
                        'feedback-error3',
@@ -1407,6 +1406,11 @@ return [
                'dependencies' => 'mediawiki.util',
                'targets' => [ 'desktop', 'mobile' ],
        ],
+       'mediawiki.user.blockcookie' => [
+               'scripts' => 'resources/src/mediawiki/mediawiki.user.blockcookie.js',
+               'dependencies' => [ 'mediawiki.cookie', 'mediawiki.storage' ],
+               'targets' => [ 'desktop', 'mobile' ],
+       ],
        'mediawiki.user' => [
                'scripts' => 'resources/src/mediawiki/mediawiki.user.js',
                'dependencies' => [
@@ -1726,6 +1730,9 @@ return [
                        'oojs-ui-core',
                        'oojs-ui-widgets',
                        'oojs-ui.styles.icons-media'
+               ],
+               'messages' => [
+                       'gallery-slideshow-toggle'
                ]
        ],
        'mediawiki.page.ready' => [
@@ -1810,11 +1817,13 @@ return [
                'targets' => [ 'desktop', 'mobile' ],
        ],
        'mediawiki.special.apisandbox.styles' => [
+               'targets' => [ 'desktop', 'mobile' ],
                'styles' => 'resources/src/mediawiki.special/mediawiki.special.apisandbox.top.css',
        ],
        'mediawiki.special.apisandbox' => [
                'styles' => 'resources/src/mediawiki.special/mediawiki.special.apisandbox.css',
                'scripts' => 'resources/src/mediawiki.special/mediawiki.special.apisandbox.js',
+               'targets' => [ 'desktop', 'mobile' ],
                'dependencies' => [
                        'mediawiki.api',
                        'mediawiki.jqueryMsg',
@@ -1860,6 +1869,11 @@ return [
                        'apisandbox-results-fixtoken-fail',
                        'apisandbox-alert-page',
                        'apisandbox-alert-field',
+                       'apisandbox-continue',
+                       'apisandbox-continue-clear',
+                       'apisandbox-continue-help',
+                       'apisandbox-param-limit',
+                       'api-format-prettyprint-status',
                        'blanknamespace',
                ],
        ],
index 610e1ee..50a8cad 100644 (file)
@@ -12,7 +12,8 @@
                        "ترجمان05",
                        "Abanima",
                        "محمد أحمد عبد الفتاح",
-                       "Hiba Alshawi"
+                       "Hiba Alshawi",
+                       "Meno25"
                ]
        },
        "ooui-outline-control-move-down": "انقل العنصر للأسفل",
@@ -27,8 +28,8 @@
        "ooui-dialog-process-dismiss": "أغلق",
        "ooui-dialog-process-retry": "حاول مرة أخرى",
        "ooui-dialog-process-continue": "استمر",
-       "ooui-selectfile-button-select": "أختر Ù\85Ù\84Ù\81",
-       "ooui-selectfile-not-supported": "تحدÙ\8aد الملفات غير مدعوم",
-       "ooui-selectfile-placeholder": "Ù\84Ù\85 Ù\8aختر أي ملف",
-       "ooui-selectfile-dragdrop-placeholder": "ترÙ\83 ملف هنا"
+       "ooui-selectfile-button-select": "اختر Ù\85Ù\84Ù\81ا",
+       "ooui-selectfile-not-supported": "اختÙ\8aار الملفات غير مدعوم",
+       "ooui-selectfile-placeholder": "Ù\84Ù\85 Ù\8aتÙ\85 Ø§Ø®ØªÙ\8aار أي ملف",
+       "ooui-selectfile-dragdrop-placeholder": "اترÙ\83 Ø§Ù\84ملف هنا"
 }
index dce3593..5a3a93d 100644 (file)
@@ -5,9 +5,12 @@
                        "Hristofor.mirchev",
                        "පසිඳු කාවින්ද",
                        "Mitzev",
-                       "Aquilax"
+                       "Aquilax",
+                       "Vodnokon4e"
                ]
        },
+       "ooui-outline-control-move-down": "Преместване на елемента надолу",
+       "ooui-outline-control-move-up": "Преместване на елемента нагоре",
        "ooui-outline-control-remove": "Премахване на обекта",
        "ooui-toolbar-more": "Още",
        "ooui-toolgroup-expand": "Още",
@@ -17,5 +20,9 @@
        "ooui-dialog-process-error": "Нещо се обърка",
        "ooui-dialog-process-dismiss": "Затвори",
        "ooui-dialog-process-retry": "Опитайте отново",
-       "ooui-dialog-process-continue": "Продължаване"
+       "ooui-dialog-process-continue": "Продължаване",
+       "ooui-selectfile-button-select": "Избиране на файл",
+       "ooui-selectfile-not-supported": "Избраният файл не се поддържа",
+       "ooui-selectfile-placeholder": "Не е избран файл",
+       "ooui-selectfile-dragdrop-placeholder": "Пуснете файла тук"
 }
index e193fb0..7e1cd56 100644 (file)
@@ -21,5 +21,6 @@
        "ooui-dialog-message-reject": "Afbryd",
        "ooui-dialog-process-error": "Noget gik galt",
        "ooui-dialog-process-retry": "Prøv igen",
-       "ooui-dialog-process-continue": "Fortsæt"
+       "ooui-dialog-process-continue": "Fortsæt",
+       "ooui-selectfile-button-select": "Vælg en fil"
 }
index 15a5de3..de8d6f1 100644 (file)
        },
        "ooui-outline-control-move-down": "घटक (आयटम) खाली सरकवा",
        "ooui-outline-control-move-up": "घटक (आयटम) वर सरकवा",
+       "ooui-outline-control-remove": "बाब हटवा",
        "ooui-toolbar-more": "अधिक",
        "ooui-toolgroup-expand": "अधिक",
+       "ooui-toolgroup-collapse": "कमी",
        "ooui-dialog-message-accept": "ठिक आहे",
        "ooui-dialog-message-reject": "रद्द करा",
+       "ooui-dialog-process-error": "काहीतरी गडबड झाली",
        "ooui-dialog-process-dismiss": "रद्द करा",
-       "ooui-dialog-process-continue": "चालू ठेवा"
+       "ooui-dialog-process-retry": "पुन्हा प्रयत्न करा",
+       "ooui-dialog-process-continue": "चालू ठेवा",
+       "ooui-selectfile-button-select": "संचिका निवडा",
+       "ooui-selectfile-not-supported": "संचिका निवडणे साहाय्यीकृत नाही",
+       "ooui-selectfile-placeholder": "संचिका निवडल्या गेली नाही",
+       "ooui-selectfile-dragdrop-placeholder": "संचिका येथे टाका"
 }
index 1e5b83d..9dee2f5 100644 (file)
@@ -1,10 +1,16 @@
 {
        "@metadata": {
                "authors": [
-                       "Zylbath"
+                       "Zylbath",
+                       "Joachim Mos"
                ]
        },
        "ooui-outline-control-move-down": "Element na ünnen schuven",
        "ooui-outline-control-move-up": "Element na baven schuven",
-       "ooui-toolbar-more": "Mehr"
+       "ooui-toolbar-more": "Mehr",
+       "ooui-dialog-message-accept": "OK",
+       "ooui-dialog-message-reject": "Afbreken",
+       "ooui-dialog-process-error": "Do is wat in'e Büx goan",
+       "ooui-dialog-process-continue": "Wiedermaken",
+       "ooui-selectfile-button-select": "En Datei utwählen"
 }
index 3e54e85..dbe9f86 100644 (file)
@@ -10,7 +10,8 @@
                        "TurkishStyles",
                        "Sayginer",
                        "Meelo",
-                       "McAang"
+                       "McAang",
+                       "Uğurkent"
                ]
        },
        "ooui-outline-control-move-down": "Ögeyi aşağı taşı",
@@ -25,5 +26,7 @@
        "ooui-dialog-process-dismiss": "Kapat",
        "ooui-dialog-process-retry": "Tekrar dene",
        "ooui-dialog-process-continue": "Devam et",
+       "ooui-selectfile-button-select": "Dosya seç",
+       "ooui-selectfile-not-supported": "Dosya seçimi desteklenmiyor",
        "ooui-selectfile-placeholder": "Herhangi bir dosya seçilmedi"
 }
index 594cea2..542447d 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:02Z
+ * Date: 2016-11-09T00:52:37Z
  */
 ( function ( OO ) {
 
index 6437ca8..bcc3778 100644 (file)
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:06Z
+ * Date: 2016-11-09T00:52:42Z
  */
 .oo-ui-element-hidden {
-       display: none !important;
-       /* stylelint-disable-line declaration-no-important */
+  display: none !important;
+  /* stylelint-disable-line declaration-no-important */
 }
 .oo-ui-buttonElement {
-       display: inline-block;
-       vertical-align: middle;
+  display: inline-block;
+  vertical-align: middle;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button {
-       cursor: pointer;
-       display: inline-block;
-       vertical-align: middle;
-       font-family: inherit;
-       font-size: inherit;
-       line-height: normal;
-       white-space: nowrap;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  cursor: pointer;
+  display: inline-block;
+  vertical-align: middle;
+  font-family: inherit;
+  font-size: inherit;
+  line-height: normal;
+  white-space: nowrap;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       display: none;
+  display: none;
 }
 .oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-       cursor: default;
-}
-.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
-       z-index: 2;
+  cursor: default;
 }
 .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       display: inline-block;
-       vertical-align: middle;
+  display: inline-block;
+  vertical-align: middle;
 }
 .oo-ui-buttonElement-frameless {
-       position: relative;
+  position: relative;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
-       vertical-align: top;
-       text-align: center;
+  vertical-align: top;
+  text-align: center;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button {
-       color: #333;
+  color: #333;
 }
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       margin-left: 0;
+  margin-left: 0;
 }
 .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       margin: 0.46875em;
+  margin: 0.46875em;
 }
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       margin-left: 0.46875em;
+  margin-left: 0.46875em;
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus {
-       outline: none;
+  outline: none;
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus > .oo-ui-iconElement-icon {
-       opacity: 1;
+  opacity: 1;
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
-       color: #000;
+  color: #000;
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #333;
+  color: #333;
 }
 .oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       margin-left: 0.25em;
+  margin-left: 0.25em;
 }
 .oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button {
-       padding-left: 0.25em;
-       color: #333;
+  padding-left: 0.25em;
+  color: #333;
 }
 .oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button:focus {
-       color: #000;
+  color: #000;
 }
 .oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #087ecc;
+  color: #087ecc;
 }
 .oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #76ab36;
+  color: #76ab36;
 }
 .oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #d45353;
+  color: #d45353;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #ccc;
+  color: #ccc;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
-       padding: 0.2em 0.8em;
-       border-radius: 0.3em;
-       text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
-       border: 1px #c9c9c9 solid;
-       -webkit-transition: border-color 100ms ease;
-          -moz-transition: border-color 100ms ease;
-               transition: border-color 100ms ease;
-       background-color: #eee;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
-       background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
-       background-image:    -moz-linear-gradient(top, #fff 0, #ddd 100%);
-       background-image:         linear-gradient(to bottom, #fff 0, #ddd 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffffffff\', endColorstr=\'#ffdddddd\' )';
+  padding: 0.2em 0.8em;
+  border-radius: 0.3em;
+  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
+  border: 1px #c9c9c9 solid;
+  -webkit-transition: border-color 100ms ease;
+     -moz-transition: border-color 100ms ease;
+          transition: border-color 100ms ease;
+  background-color: #eeeeee;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
+  background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
+  background-image:    -moz-linear-gradient(top, #fff 0, #ddd 100%);
+  background-image:         linear-gradient(to bottom, #fff 0, #ddd 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:focus {
-       border-color: #aaa;
-       outline: none;
+  border-color: #aaa;
+  outline: none;
 }
 .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.875em;
+  line-height: 1.875em;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
-       color: #000;
-       border-color: #c9c9c9;
-       background-color: #eee;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ddd), color-stop(100%, #fff));
-       background-image: -webkit-linear-gradient(top, #ddd 0, #fff 100%);
-       background-image:    -moz-linear-gradient(top, #ddd 0, #fff 100%);
-       background-image:         linear-gradient(to bottom, #ddd 0, #fff 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffdddddd\', endColorstr=\'#ffffffff\' )';
+  box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
+  color: #000;
+  border-color: #c9c9c9;
+  background-color: #eeeeee;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ddd), color-stop(100%, #fff));
+  background-image: -webkit-linear-gradient(top, #ddd 0, #fff 100%);
+  background-image:    -moz-linear-gradient(top, #ddd 0, #fff 100%);
+  background-image:         linear-gradient(to bottom, #ddd 0, #fff 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffdddddd', endColorstr='#ffffffff' )";
 }
 .oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       margin-left: -0.5em;
-       margin-right: -0.5em;
+  margin-left: -0.5em;
+  margin-right: -0.5em;
 }
 .oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       margin-right: 0.3em;
+  margin-right: 0.3em;
 }
 .oo-ui-buttonElement-framed.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       margin-left: -0.005em;
-       margin-right: -0.005em;
+  margin-left: -0.005em;
+  margin-right: -0.005em;
 }
 .oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
 .oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-iconElement:not( .oo-ui-labelElement ) > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       margin-left: 0.46875em;
-       margin-right: -0.275em;
+  margin-left: 0.46875em;
+  margin-right: -0.275em;
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
-       border: 1px solid #a6cee1;
-       background-color: #cde7f4;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #eaf4fa), color-stop(100%, #b0d9ee));
-       background-image: -webkit-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
-       background-image:    -moz-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
-       background-image:         linear-gradient(to bottom, #eaf4fa 0, #b0d9ee 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffeaf4fa\', endColorstr=\'#ffb0d9ee\' )';
+  border: 1px solid #a6cee1;
+  background-color: #cde7f4;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #eaf4fa), color-stop(100%, #b0d9ee));
+  background-image: -webkit-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
+  background-image:    -moz-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
+  background-image:         linear-gradient(to bottom, #eaf4fa 0, #b0d9ee 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffeaf4fa', endColorstr='#ffb0d9ee' )";
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
-       border-color: #9dc2d4;
+  border-color: #9dc2d4;
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       border: 1px solid #a6cee1;
-       background-color: #cde7f4;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #b0d9ee), color-stop(100%, #eaf4fa));
-       background-image: -webkit-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
-       background-image:    -moz-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
-       background-image:         linear-gradient(to bottom, #b0d9ee 0, #eaf4fa 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffb0d9ee\', endColorstr=\'#ffeaf4fa\' )';
+  border: 1px solid #a6cee1;
+  background-color: #cde7f4;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #b0d9ee), color-stop(100%, #eaf4fa));
+  background-image: -webkit-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
+  background-image:    -moz-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
+  background-image:         linear-gradient(to bottom, #b0d9ee 0, #eaf4fa 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffb0d9ee', endColorstr='#ffeaf4fa' )";
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
-       border: 1px solid #b8d892;
-       background-color: #daf0bd;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f0fbe1), color-stop(100%, #c3e59a));
-       background-image: -webkit-linear-gradient(top, #f0fbe1 0, #c3e59a 100%);
-       background-image:    -moz-linear-gradient(top, #f0fbe1 0, #c3e59a 100%);
-       background-image:         linear-gradient(to bottom, #f0fbe1 0, #c3e59a 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#fff0fbe1\', endColorstr=\'#ffc3e59a\' )';
+  border: 1px solid #b8d892;
+  background-color: #daf0bd;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f0fbe1), color-stop(100%, #c3e59a));
+  background-image: -webkit-linear-gradient(top, #f0fbe1 0, #c3e59a 100%);
+  background-image:    -moz-linear-gradient(top, #f0fbe1 0, #c3e59a 100%);
+  background-image:         linear-gradient(to bottom, #f0fbe1 0, #c3e59a 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff0fbe1', endColorstr='#ffc3e59a' )";
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
-       border-color: #adcb89;
+  border-color: #adcb89;
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       border: 1px solid #b8d892;
-       background-color: #daf0bd;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #c3e59a), color-stop(100%, #f0fbe1));
-       background-image: -webkit-linear-gradient(top, #c3e59a 0, #f0fbe1 100%);
-       background-image:    -moz-linear-gradient(top, #c3e59a 0, #f0fbe1 100%);
-       background-image:         linear-gradient(to bottom, #c3e59a 0, #f0fbe1 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffc3e59a\', endColorstr=\'#fff0fbe1\' )';
+  border: 1px solid #b8d892;
+  background-color: #daf0bd;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #c3e59a), color-stop(100%, #f0fbe1));
+  background-image: -webkit-linear-gradient(top, #c3e59a 0, #f0fbe1 100%);
+  background-image:    -moz-linear-gradient(top, #c3e59a 0, #f0fbe1 100%);
+  background-image:         linear-gradient(to bottom, #c3e59a 0, #f0fbe1 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffc3e59a', endColorstr='#fff0fbe1' )";
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
-       color: #d45353;
+  color: #d45353;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-       opacity: 0.5;
-       -webkit-transform: translate3d(0, 0, 0);
-       box-shadow: none;
-       color: #333;
-       background: #eee;
-       border-color: #ccc;
+  opacity: 0.5;
+  -webkit-transform: translate3d(0, 0, 0);
+  box-shadow: none;
+  color: #333;
+  background: #eee;
+  border-color: #ccc;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button:focus,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:focus,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button:focus {
-       border-color: #ccc;
-       box-shadow: none;
+  border-color: #ccc;
+  box-shadow: none;
 }
 .oo-ui-clippableElement-clippable {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-floatableElement-hidden {
-       display: none;
+  display: none;
 }
 .oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-iconElement.oo-ui-iconElement-icon {
-       background-size: contain;
-       background-position: center center;
-       background-repeat: no-repeat;
-       min-width: 24px;
-       width: 1.875em;
-       min-height: 24px;
-       height: 1.875em;
+  background-size: contain;
+  background-position: center center;
+  background-repeat: no-repeat;
+  min-width: 24px;
+  width: 1.875em;
+  min-height: 24px;
+  height: 1.875em;
 }
 .oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-iconElement.oo-ui-iconElement-icon {
-       opacity: 0.8;
+  opacity: 0.8;
 }
 .oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
 .oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
-       background-size: contain;
-       background-position: center center;
-       background-repeat: no-repeat;
-       min-width: 12px;
-       width: 0.9375em;
-       min-height: 12px;
-       height: 0.9375em;
+  background-size: contain;
+  background-position: center center;
+  background-repeat: no-repeat;
+  min-width: 12px;
+  width: 0.9375em;
+  min-height: 12px;
+  height: 0.9375em;
 }
 .oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
 .oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
-       opacity: 0.8;
+  opacity: 0.8;
 }
 .oo-ui-labelElement .oo-ui-labelElement-label-highlight {
-       font-weight: bold;
+  font-weight: bold;
 }
 .oo-ui-pendingElement-pending {
-       background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
+  background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
 }
 .oo-ui-fieldLayout {
-       display: block;
-       margin-bottom: 1em;
+  display: block;
+  margin-bottom: 1em;
 }
 .oo-ui-fieldLayout:before,
 .oo-ui-fieldLayout:after {
-       content: ' ';
-       display: table;
+  content: ' ';
+  display: table;
 }
 .oo-ui-fieldLayout:after {
-       clear: both;
+  clear: both;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       display: block;
-       float: left;
+  display: block;
+  float: left;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       text-align: right;
+  text-align: right;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
-       display: table;
+  display: table;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       display: table-cell;
-       vertical-align: middle;
+  display: table-cell;
+  vertical-align: middle;
 }
 .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       display: inline-block;
+  display: inline-block;
 }
 .oo-ui-fieldLayout > .oo-ui-fieldLayout-help {
-       float: right;
+  float: right;
 }
 .oo-ui-fieldLayout > .oo-ui-fieldLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
-       z-index: 1;
+  z-index: 1;
 }
 .oo-ui-fieldLayout > .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content {
-       padding: 0.5em 0.75em;
-       line-height: 1.5;
+  padding: 0.5em 0.75em;
+  line-height: 1.5;
 }
 .oo-ui-fieldLayout:last-child {
-       margin-bottom: 0;
+  margin-bottom: 0;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       padding-top: 0.5em;
-       margin-right: 5%;
-       width: 35%;
+  padding-top: 0.5em;
+  margin-right: 5%;
+  width: 35%;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       width: 60%;
+  width: 60%;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline {
-       margin-bottom: 1.25em;
+  margin-bottom: 1.25em;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       padding: 0.25em 0.25em 0.25em 0.5em;
+  padding: 0.25em 0.25em 0.25em 0.5em;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       padding: 0.5em 0;
+  padding: 0.5em 0;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget {
-       margin-right: 0;
-       margin-top: 0.25em;
+  margin-right: 0;
+  margin-top: 0.25em;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       color: #ccc;
+  color: #ccc;
 }
 .oo-ui-fieldLayout-messages {
-       list-style: none none;
-       margin: 0;
-       padding: 0;
-       margin-top: 0.25em;
-       margin-left: 0.25em;
+  list-style: none none;
+  margin: 0;
+  padding: 0;
+  margin-top: 0.25em;
+  margin-left: 0.25em;
 }
 .oo-ui-fieldLayout-messages > li {
-       margin: 0;
-       padding: 0;
+  margin: 0;
+  padding: 0;
 }
 .oo-ui-fieldLayout-messages .oo-ui-iconWidget {
-       display: none;
+  display: none;
 }
 .oo-ui-fieldLayout-messages .oo-ui-fieldLayout-messages-error {
-       color: #d45353;
+  color: #d45353;
 }
 .oo-ui-fieldLayout-messages .oo-ui-labelWidget {
-       padding: 0.1em 0;
-       line-height: 1.5em;
-       vertical-align: middle;
+  padding: 0.1em 0;
+  line-height: 1.5em;
+  vertical-align: middle;
 }
 .oo-ui-actionFieldLayout {
-       max-width: 50em;
+  max-width: 50em;
 }
 .oo-ui-actionFieldLayout-input,
 .oo-ui-actionFieldLayout-button {
-       display: table-cell;
-       vertical-align: middle;
+  display: table-cell;
+  vertical-align: middle;
 }
 .oo-ui-actionFieldLayout-input {
-       padding-right: 1em;
+  padding-right: 1em;
 }
 .oo-ui-actionFieldLayout-button {
-       width: 1%;
-       white-space: nowrap;
+  width: 1%;
+  white-space: nowrap;
 }
 .oo-ui-fieldsetLayout {
-       position: relative;
-       min-width: 0;
-       margin: 0;
-       border: 0;
-       padding: 0.01px 0 0 0;
+  position: relative;
+  min-width: 0;
+  margin: 0;
+  border: 0;
+  padding: 0.01px 0 0 0;
 }
 body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
-       display: table-cell;
+  display: table-cell;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
-       display: block;
-       position: absolute;
+  display: block;
+  position: absolute;
 }
 .oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
-       color: inherit;
-       display: inline-table;
-       box-sizing: border-box;
-       max-width: 100%;
-       padding: 0;
-       white-space: normal;
+  color: inherit;
+  display: inline-table;
+  box-sizing: border-box;
+  max-width: 100%;
+  padding: 0;
+  white-space: normal;
+  float: left;
+}
+.oo-ui-fieldsetLayout-group {
+  clear: both;
 }
 .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help {
-       float: right;
+  float: right;
 }
 .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
-       z-index: 1;
+  z-index: 1;
 }
 .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help .oo-ui-fieldsetLayout-help-content {
-       padding: 0.5em 0.75em;
-       line-height: 1.5;
+  padding: 0.5em 0.75em;
+  line-height: 1.5;
 }
 .oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout,
 .oo-ui-fieldsetLayout + .oo-ui-formLayout {
-       margin-top: 2em;
+  margin-top: 2em;
 }
 .oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
-       font-size: 1.1em;
-       margin-bottom: 0.5em;
-       padding: 0.25em 0;
-       font-weight: bold;
+  font-size: 1.1em;
+  margin-bottom: 0.5em;
+  padding: 0.25em 0;
+  font-weight: bold;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-labelElement-label {
-       padding-left: 2em;
-       line-height: 1.8em;
+  padding-left: 2em;
+  line-height: 1.8em;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
-       left: 0;
-       top: 0.25em;
+  left: 0;
+  top: 0.25em;
 }
 .oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-formLayout + .oo-ui-fieldsetLayout,
 .oo-ui-formLayout + .oo-ui-formLayout {
-       margin-top: 2em;
+  margin-top: 2em;
 }
 .oo-ui-panelLayout {
-       position: relative;
+  position: relative;
 }
 .oo-ui-panelLayout-scrollable {
-       overflow-y: auto;
+  overflow-y: auto;
 }
 .oo-ui-panelLayout-expanded {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 0;
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
 }
 .oo-ui-panelLayout-padded {
-       padding: 1.25em;
+  padding: 1.25em;
 }
 .oo-ui-panelLayout-framed {
-       border-radius: 0.5em;
-       box-shadow: 0 0.25em 1em rgba(0, 0, 0, 0.25);
+  border-radius: 0.5em;
+  box-shadow: 0 0.25em 1em rgba(0, 0, 0, 0.25);
 }
 .oo-ui-panelLayout-padded.oo-ui-panelLayout-framed {
-       margin: 1em 0;
+  margin: 1em 0;
 }
 .oo-ui-horizontalLayout > .oo-ui-widget {
-       display: inline-block;
-       vertical-align: middle;
+  display: inline-block;
+  vertical-align: middle;
 }
 .oo-ui-horizontalLayout > .oo-ui-layout {
-       display: inline-block;
+  display: inline-block;
 }
 .oo-ui-horizontalLayout > .oo-ui-layout,
 .oo-ui-horizontalLayout > .oo-ui-widget {
-       margin-right: 0.5em;
+  margin-right: 0.5em;
 }
 .oo-ui-horizontalLayout > .oo-ui-layout:last-child,
 .oo-ui-horizontalLayout > .oo-ui-widget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-horizontalLayout > .oo-ui-layout {
-       margin-bottom: 0;
+  margin-bottom: 0;
 }
 .oo-ui-optionWidget {
-       position: relative;
-       display: block;
-       padding: 0.25em 0.5em;
-       border: 0;
+  position: relative;
+  display: block;
+  padding: 0.25em 0.5em;
+  border: 0;
 }
 .oo-ui-optionWidget.oo-ui-widget-enabled {
-       cursor: pointer;
+  cursor: pointer;
 }
 .oo-ui-optionWidget.oo-ui-widget-disabled {
-       cursor: default;
+  cursor: default;
 }
 .oo-ui-optionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: block;
-       white-space: nowrap;
-       text-overflow: ellipsis;
-       overflow: hidden;
+  display: block;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
 }
 .oo-ui-optionWidget-highlighted {
-       background-color: #e1f3ff;
+  background-color: #e1f3ff;
 }
 .oo-ui-optionWidget .oo-ui-labelElement-label {
-       line-height: 1.5em;
+  line-height: 1.5em;
 }
 .oo-ui-selectWidget-depressed .oo-ui-optionWidget-selected {
-       background-color: #a7dcff;
+  background-color: #a7dcff;
 }
 .oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed,
 .oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed.oo-ui-optionWidget-highlighted,
 .oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed.oo-ui-optionWidget-highlighted.oo-ui-optionWidget-selected {
-       background-color: #a7dcff;
+  background-color: #a7dcff;
 }
 .oo-ui-optionWidget.oo-ui-widget-disabled {
-       color: #ccc;
+  color: #ccc;
 }
 .oo-ui-decoratedOptionWidget {
-       padding: 0.5em 2em 0.5em 3em;
+  padding: 0.5em 2em 0.5em 3em;
 }
 .oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
 .oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
-       position: absolute;
+  position: absolute;
 }
 .oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       top: 0;
-       height: 100%;
+  top: 0;
+  height: 100%;
 }
 .oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-       left: 0.5em;
+  left: 0.5em;
 }
 .oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       right: 0.5em;
+  right: 0.5em;
 }
 .oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
 .oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-radioOptionWidget {
-       cursor: default;
-       padding: 0;
-       background-color: transparent;
+  cursor: default;
+  padding: 0;
+  background-color: transparent;
 }
 .oo-ui-radioOptionWidget .oo-ui-radioInputWidget,
 .oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: inline-block;
-       vertical-align: middle;
+  display: inline-block;
+  vertical-align: middle;
 }
 .oo-ui-radioOptionWidget.oo-ui-optionWidget-selected,
 .oo-ui-radioOptionWidget.oo-ui-optionWidget-pressed,
 .oo-ui-radioOptionWidget.oo-ui-optionWidget-highlighted {
-       background-color: transparent;
+  background-color: transparent;
 }
 .oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       padding-left: 0.5em;
+  padding-left: 0.5em;
 }
 .oo-ui-radioOptionWidget .oo-ui-radioInputWidget {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-labelWidget {
-       display: inline-block;
-       padding: 0.5em 0;
+  display: inline-block;
+  padding: 0.5em 0;
 }
 .oo-ui-iconWidget {
-       display: inline-block;
-       vertical-align: middle;
-       line-height: 2.5em;
+  display: inline-block;
+  vertical-align: middle;
+  line-height: 2.5em;
 }
 .oo-ui-iconWidget.oo-ui-widget-disabled {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-indicatorWidget {
-       display: inline-block;
-       vertical-align: middle;
-       line-height: 2.5em;
-       margin: 0.46875em;
+  display: inline-block;
+  vertical-align: middle;
+  line-height: 2.5em;
+  margin: 0.46875em;
 }
 .oo-ui-indicatorWidget.oo-ui-widget-disabled {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-buttonWidget {
-       margin-right: 0.5em;
+  margin-right: 0.5em;
 }
 .oo-ui-buttonWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-buttonGroupWidget {
-       display: inline-block;
-       white-space: nowrap;
-       border-radius: 0.3em;
-       margin-right: 0.5em;
+  display: inline-block;
+  white-space: nowrap;
+  border-radius: 0.3em;
+  margin-right: 0.5em;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-active .oo-ui-buttonElement-button {
+  cursor: default;
 }
 .oo-ui-buttonGroupWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
-       border-radius: 0;
-       margin-left: -1px;
+  border-radius: 0;
+  margin-left: -1px;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
-       border-bottom-left-radius: 0.3em;
-       border-top-left-radius: 0.3em;
-       margin-left: 0;
+  border-bottom-left-radius: 0.3em;
+  border-top-left-radius: 0.3em;
+  margin-left: 0;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:last-child .oo-ui-buttonElement-button {
-       border-bottom-right-radius: 0.3em;
-       border-top-right-radius: 0.3em;
+  border-bottom-right-radius: 0.3em;
+  border-top-right-radius: 0.3em;
 }
 .oo-ui-popupWidget {
-       position: absolute;
-       /* @noflip */
-       left: 0;
+  position: absolute;
+  /* @noflip */
+  left: 0;
 }
 .oo-ui-popupWidget-popup {
-       position: relative;
-       overflow: hidden;
-       z-index: 1;
+  position: relative;
+  overflow: hidden;
+  z-index: 1;
 }
 .oo-ui-popupWidget-anchor {
-       display: none;
-       z-index: 1;
+  display: none;
+  z-index: 1;
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor {
-       display: block;
-       position: absolute;
-       top: 0;
-       /* @noflip */
-       left: 0;
-       background-repeat: no-repeat;
+  display: block;
+  position: absolute;
+  top: 0;
+  /* @noflip */
+  left: 0;
+  background-repeat: no-repeat;
 }
 .oo-ui-popupWidget-head {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-popupWidget-head > .oo-ui-buttonWidget {
-       float: right;
+  float: right;
 }
 .oo-ui-popupWidget-head > .oo-ui-labelElement-label {
-       float: left;
-       cursor: default;
+  float: left;
+  cursor: default;
 }
 .oo-ui-popupWidget-body {
-       clear: both;
-       overflow: hidden;
+  clear: both;
+  overflow: hidden;
 }
 .oo-ui-popupWidget-popup {
-       background-color: #fff;
-       border: 1px solid #ccc;
-       border-radius: 0.25em;
-       box-shadow: 0 0.15em 0.5em 0 rgba(0, 0, 0, 0.2);
+  background-color: #fff;
+  border: 1px solid #ccc;
+  border-radius: 0.25em;
+  box-shadow: 0 0.15em 0.5em 0 rgba(0, 0, 0, 0.2);
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-popup {
-       margin-top: 6px;
+  margin-top: 6px;
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before,
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
-       content: '';
-       position: absolute;
-       width: 0;
-       height: 0;
-       border-style: solid;
-       border-color: transparent;
-       border-top: 0;
+  content: '';
+  position: absolute;
+  width: 0;
+  height: 0;
+  border-style: solid;
+  border-color: transparent;
+  border-top: 0;
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before {
-       bottom: -7px;
-       left: -6px;
-       border-bottom-color: #aaa;
-       border-width: 7px;
+  bottom: -7px;
+  left: -6px;
+  border-bottom-color: #aaa;
+  border-width: 7px;
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
-       bottom: -7px;
-       left: -5px;
-       border-bottom-color: #fff;
-       border-width: 6px;
+  bottom: -7px;
+  left: -5px;
+  border-bottom-color: #fff;
+  border-width: 6px;
 }
 .oo-ui-popupWidget-transitioning .oo-ui-popupWidget-popup {
-       -webkit-transition: width 100ms ease, height 100ms ease, left 100ms ease;
-          -moz-transition: width 100ms ease, height 100ms ease, left 100ms ease;
-               transition: width 100ms ease, height 100ms ease, left 100ms ease;
+  -webkit-transition: width 100ms ease, height 100ms ease, left 100ms ease;
+     -moz-transition: width 100ms ease, height 100ms ease, left 100ms ease;
+          transition: width 100ms ease, height 100ms ease, left 100ms ease;
 }
 .oo-ui-popupWidget-head {
-       height: 2.5em;
+  height: 2.5em;
 }
 .oo-ui-popupWidget-head > .oo-ui-buttonWidget {
-       margin: 0.25em;
+  margin: 0.25em;
 }
 .oo-ui-popupWidget-head > .oo-ui-labelElement-label {
-       margin: 0.75em 1em;
+  margin: 0.75em 1em;
 }
 .oo-ui-popupWidget-body-padded {
-       padding: 0 1em;
+  padding: 0 1em;
 }
 .oo-ui-popupButtonWidget {
-       position: relative;
+  position: relative;
 }
 .oo-ui-popupButtonWidget .oo-ui-popupWidget {
-       position: absolute;
-       cursor: auto;
+  position: absolute;
+  cursor: auto;
 }
 .oo-ui-popupButtonWidget.oo-ui-buttonElement-frameless > .oo-ui-popupWidget {
-       /* @noflip */
-       left: 0.9375em;
+  /* @noflip */
+  left: 0.9375em;
 }
 .oo-ui-popupButtonWidget.oo-ui-buttonElement-framed > .oo-ui-popupWidget {
-       /* @noflip */
-       left: 1.2375em;
+  /* @noflip */
+  left: 1.2375em;
 }
 .oo-ui-inputWidget {
-       margin-right: 0.5em;
+  margin-right: 0.5em;
 }
 .oo-ui-inputWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-buttonInputWidget > button,
 .oo-ui-buttonInputWidget > input {
-       border: 0;
-       padding: 0;
-       background-color: transparent;
+  border: 0;
+  padding: 0;
+  background-color: transparent;
 }
 .oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout {
-       margin-bottom: 0;
+  margin-bottom: 0;
 }
 .oo-ui-dropdownInputWidget {
-       position: relative;
-       vertical-align: middle;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       width: 100%;
-       max-width: 50em;
+  position: relative;
+  vertical-align: middle;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  width: 100%;
+  max-width: 50em;
 }
 .oo-ui-dropdownInputWidget .oo-ui-dropdownWidget,
 .oo-ui-dropdownInputWidget select {
-       display: block;
+  display: block;
 }
 .oo-ui-dropdownInputWidget select {
-       width: 100%;
-       cursor: pointer;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  width: 100%;
+  cursor: pointer;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-dropdownInputWidget select {
-       background-color: #fff;
-       height: 2.5em;
-       padding: 0.5em;
-       font-size: inherit;
-       font-family: inherit;
-       border: 1px solid rgba(0, 0, 0, 0.1);
-       border-radius: 0.25em;
+  background-color: #fff;
+  height: 2.5em;
+  padding: 0.5em;
+  font-size: inherit;
+  font-family: inherit;
+  border: 1px solid rgba(0, 0, 0, 0.1);
+  border-radius: 0.25em;
 }
 .oo-ui-dropdownInputWidget option {
-       font-size: inherit;
-       font-family: inherit;
-       height: 1.5em;
-       padding: 0.5em 1em;
+  font-size: inherit;
+  font-family: inherit;
+  height: 1.5em;
+  padding: 0.5em 1em;
 }
 .oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:hover,
 .oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:focus {
-       border-color: rgba(0, 0, 0, 0.2);
-       outline: none;
+  border-color: rgba(0, 0, 0, 0.2);
+  outline: none;
 }
 .oo-ui-dropdownInputWidget.oo-ui-widget-disabled select {
-       color: #ccc;
-       border-color: #ddd;
-       background-color: #f3f3f3;
+  color: #ccc;
+  border-color: #ddd;
+  background-color: #f3f3f3;
 }
 .oo-ui-radioSelectInputWidget .oo-ui-fieldLayout {
-       margin-bottom: 0;
+  margin-bottom: 0;
 }
 .oo-ui-textInputWidget {
-       position: relative;
-       vertical-align: middle;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       width: 100%;
-       max-width: 50em;
+  position: relative;
+  vertical-align: middle;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  width: 100%;
+  max-width: 50em;
 }
 .oo-ui-textInputWidget input,
 .oo-ui-textInputWidget textarea {
-       display: block;
-       width: 100%;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  display: block;
+  width: 100%;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-textInputWidget textarea {
-       overflow: auto;
-       resize: none;
+  overflow: auto;
+  resize: none;
 }
 .oo-ui-textInputWidget [type='number'] {
-       -moz-appearance: textfield;
+  -moz-appearance: textfield;
 }
 .oo-ui-textInputWidget [type='number']::-webkit-outer-spin-button,
 .oo-ui-textInputWidget [type='number']::-webkit-inner-spin-button {
-       -webkit-appearance: none;
-       margin: 0;
+  -webkit-appearance: none;
+  margin: 0;
 }
 .oo-ui-textInputWidget [type='search'] {
-       -webkit-appearance: textfield;
+  -webkit-appearance: textfield;
 }
 .oo-ui-textInputWidget [type='search']::-ms-clear {
-       display: none;
+  display: none;
 }
 .oo-ui-textInputWidget [type='search']::-webkit-search-decoration,
 .oo-ui-textInputWidget [type='search']::-webkit-search-cancel-button {
-       display: none;
+  display: none;
 }
 .oo-ui-textInputWidget > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator,
 .oo-ui-textInputWidget > .oo-ui-labelElement-label {
-       display: none;
+  display: none;
 }
 .oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
-       display: block;
-       position: absolute;
-       top: 0;
-       height: 100%;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  display: block;
+  position: absolute;
+  top: 0;
+  height: 100%;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
-       cursor: text;
+  cursor: text;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator {
-       cursor: pointer;
+  cursor: pointer;
 }
 .oo-ui-textInputWidget.oo-ui-widget-disabled input,
 .oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
-       display: block;
+  display: block;
 }
 .oo-ui-textInputWidget > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget-labelPosition-before > .oo-ui-labelElement-label {
-       left: 0;
+  left: 0;
 }
 .oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator,
 .oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label {
-       right: 0;
+  right: 0;
 }
 .oo-ui-textInputWidget > .oo-ui-labelElement-label {
-       position: absolute;
-       top: 0;
+  position: absolute;
+  top: 0;
 }
 .oo-ui-textInputWidget input,
 .oo-ui-textInputWidget textarea {
-       padding: 0.5em;
-       line-height: 1.275em;
-       font-size: inherit;
-       font-family: inherit;
-       background-color: #fff;
-       color: #000;
-       border: 1px solid #ccc;
-       box-shadow: 0 0 0 #fff, inset 0 0.1em 0.2em #ddd;
-       border-radius: 0.25em;
-       -webkit-transition: border-color 250ms ease, box-shadow 250ms ease;
-          -moz-transition: border-color 250ms ease, box-shadow 250ms ease;
-               transition: border-color 250ms ease, box-shadow 250ms ease;
+  padding: 0.5em;
+  line-height: 1.275em;
+  font-size: inherit;
+  font-family: inherit;
+  background-color: #fff;
+  color: #000;
+  border: 1px solid #ccc;
+  box-shadow: 0 0 0 #fff, inset 0 0.1em 0.2em #ddd;
+  border-radius: 0.25em;
+  -webkit-transition: border-color 250ms ease, box-shadow 250ms ease;
+     -moz-transition: border-color 250ms ease, box-shadow 250ms ease;
+          transition: border-color 250ms ease, box-shadow 250ms ease;
 }
 .oo-ui-textInputWidget input.oo-ui-pendingElement-pending,
 .oo-ui-textInputWidget textarea.oo-ui-pendingElement-pending {
-       background-color: transparent;
+  background-color: transparent;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input:focus,
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
-       outline: none;
-       border-color: #a7dcff;
-       box-shadow: 0 0 0.3em #a7dcff, 0 0 0 #fff;
+  outline: none;
+  border-color: #a7dcff;
+  box-shadow: 0 0 0.3em #a7dcff, 0 0 0 #fff;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly],
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly] {
-       color: #777;
+  color: #777;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
-       background-color: #fdd;
+  background-color: #fdd;
 }
 .oo-ui-textInputWidget.oo-ui-widget-disabled input,
 .oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
-       color: #ccc;
-       text-shadow: 0 1px 1px #fff;
-       border-color: #ddd;
-       background-color: #f3f3f3;
+  color: #ccc;
+  text-shadow: 0 1px 1px #fff;
+  border-color: #ddd;
+  background-color: #f3f3f3;
 }
 .oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
-       color: #ddd;
-       text-shadow: 0 1px 1px #fff;
+  color: #ddd;
+  text-shadow: 0 1px 1px #fff;
 }
 .oo-ui-textInputWidget.oo-ui-iconElement input,
 .oo-ui-textInputWidget.oo-ui-iconElement textarea {
-       padding-left: 2.475em;
+  padding-left: 2.475em;
 }
 .oo-ui-textInputWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-       max-height: 2.375em;
-       margin-left: 0.3em;
+  max-height: 2.375em;
+  margin-left: 0.3em;
 }
 .oo-ui-textInputWidget.oo-ui-indicatorElement input,
 .oo-ui-textInputWidget.oo-ui-indicatorElement textarea {
-       padding-right: 2.4875em;
+  padding-right: 2.4875em;
 }
 .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       max-height: 2.375em;
-       margin-right: 0.775em;
+  max-height: 2.375em;
+  margin-right: 0.775em;
 }
 .oo-ui-textInputWidget > .oo-ui-labelElement-label {
-       padding: 0.4em;
-       line-height: 1.5em;
-       color: #888;
+  padding: 0.4em;
+  line-height: 1.5em;
+  color: #888;
 }
 .oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
-       margin-right: 2.0875em;
+  margin-right: 2.0875em;
 }
 .oo-ui-textInputWidget-labelPosition-before.oo-ui-iconElement > .oo-ui-labelElement-label {
-       margin-left: 2.075em;
+  margin-left: 2.075em;
 }
 .oo-ui-menuSelectWidget {
-       position: absolute;
-       width: 100%;
-       z-index: 4;
-       background-color: #fff;
-       margin-top: -1px;
-       border: 1px solid #ccc;
-       border-radius: 0 0 0.25em 0.25em;
-       box-shadow: 0 0.15em 1em 0 rgba(0, 0, 0, 0.2);
+  position: absolute;
+  width: 100%;
+  z-index: 4;
+  background-color: #fff;
+  margin-top: -1px;
+  border: 1px solid #ccc;
+  border-radius: 0 0 0.25em 0.25em;
+  box-shadow: 0 0.15em 1em 0 rgba(0, 0, 0, 0.2);
 }
 .oo-ui-menuSelectWidget input {
-       position: absolute;
-       width: 0;
-       height: 0;
-       overflow: hidden;
-       opacity: 0;
+  position: absolute;
+  width: 0;
+  height: 0;
+  overflow: hidden;
+  opacity: 0;
 }
 .oo-ui-menuOptionWidget {
-       position: relative;
+  position: relative;
 }
 .oo-ui-menuOptionWidget .oo-ui-iconElement-icon {
-       display: none;
+  display: none;
 }
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
-       display: block;
+  display: block;
 }
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
-       background-color: transparent;
+  background-color: transparent;
 }
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted,
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted.oo-ui-optionWidget-selected {
-       background-color: #e1f3ff;
+  background-color: #e1f3ff;
 }
 .oo-ui-menuSectionOptionWidget {
-       cursor: default;
-       padding: 0.33em 0.75em;
-       color: #888;
+  cursor: default;
+  padding: 0.33em 0.75em;
+  color: #888;
 }
 .oo-ui-dropdownWidget {
-       display: inline-block;
-       position: relative;
-       width: 100%;
-       max-width: 50em;
-       background-color: #fff;
-       margin-right: 0.5em;
+  display: inline-block;
+  position: relative;
+  width: 100%;
+  max-width: 50em;
+  background-color: #fff;
+  margin-right: 0.5em;
 }
 .oo-ui-dropdownWidget-handle {
-       width: 100%;
-       display: block;
-       white-space: nowrap;
-       overflow: hidden;
-       text-overflow: ellipsis;
-       cursor: default;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  width: 100%;
+  display: block;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  cursor: default;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator,
 .oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
-       position: absolute;
+  position: absolute;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle {
-       cursor: pointer;
+  cursor: pointer;
 }
 .oo-ui-dropdownWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-dropdownWidget-handle {
-       height: 2.5em;
-       border: 1px solid rgba(0, 0, 0, 0.1);
-       border-radius: 0.25em;
+  height: 2.5em;
+  border: 1px solid rgba(0, 0, 0, 0.1);
+  border-radius: 0.25em;
 }
 .oo-ui-dropdownWidget-handle:hover {
-       border-color: rgba(0, 0, 0, 0.2);
+  border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
-       top: 0;
-       right: 0;
-       margin: 0.775em;
+  top: 0;
+  right: 0;
+  margin: 0.775em;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
-       top: 0;
-       left: 0.25em;
-       margin: 0.3em;
+  top: 0;
+  left: 0.25em;
+  margin: 0.3em;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-       line-height: 2.5em;
-       margin: 0 0.5em;
+  line-height: 2.5em;
+  margin: 0 0.5em;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle {
-       color: #ccc;
-       text-shadow: 0 1px 1px #fff;
-       border-color: #ddd;
-       background-color: #f3f3f3;
+  color: #ccc;
+  text-shadow: 0 1px 1px #fff;
+  border-color: #ddd;
+  background-color: #f3f3f3;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle:focus {
-       outline: 0;
+  outline: 0;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-dropdownWidget.oo-ui-iconElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-       margin-left: 3em;
+  margin-left: 3em;
 }
 .oo-ui-dropdownWidget.oo-ui-indicatorElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-       margin-right: 2em;
+  margin-right: 2em;
 }
 .oo-ui-comboBoxInputWidget {
-       display: inline-block;
-       width: 100%;
-       max-width: 50em;
-       margin-right: 0.5em;
-}
-.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
-       cursor: pointer;
+  display: inline-block;
+  position: relative;
+  width: 100%;
+  max-width: 50em;
+  margin-right: 0.5em;
+}
+.oo-ui-comboBoxInputWidget-field {
+  display: table;
+  width: 100%;
+  table-layout: fixed;
+}
+.oo-ui-comboBoxInputWidget .oo-ui-inputWidget-input {
+  display: table-cell;
+  vertical-align: middle;
+  position: relative;
+  overflow: hidden;
+}
+.oo-ui-comboBoxInputWidget-dropdownButton {
+  display: table-cell;
+}
+.oo-ui-comboBoxInputWidget-dropdownButton > .oo-ui-buttonElement-button {
+  display: block;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  overflow: hidden;
+}
+.oo-ui-comboBoxInputWidget.oo-ui-comboBoxInputWidget-empty .oo-ui-comboBoxInputWidget-dropdownButton {
+  display: none;
 }
 .oo-ui-comboBoxInputWidget-php ::-webkit-calendar-picker-indicator {
-       opacity: 0;
-       position: absolute;
-       right: 0;
-       top: 0;
-       height: 2.5em;
-       width: 2.5em;
-       padding: 0;
+  opacity: 0;
+  position: absolute;
+  right: 0;
+  top: 0;
+  height: 2.5em;
+  width: 2.5em;
+  padding: 0;
 }
 .oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorElement-indicator {
-       pointer-events: none;
+  pointer-events: none;
 }
 .oo-ui-comboBoxInputWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
+}
+.oo-ui-comboBoxInputWidget-dropdownButton {
+  position: absolute;
+  top: 0;
+  right: 0;
+  visibility: hidden;
+}
+.oo-ui-comboBoxInputWidget-dropdownButton .oo-ui-buttonElement-button {
+  padding: 0;
+}
+.oo-ui-comboBoxInputWidget-dropdownButton .oo-ui-buttonElement-button .oo-ui-indicatorElement-indicator.oo-ui-indicator-down {
+  visibility: visible;
+  margin: 0.775em;
 }
-.oo-ui-comboBoxInputWidget.oo-ui-widget-disabled .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
-.oo-ui-comboBoxInputWidget-empty .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       cursor: default;
-       opacity: 0.2;
+.oo-ui-comboBoxInputWidget.oo-ui-widget-disabled .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+  cursor: default;
+  opacity: 0.2;
 }
 .oo-ui-multioptionWidget {
-       position: relative;
-       display: block;
+  position: relative;
+  display: block;
 }
 .oo-ui-multioptionWidget.oo-ui-widget-enabled {
-       cursor: pointer;
+  cursor: pointer;
 }
 .oo-ui-multioptionWidget.oo-ui-widget-disabled {
-       cursor: default;
+  cursor: default;
 }
 .oo-ui-multioptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: block;
-       white-space: nowrap;
-       text-overflow: ellipsis;
-       overflow: hidden;
+  display: block;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
 }
 .oo-ui-multioptionWidget .oo-ui-labelElement-label {
-       line-height: 1.5em;
+  line-height: 1.5em;
 }
 .oo-ui-multioptionWidget.oo-ui-widget-disabled {
-       color: #ccc;
+  color: #ccc;
 }
 .oo-ui-checkboxMultioptionWidget {
-       cursor: default;
-       padding: 0;
+  cursor: default;
+  padding: 0;
 }
 .oo-ui-checkboxMultioptionWidget .oo-ui-checkboxInputWidget,
 .oo-ui-checkboxMultioptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: inline-block;
-       vertical-align: middle;
+  display: inline-block;
+  vertical-align: middle;
 }
 .oo-ui-checkboxMultioptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       padding-left: 0.5em;
+  padding-left: 0.5em;
 }
 .oo-ui-checkboxMultioptionWidget .oo-ui-checkboxInputWidget {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-progressBarWidget {
-       max-width: 50em;
-       background-color: #fff;
-       border: 1px solid #ccc;
-       border-radius: 0.25em;
-       overflow: hidden;
+  max-width: 50em;
+  background-color: #fff;
+  border: 1px solid #ccc;
+  border-radius: 0.25em;
+  overflow: hidden;
 }
 .oo-ui-progressBarWidget-bar {
-       height: 1em;
-       border-right: 1px solid #ccc;
-       -webkit-transition: width 250ms ease, margin-left 250ms ease;
-          -moz-transition: width 250ms ease, margin-left 250ms ease;
-               transition: width 250ms ease, margin-left 250ms ease;
-       background-color: #cde7f4;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #eaf4fa), color-stop(100%, #b0d9ee));
-       background-image: -webkit-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
-       background-image:    -moz-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
-       background-image:         linear-gradient(to bottom, #eaf4fa 0, #b0d9ee 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffeaf4fa\', endColorstr=\'#ffb0d9ee\' )';
+  height: 1em;
+  border-right: 1px solid #ccc;
+  -webkit-transition: width 250ms ease, margin-left 250ms ease;
+     -moz-transition: width 250ms ease, margin-left 250ms ease;
+          transition: width 250ms ease, margin-left 250ms ease;
+  background-color: #cde7f4;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #eaf4fa), color-stop(100%, #b0d9ee));
+  background-image: -webkit-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
+  background-image:    -moz-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
+  background-image:         linear-gradient(to bottom, #eaf4fa 0, #b0d9ee 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffeaf4fa', endColorstr='#ffb0d9ee' )";
 }
 .oo-ui-progressBarWidget-indeterminate .oo-ui-progressBarWidget-bar {
-       -webkit-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
-          -moz-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
-               animation: oo-ui-progressBarWidget-slide 2s infinite linear;
-       width: 40%;
-       margin-left: -10%;
-       border-left: 1px solid #a6cee1;
+  -webkit-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
+     -moz-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
+          animation: oo-ui-progressBarWidget-slide 2s infinite linear;
+  width: 40%;
+  margin-left: -10%;
+  border-left: 1px solid #a6cee1;
 }
 .oo-ui-progressBarWidget.oo-ui-widget-disabled {
-       opacity: 0.6;
+  opacity: 0.6;
 }
 @-webkit-keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
+  from {
+    margin-left: -40%;
+  }
+  to {
+    margin-left: 100%;
+  }
 }
 @-moz-keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
+  from {
+    margin-left: -40%;
+  }
+  to {
+    margin-left: 100%;
+  }
 }
 @keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
+  from {
+    margin-left: -40%;
+  }
+  to {
+    margin-left: 100%;
+  }
 }
index 08d91b4..e7c2ee0 100644 (file)
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:06Z
+ * Date: 2016-11-09T00:52:42Z
  */
 .oo-ui-element-hidden {
-       display: none !important;
-       /* stylelint-disable-line declaration-no-important */
+  display: none !important;
+  /* stylelint-disable-line declaration-no-important */
 }
 .oo-ui-buttonElement {
-       display: inline-block;
-       vertical-align: middle;
+  display: inline-block;
+  vertical-align: middle;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button {
-       cursor: pointer;
-       display: inline-block;
-       vertical-align: middle;
-       font-family: inherit;
-       font-size: inherit;
-       line-height: normal;
-       white-space: nowrap;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  cursor: pointer;
+  display: inline-block;
+  vertical-align: middle;
+  font-family: inherit;
+  font-size: inherit;
+  line-height: normal;
+  white-space: nowrap;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       display: none;
+  display: none;
 }
 .oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-       cursor: default;
-}
-.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover,
-.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
-       z-index: 2;
+  cursor: default;
 }
 .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       display: inline-block;
-       vertical-align: middle;
+  display: inline-block;
+  vertical-align: middle;
 }
 .oo-ui-buttonElement-frameless {
-       position: relative;
+  position: relative;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
-       vertical-align: top;
-       text-align: center;
+  vertical-align: top;
+  text-align: center;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button {
-       font-weight: bold;
-       text-decoration: none;
+  font-weight: bold;
+  text-decoration: none;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button:focus {
-       border-radius: 2px;
-       outline: 0;
+  border-radius: 2px;
+  outline: 0;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button:focus::-moz-focus-inner {
+  border-color: transparent;
 }
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       margin-left: 0;
+  margin-left: 0;
 }
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       margin-right: 0.25em;
-       margin-left: 0.46875em;
+  margin-right: 0.25em;
+  margin-left: 0.46875em;
 }
 .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
-       -webkit-transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
-          -moz-transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
-               transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
+  -webkit-transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
+     -moz-transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
+          transition: background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
 }
 .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       opacity: 0.87;
-       -webkit-transition: opacity 100ms;
-          -moz-transition: opacity 100ms;
-               transition: opacity 100ms;
+  opacity: 0.87;
+  -webkit-transition: opacity 100ms;
+     -moz-transition: opacity 100ms;
+          transition: opacity 100ms;
 }
 .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon.oo-ui-image-invert,
 .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator.oo-ui-image-invert {
-       opacity: 1;
+  opacity: 1;
 }
 .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-indicatorElement-indicator {
-       opacity: 0.73;
+  opacity: 0.73;
 }
 .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-iconElement-icon.oo-ui-image-invert,
 .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover > .oo-ui-indicatorElement-indicator.oo-ui-image-invert {
-       opacity: 1;
+  opacity: 1;
 }
 .oo-ui-buttonElement.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       opacity: 1;
+  opacity: 1;
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button .oo-ui-indicatorElement-indicator {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       margin-left: 0.25em;
-       margin-right: 0.25em;
+  margin-left: 0.25em;
+  margin-right: 0.25em;
 }
 .oo-ui-buttonElement-frameless > input.oo-ui-buttonElement-button {
-       padding-left: 0.25em;
-       padding-right: 0.25em;
+  padding-left: 0.25em;
+  padding-right: 0.25em;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
-       color: #222;
+  color: #222;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
-       color: #444;
+  color: #444;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
-       box-shadow: inset 0 0 0 1px #36c, 0 0 0 1px #36c;
+  box-shadow: inset 0 0 0 1px #36c, 0 0 0 1px #36c;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > input.oo-ui-buttonElement-button,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button:active {
-       color: #000;
+  color: #000;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #36c;
+  color: #36c;
 }
-.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: #447ff5;
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label {
+  color: #447ff5;
 }
-.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: #2a4b8d;
-       box-shadow: none;
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  color: #2a4b8d;
+  box-shadow: none;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #36c;
+  color: #36c;
 }
-.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: #447ff5;
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label {
+  color: #447ff5;
 }
-.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: #2a4b8d;
-       box-shadow: none;
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  color: #2a4b8d;
+  box-shadow: none;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       color: #c33;
+  color: #c33;
 }
-.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: #e53939;
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label {
+  color: #e53939;
 }
-.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: #873636;
-       box-shadow: none;
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  color: #873636;
+  box-shadow: none;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled[class*='oo-ui-flaggedElement'] > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled[class*='oo-ui-flaggedElement'] > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       opacity: 1;
+  opacity: 1;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled[class*='oo-ui-flaggedElement'] > .oo-ui-buttonElement-button:hover > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled[class*='oo-ui-flaggedElement'] > .oo-ui-buttonElement-button:hover > .oo-ui-indicatorElement-indicator {
-       opacity: 0.73;
+  opacity: 0.73;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-       color: #72777d;
+  color: #72777d;
 }
 .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.51;
+  opacity: 0.51;
 }
 .oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button {
-       padding-left: 2.4em;
+  padding-left: 2.4em;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
-       padding: 0.5em 1em;
-       min-height: 1.2em;
-       min-width: 1em;
-       border-radius: 2px;
-       position: relative;
+  padding: 0.546875em 1em;
+  min-height: 1.25em;
+  min-width: 1em;
+  border-radius: 2px;
+  position: relative;
 }
 .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.2;
+  line-height: 1.25;
 }
 .oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       position: absolute;
-       top: 0.2em;
-       left: 0.5625em;
+  position: absolute;
+  top: 0.2em;
+  left: 0.5625em;
 }
 .oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       margin-left: 0.3em;
+  margin-left: 0.3em;
 }
 .oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
 .oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-iconElement:not( .oo-ui-labelElement ) > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       margin-left: 0.46875em;
-       margin-right: -0.275em;
+  margin-left: 0.46875em;
+  margin-right: -0.275em;
 }
 .oo-ui-buttonElement-framed.oo-ui-indicatorElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       position: relative;
-       left: 0.2em;
+  position: relative;
+  left: 0.2em;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-       background-color: #c8ccd1;
-       color: #fff;
-       border: 1px solid #c8ccd1;
+  background-color: #c8ccd1;
+  color: #fff;
+  border: 1px solid #c8ccd1;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled + .oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-       border-left-color: #fff;
+  border-left-color: #fff;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
-       background-color: #f8f9fa;
-       color: #222;
-       border: 1px solid #9aa0a7;
+  background-color: #f8f9fa;
+  color: #222;
+  border: 1px solid #a2a9b1;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
-       background-color: #fff;
-       color: #444;
-       border-color: #a2a9b1;
+  background-color: #fff;
+  color: #444;
+  border-color: #a2a9b1;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
-       border-color: #36c;
-       box-shadow: inset 0 0 0 1px #36c;
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c;
 }
 .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 {
-       background-color: #d9d9d9;
-       color: #000;
-       border-color: #72777d;
+  background-color: #d9d9d9;
+  color: #000;
+  border-color: #72777d;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       background-color: #2a4b8d;
-       color: #fff;
-       border-color: #2a4b8d;
-       z-index: 3;
+  background-color: #2a4b8d;
+  color: #fff;
+  border-color: #2a4b8d;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:focus {
-       border-color: #36c;
-       box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
-       color: #36c;
+  color: #36c;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
-       background-color: #fff;
-       border-color: #859dcc;
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover {
+  background-color: #fff;
+  border-color: #859dcc;
 }
-.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,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       background-color: #eff3fa;
-       color: #2a4b8d;
-       border-color: #2a4b8d;
-       box-shadow: none;
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:active:focus,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+  background-color: #eff3fa;
+  color: #2a4b8d;
+  border-color: #2a4b8d;
+  box-shadow: none;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
-       border-color: #36c;
-       box-shadow: inset 0 0 0 1px #36c;
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
-       color: #36c;
+  color: #36c;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
-       background-color: #fff;
-       border-color: #859dcc;
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover {
+  background-color: #fff;
+  border-color: #859dcc;
 }
-.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,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       background-color: #eff3fa;
-       color: #2a4b8d;
-       border-color: #2a4b8d;
-       box-shadow: none;
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:active:focus,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+  background-color: #eff3fa;
+  color: #2a4b8d;
+  border-color: #2a4b8d;
+  box-shadow: none;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
-       border-color: #36c;
-       box-shadow: inset 0 0 0 1px #36c;
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
-       color: #c33;
+  color: #c33;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
-       background-color: #fff;
-       border-color: #b77c79;
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover {
+  background-color: #fff;
+  border-color: #b77c79;
 }
-.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,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       background-color: #fbf4f4;
-       color: #873636;
-       border-color: #873636;
-       box-shadow: none;
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active:focus,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+  background-color: #fbf4f4;
+  color: #873636;
+  border-color: #873636;
+  box-shadow: none;
 }
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
-       border-color: #c33;
-       box-shadow: inset 0 0 0 1px #c33;
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
+  border-color: #c33;
+  box-shadow: inset 0 0 0 1px #c33;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
-       color: #fff;
-       background-color: #36c;
-       border-color: #36c;
-}
-.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: #447ff5;
-       border-color: #447ff5;
-}
-.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,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       color: #fff;
-       background-color: #2a4b8d;
-       border-color: #2a4b8d;
-       box-shadow: none;
-}
-.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: #36c;
-       box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
+  color: #fff;
+  background-color: #36c;
+  border-color: #36c;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover {
+  background-color: #447ff5;
+  border-color: #447ff5;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:active:focus,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+  color: #fff;
+  background-color: #2a4b8d;
+  border-color: #2a4b8d;
+  box-shadow: none;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
-       color: #fff;
-       background-color: #36c;
-       border-color: #36c;
-}
-.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: #447ff5;
-       border-color: #447ff5;
-}
-.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,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       color: #fff;
-       background-color: #2a4b8d;
-       border-color: #2a4b8d;
-       box-shadow: none;
-}
-.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: #36c;
-       box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
+  color: #fff;
+  background-color: #36c;
+  border-color: #36c;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover {
+  background-color: #447ff5;
+  border-color: #447ff5;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:active:focus,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+  color: #fff;
+  background-color: #2a4b8d;
+  border-color: #2a4b8d;
+  box-shadow: none;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
-       color: #fff;
-       background-color: #c33;
-       border-color: #c33;
-}
-.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: #e53939;
-       border-color: #e53939;
-}
-.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,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
-       color: #fff;
-       background-color: #873636;
-       border-color: #873636;
-       box-shadow: none;
-}
-.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: #c33;
-       box-shadow: inset 0 0 0 1px #c33, inset 0 0 0 2px #fff;
+  color: #fff;
+  background-color: #c33;
+  border-color: #c33;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover {
+  background-color: #e53939;
+  border-color: #e53939;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active:focus,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+  color: #fff;
+  background-color: #873636;
+  border-color: #873636;
+  box-shadow: none;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
+  border-color: #c33;
+  box-shadow: inset 0 0 0 1px #c33, inset 0 0 0 2px #fff;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-       opacity: 1;
+  opacity: 1;
 }
 .oo-ui-clippableElement-clippable {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-floatableElement-hidden {
-       display: none;
+  display: none;
 }
 .oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-iconElement.oo-ui-iconElement-icon {
-       background-size: contain;
-       background-position: center center;
-       background-repeat: no-repeat;
-       min-width: 24px;
-       width: 1.875em;
-       min-height: 24px;
-       height: 1.875em;
+  background-size: contain;
+  background-position: center center;
+  background-repeat: no-repeat;
+  min-width: 24px;
+  width: 1.875em;
+  min-height: 24px;
+  height: 1.875em;
 }
 .oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
 .oo-ui-indicatorElement.oo-ui-indicatorElement-indicator {
-       background-size: contain;
-       background-position: center center;
-       background-repeat: no-repeat;
-       min-width: 12px;
-       width: 0.9375em;
-       min-height: 12px;
-       height: 0.9375em;
+  background-size: contain;
+  background-position: center center;
+  background-repeat: no-repeat;
+  min-width: 12px;
+  width: 0.9375em;
+  min-height: 12px;
+  height: 0.9375em;
 }
 .oo-ui-labelElement .oo-ui-labelElement-label-highlight {
-       font-weight: bold;
+  font-weight: bold;
 }
 .oo-ui-pendingElement-pending {
-       background-image: /* @embed */ url(themes/mediawiki/images/textures/pending.gif);
+  background-image: /* @embed */ url(themes/mediawiki/images/textures/pending.gif);
 }
 .oo-ui-fieldLayout {
-       display: block;
-       margin-bottom: 1em;
+  display: block;
+  margin-bottom: 1em;
 }
 .oo-ui-fieldLayout:before,
 .oo-ui-fieldLayout:after {
-       content: ' ';
-       display: table;
+  content: ' ';
+  display: table;
 }
 .oo-ui-fieldLayout:after {
-       clear: both;
+  clear: both;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       display: block;
-       float: left;
+  display: block;
+  float: left;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       text-align: right;
+  text-align: right;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body {
-       display: table;
+  display: table;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       display: table-cell;
-       vertical-align: middle;
+  display: table-cell;
+  vertical-align: middle;
 }
 .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       display: inline-block;
+  display: inline-block;
 }
 .oo-ui-fieldLayout > .oo-ui-fieldLayout-help {
-       float: right;
+  float: right;
 }
 .oo-ui-fieldLayout > .oo-ui-fieldLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
-       z-index: 1;
+  z-index: 1;
 }
 .oo-ui-fieldLayout > .oo-ui-fieldLayout-help .oo-ui-fieldLayout-help-content {
-       padding: 0.5em 0.75em;
-       line-height: 1.5;
+  padding: 0.5em 0.75em;
+  line-height: 1.5;
 }
 .oo-ui-fieldLayout:last-child {
-       margin-bottom: 0;
+  margin-bottom: 0;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       padding-top: 0.5em;
-       margin-right: 5%;
-       width: 35%;
+  padding-top: 0.5em;
+  margin-right: 5%;
+  width: 35%;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
-       width: 60%;
+  width: 60%;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline {
-       margin-bottom: 1.25em;
+  margin-bottom: 1.25em;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       padding: 0.25em 0.25em 0.25em 0.5em;
+  padding: 0.25em 0.25em 0.25em 0.5em;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       padding-top: 0.25em;
-       padding-bottom: 0.5em;
+  padding-top: 0.25em;
+  padding-bottom: 0.5em;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-fieldLayout-disabled > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
-       color: #72777d;
+  color: #72777d;
 }
 .oo-ui-fieldLayout-messages {
-       list-style: none none;
-       margin: 0.25em 0 0 0.25em;
-       padding: 0;
+  list-style: none none;
+  margin: 0.25em 0 0 0.25em;
+  padding: 0;
 }
 .oo-ui-fieldLayout-messages > li {
-       margin: 0;
-       padding: 0;
-       display: table;
+  margin: 0;
+  padding: 0;
+  display: table;
 }
 .oo-ui-fieldLayout-messages .oo-ui-iconWidget {
-       display: table-cell;
-       border-right: 0.5em solid transparent;
+  display: table-cell;
+  border-right: 0.5em solid transparent;
 }
 .oo-ui-fieldLayout-messages .oo-ui-labelWidget {
-       display: table-cell;
-       padding: 0.1em 0;
-       line-height: 1.5;
-       vertical-align: middle;
+  display: table-cell;
+  padding: 0.1em 0;
+  line-height: 1.5;
+  vertical-align: middle;
 }
 .oo-ui-actionFieldLayout {
-       max-width: 50em;
+  max-width: 50em;
 }
 .oo-ui-actionFieldLayout-input,
 .oo-ui-actionFieldLayout-button {
-       display: table-cell;
-       vertical-align: middle;
+  display: table-cell;
+  vertical-align: middle;
 }
 .oo-ui-actionFieldLayout-input {
-       padding-right: 1em;
+  padding-right: 1em;
 }
 .oo-ui-actionFieldLayout-button {
-       width: 1%;
-       white-space: nowrap;
+  width: 1%;
+  white-space: nowrap;
 }
 .oo-ui-fieldsetLayout {
-       position: relative;
-       min-width: 0;
-       margin: 0;
-       border: 0;
-       padding: 0.01px 0 0 0;
+  position: relative;
+  min-width: 0;
+  margin: 0;
+  border: 0;
+  padding: 0.01px 0 0 0;
 }
 body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
-       display: table-cell;
+  display: table-cell;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
-       display: block;
-       position: absolute;
+  display: block;
+  position: absolute;
 }
 .oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
-       color: inherit;
-       display: inline-table;
-       box-sizing: border-box;
-       max-width: 100%;
-       padding: 0;
-       white-space: normal;
+  color: inherit;
+  display: inline-table;
+  box-sizing: border-box;
+  max-width: 100%;
+  padding: 0;
+  white-space: normal;
+  float: left;
+}
+.oo-ui-fieldsetLayout-group {
+  clear: both;
 }
 .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help {
-       float: right;
+  float: right;
 }
 .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
-       z-index: 1;
+  z-index: 1;
 }
 .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help .oo-ui-fieldsetLayout-help-content {
-       padding: 0.5em 0.75em;
-       line-height: 1.5;
+  padding: 0.5em 0.75em;
+  line-height: 1.5;
 }
 .oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout,
 .oo-ui-fieldsetLayout + .oo-ui-formLayout {
-       margin-top: 2em;
+  margin-top: 2em;
 }
 .oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
-       margin-bottom: 0.5em;
-       font-size: 1.1em;
-       font-weight: bold;
+  margin-bottom: 0.5em;
+  font-size: 1.1em;
+  font-weight: bold;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-labelElement-label {
-       padding-left: 2em;
-       line-height: 1.8;
+  padding-left: 2em;
+  line-height: 1.8;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
-       left: 0;
-       top: 0.25em;
+  top: 0;
+  left: 0;
 }
 .oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-formLayout + .oo-ui-fieldsetLayout,
 .oo-ui-formLayout + .oo-ui-formLayout {
-       margin-top: 2em;
+  margin-top: 2em;
 }
 .oo-ui-panelLayout {
-       position: relative;
+  position: relative;
 }
 .oo-ui-panelLayout-scrollable {
-       overflow-y: auto;
+  overflow-y: auto;
 }
 .oo-ui-panelLayout-expanded {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 0;
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
 }
 .oo-ui-panelLayout-padded {
-       padding: 1.25em;
+  padding: 1.25em;
 }
 .oo-ui-panelLayout-framed {
-       border: 1px solid #a2a9b1;
-       border-radius: 2px;
-       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
+  border: 1px solid #a2a9b1;
+  border-radius: 2px;
+  box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
 }
 .oo-ui-panelLayout-padded.oo-ui-panelLayout-framed {
-       margin: 1em 0;
+  margin: 1em 0;
 }
 .oo-ui-horizontalLayout > .oo-ui-widget {
-       display: inline-block;
-       vertical-align: middle;
+  display: inline-block;
+  vertical-align: middle;
 }
 .oo-ui-horizontalLayout > .oo-ui-layout {
-       display: inline-block;
+  display: inline-block;
 }
 .oo-ui-horizontalLayout > .oo-ui-layout,
 .oo-ui-horizontalLayout > .oo-ui-widget {
-       margin-right: 0.5em;
+  margin-right: 0.5em;
 }
 .oo-ui-horizontalLayout > .oo-ui-layout:last-child,
 .oo-ui-horizontalLayout > .oo-ui-widget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-horizontalLayout > .oo-ui-layout {
-       margin-bottom: 0;
+  margin-bottom: 0;
 }
 .oo-ui-optionWidget {
-       position: relative;
-       display: block;
-       border: 0;
-       padding: 0.25em 0.5em;
+  position: relative;
+  display: block;
+  border: 0;
+  padding: 0.25em 0.5em;
 }
 .oo-ui-optionWidget.oo-ui-widget-enabled {
-       cursor: pointer;
+  cursor: pointer;
 }
 .oo-ui-optionWidget.oo-ui-widget-disabled {
-       cursor: default;
+  cursor: default;
 }
 .oo-ui-optionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: block;
-       white-space: nowrap;
-       text-overflow: ellipsis;
-       overflow: hidden;
+  display: block;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
 }
 .oo-ui-optionWidget .oo-ui-labelElement-label {
-       line-height: 1.5;
+  line-height: 1.5;
 }
 .oo-ui-optionWidget-selected .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       opacity: 1;
+  opacity: 1;
 }
 .oo-ui-optionWidget.oo-ui-widget-disabled {
-       color: #72777d;
+  color: #72777d;
 }
 .oo-ui-decoratedOptionWidget {
-       padding: 0.5em 2em 0.5em 3em;
+  padding: 0.5em 2em 0.5em 3em;
 }
 .oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
 .oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
-       position: absolute;
+  position: absolute;
 }
 .oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       top: 0;
-       height: 100%;
+  top: 0;
+  height: 100%;
 }
 .oo-ui-decoratedOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-       left: 0.5em;
+  left: 0.5em;
 }
 .oo-ui-decoratedOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       right: 0.5em;
+  right: 0.5em;
 }
 .oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
 .oo-ui-decoratedOptionWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 0.51;
+  opacity: 0.51;
 }
 .oo-ui-radioSelectWidget:focus {
-       outline: 0;
+  outline: 0;
 }
 .oo-ui-radioSelectWidget:focus [type='radio']:checked + span:before {
-       border-color: #fff;
+  border-color: #fff;
 }
 .oo-ui-radioOptionWidget {
-       cursor: default;
-       padding: 0.25em 0;
-       background-color: transparent;
+  cursor: default;
+  padding: 0.25em 0;
+  background-color: transparent;
 }
 .oo-ui-radioOptionWidget .oo-ui-radioInputWidget,
 .oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: inline-block;
-       vertical-align: middle;
+  display: inline-block;
+  vertical-align: middle;
 }
 .oo-ui-radioOptionWidget.oo-ui-optionWidget-selected,
 .oo-ui-radioOptionWidget.oo-ui-optionWidget-pressed,
 .oo-ui-radioOptionWidget.oo-ui-optionWidget-highlighted {
-       background-color: transparent;
+  background-color: transparent;
 }
 .oo-ui-radioOptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       padding: 0.25em 0.25em 0.25em 0.5em;
+  padding: 0.25em 0.25em 0.25em 0.5em;
 }
 .oo-ui-radioOptionWidget .oo-ui-radioInputWidget {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-labelWidget {
-       display: inline-block;
+  display: inline-block;
 }
 .oo-ui-iconWidget {
-       display: inline-block;
-       vertical-align: middle;
-       line-height: 2.5;
+  display: inline-block;
+  vertical-align: middle;
+  line-height: 2.5;
 }
 .oo-ui-iconWidget.oo-ui-widget-disabled {
-       opacity: 0.51;
+  opacity: 0.51;
 }
 .oo-ui-indicatorWidget {
-       display: inline-block;
-       vertical-align: middle;
-       line-height: 2.5;
-       margin: 0.46875em;
+  display: inline-block;
+  vertical-align: middle;
+  line-height: 2.5;
+  margin: 0.46875em;
 }
 .oo-ui-indicatorWidget.oo-ui-widget-disabled {
-       opacity: 0.51;
+  opacity: 0.51;
 }
 .oo-ui-buttonWidget {
-       margin-right: 0.5em;
+  margin-right: 0.5em;
 }
 .oo-ui-buttonWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-buttonGroupWidget {
-       display: inline-block;
-       white-space: nowrap;
-       border-radius: 2px;
-       margin-right: 0.5em;
+  display: inline-block;
+  white-space: nowrap;
+  border-radius: 2px;
+  margin-right: 0.5em;
+  z-index: 0;
+  position: relative;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-active .oo-ui-buttonElement-button {
+  cursor: default;
 }
 .oo-ui-buttonGroupWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
-       border-radius: 0;
-       margin-left: -1px;
+  border-radius: 0;
+  margin-left: -1px;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
-       border-bottom-left-radius: 2px;
-       border-top-left-radius: 2px;
-       margin-left: 0;
+  border-bottom-left-radius: 2px;
+  border-top-left-radius: 2px;
+  margin-left: 0;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:last-child .oo-ui-buttonElement-button {
-       border-bottom-right-radius: 2px;
-       border-top-right-radius: 2px;
+  border-bottom-right-radius: 2px;
+  border-top-right-radius: 2px;
 }
-.oo-ui-buttonGroupWidget.oo-ui-widget-enabled .oo-ui-buttonElement .oo-ui-buttonElement-button:focus {
-       border-color: #36c;
-       z-index: 3;
+.oo-ui-buttonGroupWidget.oo-ui-widget-enabled .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonGroupWidget.oo-ui-widget-enabled .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active {
+  z-index: 1;
+}
+.oo-ui-buttonGroupWidget.oo-ui-widget-enabled .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:focus {
+  z-index: 2;
+}
+.oo-ui-buttonGroupWidget.oo-ui-widget-enabled .oo-ui-buttonElement.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+  z-index: 3;
+}
+.oo-ui-buttonGroupWidget.oo-ui-widget-enabled .oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
+  z-index: -1;
 }
 .oo-ui-popupWidget {
-       position: absolute;
-       /* @noflip */
-       left: 0;
+  position: absolute;
+  /* @noflip */
+  left: 0;
 }
 .oo-ui-popupWidget-popup {
-       position: relative;
-       overflow: hidden;
-       z-index: 1;
+  position: relative;
+  overflow: hidden;
+  z-index: 1;
 }
 .oo-ui-popupWidget-anchor {
-       display: none;
-       z-index: 1;
+  display: none;
+  z-index: 1;
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor {
-       display: block;
-       position: absolute;
-       top: 0;
-       /* @noflip */
-       left: 0;
-       background-repeat: no-repeat;
+  display: block;
+  position: absolute;
+  top: 0;
+  /* @noflip */
+  left: 0;
+  background-repeat: no-repeat;
 }
 .oo-ui-popupWidget-head {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-popupWidget-head > .oo-ui-buttonWidget {
-       float: right;
+  float: right;
 }
 .oo-ui-popupWidget-head > .oo-ui-labelElement-label {
-       float: left;
-       cursor: default;
+  float: left;
+  cursor: default;
 }
 .oo-ui-popupWidget-body {
-       clear: both;
-       overflow: hidden;
+  clear: both;
+  overflow: hidden;
 }
 .oo-ui-popupWidget-popup {
-       background-color: #fff;
-       border: 1px solid #a2a9b1;
-       border-radius: 2px;
-       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
+  background-color: #fff;
+  border: 1px solid #a2a9b1;
+  border-radius: 2px;
+  box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-popup {
-       margin-top: 9px;
+  margin-top: 9px;
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before,
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
-       content: '';
-       position: absolute;
-       width: 0;
-       height: 0;
-       border-style: solid;
-       border-color: transparent;
-       border-top: 0;
+  content: '';
+  position: absolute;
+  width: 0;
+  height: 0;
+  border-style: solid;
+  border-color: transparent;
+  border-top: 0;
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:before {
-       bottom: -10px;
-       left: -9px;
-       border-bottom-color: #888;
-       border-width: 10px;
+  bottom: -10px;
+  left: -9px;
+  border-bottom-color: #888;
+  border-width: 10px;
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor:after {
-       bottom: -10px;
-       left: -8px;
-       border-bottom-color: #fff;
-       border-width: 9px;
+  bottom: -10px;
+  left: -8px;
+  border-bottom-color: #fff;
+  border-width: 9px;
 }
 .oo-ui-popupWidget-transitioning .oo-ui-popupWidget-popup {
-       -webkit-transition: width 100ms, height 100ms, left 100ms;
-          -moz-transition: width 100ms, height 100ms, left 100ms;
-               transition: width 100ms, height 100ms, left 100ms;
+  -webkit-transition: width 100ms, height 100ms, left 100ms;
+     -moz-transition: width 100ms, height 100ms, left 100ms;
+          transition: width 100ms, height 100ms, left 100ms;
 }
 .oo-ui-popupWidget-head {
-       height: 2.5em;
+  height: 2.5em;
 }
 .oo-ui-popupWidget-head > .oo-ui-buttonWidget {
-       margin: 0.25em;
+  margin: 0.25em;
 }
 .oo-ui-popupWidget-head > .oo-ui-labelElement-label {
-       margin: 0.75em 1em;
+  margin: 0.75em 1em;
 }
 .oo-ui-popupWidget-body-padded {
-       padding: 0 1em;
+  padding: 0 1em;
 }
 .oo-ui-popupButtonWidget {
-       position: relative;
+  position: relative;
 }
 .oo-ui-popupButtonWidget .oo-ui-popupWidget {
-       position: absolute;
-       cursor: auto;
+  position: absolute;
+  cursor: auto;
 }
 .oo-ui-popupButtonWidget.oo-ui-buttonElement-frameless > .oo-ui-popupWidget {
-       /* @noflip */
-       left: 0.9375em;
+  /* @noflip */
+  left: 0.9375em;
 }
 .oo-ui-popupButtonWidget.oo-ui-buttonElement-framed > .oo-ui-popupWidget {
-       /* @noflip */
-       left: 1.5em;
+  /* @noflip */
+  left: 1.5em;
 }
 .oo-ui-inputWidget {
-       margin-right: 0.5em;
+  margin-right: 0.5em;
 }
 .oo-ui-inputWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-buttonInputWidget > button,
 .oo-ui-buttonInputWidget > input {
-       border: 0;
-       padding: 0;
-       background-color: transparent;
+  border: 0;
+  padding: 0;
+  background-color: transparent;
 }
 .oo-ui-checkboxInputWidget {
-       position: relative;
-       line-height: 1.6em;
-       white-space: nowrap;
+  position: relative;
+  line-height: 1.6em;
+  white-space: nowrap;
 }
 .oo-ui-checkboxInputWidget * {
-       font: inherit;
-       vertical-align: middle;
+  font: inherit;
+  vertical-align: middle;
 }
 .oo-ui-checkboxInputWidget [type='checkbox'] {
-       position: relative;
-       max-width: none;
-       width: 1.6em;
-       height: 1.6em;
-       margin: 0;
-       opacity: 0;
-       z-index: 1;
+  position: relative;
+  max-width: none;
+  width: 1.6em;
+  height: 1.6em;
+  margin: 0;
+  opacity: 0;
+  z-index: 1;
 }
 .oo-ui-checkboxInputWidget [type='checkbox'] + span {
-       background-color: #fff;
-       background-origin: border-box;
-       background-position: center center;
-       background-repeat: no-repeat;
-       background-size: 0 0;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       position: absolute;
-       left: 0;
-       width: 1.6em;
-       height: 1.6em;
-       border: 1px solid #72777d;
-       border-radius: 2px;
+  background-color: #fff;
+  background-origin: border-box;
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-size: 0 0;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  position: absolute;
+  left: 0;
+  width: 1.6em;
+  height: 1.6em;
+  border: 1px solid #72777d;
+  border-radius: 2px;
 }
 .oo-ui-checkboxInputWidget [type='checkbox']:checked + span {
-       background-image: url('themes/mediawiki/images/icons/check-invert.png');
-       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url('themes/mediawiki/images/icons/check-invert.svg');
-       background-image:         linear-gradient(transparent, transparent), /* @embed */ url('themes/mediawiki/images/icons/check-invert.svg');
-       background-image:      -o-linear-gradient(transparent, transparent), url('themes/mediawiki/images/icons/check-invert.png');
-       background-size: 90% 90%;
+  background-image: url('themes/mediawiki/images/icons/check-invert.png');
+  background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url('themes/mediawiki/images/icons/check-invert.svg');
+  background-image:         linear-gradient(transparent, transparent), /* @embed */ url('themes/mediawiki/images/icons/check-invert.svg');
+  background-image:      -o-linear-gradient(transparent, transparent), url('themes/mediawiki/images/icons/check-invert.png');
+  background-size: 90% 90%;
 }
 .oo-ui-checkboxInputWidget [type='checkbox']:disabled + span {
-       background-color: #c8ccd1;
-       border-color: #c8ccd1;
+  background-color: #c8ccd1;
+  border-color: #c8ccd1;
 }
 .oo-ui-checkboxInputWidget [type='checkbox']:disabled:hover + span {
-       background-color: #c8ccd1;
-       border-color: #c8ccd1;
+  background-color: #c8ccd1;
+  border-color: #c8ccd1;
 }
 .oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox'] {
-       cursor: pointer;
+  cursor: pointer;
 }
 .oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox'] + span {
-       cursor: pointer;
-       -webkit-transition: background-color 100ms, background-size 100ms, border-color 100ms, box-shadow 100ms;
-          -moz-transition: background-color 100ms, background-size 100ms, border-color 100ms, box-shadow 100ms;
-               transition: background-color 100ms, background-size 100ms, border-color 100ms, box-shadow 100ms;
+  cursor: pointer;
+  -webkit-transition: background-color 100ms, background-size 100ms, border-color 100ms, box-shadow 100ms;
+     -moz-transition: background-color 100ms, background-size 100ms, border-color 100ms, box-shadow 100ms;
+          transition: background-color 100ms, background-size 100ms, border-color 100ms, box-shadow 100ms;
 }
 .oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:hover + span,
 .oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:focus:hover + span {
-       border-color: #36c;
+  border-color: #36c;
 }
-.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:active + span {
-       background-color: #2a4b8d;
-       border-color: #2a4b8d;
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:active + span,
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:active:focus + span {
+  background-color: #2a4b8d;
+  border-color: #2a4b8d;
+  box-shadow: inset 0 0 0 1px #2a4b8d;
 }
 .oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:focus + span {
-       border-color: #36c;
-       box-shadow: inset 0 0 0 1px #36c;
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c;
 }
 .oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked + span {
-       background-color: #2a4b8d;
-       border-color: #2a4b8d;
+  background-color: #36c;
+  border-color: #36c;
 }
 .oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked:hover + span,
 .oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked:focus:hover + span {
-       background-color: #36c;
-       border-color: #36c;
+  background-color: #447ff5;
+  border-color: #447ff5;
 }
 .oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked:active + span,
-.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked:active:hover + span {
-       background-color: #2a4b8d;
-       border-color: #2a4b8d;
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked:active:hover + span,
+.oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked:active:focus + span {
+  background-color: #2a4b8d;
+  border-color: #2a4b8d;
+  box-shadow: inset 0 0 0 1px #2a4b8d;
 }
 .oo-ui-checkboxInputWidget.oo-ui-widget-enabled [type='checkbox']:checked:focus + span {
-       background-color: #2a4b8d;
-       border-color: #2a4b8d;
-       box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
+  background-color: #36c;
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
 }
 .oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout {
-       margin-bottom: 0;
+  margin-bottom: 0;
 }
 .oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body {
-       padding: 0.25em 0;
+  padding: 0.25em 0;
 }
 .oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body .oo-ui-labelElement-label {
-       line-height: 1.5;
+  line-height: 1.5;
 }
 .oo-ui-dropdownInputWidget {
-       position: relative;
-       vertical-align: middle;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       width: 100%;
-       max-width: 50em;
+  position: relative;
+  vertical-align: middle;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  width: 100%;
+  max-width: 50em;
 }
 .oo-ui-dropdownInputWidget .oo-ui-dropdownWidget,
 .oo-ui-dropdownInputWidget select {
-       display: block;
+  display: block;
 }
 .oo-ui-dropdownInputWidget select {
-       width: 100%;
-       cursor: pointer;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  width: 100%;
+  cursor: pointer;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-dropdownInputWidget select {
-       background-color: #fff;
-       height: 2.275em;
-       font-size: inherit;
-       font-family: inherit;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       border: 1px solid #9aa0a7;
-       border-radius: 2px;
-       padding-left: 1em;
-       vertical-align: middle;
+  background-color: #fff;
+  height: 2.275em;
+  font-size: inherit;
+  font-family: inherit;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  border: 1px solid #a2a9b1;
+  border-radius: 2px;
+  padding-left: 1em;
+  vertical-align: middle;
 }
 .oo-ui-dropdownInputWidget option {
-       font-size: inherit;
-       font-family: inherit;
-       height: 1.5em;
-       padding: 0.5em 1em;
+  font-size: inherit;
+  font-family: inherit;
+  height: 1.5em;
+  padding: 0.5em 1em;
 }
 .oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:hover,
 .oo-ui-dropdownInputWidget.oo-ui-widget-enabled select:focus {
-       border-color: #a2a9b1;
-       outline: 0;
+  outline: 0;
 }
 .oo-ui-dropdownInputWidget.oo-ui-widget-disabled select {
-       color: #72777d;
-       border-color: #c8ccd1;
-       background-color: #eaecf0;
+  color: #72777d;
+  border-color: #c8ccd1;
+  background-color: #eaecf0;
 }
 .oo-ui-radioInputWidget {
-       position: relative;
-       line-height: 1.6em;
-       white-space: nowrap;
+  position: relative;
+  line-height: 1.6em;
+  white-space: nowrap;
 }
 .oo-ui-radioInputWidget * {
-       font: inherit;
-       vertical-align: middle;
+  font: inherit;
+  vertical-align: middle;
 }
 .oo-ui-radioInputWidget [type='radio'] {
-       position: relative;
-       max-width: none;
-       width: 1.6em;
-       height: 1.6em;
-       margin: 0;
-       opacity: 0;
-       z-index: 1;
+  position: relative;
+  max-width: none;
+  width: 1.6em;
+  height: 1.6em;
+  margin: 0;
+  opacity: 0;
+  z-index: 1;
 }
 .oo-ui-radioInputWidget [type='radio'] + span {
-       background-color: #fff;
-       position: absolute;
-       left: 0;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       width: 1.6em;
-       height: 1.6em;
-       border: 1px solid #72777d;
-       border-radius: 100%;
+  background-color: #fff;
+  position: absolute;
+  left: 0;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  width: 1.6em;
+  height: 1.6em;
+  border: 1px solid #72777d;
+  border-radius: 100%;
 }
 .oo-ui-radioInputWidget [type='radio'] + span:before {
-       content: ' ';
-       position: absolute;
-       top: -4px;
-       left: -4px;
-       right: -4px;
-       bottom: -4px;
-       border: 1px solid transparent;
-       border-radius: 100%;
+  content: ' ';
+  position: absolute;
+  top: -4px;
+  left: -4px;
+  right: -4px;
+  bottom: -4px;
+  border: 1px solid transparent;
+  border-radius: 100%;
 }
 .oo-ui-radioInputWidget [type='radio']:checked + span {
-       border-width: 0.4em;
+  border-width: 0.4em;
 }
 .oo-ui-radioInputWidget [type='radio']:checked:hover + span,
 .oo-ui-radioInputWidget [type='radio']:checked:focus:hover + span {
-       border-width: 0.4em;
+  border-width: 0.4em;
 }
 .oo-ui-radioInputWidget [type='radio']:disabled + span {
-       background-color: #c8ccd1;
-       border-color: #c8ccd1;
+  background-color: #c8ccd1;
+  border-color: #c8ccd1;
 }
 .oo-ui-radioInputWidget [type='radio']:disabled:checked + span {
-       background-color: #fff;
+  background-color: #fff;
 }
 .oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio'] {
-       cursor: pointer;
+  cursor: pointer;
 }
 .oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio'] + span {
-       cursor: pointer;
-       -webkit-transition: background-color 100ms, border-color 100ms, border-width 100ms;
-          -moz-transition: background-color 100ms, border-color 100ms, border-width 100ms;
-               transition: background-color 100ms, border-color 100ms, border-width 100ms;
+  cursor: pointer;
+  -webkit-transition: background-color 100ms, border-color 100ms, border-width 100ms;
+     -moz-transition: background-color 100ms, border-color 100ms, border-width 100ms;
+          transition: background-color 100ms, border-color 100ms, border-width 100ms;
 }
 .oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:hover + span {
-       border-color: #36c;
+  border-color: #36c;
 }
 .oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:active + span {
-       background-color: #2a4b8d;
-       border-color: #2a4b8d;
+  background-color: #2a4b8d;
+  border-color: #2a4b8d;
 }
 .oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked + span {
-       border-color: #2a4b8d;
+  border-color: #36c;
 }
 .oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:hover + span {
-       border-color: #36c;
+  border-color: #447ff5;
 }
 .oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:hover:focus + span {
-       border-color: #36c;
-       box-shadow: inset 0 0 0 1px #36c;
+  border-color: #447ff5;
+  box-shadow: inset 0 0 0 1px #447ff5;
 }
 .oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:active + span,
 .oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:active:focus + span {
-       border-color: #2a4b8d;
-       box-shadow: inset 0 0 0 1px #2a4b8d;
+  border-color: #2a4b8d;
+  box-shadow: inset 0 0 0 1px #2a4b8d;
+}
+.oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:active + span:before,
+.oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:active:focus + span:before {
+  border-color: #2a4b8d;
 }
 .oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:focus + span {
-       box-shadow: inset 0 0 0 1px #36c;
+  box-shadow: inset 0 0 0 1px #36c;
 }
 .oo-ui-radioInputWidget.oo-ui-widget-enabled [type='radio']:checked:focus + span:before {
-       border-color: #fff;
-       top: -3px;
-       right: -3px;
-       bottom: -3px;
-       left: -3px;
+  border-color: #fff;
+  top: -3px;
+  right: -3px;
+  bottom: -3px;
+  left: -3px;
 }
 .oo-ui-radioSelectInputWidget .oo-ui-fieldLayout {
-       margin-bottom: 0;
+  margin-bottom: 0;
 }
 .oo-ui-radioSelectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body {
-       padding: 0.25em 0;
+  padding: 0.25em 0;
 }
 .oo-ui-radioSelectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body .oo-ui-labelElement-label {
-       line-height: 1.5;
+  line-height: 1.5;
 }
 .oo-ui-textInputWidget {
-       position: relative;
-       vertical-align: middle;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       width: 100%;
-       max-width: 50em;
+  position: relative;
+  vertical-align: middle;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  width: 100%;
+  max-width: 50em;
 }
 .oo-ui-textInputWidget input,
 .oo-ui-textInputWidget textarea {
-       display: block;
-       width: 100%;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  display: block;
+  width: 100%;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-textInputWidget textarea {
-       overflow: auto;
-       resize: none;
+  overflow: auto;
+  resize: none;
 }
 .oo-ui-textInputWidget [type='number'] {
-       -moz-appearance: textfield;
+  -moz-appearance: textfield;
 }
 .oo-ui-textInputWidget [type='number']::-webkit-outer-spin-button,
 .oo-ui-textInputWidget [type='number']::-webkit-inner-spin-button {
-       -webkit-appearance: none;
-       margin: 0;
+  -webkit-appearance: none;
+  margin: 0;
 }
 .oo-ui-textInputWidget [type='search'] {
-       -webkit-appearance: textfield;
+  -webkit-appearance: textfield;
 }
 .oo-ui-textInputWidget [type='search']::-ms-clear {
-       display: none;
+  display: none;
 }
 .oo-ui-textInputWidget [type='search']::-webkit-search-decoration,
 .oo-ui-textInputWidget [type='search']::-webkit-search-cancel-button {
-       display: none;
+  display: none;
 }
 .oo-ui-textInputWidget > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator,
 .oo-ui-textInputWidget > .oo-ui-labelElement-label {
-       display: none;
+  display: none;
 }
 .oo-ui-textInputWidget.oo-ui-iconElement > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget.oo-ui-indicatorElement > .oo-ui-indicatorElement-indicator {
-       display: block;
-       position: absolute;
-       top: 0;
-       height: 100%;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  display: block;
+  position: absolute;
+  top: 0;
+  height: 100%;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
-       cursor: text;
+  cursor: text;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-textInputWidget-type-search > .oo-ui-indicatorElement-indicator {
-       cursor: pointer;
+  cursor: pointer;
 }
 .oo-ui-textInputWidget.oo-ui-widget-disabled input,
 .oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-textInputWidget.oo-ui-labelElement > .oo-ui-labelElement-label {
-       display: block;
+  display: block;
 }
 .oo-ui-textInputWidget > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget-labelPosition-before > .oo-ui-labelElement-label {
-       left: 0;
+  left: 0;
 }
 .oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator,
 .oo-ui-textInputWidget-labelPosition-after > .oo-ui-labelElement-label {
-       right: 0;
+  right: 0;
 }
 .oo-ui-textInputWidget > .oo-ui-labelElement-label {
-       position: absolute;
-       top: 0;
+  position: absolute;
+  top: 0;
 }
 .oo-ui-textInputWidget input,
 .oo-ui-textInputWidget textarea {
-       padding: 0.5em;
-       margin: 0;
-       font-size: inherit;
-       font-family: inherit;
-       background-color: #fff;
-       color: #000;
-       border: 1px solid #9aa0a7;
-       border-radius: 2px;
+  margin: 0;
+  font-size: inherit;
+  font-family: inherit;
+  background-color: #fff;
+  color: #000;
+  border: 1px solid #a2a9b1;
+  border-radius: 2px;
+  padding: 0.625em 0.546875em 0.546875em;
+}
+.oo-ui-textInputWidget input {
+  line-height: 1.172em;
 }
 .oo-ui-textInputWidget textarea {
-       line-height: 1.275;
+  line-height: 1.275;
 }
 .oo-ui-textInputWidget .oo-ui-pendingElement-pending {
-       background-color: transparent;
+  background-color: transparent;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input,
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea {
-       box-shadow: inset 0 0 0 0.1em #fff;
-       -webkit-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
-          -moz-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
-               transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+  box-shadow: inset 0 0 0 0.1em #fff;
+  -webkit-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+     -moz-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+          transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input:hover,
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea:hover {
-       border-color: #72777d;
+  border-color: #72777d;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input:focus,
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
-       outline: 0;
-       border-color: #36c;
-       box-shadow: inset 0 0 0 1px #36c;
+  outline: 0;
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly],
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly] {
-       color: #777;
-       text-shadow: 0 1px 1px #fff;
+  color: #72777d;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly]:hover,
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly]:hover {
-       border-color: #ccc;
+  border-color: #c8ccd1;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input[readonly]:focus,
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea[readonly]:focus {
-       border-color: #ccc;
-       box-shadow: inset 0 0 0 0.1em #ccc;
+  border-color: #c8ccd1;
+  box-shadow: inset 0 0 0 1px #c8ccd1;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled :-moz-placeholder {
-       color: #54595d;
-       opacity: 1;
+  color: #72777d;
+  opacity: 1;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled ::-moz-placeholder {
-       color: #54595d;
-       opacity: 1;
+  color: #72777d;
+  opacity: 1;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled :-ms-input-placeholder {
-       color: #54595d;
+  color: #72777d;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled ::-webkit-input-placeholder {
-       color: #54595d;
+  color: #72777d;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled :placeholder-shown {
+  color: #72777d;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
-       border-color: #f00;
+  border-color: #f00;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input:hover,
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea:hover {
-       border-color: #f00;
+  border-color: #f00;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input:focus,
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea:focus {
-       border-color: #f00;
-       box-shadow: inset 0 0 0 0.1em #f00;
+  border-color: #f00;
+  box-shadow: inset 0 0 0 0.1em #f00;
 }
 .oo-ui-textInputWidget.oo-ui-widget-disabled input,
 .oo-ui-textInputWidget.oo-ui-widget-disabled textarea {
-       background-color: #eaecf0;
-       color: #72777d;
-       text-shadow: 0 1px 1px #fff;
-       border-color: #c8ccd1;
+  background-color: #eaecf0;
+  color: #72777d;
+  text-shadow: 0 1px 1px #fff;
+  border-color: #c8ccd1;
 }
 .oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 0.51;
+  opacity: 0.51;
 }
 .oo-ui-textInputWidget.oo-ui-widget-disabled .oo-ui-labelElement-label {
-       color: #72777d;
-       text-shadow: 0 1px 1px #fff;
+  color: #72777d;
+  text-shadow: 0 1px 1px #fff;
 }
 .oo-ui-textInputWidget.oo-ui-iconElement input,
 .oo-ui-textInputWidget.oo-ui-iconElement textarea {
-       padding-left: 2.875em;
+  padding-left: 2.875em;
 }
 .oo-ui-textInputWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-       left: 0;
-       height: 100%;
-       max-height: 2.375em;
-       margin-left: 0.5em;
-       background-position: right center;
+  left: 0;
+  height: 100%;
+  max-height: 2.375em;
+  margin-left: 0.5em;
+  background-position: right center;
 }
 .oo-ui-textInputWidget.oo-ui-indicatorElement input,
 .oo-ui-textInputWidget.oo-ui-indicatorElement textarea {
-       padding-right: 2.4875em;
+  padding-right: 2.4875em;
 }
 .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       height: 100%;
-       max-height: 2.375em;
-       margin: 0 0.775em;
+  height: 100%;
+  max-height: 2.375em;
+  margin: 0 0.775em;
 }
 .oo-ui-textInputWidget > .oo-ui-labelElement-label {
-       padding: 0.4em;
-       line-height: 1.5;
-       color: #888;
+  color: #72777d;
+  padding: 0.4em;
+  line-height: 1.5;
 }
 .oo-ui-textInputWidget-labelPosition-after.oo-ui-indicatorElement > .oo-ui-labelElement-label {
-       margin-right: 2.0875em;
+  margin-right: 2.0875em;
 }
 .oo-ui-textInputWidget-labelPosition-before.oo-ui-iconElement > .oo-ui-labelElement-label {
-       margin-left: 2.475em;
+  margin-left: 2.475em;
 }
 .oo-ui-menuSelectWidget {
-       position: absolute;
-       width: 100%;
-       z-index: 4;
-       background-color: #fff;
-       margin-top: -1px;
-       border: 1px solid #a2a9b1;
-       border-radius: 0 0 2px 2px;
-       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
+  position: absolute;
+  width: 100%;
+  z-index: 4;
+  background-color: #fff;
+  margin-top: -1px;
+  border: 1px solid #a2a9b1;
+  border-radius: 0 0 2px 2px;
+  box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
 }
 .oo-ui-menuSelectWidget input {
-       position: absolute;
-       width: 0;
-       height: 0;
-       overflow: hidden;
-       opacity: 0;
+  position: absolute;
+  width: 0;
+  height: 0;
+  overflow: hidden;
+  opacity: 0;
 }
 .oo-ui-menuOptionWidget {
-       position: relative;
-       padding: 0.5em 1em;
-       -webkit-transition: background-color 100ms, color 100ms;
-          -moz-transition: background-color 100ms, color 100ms;
-               transition: background-color 100ms, color 100ms;
+  position: relative;
+  padding: 0.5em 1em;
+  -webkit-transition: background-color 100ms, color 100ms;
+     -moz-transition: background-color 100ms, color 100ms;
+          transition: background-color 100ms, color 100ms;
 }
 .oo-ui-menuOptionWidget .oo-ui-iconElement-icon {
-       display: none;
+  display: none;
 }
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
-       display: block;
+  display: block;
 }
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted {
-       background-color: #eaecf0;
-       color: #000;
+  background-color: #eaecf0;
+  color: #000;
 }
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-selected {
-       background-color: #eaf3ff;
-       color: #36c;
+  background-color: #eaf3ff;
+  color: #36c;
 }
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
-       display: none;
+  display: none;
 }
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-selected.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted,
 .oo-ui-menuOptionWidget.oo-ui-optionWidget-pressed.oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted {
-       background-color: rgba(41, 98, 204, 0.1);
-       color: #36c;
+  background-color: rgba(41, 98, 204, 0.1);
+  color: #36c;
 }
 .oo-ui-menuSectionOptionWidget {
-       cursor: default;
-       padding: 0.33em 0.75em;
-       color: #888;
+  cursor: default;
+  color: #72777d;
+  padding: 0.33em 0.75em;
 }
 .oo-ui-dropdownWidget {
-       display: inline-block;
-       position: relative;
-       width: 100%;
-       max-width: 50em;
-       margin-right: 0.5em;
+  display: inline-block;
+  position: relative;
+  width: 100%;
+  max-width: 50em;
+  margin-right: 0.5em;
 }
 .oo-ui-dropdownWidget-handle {
-       width: 100%;
-       display: block;
-       white-space: nowrap;
-       overflow: hidden;
-       text-overflow: ellipsis;
-       cursor: default;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  width: 100%;
+  display: block;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  cursor: default;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator,
 .oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
-       position: absolute;
+  position: absolute;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle {
-       cursor: pointer;
+  cursor: pointer;
 }
 .oo-ui-dropdownWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-dropdownWidget-handle {
-       padding: 0.5em 0;
-       height: 2.275em;
-       line-height: 1.275;
-       border: 1px solid #9aa0a7;
-       border-radius: 2px;
+  padding: 0.546875em 0;
+  height: 2.5em;
+  line-height: 1.275;
+  border: 1px solid #a2a9b1;
+  border-radius: 2px;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
-       top: 0;
-       right: 0;
-       margin: 0.775em;
+  top: 0;
+  right: 0;
+  margin: 0.775em;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon {
-       top: 0;
-       left: 0.25em;
-       margin: 0.3em;
+  top: 0;
+  left: 0.25em;
+  margin: 0.3em;
 }
 .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-       margin: 0 1em;
+  margin: 0 1em;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle {
-       background-color: #f8f9fa;
-       color: #222;
-       -webkit-transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
-          -moz-transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
-               transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
+  background-color: #f8f9fa;
+  color: #222;
+  -webkit-transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
+     -moz-transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
+          transition: background-color 100ms, border-color 100ms, box-shadow 100ms;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:hover {
-       background-color: #fff;
-       border-color: #a2a9b1;
+  background-color: #fff;
+  border-color: #a2a9b1;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:hover .oo-ui-iconElement-icon,
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:hover .oo-ui-indicatorElement-indicator {
-       opacity: 0.73;
+  opacity: 0.73;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle:focus {
-       border-color: #36c;
-       outline: 0;
-       box-shadow: inset 0 0 0 1px #36c;
+  border-color: #36c;
+  outline: 0;
+  box-shadow: inset 0 0 0 1px #36c;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon,
 .oo-ui-dropdownWidget.oo-ui-widget-enabled .oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
-       opacity: 0.87;
-       -webkit-transition: opacity 100ms;
-          -moz-transition: opacity 100ms;
-               transition: opacity 100ms;
+  opacity: 0.87;
+  -webkit-transition: opacity 100ms;
+     -moz-transition: opacity 100ms;
+          transition: opacity 100ms;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled.oo-ui-dropdownWidget-open .oo-ui-dropdownWidget-handle {
-       background-color: #fff;
+  background-color: #fff;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-enabled.oo-ui-dropdownWidget-open .oo-ui-dropdownWidget-handle .oo-ui-iconElement-icon,
 .oo-ui-dropdownWidget.oo-ui-widget-enabled.oo-ui-dropdownWidget-open .oo-ui-dropdownWidget-handle .oo-ui-indicatorElement-indicator {
-       opacity: 1;
+  opacity: 1;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle {
-       color: #72777d;
-       text-shadow: 0 1px 1px #fff;
-       border-color: #c8ccd1;
-       background-color: #eaecf0;
+  color: #72777d;
+  text-shadow: 0 1px 1px #fff;
+  border-color: #c8ccd1;
+  background-color: #eaecf0;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-dropdownWidget-handle:focus {
-       outline: 0;
+  outline: 0;
 }
 .oo-ui-dropdownWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 0.15;
+  opacity: 0.15;
 }
 .oo-ui-dropdownWidget.oo-ui-iconElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-       margin-left: 3em;
+  margin-left: 3em;
 }
 .oo-ui-dropdownWidget.oo-ui-indicatorElement .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {
-       margin-right: 2em;
+  margin-right: 2em;
 }
 .oo-ui-comboBoxInputWidget {
-       display: inline-block;
+  display: inline-block;
+  position: relative;
+}
+.oo-ui-comboBoxInputWidget-field {
+  display: table;
+  width: 100%;
+  table-layout: fixed;
+}
+.oo-ui-comboBoxInputWidget .oo-ui-inputWidget-input {
+  display: table-cell;
+  vertical-align: middle;
+  position: relative;
+  overflow: hidden;
+}
+.oo-ui-comboBoxInputWidget-dropdownButton {
+  display: table-cell;
 }
-.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator {
-       cursor: pointer;
+.oo-ui-comboBoxInputWidget-dropdownButton > .oo-ui-buttonElement-button {
+  display: block;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  overflow: hidden;
+}
+.oo-ui-comboBoxInputWidget.oo-ui-comboBoxInputWidget-empty .oo-ui-comboBoxInputWidget-dropdownButton {
+  display: none;
 }
 .oo-ui-comboBoxInputWidget-php ::-webkit-calendar-picker-indicator {
-       opacity: 0;
-       position: absolute;
-       right: 0;
-       top: 0;
-       height: 2.5em;
-       width: 2.5em;
-       padding: 0;
+  opacity: 0;
+  position: absolute;
+  right: 0;
+  top: 0;
+  height: 2.5em;
+  width: 2.5em;
+  padding: 0;
 }
 .oo-ui-comboBoxInputWidget-php > .oo-ui-indicatorElement-indicator {
-       pointer-events: none;
+  pointer-events: none;
 }
 .oo-ui-comboBoxInputWidget input,
 .oo-ui-comboBoxInputWidget textarea {
-       height: 2.35em;
+  height: 2.5em;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+  border-right-width: 0;
+}
+.oo-ui-comboBoxInputWidget-dropdownButton {
+  width: 2.5em;
+}
+.oo-ui-comboBoxInputWidget-dropdownButton .oo-ui-buttonElement-button {
+  min-height: 2.5em;
+  padding: 0.546875em;
 }
-.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled:hover input,
-.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled:hover textarea {
-       border-color: #a2a9b1;
+.oo-ui-comboBoxInputWidget-dropdownButton .oo-ui-buttonElement-button,
+.oo-ui-comboBoxInputWidget-dropdownButton .oo-ui-buttonElement-button:focus {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
 }
-.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled:hover input:focus,
-.oo-ui-comboBoxInputWidget.oo-ui-widget-enabled:hover textarea:focus {
-       border-color: #36c;
+.oo-ui-comboBoxInputWidget.oo-ui-comboBoxInputWidget-empty input,
+.oo-ui-comboBoxInputWidget.oo-ui-comboBoxInputWidget-empty textarea {
+  border-right-width: 1px;
 }
 .oo-ui-comboBoxInputWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-       opacity: 0.15;
+  opacity: 1;
 }
 .oo-ui-multioptionWidget {
-       position: relative;
-       display: block;
+  position: relative;
+  display: block;
 }
 .oo-ui-multioptionWidget.oo-ui-widget-enabled {
-       cursor: pointer;
+  cursor: pointer;
 }
 .oo-ui-multioptionWidget.oo-ui-widget-disabled {
-       cursor: default;
+  cursor: default;
 }
 .oo-ui-multioptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: block;
-       white-space: nowrap;
-       text-overflow: ellipsis;
-       overflow: hidden;
+  display: block;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
 }
 .oo-ui-multioptionWidget .oo-ui-labelElement-label {
-       line-height: 1.5;
+  line-height: 1.5;
 }
 .oo-ui-multioptionWidget.oo-ui-widget-disabled {
-       color: #72777d;
+  color: #72777d;
 }
 .oo-ui-checkboxMultioptionWidget {
-       cursor: default;
-       padding: 0.25em 0;
+  cursor: default;
+  padding: 0.25em 0;
 }
 .oo-ui-checkboxMultioptionWidget .oo-ui-checkboxInputWidget,
 .oo-ui-checkboxMultioptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: inline-block;
-       vertical-align: middle;
+  display: inline-block;
+  vertical-align: middle;
 }
 .oo-ui-checkboxMultioptionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       padding: 0.25em 0.25em 0.25em 0.5em;
+  padding: 0.25em 0.25em 0.25em 0.5em;
 }
 .oo-ui-checkboxMultioptionWidget .oo-ui-checkboxInputWidget {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-progressBarWidget {
-       max-width: 50em;
-       background-color: #fff;
-       border: 1px solid #9aa0a7;
-       border-radius: 2px;
-       overflow: hidden;
+  max-width: 50em;
+  background-color: #fff;
+  border: 1px solid #a2a9b1;
+  border-radius: 2px;
+  overflow: hidden;
 }
 .oo-ui-progressBarWidget-bar {
-       background-color: #ddd;
-       height: 1em;
-       -webkit-transition: width 200ms, margin-left 200ms;
-          -moz-transition: width 200ms, margin-left 200ms;
-               transition: width 200ms, margin-left 200ms;
+  background-color: #36c;
+  height: 1em;
+  -webkit-transition: width 200ms, margin-left 200ms;
+     -moz-transition: width 200ms, margin-left 200ms;
+          transition: width 200ms, margin-left 200ms;
 }
 .oo-ui-progressBarWidget-indeterminate .oo-ui-progressBarWidget-bar {
-       -webkit-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
-          -moz-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
-               animation: oo-ui-progressBarWidget-slide 2s infinite linear;
-       width: 40%;
-       margin-left: -10%;
-       border-left-width: 1px;
+  -webkit-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
+     -moz-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
+          animation: oo-ui-progressBarWidget-slide 2s infinite linear;
+  width: 40%;
+  margin-left: -10%;
+  border-left-width: 1px;
 }
 .oo-ui-progressBarWidget.oo-ui-widget-disabled {
-       opacity: 0.6;
+  opacity: 0.6;
 }
 @-webkit-keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
+  from {
+    margin-left: -40%;
+  }
+  to {
+    margin-left: 100%;
+  }
 }
 @-moz-keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
+  from {
+    margin-left: -40%;
+  }
+  to {
+    margin-left: 100%;
+  }
 }
 @keyframes oo-ui-progressBarWidget-slide {
-       from {
-               margin-left: -40%;
-       }
-       to {
-               margin-left: 100%;
-       }
+  from {
+    margin-left: -40%;
+  }
+  to {
+    margin-left: 100%;
+  }
 }
index c982010..fd4e033 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:02Z
+ * Date: 2016-11-09T00:52:37Z
  */
 ( function ( OO ) {
 
@@ -260,6 +260,18 @@ OO.ui.debounce = function ( func, wait, immediate ) {
        };
 };
 
+/**
+ * Puts a console warning with provided message.
+ *
+ * @param {string} message
+ */
+OO.ui.warnDeprecation = function ( message ) {
+       if ( OO.getProp( window, 'console', 'warn' ) !== undefined ) {
+               // eslint-disable-next-line no-console
+               console.warn( message );
+       }
+};
+
 /**
  * Returns a function, that, when invoked, will only be triggered at most once
  * during a given window of time. If called again during that window, it will
@@ -312,30 +324,6 @@ OO.ui.now = Date.now || function () {
        return new Date().getTime();
 };
 
-/**
- * Proxy for `node.addEventListener( eventName, handler, true )`.
- *
- * @param {HTMLElement} node
- * @param {string} eventName
- * @param {Function} handler
- * @deprecated since 0.15.0
- */
-OO.ui.addCaptureEventListener = function ( node, eventName, handler ) {
-       node.addEventListener( eventName, handler, true );
-};
-
-/**
- * Proxy for `node.removeEventListener( eventName, handler, true )`.
- *
- * @param {HTMLElement} node
- * @param {string} eventName
- * @param {Function} handler
- * @deprecated since 0.15.0
- */
-OO.ui.removeCaptureEventListener = function ( node, eventName, handler ) {
-       node.removeEventListener( eventName, handler, true );
-};
-
 /**
  * Reconstitute a JavaScript object corresponding to a widget created by
  * the PHP implementation.
@@ -747,6 +735,7 @@ OO.ui.Element.static.unsafeInfuse = function ( idOrNode, domPromise ) {
        // pick up dynamic state, like focus, value of form inputs, scroll position, etc.
        state = cls.static.gatherPreInfuseState( $elem[ 0 ], data );
        // rebuild widget
+       // eslint-disable-next-line new-cap
        obj = new cls( data );
        // now replace old DOM with this new DOM.
        if ( top ) {
@@ -1610,7 +1599,6 @@ OO.ui.Theme.prototype.getElementClasses = function () {
  * For elements with theme logic hooks, this should be called any time there's a state change.
  *
  * @param {OO.ui.Element} element Element for which to update classes
- * @return {Object.<string,string[]>} Categorized class names with `on` and `off` lists
  */
 OO.ui.Theme.prototype.updateElementClasses = function ( element ) {
        var $elements = $( [] ),
@@ -1871,13 +1859,18 @@ OO.ui.mixin.ButtonElement.prototype.setButtonElement = function ( $button ) {
 
        this.$button = $button
                .addClass( 'oo-ui-buttonElement-button' )
-               .attr( { role: 'button' } )
                .on( {
                        mousedown: this.onMouseDownHandler,
                        keydown: this.onKeyDownHandler,
                        click: this.onClickHandler,
                        keypress: this.onKeyPressHandler
                } );
+
+       // Add `role="button"` on `<a>` elements, where it's needed
+       // `toUppercase()` is added for XHTML documents
+       if ( this.$button.prop( 'tagName' ).toUpperCase() === 'A' ) {
+               this.$button.attr( 'role', 'button' );
+       }
 };
 
 /**
@@ -3393,31 +3386,14 @@ OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.FlaggedElement );
 OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.TabIndexedElement );
 OO.mixinClass( OO.ui.ButtonWidget, OO.ui.mixin.AccessKeyedElement );
 
-/* Methods */
-
-/**
- * @inheritdoc
- */
-OO.ui.ButtonWidget.prototype.onMouseDown = function ( e ) {
-       if ( !this.isDisabled() ) {
-               // Remove the tab-index while the button is down to prevent the button from stealing focus
-               this.$button.removeAttr( 'tabindex' );
-       }
-
-       return OO.ui.mixin.ButtonElement.prototype.onMouseDown.call( this, e );
-};
+/* Static Properties */
 
 /**
  * @inheritdoc
  */
-OO.ui.ButtonWidget.prototype.onMouseUp = function ( e ) {
-       if ( !this.isDisabled() ) {
-               // Restore the tab-index after the button is up to restore the button's accessibility
-               this.$button.attr( 'tabindex', this.tabIndex );
-       }
+OO.ui.ButtonWidget.static.cancelButtonMouseDownEvents = false;
 
-       return OO.ui.mixin.ButtonElement.prototype.onMouseUp.call( this, e );
-};
+/* Methods */
 
 /**
  * Get hyperlink location.
@@ -7582,18 +7558,6 @@ OO.ui.InputWidget.prototype.getValue = function () {
        return this.value;
 };
 
-/**
- * Set the directionality of the input, either RTL (right-to-left) or LTR (left-to-right).
- *
- * @deprecated since v0.13.1; use #setDir directly
- * @param {boolean} isRTL Directionality is right-to-left
- * @chainable
- */
-OO.ui.InputWidget.prototype.setRTL = function ( isRTL ) {
-       this.setDir( isRTL ? 'rtl' : 'ltr' );
-       return this;
-};
-
 /**
  * Set the directionality of the input.
  *
@@ -8612,7 +8576,7 @@ OO.ui.CheckboxMultiselectInputWidget.prototype.setOptions = function ( options )
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {string} [type='text'] The value of the HTML `type` attribute: 'text', 'password', 'search',
- *  'email', 'url', 'date' or 'number'. Ignored if `multiline` is true.
+ *  'email', 'url', 'date', 'month' or 'number'. Ignored if `multiline` is true.
  *
  *  Some values of `type` result in additional behaviors:
  *
@@ -8646,17 +8610,14 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
                type: 'text',
                labelPosition: 'after'
        }, config );
+
        if ( config.type === 'search' ) {
+               OO.ui.warnDeprecation( 'TextInputWidget: config.type=\'search\' is deprecated. Use the SearchInputWidget instead. See T148471 for details.' );
                if ( config.icon === undefined ) {
                        config.icon = 'search';
                }
                // indicator: 'clear' is set dynamically later, depending on value
        }
-       if ( config.required ) {
-               if ( config.indicator === undefined ) {
-                       config.indicator = 'required';
-               }
-       }
 
        // Parent constructor
        OO.ui.TextInputWidget.parent.call( this, config );
@@ -8670,6 +8631,7 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
        // Properties
        this.type = this.getSaneType( config );
        this.readOnly = false;
+       this.required = false;
        this.multiline = !!config.multiline;
        this.autosize = !!config.autosize;
        this.minRows = config.rows !== undefined ? config.rows : '';
@@ -8713,6 +8675,7 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
                .addClass( 'oo-ui-textInputWidget oo-ui-textInputWidget-type-' + this.type )
                .append( this.$icon, this.$indicator );
        this.setReadOnly( !!config.readOnly );
+       this.setRequired( !!config.required );
        this.updateSearchIndicator();
        if ( config.placeholder !== undefined ) {
                this.$input.attr( 'placeholder', config.placeholder );
@@ -8723,10 +8686,6 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
        if ( config.autofocus ) {
                this.$input.attr( 'autofocus', 'autofocus' );
        }
-       if ( config.required ) {
-               this.$input.attr( 'required', 'required' );
-               this.$input.attr( 'aria-required', 'true' );
-       }
        if ( config.autocomplete === false ) {
                this.$input.attr( 'autocomplete', 'off' );
                // Turning off autocompletion also disables "form caching" when the user navigates to a
@@ -8925,6 +8884,42 @@ OO.ui.TextInputWidget.prototype.setReadOnly = function ( state ) {
        return this;
 };
 
+/**
+ * Check if the input is {@link #required required}.
+ *
+ * @return {boolean}
+ */
+OO.ui.TextInputWidget.prototype.isRequired = function () {
+       return this.required;
+};
+
+/**
+ * Set the {@link #required required} state of the input.
+ *
+ * @param {boolean} state Make input required
+ * @chainable
+ */
+OO.ui.TextInputWidget.prototype.setRequired = function ( state ) {
+       this.required = !!state;
+       if ( this.required ) {
+               this.$input
+                       .attr( 'required', 'required' )
+                       .attr( 'aria-required', 'true' );
+               if ( this.getIndicator() === null ) {
+                       this.setIndicator( 'required' );
+               }
+       } else {
+               this.$input
+                       .removeAttr( 'required' )
+                       .removeAttr( 'aria-required' );
+               if ( this.getIndicator() === 'required' ) {
+                       this.setIndicator( null );
+               }
+       }
+       this.updateSearchIndicator();
+       return this;
+};
+
 /**
  * Support function for making #onElementAttach work across browsers.
  *
@@ -9100,6 +9095,7 @@ OO.ui.TextInputWidget.prototype.getSaneType = function ( config ) {
                'email',
                'url',
                'date',
+               'month',
                'number'
        ];
        return allowedTypes.indexOf( config.type ) !== -1 ? config.type : 'text';
@@ -9297,30 +9293,6 @@ OO.ui.TextInputWidget.prototype.setValidityFlag = function ( isValid ) {
        }
 };
 
-/**
- * Check if a value is valid.
- *
- * This method returns a promise that resolves with a boolean `true` if the current value is
- * considered valid according to the supplied {@link #validate validation pattern}.
- *
- * @deprecated since v0.12.3
- * @return {jQuery.Promise} A promise that resolves to a boolean `true` if the value is valid.
- */
-OO.ui.TextInputWidget.prototype.isValid = function () {
-       var result;
-
-       if ( this.validate instanceof Function ) {
-               result = this.validate( this.getValue() );
-               if ( result && $.isFunction( result.promise ) ) {
-                       return result.promise();
-               } else {
-                       return $.Deferred().resolve( !!result ).promise();
-               }
-       } else {
-               return $.Deferred().resolve( !!this.getValue().match( this.validate ) ).promise();
-       }
-};
-
 /**
  * Get the validity of current value.
  *
@@ -9449,6 +9421,99 @@ OO.ui.TextInputWidget.prototype.restorePreInfuseState = function ( state ) {
        }
 };
 
+/**
+ * @class
+ * @extends OO.ui.TextInputWidget
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.SearchInputWidget = function OoUiSearchInputWidget( config ) {
+       config = $.extend( {
+               icon: 'search'
+       }, config );
+
+       // Set type to text so that TextInputWidget doesn't
+       // get stuck in an infinite loop.
+       config.type = 'text';
+
+       // Parent constructor
+       OO.ui.SearchInputWidget.parent.call( this, config );
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-textInputWidget-type-search' );
+       this.updateSearchIndicator();
+       this.connect( this, {
+               disable: 'onDisable'
+       } );
+};
+
+/* Setup */
+
+OO.inheritClass( OO.ui.SearchInputWidget, OO.ui.TextInputWidget );
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ * @protected
+ */
+OO.ui.SearchInputWidget.prototype.getInputElement = function () {
+       return $( '<input>' ).attr( 'type', 'search' );
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.SearchInputWidget.prototype.onIndicatorMouseDown = function ( e ) {
+       if ( e.which === OO.ui.MouseButtons.LEFT ) {
+               // Clear the text field
+               this.setValue( '' );
+               this.$input[ 0 ].focus();
+               return false;
+       }
+};
+
+/**
+ * Update the 'clear' indicator displayed on type: 'search' text
+ * fields, hiding it when the field is already empty or when it's not
+ * editable.
+ */
+OO.ui.SearchInputWidget.prototype.updateSearchIndicator = function () {
+       if ( this.getValue() === '' || this.isDisabled() || this.isReadOnly() ) {
+               this.setIndicator( null );
+       } else {
+               this.setIndicator( 'clear' );
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.SearchInputWidget.prototype.onChange = function () {
+       OO.ui.SearchInputWidget.parent.prototype.onChange.call( this );
+       this.updateSearchIndicator();
+};
+
+/**
+ * Handle disable events.
+ *
+ * @param {boolean} disabled Element is disabled
+ * @private
+ */
+OO.ui.SearchInputWidget.prototype.onDisable = function () {
+       this.updateSearchIndicator();
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.SearchInputWidget.prototype.setReadOnly = function ( state ) {
+       OO.ui.SearchInputWidget.parent.prototype.setReadOnly.call( this, state );
+       this.updateSearchIndicator();
+       return this;
+};
+
 /**
  * ComboBoxInputWidgets combine a {@link OO.ui.TextInputWidget text input} (where a value
  * can be entered manually) and a {@link OO.ui.MenuSelectWidget menu of options} (from which
@@ -9511,17 +9576,19 @@ OO.ui.TextInputWidget.prototype.restorePreInfuseState = function ( state ) {
 OO.ui.ComboBoxInputWidget = function OoUiComboBoxInputWidget( config ) {
        // Configuration initialization
        config = $.extend( {
-               indicator: 'down',
                autocomplete: false
        }, config );
-       // For backwards-compatibility with ComboBoxWidget config
-       $.extend( config, config.input );
 
        // Parent constructor
        OO.ui.ComboBoxInputWidget.parent.call( this, config );
 
        // Properties
        this.$overlay = config.$overlay || this.$element;
+       this.dropdownButton = new OO.ui.ButtonWidget( {
+               classes: [ 'oo-ui-comboBoxInputWidget-dropdownButton' ],
+               indicator: 'down',
+               disabled: this.disabled
+       } );
        this.menu = new OO.ui.FloatingMenuSelectWidget( $.extend(
                {
                        widget: this,
@@ -9531,18 +9598,15 @@ OO.ui.ComboBoxInputWidget = function OoUiComboBoxInputWidget( config ) {
                },
                config.menu
        ) );
-       // For backwards-compatibility with ComboBoxWidget
-       this.input = this;
 
        // Events
-       this.$indicator.on( {
-               click: this.onIndicatorClick.bind( this ),
-               keypress: this.onIndicatorKeyPress.bind( this )
-       } );
        this.connect( this, {
                change: 'onInputChange',
                enter: 'onInputEnter'
        } );
+       this.dropdownButton.connect( this, {
+               click: 'onDropdownButtonClick'
+       } );
        this.menu.connect( this, {
                choose: 'onMenuChoose',
                add: 'onMenuItemsChange',
@@ -9558,8 +9622,12 @@ OO.ui.ComboBoxInputWidget = function OoUiComboBoxInputWidget( config ) {
        if ( config.options !== undefined ) {
                this.setOptions( config.options );
        }
-       // Extra class for backwards-compatibility with ComboBoxWidget
-       this.$element.addClass( 'oo-ui-comboBoxInputWidget oo-ui-comboBoxWidget' );
+       this.$field = $( '<div>' )
+               .addClass( 'oo-ui-comboBoxInputWidget-field' )
+               .append( this.$input, this.dropdownButton.$element );
+       this.$element
+               .addClass( 'oo-ui-comboBoxInputWidget' )
+               .append( this.$field );
        this.$overlay.append( this.menu.$element );
        this.onMenuItemsChange();
 };
@@ -9608,42 +9676,24 @@ OO.ui.ComboBoxInputWidget.prototype.onInputChange = function ( value ) {
 };
 
 /**
- * Handle mouse click events.
- *
- * @private
- * @param {jQuery.Event} e Mouse click event
- */
-OO.ui.ComboBoxInputWidget.prototype.onIndicatorClick = function ( e ) {
-       if ( !this.isDisabled() && e.which === OO.ui.MouseButtons.LEFT ) {
-               this.menu.toggle();
-               this.$input[ 0 ].focus();
-       }
-       return false;
-};
-
-/**
- * Handle key press events.
+ * Handle input enter events.
  *
  * @private
- * @param {jQuery.Event} e Key press event
  */
-OO.ui.ComboBoxInputWidget.prototype.onIndicatorKeyPress = function ( e ) {
-       if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
-               this.menu.toggle();
-               this.$input[ 0 ].focus();
-               return false;
+OO.ui.ComboBoxInputWidget.prototype.onInputEnter = function () {
+       if ( !this.isDisabled() ) {
+               this.menu.toggle( false );
        }
 };
 
 /**
- * Handle input enter events.
+ * Handle button click events.
  *
  * @private
  */
-OO.ui.ComboBoxInputWidget.prototype.onInputEnter = function () {
-       if ( !this.isDisabled() ) {
-               this.menu.toggle( false );
-       }
+OO.ui.ComboBoxInputWidget.prototype.onDropdownButtonClick = function () {
+       this.menu.toggle();
+       this.$input[ 0 ].focus();
 };
 
 /**
@@ -9677,6 +9727,9 @@ OO.ui.ComboBoxInputWidget.prototype.setDisabled = function ( disabled ) {
        // Parent method
        OO.ui.ComboBoxInputWidget.parent.prototype.setDisabled.call( this, disabled );
 
+       if ( this.dropdownButton ) {
+               this.dropdownButton.setDisabled( this.isDisabled() );
+       }
        if ( this.menu ) {
                this.menu.setDisabled( this.isDisabled() );
        }
@@ -9703,12 +9756,6 @@ OO.ui.ComboBoxInputWidget.prototype.setOptions = function ( options ) {
        return this;
 };
 
-/**
- * @class
- * @deprecated since 0.13.2; use OO.ui.ComboBoxInputWidget instead
- */
-OO.ui.ComboBoxWidget = OO.ui.ComboBoxInputWidget;
-
 /**
  * FieldLayouts are used with OO.ui.FieldsetLayout. Each FieldLayout requires a field-widget,
  * which is a widget that is specified by reference before any optional configuration settings.
@@ -10015,6 +10062,7 @@ OO.ui.FieldLayout.prototype.updateMessages = function () {
  * @constructor
  * @param {OO.ui.Widget} fieldWidget Field widget
  * @param {OO.ui.ButtonWidget} buttonWidget Button widget
+ * @param {Object} config
  */
 OO.ui.ActionFieldLayout = function OoUiActionFieldLayout( fieldWidget, buttonWidget, config ) {
        // Allow passing positional parameters inside the config object
@@ -10121,6 +10169,7 @@ OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {
        }
 
        // Initialization
+       this.$group.addClass( 'oo-ui-fieldsetLayout-group' );
        this.$element
                .addClass( 'oo-ui-fieldsetLayout' )
                .prepend( this.$label, this.$help, this.$icon, this.$group );
index 343508c..17bca7e 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:02Z
+ * Date: 2016-11-09T00:52:37Z
  */
 ( function ( OO ) {
 
index 9c9954e..7fb36c4 100644 (file)
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:06Z
+ * Date: 2016-11-09T00:52:42Z
  */
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
-       z-index: 4;
+  z-index: 4;
 }
 .oo-ui-popupTool .oo-ui-popupWidget {
-       /* @noflip */
-       margin-left: 1.25em;
+  /* @noflip */
+  margin-left: 1.25em;
 }
 .oo-ui-toolGroupTool > .oo-ui-popupToolGroup {
-       border: 0;
-       border-radius: 0;
-       margin: 0;
+  border: 0;
+  border-radius: 0;
+  margin: 0;
 }
 .oo-ui-toolGroupTool:first-child > .oo-ui-popupToolGroup {
-       border-top-left-radius: 0.3125em;
-       border-bottom-left-radius: 0.3125em;
+  border-top-left-radius: 0.3125em;
+  border-bottom-left-radius: 0.3125em;
 }
 .oo-ui-toolGroupTool:last-child > .oo-ui-popupToolGroup {
-       border-top-right-radius: 0.3125em;
-       border-bottom-right-radius: 0.3125em;
+  border-top-right-radius: 0.3125em;
+  border-bottom-right-radius: 0.3125em;
 }
 .oo-ui-toolGroupTool > .oo-ui-popupToolGroup > .oo-ui-popupToolGroup-handle {
-       height: 1.875em;
-       padding: 0.3125em;
+  height: 1.875em;
+  padding: 0.3125em;
 }
 .oo-ui-toolGroupTool > .oo-ui-popupToolGroup > .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       height: 1.875em;
-       width: 1.875em;
+  height: 1.875em;
+  width: 1.875em;
 }
 .oo-ui-toolGroupTool > .oo-ui-popupToolGroup.oo-ui-labelElement > .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       line-height: 2.1em;
+  line-height: 2.1em;
 }
 .oo-ui-toolGroup {
-       display: inline-block;
-       vertical-align: middle;
-       margin: 0.375em;
-       border-radius: 0.3125em;
-       border: 1px solid transparent;
-       -webkit-transition: border-color 250ms ease;
-          -moz-transition: border-color 250ms ease;
-               transition: border-color 250ms ease;
+  display: inline-block;
+  vertical-align: middle;
+  margin: 0.375em;
+  border-radius: 0.3125em;
+  border: 1px solid transparent;
+  -webkit-transition: border-color 250ms ease;
+     -moz-transition: border-color 250ms ease;
+          transition: border-color 250ms ease;
 }
 .oo-ui-toolGroup-empty {
-       display: none;
+  display: none;
 }
 .oo-ui-toolGroup .oo-ui-tool-link {
-       text-decoration: none;
-       cursor: pointer;
+  text-decoration: none;
+  cursor: pointer;
 }
 .oo-ui-toolGroup.oo-ui-widget-disabled .oo-ui-tool-link,
 .oo-ui-toolGroup .oo-ui-widget-disabled > .oo-ui-tool-link {
-       outline: 0;
-       cursor: default;
+  outline: 0;
+  cursor: default;
 }
 .oo-ui-toolbar-narrow .oo-ui-toolGroup + .oo-ui-toolGroup {
-       margin-left: 0;
+  margin-left: 0;
 }
 .oo-ui-toolGroup.oo-ui-widget-enabled:hover {
-       border-color: rgba(0, 0, 0, 0.1);
+  border-color: rgba(0, 0, 0, 0.1);
 }
 .oo-ui-toolGroup.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-tool-title {
-       color: #000;
+  color: #000;
 }
 .oo-ui-barToolGroup > .oo-ui-iconElement-icon,
 .oo-ui-barToolGroup > .oo-ui-labelElement-label {
-       display: none;
+  display: none;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool {
-       display: inline-block;
-       position: relative;
-       vertical-align: top;
+  display: inline-block;
+  position: relative;
+  vertical-align: top;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
-       display: block;
+  display: block;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-accel {
-       display: none;
+  display: none;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       display: inline-block;
-       vertical-align: top;
+  display: inline-block;
+  vertical-align: top;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement > .oo-ui-tool-link .oo-ui-tool-title {
-       display: none;
+  display: none;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement.oo-ui-tool-with-label > .oo-ui-tool-link .oo-ui-tool-title {
-       display: inline;
+  display: inline;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool {
-       margin: -1px 0 -1px -1px;
-       border: 1px solid transparent;
+  margin: -1px 0 -1px -1px;
+  border: 1px solid transparent;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool:first-child {
-       border-top-left-radius: 0.3125em;
-       border-bottom-left-radius: 0.3125em;
+  border-top-left-radius: 0.3125em;
+  border-bottom-left-radius: 0.3125em;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool:last-child {
-       margin-right: -1px;
-       border-top-right-radius: 0.3125em;
-       border-bottom-right-radius: 0.3125em;
+  margin-right: -1px;
+  border-top-right-radius: 0.3125em;
+  border-bottom-right-radius: 0.3125em;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
-       height: 1.875em;
-       padding: 0.3125em;
+  height: 1.875em;
+  padding: 0.3125em;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       height: 1.875em;
-       width: 1.875em;
+  height: 1.875em;
+  width: 1.875em;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
-       line-height: 2.1em;
+  line-height: 2.1em;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover {
-       border-color: rgba(0, 0, 0, 0.2);
+  border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled {
-       border-color: rgba(0, 0, 0, 0.2);
-       box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
-       background-color: #f8fbfd;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #fff));
-       background-image: -webkit-linear-gradient(top, #f1f7fb 0, #fff 100%);
-       background-image:    -moz-linear-gradient(top, #f1f7fb 0, #fff 100%);
-       background-image:         linear-gradient(to bottom, #f1f7fb 0, #fff 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#fff1f7fb\', endColorstr=\'#ffffffff\' )';
+  border-color: rgba(0, 0, 0, 0.2);
+  box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
+  background-color: #f8fbfd;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #F1F7FB), color-stop(100%, #fff));
+  background-image: -webkit-linear-gradient(top, #F1F7FB 0, #fff 100%);
+  background-image:    -moz-linear-gradient(top, #F1F7FB 0, #fff 100%);
+  background-image:         linear-gradient(to bottom, #F1F7FB 0, #fff 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
-       border-left-color: rgba(0, 0, 0, 0.1);
+  border-left-color: rgba(0, 0, 0, 0.1);
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link:focus {
-       outline: 0;
+  outline: 0;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-tool-title {
-       color: #ccc;
+  color: #ccc;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 1;
+  opacity: 1;
 }
 .oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool:focus {
-       outline: 0;
+  outline: 0;
 }
 .oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link:focus {
-       outline: 0;
+  outline: 0;
 }
 .oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
-       color: #ccc;
+  color: #ccc;
 }
 .oo-ui-barToolGroup.oo-ui-widget-disabled > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-popupToolGroup {
-       position: relative;
-       height: 2.5em;
-       min-width: 2.5em;
+  position: relative;
+  height: 2.5em;
+  min-width: 2.5em;
 }
 .oo-ui-popupToolGroup-handle {
-       display: block;
-       cursor: pointer;
+  display: block;
+  cursor: pointer;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
 .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       position: absolute;
+  position: absolute;
 }
 .oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle {
-       outline: 0;
-       cursor: default;
+  outline: 0;
+  cursor: default;
 }
 .oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
-       display: none;
-       position: absolute;
-       z-index: 4;
+  display: none;
+  position: absolute;
+  z-index: 4;
 }
 .oo-ui-popupToolGroup-active.oo-ui-widget-enabled > .oo-ui-toolGroup-tools {
-       display: block;
+  display: block;
 }
 .oo-ui-popupToolGroup-left > .oo-ui-toolGroup-tools {
-       left: 0;
+  left: 0;
 }
 .oo-ui-popupToolGroup-right > .oo-ui-toolGroup-tools {
-       right: 0;
+  right: 0;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link {
-       display: table;
-       width: 100%;
-       vertical-align: middle;
-       white-space: nowrap;
+  display: table;
+  width: 100%;
+  vertical-align: middle;
+  white-space: nowrap;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon,
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel,
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-       display: table-cell;
-       vertical-align: middle;
+  display: table-cell;
+  vertical-align: middle;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
-       text-align: right;
+  text-align: right;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel:not( :empty ) {
-       padding-left: 3em;
+  padding-left: 3em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup {
-       min-width: 1.875em;
+  min-width: 1.875em;
 }
 .oo-ui-popupToolGroup.oo-ui-iconElement {
-       min-width: 3.125em;
+  min-width: 3.125em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-iconElement {
-       min-width: 2.5em;
+  min-width: 2.5em;
 }
 .oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
-       min-width: 4.375em;
+  min-width: 4.375em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
-       min-width: 3.75em;
+  min-width: 3.75em;
 }
 .oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       line-height: 2.6em;
-       margin: 0 1em;
+  line-height: 2.6em;
+  margin: 0 1em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin: 0 0.5em;
+  margin: 0 0.5em;
 }
 .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-left: 3em;
+  margin-left: 3em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-left: 2.5em;
+  margin-left: 2.5em;
 }
 .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-right: 2.25em;
+  margin-right: 2.25em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-right: 1.75em;
+  margin-right: 1.75em;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
-       width: 0.9375em;
-       height: 0.9375em;
-       margin: 0.78125em;
-       top: 0;
-       right: 0;
+  width: 0.9375em;
+  height: 0.9375em;
+  margin: 0.78125em;
+  top: 0;
+  right: 0;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
-       right: -0.3125em;
+  right: -0.3125em;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       width: 1.875em;
-       height: 1.875em;
-       margin: 0.3125em;
-       top: 0;
-       left: 0.3125em;
+  width: 1.875em;
+  height: 1.875em;
+  margin: 0.3125em;
+  top: 0;
+  left: 0.3125em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       left: 0;
+  left: 0;
 }
 .oo-ui-popupToolGroup-header {
-       line-height: 2.6em;
-       margin: 0 0.6em;
-       font-weight: bold;
+  line-height: 2.6em;
+  margin: 0 0.6em;
+  font-weight: bold;
 }
 .oo-ui-popupToolGroup-active.oo-ui-widget-enabled {
-       border-bottom-left-radius: 0;
-       border-bottom-right-radius: 0;
-       box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
-       background-color: #f8fbfd;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #fff));
-       background-image: -webkit-linear-gradient(top, #f1f7fb 0, #fff 100%);
-       background-image:    -moz-linear-gradient(top, #f1f7fb 0, #fff 100%);
-       background-image:         linear-gradient(to bottom, #f1f7fb 0, #fff 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#fff1f7fb\', endColorstr=\'#ffffffff\' )';
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+  box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
+  background-color: #f8fbfd;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #F1F7FB), color-stop(100%, #fff));
+  background-image: -webkit-linear-gradient(top, #F1F7FB 0, #fff 100%);
+  background-image:    -moz-linear-gradient(top, #F1F7FB 0, #fff 100%);
+  background-image:         linear-gradient(to bottom, #F1F7FB 0, #fff 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
 }
 .oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
-       top: 2.5em;
-       margin: 0 -1px;
-       border: 1px solid #ccc;
-       background-color: #fff;
-       box-shadow: 0 0.3125em 1.25em rgba(0, 0, 0, 0.25);
+  top: 2.5em;
+  margin: 0 -1px;
+  border: 1px solid #ccc;
+  background-color: #fff;
+  box-shadow: 0 0.3125em 1.25em rgba(0, 0, 0, 0.25);
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link {
-       padding: 0.3125em 0 0.3125em 0.3125em;
+  padding: 0.3125em 0 0.3125em 0.3125em;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-       height: 1.875em;
-       width: 1.875em;
-       min-width: 1.875em;
+  height: 1.875em;
+  width: 1.875em;
+  min-width: 1.875em;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-       padding-left: 0.5em;
+  padding-left: 0.5em;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel,
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-       line-height: 2em;
+  line-height: 2em;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
-       color: #888;
+  color: #888;
 }
 .oo-ui-listToolGroup .oo-ui-tool {
-       display: block;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  display: block;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-listToolGroup .oo-ui-toolGroup-tools {
-       padding: 0.3125em;
+  padding: 0.3125em;
 }
 .oo-ui-listToolGroup.oo-ui-popupToolGroup-active {
-       border-color: rgba(0, 0, 0, 0.2);
+  border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-listToolGroup .oo-ui-tool {
-       border: 1px solid transparent;
-       margin: -1px 0;
-       padding: 0 0.625em 0 0;
+  border: 1px solid transparent;
+  margin: -1px 0;
+  padding: 0 0.625em 0 0;
 }
 .oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled {
-       border-color: rgba(0, 0, 0, 0.1);
-       box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
-       background-color: #f8fbfd;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #f1f7fb), color-stop(100%, #fff));
-       background-image: -webkit-linear-gradient(top, #f1f7fb 0, #fff 100%);
-       background-image:    -moz-linear-gradient(top, #f1f7fb 0, #fff 100%);
-       background-image:         linear-gradient(to bottom, #f1f7fb 0, #fff 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#fff1f7fb\', endColorstr=\'#ffffffff\' )';
+  border-color: rgba(0, 0, 0, 0.1);
+  box-shadow: inset 0 0.0875em 0.0875em 0 rgba(0, 0, 0, 0.07);
+  background-color: #f8fbfd;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #F1F7FB), color-stop(100%, #fff));
+  background-image: -webkit-linear-gradient(top, #F1F7FB 0, #fff 100%);
+  background-image:    -moz-linear-gradient(top, #F1F7FB 0, #fff 100%);
+  background-image:         linear-gradient(to bottom, #F1F7FB 0, #fff 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff1f7fb', endColorstr='#ffffffff' )";
 }
 .oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
-       border-top-color: rgba(0, 0, 0, 0.1);
+  border-top-color: rgba(0, 0, 0, 0.1);
 }
 .oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled:hover {
-       border-color: rgba(0, 0, 0, 0.2);
+  border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
-       border-color: rgba(0, 0, 0, 0.2);
+  border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 1;
+  opacity: 1;
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
-       color: #ccc;
+  color: #ccc;
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-accel {
-       color: #ddd;
+  color: #ddd;
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-listToolGroup.oo-ui-widget-disabled {
-       color: #ccc;
+  color: #ccc;
 }
 .oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
 .oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-menuToolGroup {
-       border-color: rgba(0, 0, 0, 0.1);
+  border-color: rgba(0, 0, 0, 0.1);
 }
 .oo-ui-menuToolGroup .oo-ui-tool {
-       display: block;
+  display: block;
 }
 .oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
-       min-width: 10em;
+  min-width: 10em;
 }
 .oo-ui-toolbar-narrow .oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
-       min-width: 8.125em;
+  min-width: 8.125em;
 }
 .oo-ui-menuToolGroup .oo-ui-toolGroup-tools {
-       padding: 0.3125em 0 0.3125em 0;
+  padding: 0.3125em 0 0.3125em 0;
 }
 .oo-ui-menuToolGroup.oo-ui-widget-enabled:hover {
-       border-color: rgba(0, 0, 0, 0.2);
+  border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-menuToolGroup.oo-ui-popupToolGroup-active {
-       border-color: rgba(0, 0, 0, 0.25);
+  border-color: rgba(0, 0, 0, 0.25);
 }
 .oo-ui-menuToolGroup .oo-ui-tool {
-       padding: 0 1.25em 0 0.3125em;
+  padding: 0 1.25em 0 0.3125em;
 }
 .oo-ui-menuToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-       background-image: none;
+  background-image: none;
 }
 .oo-ui-menuToolGroup .oo-ui-tool-active .oo-ui-tool-link .oo-ui-iconElement-icon {
-       background-image: url('themes/apex/images/icons/check.png');
-       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url('themes/apex/images/icons/check.svg');
-       background-image:         linear-gradient(transparent, transparent), /* @embed */ url('themes/apex/images/icons/check.svg');
-       background-image:      -o-linear-gradient(transparent, transparent), url('themes/apex/images/icons/check.png');
-       background-size: contain;
-       background-position: center center;
-       background-repeat: no-repeat;
+  background-image: url('themes/apex/images/icons/check.png');
+  background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url('themes/apex/images/icons/check.svg');
+  background-image:         linear-gradient(transparent, transparent), /* @embed */ url('themes/apex/images/icons/check.svg');
+  background-image:      -o-linear-gradient(transparent, transparent), url('themes/apex/images/icons/check.png');
+  background-size: contain;
+  background-position: center center;
+  background-repeat: no-repeat;
 }
 .oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
-       background-color: #e1f3ff;
+  background-color: #e1f3ff;
 }
 .oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
-       color: #ccc;
+  color: #ccc;
 }
 .oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-menuToolGroup.oo-ui-widget-disabled {
-       color: #ccc;
-       border-color: rgba(0, 0, 0, 0.05);
+  color: #ccc;
+  border-color: rgba(0, 0, 0, 0.05);
 }
 .oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
 .oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-toolbar {
-       clear: both;
+  clear: both;
 }
 .oo-ui-toolbar-bar {
-       line-height: 1;
-       position: relative;
+  line-height: 1;
+  position: relative;
 }
 .oo-ui-toolbar-tools,
 .oo-ui-toolbar-actions,
 .oo-ui-toolbar-shadow {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-toolbar-tools {
-       display: inline;
-       white-space: nowrap;
+  display: inline;
+  white-space: nowrap;
 }
 .oo-ui-toolbar-narrow .oo-ui-toolbar-tools {
-       white-space: normal;
+  white-space: normal;
 }
 .oo-ui-toolbar-tools .oo-ui-tool {
-       white-space: normal;
+  white-space: normal;
 }
 .oo-ui-toolbar-actions {
-       float: right;
+  float: right;
 }
 .oo-ui-toolbar-actions .oo-ui-toolbar {
-       display: inline-block;
+  display: inline-block;
 }
 .oo-ui-toolbar-actions .oo-ui-popupWidget {
-       -webkit-touch-callout: default;
-       -webkit-user-select: all;
-          -moz-user-select: all;
-           -ms-user-select: all;
-               user-select: all;
+  -webkit-touch-callout: default;
+  -webkit-user-select: all;
+     -moz-user-select: all;
+      -ms-user-select: all;
+          user-select: all;
 }
 .oo-ui-toolbar-shadow {
-       background-position: left top;
-       background-repeat: repeat-x;
-       position: absolute;
-       width: 100%;
-       pointer-events: none;
+  background-position: left top;
+  background-repeat: repeat-x;
+  position: absolute;
+  width: 100%;
+  pointer-events: none;
 }
 .oo-ui-toolbar-bar {
-       border-bottom: 1px solid #ccc;
-       background-color: #f8fbfd;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #f1f7fb));
-       background-image: -webkit-linear-gradient(top, #fff 0, #f1f7fb 100%);
-       background-image:    -moz-linear-gradient(top, #fff 0, #f1f7fb 100%);
-       background-image:         linear-gradient(to bottom, #fff 0, #f1f7fb 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffffffff\', endColorstr=\'#fff1f7fb\' )';
+  border-bottom: 1px solid #ccc;
+  background-color: #f8fbfd;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #F1F7FB));
+  background-image: -webkit-linear-gradient(top, #fff 0, #F1F7FB 100%);
+  background-image:    -moz-linear-gradient(top, #fff 0, #F1F7FB 100%);
+  background-image:         linear-gradient(to bottom, #fff 0, #F1F7FB 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#fff1f7fb' )";
 }
 .oo-ui-toolbar-bar .oo-ui-toolbar-bar {
-       border: 0;
-       background: none;
+  border: 0;
+  background: none;
 }
 .oo-ui-toolbar-actions > .oo-ui-buttonElement-framed,
 .oo-ui-toolbar-actions > .oo-ui-buttonElement-framed:last-child {
-       margin-top: 0.4em;
-       margin-bottom: 0.4em;
-       margin-right: 0.5em;
+  margin-top: 0.4em;
+  margin-bottom: 0.4em;
+  margin-right: 0.5em;
 }
 .oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless.oo-ui-labelElement,
 .oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless:last-child.oo-ui-labelElement {
-       margin: 0;
+  margin: 0;
 }
 .oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button,
 .oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless:last-child.oo-ui-labelElement > .oo-ui-buttonElement-button {
-       margin: 0;
-       padding: 0 0.3125em;
+  margin: 0;
+  padding: 0 0.3125em;
 }
 .oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
 .oo-ui-toolbar-actions > .oo-ui-buttonElement-frameless:last-child.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       margin: 0 1em;
-       line-height: 3.40625em;
+  margin: 0 1em;
+  line-height: 3.40625em;
 }
 .oo-ui-toolbar-shadow {
-       background-image: /* @embed */ url(themes/apex/images/toolbar-shadow.png);
-       bottom: -9px;
-       height: 9px;
-       opacity: 0.5;
-       -webkit-transition: opacity 500ms ease;
-          -moz-transition: opacity 500ms ease;
-               transition: opacity 500ms ease;
+  background-image: /* @embed */ url(themes/apex/images/toolbar-shadow.png);
+  bottom: -9px;
+  height: 9px;
+  opacity: 0.5;
+  -webkit-transition: opacity 500ms ease;
+     -moz-transition: opacity 500ms ease;
+          transition: opacity 500ms ease;
 }
index a413005..cb9660a 100644 (file)
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:06Z
+ * Date: 2016-11-09T00:52:42Z
  */
 .oo-ui-tool.oo-ui-widget-enabled {
-       -webkit-transition: background-color 100ms;
-          -moz-transition: background-color 100ms;
-               transition: background-color 100ms;
+  -webkit-transition: background-color 100ms;
+     -moz-transition: background-color 100ms;
+          transition: background-color 100ms;
 }
 .oo-ui-tool.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-tool-title {
-       -webkit-transition: color 100ms;
-          -moz-transition: color 100ms;
-               transition: color 100ms;
+  -webkit-transition: color 100ms;
+     -moz-transition: color 100ms;
+          transition: color 100ms;
 }
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
-       z-index: 4;
+  z-index: 4;
 }
 .oo-ui-popupTool .oo-ui-popupWidget {
-       /* @noflip */
-       margin-left: 1.25em;
+  /* @noflip */
+  margin-left: 1.25em;
 }
 .oo-ui-toolGroupTool > .oo-ui-toolGroup {
-       border-right: 0;
+  border-right: 0;
 }
 .oo-ui-toolGroupTool > .oo-ui-popupToolGroup > .oo-ui-popupToolGroup-handle {
-       height: 2.5em;
-       padding: 0.3125em;
+  height: 2.5em;
+  padding: 0.3125em;
 }
 .oo-ui-toolGroupTool > .oo-ui-popupToolGroup > .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       height: 2.5em;
-       width: 1.875em;
+  height: 2.5em;
+  width: 1.875em;
 }
 .oo-ui-toolGroupTool > .oo-ui-popupToolGroup.oo-ui-labelElement > .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       line-height: 2.1;
+  line-height: 2.1;
 }
 .oo-ui-toolGroup {
-       display: inline-block;
-       vertical-align: middle;
-       border-right: 1px solid #c8ccd1;
+  display: inline-block;
+  vertical-align: middle;
+  border-right: 1px solid #c8ccd1;
 }
 .oo-ui-toolGroup-empty {
-       display: none;
+  display: none;
 }
 .oo-ui-toolGroup .oo-ui-tool-link {
-       text-decoration: none;
-       cursor: pointer;
+  text-decoration: none;
+  cursor: pointer;
 }
 .oo-ui-toolGroup.oo-ui-widget-disabled .oo-ui-tool-link,
 .oo-ui-toolGroup .oo-ui-widget-disabled > .oo-ui-tool-link {
-       outline: 0;
-       cursor: default;
+  outline: 0;
+  cursor: default;
 }
 .oo-ui-toolbar-actions .oo-ui-toolGroup {
-       border-right: 0;
-       border-left: 1px solid #9aa0a7;
+  border-right: 0;
+  border-left: 1px solid #c8ccd1;
 }
 .oo-ui-toolbar-narrow .oo-ui-toolGroup + .oo-ui-toolGroup {
-       margin-left: 0;
+  margin-left: 0;
 }
 .oo-ui-barToolGroup > .oo-ui-iconElement-icon,
 .oo-ui-barToolGroup > .oo-ui-labelElement-label {
-       display: none;
+  display: none;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool {
-       display: inline-block;
-       position: relative;
-       vertical-align: top;
+  display: inline-block;
+  position: relative;
+  vertical-align: top;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
-       display: block;
+  display: block;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-accel {
-       display: none;
+  display: none;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       display: inline-block;
-       vertical-align: top;
+  display: inline-block;
+  vertical-align: top;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement > .oo-ui-tool-link .oo-ui-tool-title {
-       display: none;
+  display: none;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-iconElement.oo-ui-tool-with-label > .oo-ui-tool-link .oo-ui-tool-title {
-       display: inline;
+  display: inline;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link {
-       height: 1.875em;
-       padding: 0.625em;
+  height: 1.875em;
+  padding: 0.625em;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       height: 1.875em;
-       width: 1.875em;
+  height: 1.875em;
+  width: 1.875em;
 }
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
-       line-height: 2.1;
-       padding: 0 0.4em;
+  line-height: 2.1;
+  padding: 0 0.4em;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled:hover {
-       background-color: #eaecf0;
+  background-color: #eaecf0;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled > .oo-ui-tool-link .oo-ui-tool-title {
-       color: #222;
-       -webkit-transition: color 100ms;
-          -moz-transition: color 100ms;
-               transition: color 100ms;
+  color: #222;
+  -webkit-transition: color 100ms;
+     -moz-transition: color 100ms;
+          transition: color 100ms;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled.oo-ui-tool-active {
-       background-color: #eaf3ff;
-       box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
+  background-color: #eaf3ff;
+  box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled.oo-ui-tool-active:hover {
-       background-color: rgba(41, 98, 204, 0.1);
+  background-color: rgba(41, 98, 204, 0.1);
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled > .oo-ui-toolGroup-tools > .oo-ui-tool.oo-ui-widget-enabled.oo-ui-tool-active > .oo-ui-tool-link .oo-ui-tool-title {
-       color: #36c;
+  color: #36c;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-tool-title,
 .oo-ui-barToolGroup.oo-ui-widget-disabled .oo-ui-tool > .oo-ui-tool-link .oo-ui-tool-title {
-       color: #72777d;
+  color: #72777d;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool.oo-ui-widget-disabled > .oo-ui-tool-link .oo-ui-iconElement-icon,
 .oo-ui-barToolGroup.oo-ui-widget-disabled .oo-ui-tool > .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.3;
+  opacity: 0.3;
 }
 .oo-ui-popupToolGroup {
-       position: relative;
-       height: 3.125em;
-       min-width: 2em;
+  position: relative;
+  height: 3.125em;
+  min-width: 2em;
 }
 .oo-ui-popupToolGroup-handle {
-       display: block;
-       cursor: pointer;
+  display: block;
+  cursor: pointer;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
 .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       position: absolute;
+  position: absolute;
 }
 .oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle {
-       outline: 0;
-       cursor: default;
+  outline: 0;
+  cursor: default;
 }
 .oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
-       display: none;
-       position: absolute;
-       z-index: 4;
+  display: none;
+  position: absolute;
+  z-index: 4;
 }
 .oo-ui-popupToolGroup-active.oo-ui-widget-enabled > .oo-ui-toolGroup-tools {
-       display: block;
+  display: block;
 }
 .oo-ui-popupToolGroup-left > .oo-ui-toolGroup-tools {
-       left: 0;
+  left: 0;
 }
 .oo-ui-popupToolGroup-right > .oo-ui-toolGroup-tools {
-       right: 0;
+  right: 0;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link {
-       display: table;
-       width: 100%;
-       vertical-align: middle;
-       white-space: nowrap;
+  display: table;
+  width: 100%;
+  vertical-align: middle;
+  white-space: nowrap;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon,
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel,
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-       display: table-cell;
-       vertical-align: middle;
+  display: table-cell;
+  vertical-align: middle;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
-       text-align: right;
+  text-align: right;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel:not( :empty ) {
-       padding-left: 3em;
+  padding-left: 3em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup {
-       min-width: 1.875em;
+  min-width: 1.875em;
 }
 .oo-ui-popupToolGroup.oo-ui-iconElement {
-       min-width: 3.125em;
+  min-width: 3.125em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-iconElement {
-       min-width: 2.5em;
+  min-width: 2.5em;
 }
 .oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
-       min-width: 4.375em;
+  min-width: 4.375em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
-       min-width: 3.75em;
+  min-width: 3.75em;
 }
 .oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       line-height: 2.6;
-       margin: 0 1em;
+  line-height: 2.6;
+  margin: 0 1em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin: 0 0.5em;
+  margin: 0 0.5em;
 }
 .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-left: 3em;
+  margin-left: 3em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-left: 2.5em;
+  margin-left: 2.5em;
 }
 .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-right: 2em;
+  margin-right: 2em;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup.oo-ui-labelElement.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-       margin-right: 1.75em;
+  margin-right: 1.75em;
 }
 .oo-ui-popupToolGroup-header {
-       line-height: 2.6;
-       margin: 0 0.6em;
-       font-weight: bold;
+  line-height: 2.6;
+  margin: 0 0.6em;
+  font-weight: bold;
 }
 .oo-ui-popupToolGroup-handle {
-       padding: 0.3125em;
-       height: 2.5em;
+  padding: 0.3125em;
+  height: 2.5em;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
-       width: 0.9375em;
-       height: 1.625em;
-       margin: 0.78125em 0.5em;
-       top: 0;
-       right: 0;
-       opacity: 0.3;
+  width: 0.9375em;
+  height: 1.625em;
+  margin: 0.78125em 0.5em;
+  top: 0;
+  right: 0;
+  opacity: 0.3;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
-       right: -0.3125em;
+  right: -0.3125em;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       width: 1.875em;
-       height: 2.6em;
-       margin: 0.25em;
-       top: 0;
-       left: 0.3125em;
-       opacity: 0.7;
+  width: 1.875em;
+  height: 2.6em;
+  margin: 0.25em;
+  top: 0;
+  left: 0.3125em;
+  opacity: 0.7;
 }
 .oo-ui-toolbar-narrow .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-       left: 0;
+  left: 0;
 }
 .oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
-       top: 3.125em;
-       margin: 0 -1px;
-       border: 1px solid #9aa0a7;
-       background-color: #fff;
-       box-shadow: 0 2px 3px rgba(0, 0, 0, 0.2);
-       min-width: 16em;
+  top: 3.125em;
+  margin: 0 -1px;
+  border: 1px solid #c8ccd1;
+  background-color: #fff;
+  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.2);
+  min-width: 16em;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link {
-       padding: 0.4em 0.625em;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  padding: 0.4em 0.625em;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-       height: 2.5em;
-       width: 1.875em;
-       min-width: 1.875em;
+  height: 2.5em;
+  width: 1.875em;
+  min-width: 1.875em;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title,
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
-       line-height: 2;
+  line-height: 2;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-       padding-left: 0.5em;
-       color: #222;
+  padding-left: 0.5em;
+  color: #222;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-accel {
-       color: #888;
+  color: #72777d;
 }
 .oo-ui-popupToolGroup.oo-ui-widget-enabled {
-       -webkit-transition: background-color 100ms, box-shadow 100ms;
-          -moz-transition: background-color 100ms, box-shadow 100ms;
-               transition: background-color 100ms, box-shadow 100ms;
+  -webkit-transition: background-color 100ms, box-shadow 100ms;
+     -moz-transition: background-color 100ms, box-shadow 100ms;
+          transition: background-color 100ms, box-shadow 100ms;
 }
 .oo-ui-popupToolGroup.oo-ui-widget-enabled.oo-ui-popupToolGroup-active {
-       box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
-       background-color: #eaecf0;
+  box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
+  background-color: #eaecf0;
 }
 .oo-ui-popupToolGroup.oo-ui-widget-enabled.oo-ui-popupToolGroup-active .oo-ui-tool-active.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-tool-title {
-       color: #36c;
+  color: #36c;
 }
 .oo-ui-popupToolGroup.oo-ui-widget-enabled-handle:hover {
-       background-color: #eaecf0;
+  background-color: #eaecf0;
 }
 .oo-ui-popupToolGroup.oo-ui-widget-enabled-handle:active {
-       background-color: #eaf3ff;
+  background-color: #eaf3ff;
 }
 .oo-ui-listToolGroup .oo-ui-tool {
-       display: block;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  display: block;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
-       background-color: #eaecf0;
+  background-color: #eaecf0;
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover .oo-ui-tool-link .oo-ui-iconElement-icon {
-       opacity: 0.9;
+  opacity: 0.9;
 }
 .oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled {
-       background-color: #eaf3ff;
+  background-color: #eaf3ff;
 }
 .oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled:first-child {
-       box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
+  box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
 }
 .oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled:hover {
-       background-color: rgba(41, 98, 204, 0.1);
+  background-color: rgba(41, 98, 204, 0.1);
 }
 .oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-tool-title {
-       color: #36c;
+  color: #36c;
 }
 .oo-ui-listToolGroup.oo-ui-widget-disabled,
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-title,
-.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-accel {
-       color: #72777d;
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-title {
+  color: #72777d;
 }
 .oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
 .oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon,
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-iconElement-icon {
-       opacity: 0.3;
+  opacity: 0.3;
 }
 .oo-ui-menuToolGroup .oo-ui-tool {
-       display: block;
+  display: block;
 }
 .oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
-       min-width: 10em;
+  min-width: 10em;
 }
 .oo-ui-toolbar-narrow .oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
-       min-width: 8.125em;
+  min-width: 8.125em;
 }
 .oo-ui-menuToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-       background-image: none;
+  background-image: none;
 }
 .oo-ui-menuToolGroup .oo-ui-tool-active .oo-ui-tool-link .oo-ui-iconElement-icon {
-       background-image: url('themes/mediawiki/images/icons/check-progressive.png');
-       background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url('themes/mediawiki/images/icons/check-progressive.svg');
-       background-image:         linear-gradient(transparent, transparent), /* @embed */ url('themes/mediawiki/images/icons/check-progressive.svg');
-       background-image:      -o-linear-gradient(transparent, transparent), url('themes/mediawiki/images/icons/check-progressive.png');
-       background-size: contain;
-       background-position: center center;
-       background-repeat: no-repeat;
+  background-image: url('themes/mediawiki/images/icons/check-progressive.png');
+  background-image: -webkit-linear-gradient(transparent, transparent), /* @embed */ url('themes/mediawiki/images/icons/check-progressive.svg');
+  background-image:         linear-gradient(transparent, transparent), /* @embed */ url('themes/mediawiki/images/icons/check-progressive.svg');
+  background-image:      -o-linear-gradient(transparent, transparent), url('themes/mediawiki/images/icons/check-progressive.png');
+  background-size: contain;
+  background-position: center center;
+  background-repeat: no-repeat;
 }
 .oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
-       background-color: rgba(41, 98, 204, 0.1);
+  background-color: rgba(41, 98, 204, 0.1);
 }
 .oo-ui-menuToolGroup .oo-ui-tool-name-menuTool.oo-ui-tool-active {
-       background-color: #eaf3ff;
+  background-color: #eaf3ff;
 }
 .oo-ui-menuToolGroup.oo-ui-widget-disabled,
 .oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-title {
-       color: #72777d;
+  color: #72777d;
 }
 .oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
 .oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon,
 .oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-iconElement-icon {
-       opacity: 0.3;
+  opacity: 0.3;
 }
 .oo-ui-toolbar {
-       clear: both;
+  clear: both;
 }
 .oo-ui-toolbar-bar {
-       line-height: 1;
-       position: relative;
+  line-height: 1;
+  position: relative;
 }
 .oo-ui-toolbar-tools,
 .oo-ui-toolbar-actions,
 .oo-ui-toolbar-shadow {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-toolbar-tools {
-       display: inline;
-       white-space: nowrap;
+  display: inline;
+  white-space: nowrap;
 }
 .oo-ui-toolbar-narrow .oo-ui-toolbar-tools {
-       white-space: normal;
+  white-space: normal;
 }
 .oo-ui-toolbar-tools .oo-ui-tool {
-       white-space: normal;
+  white-space: normal;
 }
 .oo-ui-toolbar-actions {
-       float: right;
+  float: right;
 }
 .oo-ui-toolbar-actions .oo-ui-toolbar {
-       display: inline-block;
+  display: inline-block;
 }
 .oo-ui-toolbar-actions .oo-ui-popupWidget {
-       -webkit-touch-callout: default;
-       -webkit-user-select: all;
-          -moz-user-select: all;
-           -ms-user-select: all;
-               user-select: all;
+  -webkit-touch-callout: default;
+  -webkit-user-select: all;
+     -moz-user-select: all;
+      -ms-user-select: all;
+          user-select: all;
 }
 .oo-ui-toolbar-shadow {
-       background-position: left top;
-       background-repeat: repeat-x;
-       position: absolute;
-       width: 100%;
-       pointer-events: none;
+  background-position: left top;
+  background-repeat: repeat-x;
+  position: absolute;
+  width: 100%;
+  pointer-events: none;
 }
 .oo-ui-toolbar-bar {
-       border-bottom: 1px solid #c8ccd1;
-       background-color: #fff;
-       box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
-       font-weight: 500;
-       color: #222;
+  border-bottom: 1px solid #c8ccd1;
+  background-color: #fff;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
+  font-weight: 500;
+  color: #222;
 }
 .oo-ui-toolbar-bar .oo-ui-toolbar-bar {
-       border-bottom: 0;
-       background-color: transparent;
-       box-shadow: none;
+  border-bottom: 0;
+  background-color: transparent;
+  box-shadow: none;
 }
 .oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement {
-       margin: 0;
+  margin: 0;
 }
 .oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button {
-       border: 0;
-       border-radius: 0;
-       padding: 0 0.3125em;
+  border: 0;
+  border-radius: 0;
+  padding: 0 0.3125em;
 }
 .oo-ui-toolbar-actions > .oo-ui-buttonElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-       margin: 0 1em;
-       line-height: 3.125em;
+  margin: 0 1em;
+  line-height: 3.125em;
 }
 .oo-ui-toolbar-actions > .oo-ui-toolbar:not( :last-child ) {
-       border-right: 1px solid #9aa0a7;
+  border-right: 1px solid #c8ccd1;
 }
index ba959cf..e17f511 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:02Z
+ * Date: 2016-11-09T00:52:37Z
  */
 ( function ( OO ) {
 
@@ -320,6 +320,7 @@ OO.ui.Toolbar = function OoUiToolbar( toolFactory, toolGroupFactory, config ) {
        this.$bar = $( '<div>' );
        this.$actions = $( '<div>' );
        this.initialized = false;
+       this.narrowThreshold = null;
        this.onWindowResizeHandler = this.onWindowResize.bind( this );
 
        // Events
@@ -402,10 +403,24 @@ OO.ui.Toolbar.prototype.onPointerDown = function ( e ) {
 OO.ui.Toolbar.prototype.onWindowResize = function () {
        this.$element.toggleClass(
                'oo-ui-toolbar-narrow',
-               this.$bar.width() <= this.narrowThreshold
+               this.$bar.width() <= this.getNarrowThreshold()
        );
 };
 
+/**
+ * Get the (lazily-computed) width threshold for applying the oo-ui-toolbar-narrow
+ * class.
+ *
+ * @private
+ * @return {number} Width threshold in pixels
+ */
+OO.ui.Toolbar.prototype.getNarrowThreshold = function () {
+       if ( this.narrowThreshold === null ) {
+               this.narrowThreshold = this.$group.width() + this.$actions.width();
+       }
+       return this.narrowThreshold;
+};
+
 /**
  * Sets up handles and preloads required information for the toolbar to work.
  * This must be called after it is attached to a visible document and before doing anything else.
@@ -413,7 +428,6 @@ OO.ui.Toolbar.prototype.onWindowResize = function () {
 OO.ui.Toolbar.prototype.initialize = function () {
        if ( !this.initialized ) {
                this.initialized = true;
-               this.narrowThreshold = this.$group.width() + this.$actions.width();
                $( this.getElementWindow() ).on( 'resize', this.onWindowResizeHandler );
                this.onWindowResize();
        }
@@ -1896,6 +1910,8 @@ OO.ui.PopupToolGroup.prototype.onHandleMouseKeyDown = function ( e ) {
  *
  * When active, the popup is visible. A mouseup event anywhere in the document will trigger
  * deactivation.
+ *
+ * @param {boolean} value The active state to set
  */
 OO.ui.PopupToolGroup.prototype.setActive = function ( value ) {
        var containerWidth, containerLeft;
index bd8034d..d6ba00b 100644 (file)
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:06Z
+ * Date: 2016-11-09T00:52:42Z
  */
 .oo-ui-draggableElement-handle,
 .oo-ui-draggableElement-handle.oo-ui-widget {
-       cursor: move;
-       cursor: url(images/grab.cur );
-       cursor: -webkit-grab;
-       cursor:    -moz-grab;
-       cursor:         grab;
+  cursor: move;
+  cursor: url(images/grab.cur );
+  cursor: -webkit-grab;
+  cursor:    -moz-grab;
+  cursor:         grab;
 }
 .oo-ui-draggableElement-handle:active {
-       cursor: url(images/grabbing.cur );
-       cursor: -webkit-grabbing;
-       cursor:    -moz-grabbing;
-       cursor:         grabbing;
+  cursor: url(images/grabbing.cur );
+  cursor: -webkit-grabbing;
+  cursor:    -moz-grabbing;
+  cursor:         grabbing;
 }
 .oo-ui-draggableElement-handle.oo-ui-widget-disabled,
 .oo-ui-widget-disabled .oo-ui-draggableElement-handle {
-       cursor: default;
+  cursor: default;
 }
 .oo-ui-draggableElement-placeholder {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-draggableGroupElement-horizontal .oo-ui-draggableElement {
-       display: inline-block;
+  display: inline-block;
 }
 .oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous > .oo-ui-panelLayout-scrollable {
-       overflow-y: hidden;
+  overflow-y: hidden;
 }
 .oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
-       width: 100%;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  width: 100%;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-scrollable {
-       overflow-y: auto;
+  overflow-y: auto;
 }
 .oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-padded {
-       padding: 2em;
+  padding: 2em;
 }
 .oo-ui-bookletLayout-outlinePanel-editable > .oo-ui-outlineSelectWidget {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 3em;
-       overflow-y: auto;
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 3em;
+  overflow-y: auto;
 }
 .oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
-       position: absolute;
-       bottom: 0;
-       left: 0;
-       right: 0;
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
 }
 .oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
-       padding: 1.5em;
+  padding: 1.5em;
 }
 .oo-ui-bookletLayout-outlinePanel {
-       border-right: 1px solid #ddd;
+  border-right: 1px solid #ddd;
 }
 .oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
-       box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.25);
+  box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.25);
 }
 .oo-ui-indexLayout > .oo-ui-menuLayout-menu {
-       height: 3em;
+  height: 3em;
 }
 .oo-ui-indexLayout > .oo-ui-menuLayout-content {
-       top: 3em;
+  top: 3em;
 }
 .oo-ui-indexLayout-stackLayout > .oo-ui-panelLayout {
-       padding: 1.5em;
+  padding: 1.5em;
 }
 .oo-ui-menuLayout {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 0;
-       /* stylelint-disable declaration-no-important */
-       /* stylelint-enable declaration-no-important */
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  /* stylelint-disable declaration-no-important */
+  /* stylelint-enable declaration-no-important */
 }
 .oo-ui-menuLayout-menu,
 .oo-ui-menuLayout-content {
-       position: absolute;
-       -webkit-transition: all 200ms ease;
-          -moz-transition: all 200ms ease;
-               transition: all 200ms ease;
+  position: absolute;
+  -webkit-transition: all 200ms ease;
+     -moz-transition: all 200ms ease;
+          transition: all 200ms ease;
 }
 .oo-ui-menuLayout-menu {
-       height: 18em;
-       width: 18em;
+  height: 18em;
+  width: 18em;
 }
 .oo-ui-menuLayout-content {
-       top: 18em;
-       left: 18em;
-       right: 18em;
-       bottom: 18em;
+  top: 18em;
+  left: 18em;
+  right: 18em;
+  bottom: 18em;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-menu {
-       width: 0 !important;
-       height: 0 !important;
-       overflow: hidden;
+  width: 0 !important;
+  height: 0 !important;
+  overflow: hidden;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-content {
-       top: 0 !important;
-       left: 0 !important;
-       right: 0 !important;
-       bottom: 0 !important;
+  top: 0 !important;
+  left: 0 !important;
+  right: 0 !important;
+  bottom: 0 !important;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-menu {
-       width: auto !important;
-       left: 0;
-       top: 0;
-       right: 0;
+  width: auto !important;
+  left: 0;
+  top: 0;
+  right: 0;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-content {
-       right: 0 !important;
-       bottom: 0 !important;
-       left: 0 !important;
+  right: 0 !important;
+  bottom: 0 !important;
+  left: 0 !important;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-menu {
-       height: auto !important;
-       top: 0;
-       right: 0;
-       bottom: 0;
+  height: auto !important;
+  top: 0;
+  right: 0;
+  bottom: 0;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-content {
-       bottom: 0 !important;
-       left: 0 !important;
-       top: 0 !important;
+  bottom: 0 !important;
+  left: 0 !important;
+  top: 0 !important;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-menu {
-       width: auto !important;
-       right: 0;
-       bottom: 0;
-       left: 0;
+  width: auto !important;
+  right: 0;
+  bottom: 0;
+  left: 0;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-content {
-       left: 0 !important;
-       top: 0 !important;
-       right: 0 !important;
+  left: 0 !important;
+  top: 0 !important;
+  right: 0 !important;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-menu {
-       height: auto !important;
-       bottom: 0;
-       left: 0;
-       top: 0;
+  height: auto !important;
+  bottom: 0;
+  left: 0;
+  top: 0;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-content {
-       top: 0 !important;
-       right: 0 !important;
-       bottom: 0 !important;
+  top: 0 !important;
+  right: 0 !important;
+  bottom: 0 !important;
 }
 .oo-ui-stackLayout-continuous > .oo-ui-panelLayout {
-       display: block;
-       position: relative;
+  display: block;
+  position: relative;
 }
 .oo-ui-buttonSelectWidget {
-       display: inline-block;
-       white-space: nowrap;
-       border-radius: 0.3em;
-       margin-right: 0.5em;
+  display: inline-block;
+  white-space: nowrap;
+  border-radius: 0.3em;
+  margin-right: 0.5em;
 }
 .oo-ui-buttonSelectWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
-       border-radius: 0;
-       margin-left: -1px;
+  border-radius: 0;
+  margin-left: -1px;
 }
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonElement-button {
-       border-bottom-left-radius: 0.3em;
-       border-top-left-radius: 0.3em;
-       margin-left: 0;
+  border-bottom-left-radius: 0.3em;
+  border-top-left-radius: 0.3em;
+  margin-left: 0;
 }
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:last-child .oo-ui-buttonElement-button {
-       border-bottom-right-radius: 0.3em;
-       border-top-right-radius: 0.3em;
+  border-bottom-right-radius: 0.3em;
+  border-top-right-radius: 0.3em;
 }
 .oo-ui-buttonOptionWidget {
-       display: inline-block;
-       padding: 0;
-       background-color: transparent;
+  display: inline-block;
+  padding: 0;
+  background-color: transparent;
 }
 .oo-ui-buttonOptionWidget.oo-ui-buttonElement-active .oo-ui-buttonElement-button {
-       cursor: default;
+  cursor: default;
 }
 .oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       position: static;
-       display: inline-block;
-       vertical-align: middle;
+  position: static;
+  display: inline-block;
+  vertical-align: middle;
 }
 .oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected,
 .oo-ui-buttonOptionWidget.oo-ui-optionWidget-pressed,
 .oo-ui-buttonOptionWidget.oo-ui-optionWidget-highlighted {
-       background-color: transparent;
+  background-color: transparent;
 }
 .oo-ui-toggleButtonWidget {
-       margin-right: 0.5em;
+  margin-right: 0.5em;
 }
 .oo-ui-toggleButtonWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-toggleSwitchWidget {
-       position: relative;
-       display: inline-block;
-       vertical-align: middle;
-       overflow: hidden;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       -webkit-transform: translateZ(0);
-          -moz-transform: translateZ(0);
-           -ms-transform: translateZ(0);
-               transform: translateZ(0);
-       height: 2em;
-       width: 4em;
-       border-radius: 1em;
-       box-shadow: 0 0 0 #fff, inset 0 0.1em 0.2em #ddd;
-       border: 1px solid #ccc;
-       margin-right: 0.5em;
-       background-color: #eee;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ddd), color-stop(100%, #fff));
-       background-image: -webkit-linear-gradient(top, #ddd 0, #fff 100%);
-       background-image:    -moz-linear-gradient(top, #ddd 0, #fff 100%);
-       background-image:         linear-gradient(to bottom, #ddd 0, #fff 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffdddddd\', endColorstr=\'#ffffffff\' )';
+  position: relative;
+  display: inline-block;
+  vertical-align: middle;
+  overflow: hidden;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  -webkit-transform: translateZ(0);
+     -moz-transform: translateZ(0);
+      -ms-transform: translateZ(0);
+          transform: translateZ(0);
+  height: 2em;
+  width: 4em;
+  border-radius: 1em;
+  box-shadow: 0 0 0 #fff, inset 0 0.1em 0.2em #ddd;
+  border: 1px solid #ccc;
+  margin-right: 0.5em;
+  background-color: #eeeeee;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #ddd), color-stop(100%, #fff));
+  background-image: -webkit-linear-gradient(top, #ddd 0, #fff 100%);
+  background-image:    -moz-linear-gradient(top, #ddd 0, #fff 100%);
+  background-image:         linear-gradient(to bottom, #ddd 0, #fff 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffdddddd', endColorstr='#ffffffff' )";
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled {
-       cursor: pointer;
+  cursor: pointer;
 }
 .oo-ui-toggleSwitchWidget-grip {
-       position: absolute;
-       display: block;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  position: absolute;
+  display: block;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-toggleSwitchWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
-       opacity: 0.5;
+  opacity: 0.5;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover,
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover .oo-ui-toggleSwitchWidget-grip {
-       border-color: #aaa;
+  border-color: #aaa;
 }
 .oo-ui-toggleSwitchWidget-grip {
-       top: 0.25em;
-       left: 0.25em;
-       width: 1.5em;
-       height: 1.5em;
-       margin-top: -1px;
-       border-radius: 1em;
-       box-shadow: 0 0.1em 0.25em rgba(0, 0, 0, 0.1);
-       border: 1px #c9c9c9 solid;
-       -webkit-transition: left 250ms ease, margin-left 250ms ease;
-          -moz-transition: left 250ms ease, margin-left 250ms ease;
-               transition: left 250ms ease, margin-left 250ms ease;
-       background-color: #eee;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
-       background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
-       background-image:    -moz-linear-gradient(top, #fff 0, #ddd 100%);
-       background-image:         linear-gradient(to bottom, #fff 0, #ddd 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffffffff\', endColorstr=\'#ffdddddd\' )';
+  top: 0.25em;
+  left: 0.25em;
+  width: 1.5em;
+  height: 1.5em;
+  margin-top: -1px;
+  border-radius: 1em;
+  box-shadow: 0 0.1em 0.25em rgba(0, 0, 0, 0.1);
+  border: 1px #c9c9c9 solid;
+  -webkit-transition: left 250ms ease, margin-left 250ms ease;
+     -moz-transition: left 250ms ease, margin-left 250ms ease;
+          transition: left 250ms ease, margin-left 250ms ease;
+  background-color: #eeeeee;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
+  background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
+  background-image:    -moz-linear-gradient(top, #fff 0, #ddd 100%);
+  background-image:         linear-gradient(to bottom, #fff 0, #ddd 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
 }
 .oo-ui-toggleSwitchWidget-glow {
-       position: absolute;
-       top: 0;
-       bottom: 0;
-       right: 0;
-       left: 0;
-       border-radius: 1em;
-       box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
-       -webkit-transition: opacity 250ms ease;
-          -moz-transition: opacity 250ms ease;
-               transition: opacity 250ms ease;
-       background-color: #cde7f4;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #b0d9ee), color-stop(100%, #eaf4fa));
-       background-image: -webkit-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
-       background-image:    -moz-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
-       background-image:         linear-gradient(to bottom, #b0d9ee 0, #eaf4fa 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffb0d9ee\', endColorstr=\'#ffeaf4fa\' )';
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  right: 0;
+  left: 0;
+  border-radius: 1em;
+  box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
+  -webkit-transition: opacity 250ms ease;
+     -moz-transition: opacity 250ms ease;
+          transition: opacity 250ms ease;
+  background-color: #cde7f4;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #b0d9ee), color-stop(100%, #eaf4fa));
+  background-image: -webkit-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
+  background-image:    -moz-linear-gradient(top, #b0d9ee 0, #eaf4fa 100%);
+  background-image:         linear-gradient(to bottom, #b0d9ee 0, #eaf4fa 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffb0d9ee', endColorstr='#ffeaf4fa' )";
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow {
-       opacity: 0;
+  opacity: 0;
 }
 .oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-grip {
-       left: 0.25em;
-       margin-left: 0;
+  left: 0.25em;
+  margin-left: 0;
 }
 .oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-glow {
-       opacity: 1;
+  opacity: 1;
 }
 .oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
-       left: 2.25em;
-       margin-left: -2px;
+  left: 2.25em;
+  margin-left: -2px;
 }
 .oo-ui-selectFileWidget {
-       display: inline-block;
-       vertical-align: middle;
-       width: 100%;
-       max-width: 50em;
-       margin-right: 0.5em;
+  display: inline-block;
+  vertical-align: middle;
+  width: 100%;
+  max-width: 50em;
+  margin-right: 0.5em;
 }
 .oo-ui-selectFileWidget-selectButton {
-       display: table-cell;
+  display: table-cell;
 }
 .oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-       position: relative;
-       overflow: hidden;
+  position: relative;
+  overflow: hidden;
 }
 .oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button > [type='file'] {
-       position: absolute;
-       top: 0;
-       bottom: 0;
-       left: 0;
-       right: 0;
-       width: 100%;
-       height: 100%;
-       opacity: 0;
-       z-index: 1;
-       cursor: pointer;
-       padding-top: 100px;
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  width: 100%;
+  height: 100%;
+  opacity: 0;
+  z-index: 1;
+  cursor: pointer;
+  padding-top: 100px;
 }
 .oo-ui-selectFileWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > [type='file'] {
-       display: none;
+  display: none;
 }
 .oo-ui-selectFileWidget-info {
-       width: 100%;
-       display: table-cell;
-       vertical-align: middle;
-       position: relative;
-       overflow: hidden;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  width: 100%;
+  display: table-cell;
+  vertical-align: middle;
+  position: relative;
+  overflow: hidden;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
 .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-       position: absolute;
+  position: absolute;
 }
 .oo-ui-widget-disabled .oo-ui-selectFileWidget-info {
-       cursor: default;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  cursor: default;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-selectFileWidget-label {
-       position: absolute;
-       top: 0;
-       bottom: 0;
-       left: 0;
-       right: 0;
-       text-overflow: ellipsis;
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  text-overflow: ellipsis;
 }
 .oo-ui-selectFileWidget-clearButton {
-       position: absolute;
-       z-index: 2;
+  position: absolute;
+  z-index: 2;
 }
 .oo-ui-selectFileWidget-dropTarget {
-       position: relative;
-       cursor: default;
-       height: 8.815em;
+  position: relative;
+  cursor: default;
+  height: 8.815em;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-dropLabel,
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton,
 .oo-ui-selectFileWidget-dropTarget .oo-ui-iconElement-icon {
-       display: none;
+  display: none;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail {
-       width: 7.815em;
-       position: absolute;
-       top: 0.5em;
-       bottom: 0.5em;
-       left: 0.5em;
-       background-position: center center;
-       background-repeat: no-repeat;
-       background-size: contain;
+  width: 7.815em;
+  position: absolute;
+  top: 0.5em;
+  bottom: 0.5em;
+  left: 0.5em;
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-size: contain;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail.oo-ui-pendingElement-pending {
-       background-repeat: repeat;
-       background-size: auto;
+  background-repeat: repeat;
+  background-size: auto;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail > .oo-ui-selectFileWidget-noThumbnail-icon {
-       opacity: 0.4;
-       height: 7.815em;
-       width: 7.815em;
+  opacity: 0.4;
+  height: 7.815em;
+  width: 7.815em;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
-       display: block;
-       height: 100%;
-       width: auto;
-       margin-left: 8.815em;
-       border: 0;
+  display: block;
+  height: 100%;
+  width: auto;
+  margin-left: 8.815em;
+  border: 0;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
-       display: block;
-       position: relative;
-       top: inherit;
+  display: block;
+  position: relative;
+  top: inherit;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-fileName {
-       display: block;
-       padding-top: 0.5em;
-       padding-right: 2.375em;
+  display: block;
+  padding-top: 0.5em;
+  padding-right: 2.375em;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-clearButton {
-       right: 0.5em;
+  right: 0.5em;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail,
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
-       display: none;
+  display: none;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton {
-       display: block;
-       margin: 2.2em 1em 1em;
+  display: block;
+  margin: 2.2em 1em 1em;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget,
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
-       text-align: center;
+  text-align: center;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info,
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
-       margin: 0;
+  margin: 0;
 }
 .oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-clearButton,
 .oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-clearButton {
-       display: none;
+  display: none;
+}
+.oo-ui-selectFileWidget-empty.oo-ui-widget-enabled .oo-ui-selectFileWidget-label {
+  cursor: default;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropLabel {
-       display: block;
+  display: block;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: 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;
+  cursor: no-drop;
 }
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
-       height: auto;
+  height: auto;
 }
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
-       padding: 1em;
+  padding: 1em;
 }
 .oo-ui-selectFileWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-       border-radius: 0 0.25em 0.25em 0;
+  border-radius: 0 0.25em 0.25em 0;
 }
 .oo-ui-selectFileWidget-info {
-       height: 2.4em;
-       background-color: #fff;
-       border: 1px solid rgba(0, 0, 0, 0.1);
-       border-radius: 0.25em 0 0 0.25em;
-       border-width: 1px 0 1px 1px;
+  height: 2.4em;
+  background-color: #fff;
+  border: 1px solid rgba(0, 0, 0, 0.1);
+  border-radius: 0.25em 0 0 0.25em;
+  border-width: 1px 0 1px 1px;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-       top: 0;
-       left: 0;
-       height: 2.3em;
-       margin-left: 0.3em;
+  top: 0;
+  left: 0;
+  height: 2.3em;
+  margin-left: 0.3em;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-       top: 0;
-       right: 0;
-       height: 2.3em;
-       margin-right: 0.775em;
+  top: 0;
+  right: 0;
+  height: 2.3em;
+  margin-right: 0.775em;
 }
 .oo-ui-selectFileWidget-label {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       left: 0.5em;
-       right: 2.175em;
-       line-height: 2.3em;
-       margin: 0;
-       overflow: hidden;
-       white-space: nowrap;
-       text-overflow: ellipsis;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  left: 0.5em;
+  right: 2.175em;
+  line-height: 2.3em;
+  margin: 0;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
 }
 .oo-ui-selectFileWidget-clearButton {
-       top: 0;
-       right: 0;
-       width: 1.875em;
-       margin-right: 0;
+  top: 0;
+  right: 0;
+  width: 1.875em;
+  margin-right: 0;
 }
 .oo-ui-selectFileWidget-clearButton .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       height: 2.3em;
+  height: 2.3em;
 }
 .oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-label {
-       color: #ccc;
+  color: #ccc;
 }
 .oo-ui-selectFileWidget.oo-ui-iconElement .oo-ui-selectFileWidget-label {
-       left: 2.475em;
+  left: 2.475em;
 }
 .oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-label {
-       right: 4.2625em;
+  right: 4.2625em;
 }
 .oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-clearButton {
-       right: 2.0875em;
+  right: 2.0875em;
 }
 .oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-label,
 .oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-label {
-       right: 0.5em;
+  right: 0.5em;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-indicatorElement .oo-ui-selectFileWidget-label,
 .oo-ui-selectFileWidget-notsupported.oo-ui-indicatorElement .oo-ui-selectFileWidget-label,
 .oo-ui-selectFileWidget-empty.oo-ui-indicatorElement .oo-ui-selectFileWidget-label,
 .oo-ui-selectFileWidget-notsupported.oo-ui-indicatorElement .oo-ui-selectFileWidget-label {
-       right: 2em;
+  right: 2em;
 }
 .oo-ui-selectFileWidget-supported.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop.oo-ui-selectFileWidget-dropTarget {
-       background-color: #e1f3ff;
+  background-color: #e1f3ff;
 }
 .oo-ui-selectFileWidget-dropTarget {
-       background-color: #fff;
-       border: 1px solid #aaa;
-       vertical-align: middle;
-       border-radius: 0.25em;
+  background-color: #fff;
+  border: 1px solid #aaa;
+  vertical-align: middle;
+  border-radius: 0.25em;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-       border-radius: 0.25em;
+  border-radius: 0.25em;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
-       line-height: 1.4;
-       overflow: inherit;
-       white-space: normal;
+  line-height: 1.4;
+  overflow: inherit;
+  white-space: normal;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget {
-       border-style: dashed;
+  border-style: dashed;
 }
 .oo-ui-selectFileWidget.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
 .oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
-       background-color: #f3f3f3;
-       color: #ccc;
-       border-color: #ddd;
-       text-shadow: 0 1px 1px #fff;
+  background-color: #f3f3f3;
+  color: #ccc;
+  border-color: #ddd;
+  text-shadow: 0 1px 1px #fff;
 }
 .oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info,
 .oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info,
 .oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info {
-       background-color: #f3f3f3;
-       color: #ccc;
-       border-color: #ddd;
-       text-shadow: 0 1px 1px #fff;
+  background-color: #f3f3f3;
+  color: #ccc;
+  border-color: #ddd;
+  text-shadow: 0 1px 1px #fff;
 }
 .oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
 .oo-ui-selectFileWidget-empty.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-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
 .oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-outlineOptionWidget {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-       font-size: 1.1em;
-       padding: 0.75em;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+  font-size: 1.1em;
+  padding: 0.75em;
 }
 .oo-ui-outlineOptionWidget .oo-ui-iconElement-icon {
-       font-size: 90.90909%;
+  font-size: 90.90909%;
 }
 .oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
-       padding-right: 1.5em;
+  padding-right: 1.5em;
 }
 .oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       opacity: 0.5;
+  opacity: 0.5;
 }
 .oo-ui-outlineOptionWidget-level-0 {
-       padding-left: 3.5em;
+  padding-left: 3.5em;
 }
 .oo-ui-outlineOptionWidget-level-0 .oo-ui-iconElement-icon {
-       left: 1em;
+  left: 1em;
 }
 .oo-ui-outlineOptionWidget-level-1 {
-       padding-left: 5em;
+  padding-left: 5em;
 }
 .oo-ui-outlineOptionWidget-level-1 .oo-ui-iconElement-icon {
-       left: 2.5em;
+  left: 2.5em;
 }
 .oo-ui-outlineOptionWidget-level-2 {
-       padding-left: 6.5em;
+  padding-left: 6.5em;
 }
 .oo-ui-outlineOptionWidget-level-2 .oo-ui-iconElement-icon {
-       left: 4em;
+  left: 4em;
 }
 .oo-ui-selectWidget-depressed .oo-ui-outlineOptionWidget.oo-ui-optionWidget-selected {
-       background-color: #a7dcff;
-       text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
+  background-color: #a7dcff;
+  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
 }
 .oo-ui-outlineOptionWidget.oo-ui-flaggedElement-important {
-       font-weight: bold;
+  font-weight: bold;
 }
 .oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
-       opacity: 0.5;
+  opacity: 0.5;
 }
 .oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
-       color: #777;
+  color: #777;
 }
 .oo-ui-outlineControlsWidget {
-       height: 3em;
-       background-color: #fff;
+  height: 3em;
+  background-color: #fff;
 }
 .oo-ui-outlineControlsWidget-items,
 .oo-ui-outlineControlsWidget-movers {
-       float: left;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  float: left;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-       float: left;
-       background-position: right center;
+  float: left;
+  background-position: right center;
 }
 .oo-ui-outlineControlsWidget-items {
-       float: left;
+  float: left;
 }
 .oo-ui-outlineControlsWidget-items .oo-ui-buttonWidget {
-       float: left;
+  float: left;
 }
 .oo-ui-outlineControlsWidget-movers {
-       float: right;
+  float: right;
 }
 .oo-ui-outlineControlsWidget-movers .oo-ui-buttonWidget {
-       float: right;
+  float: right;
 }
 .oo-ui-outlineControlsWidget-items,
 .oo-ui-outlineControlsWidget-movers {
-       height: 2em;
-       margin: 0.5em 0.5em 0.5em 0;
-       padding: 0;
+  height: 2em;
+  margin: 0.5em 0.5em 0.5em 0;
+  padding: 0;
 }
 .oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-       width: 1.5em;
-       height: 2em;
-       margin: 0.5em 0 0.5em 0.5em;
-       opacity: 0.2;
+  width: 1.5em;
+  height: 2em;
+  margin: 0.5em 0 0.5em 0.5em;
+  opacity: 0.2;
 }
 .oo-ui-tabSelectWidget {
-       text-align: left;
-       white-space: nowrap;
-       overflow: hidden;
-       background-color: #eee;
-       box-shadow: inset 0 -0.015em 0.1em rgba(0, 0, 0, 0.1);
+  text-align: left;
+  white-space: nowrap;
+  overflow: hidden;
+  background-color: #eee;
+  box-shadow: inset 0 -0.015em 0.1em rgba(0, 0, 0, 0.1);
 }
 .oo-ui-tabOptionWidget {
-       display: inline-block;
-       vertical-align: bottom;
-       padding: 0.5em 1em;
-       margin: 0.5em 0 0 0.75em;
-       border: 1px solid transparent;
-       border-bottom: 0;
-       border-top-left-radius: 0.5em;
-       border-top-right-radius: 0.5em;
+  display: inline-block;
+  vertical-align: bottom;
+  padding: 0.5em 1em;
+  margin: 0.5em 0 0 0.75em;
+  border: 1px solid transparent;
+  border-bottom: 0;
+  border-top-left-radius: 0.5em;
+  border-top-right-radius: 0.5em;
 }
 .oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
-       padding-right: 1.5em;
+  padding-right: 1.5em;
 }
 .oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       opacity: 0.5;
+  opacity: 0.5;
 }
 .oo-ui-selectWidget-pressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-pressed {
-       background-color: transparent;
+  background-color: transparent;
 }
 .oo-ui-tabOptionWidget.oo-ui-widget-enabled:hover {
-       background-color: rgba(255, 255, 255, 0.2);
-       border-color: #ddd;
+  background-color: rgba(255, 255, 255, 0.2);
+  border-color: #ddd;
 }
 .oo-ui-tabOptionWidget.oo-ui-widget-enabled:active {
-       background-color: #fff;
-       border-color: #ddd;
+  background-color: #fff;
+  border-color: #ddd;
 }
 .oo-ui-selectWidget-pressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
 .oo-ui-selectWidget-depressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
 .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected:hover {
-       background-color: #fff;
-       border-color: #ddd;
+  background-color: #fff;
+  border-color: #ddd;
 }
 .oo-ui-capsuleMultiselectWidget {
-       display: inline-block;
-       position: relative;
-       width: 100%;
-       max-width: 50em;
+  display: inline-block;
+  position: relative;
+  width: 100%;
+  max-width: 50em;
 }
 .oo-ui-capsuleMultiselectWidget-handle {
-       width: 100%;
-       display: block;
-       position: relative;
+  width: 100%;
+  display: block;
+  position: relative;
 }
 .oo-ui-capsuleMultiselectWidget-content {
-       position: relative;
+  position: relative;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-content > input {
-       display: none;
+  display: none;
 }
 .oo-ui-capsuleMultiselectWidget-group {
-       display: inline;
+  display: inline;
 }
 .oo-ui-capsuleMultiselectWidget-handle {
-       background-color: #fff;
-       cursor: text;
-       min-height: 2.4em;
-       margin-right: 0.5em;
-       padding: 0.15em 0.25em;
-       border: 1px solid rgba(0, 0, 0, 0.1);
-       border-radius: 0.25em;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  background-color: #fff;
+  cursor: text;
+  min-height: 2.4em;
+  margin-right: 0.5em;
+  padding: 0.15em 0.25em;
+  border: 1px solid rgba(0, 0, 0, 0.1);
+  border-radius: 0.25em;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-capsuleMultiselectWidget-handle:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator,
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon {
-       position: absolute;
+  position: absolute;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input {
-       border: 0;
-       line-height: 1.675em;
-       margin: 0;
-       margin-left: 0.2em;
-       padding: 0;
-       font-size: inherit;
-       font-family: inherit;
-       background-color: transparent;
-       color: #000;
-       vertical-align: middle;
+  border: 0;
+  line-height: 1.675em;
+  margin: 0;
+  margin-left: 0.2em;
+  padding: 0;
+  font-size: inherit;
+  font-family: inherit;
+  background-color: transparent;
+  color: #000;
+  vertical-align: middle;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:focus {
-       outline: none;
+  outline: none;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle {
-       padding-right: 2.4875em;
+  padding-right: 2.4875em;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
-       right: 0;
-       top: 0;
-       margin: 0.775em;
+  right: 0;
+  top: 0;
+  margin: 0.775em;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-iconElement .oo-ui-capsuleMultiselectWidget-handle {
-       padding-left: 2.475em;
+  padding-left: 2.475em;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-iconElement .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon {
-       left: 0;
-       top: 0;
-       margin: 0.3em;
+  left: 0;
+  top: 0;
+  margin: 0.3em;
 }
 .oo-ui-capsuleMultiselectWidget:hover .oo-ui-capsuleMultiselectWidget-handle {
-       border-color: rgba(0, 0, 0, 0.2);
+  border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-handle {
-       color: #ccc;
-       text-shadow: 0 1px 1px #fff;
-       border-color: #ddd;
-       background-color: #f3f3f3;
-       cursor: default;
+  color: #ccc;
+  text-shadow: 0 1px 1px #fff;
+  border-color: #ddd;
+  background-color: #f3f3f3;
+  cursor: default;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon,
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-capsuleItemWidget {
-       position: relative;
-       display: inline-block;
-       cursor: default;
-       white-space: nowrap;
-       width: auto;
-       max-width: 100%;
-       -webkit-box-sizing: border-box;
-          -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: #eee;
-       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
-       background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
-       background-image:    -moz-linear-gradient(top, #fff 0, #ddd 100%);
-       background-image:         linear-gradient(to bottom, #fff 0, #ddd 100%);
-       -ms-filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffffffff\', endColorstr=\'#ffdddddd\' )';
-       border: 1px solid #ccc;
-       color: #555;
-       border-radius: 0.25em;
+  position: relative;
+  display: inline-block;
+  cursor: default;
+  white-space: nowrap;
+  width: auto;
+  max-width: 100%;
+  -webkit-box-sizing: border-box;
+     -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;
+  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #fff), color-stop(100%, #ddd));
+  background-image: -webkit-linear-gradient(top, #fff 0, #ddd 100%);
+  background-image:    -moz-linear-gradient(top, #fff 0, #ddd 100%);
+  background-image:         linear-gradient(to bottom, #fff 0, #ddd 100%);
+  -ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffffff', endColorstr='#ffdddddd' )";
+  border: 1px solid #ccc;
+  color: #555;
+  border-radius: 0.25em;
 }
 .oo-ui-capsuleItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: inline-block;
-       text-overflow: ellipsis;
-       overflow: hidden;
+  display: inline-block;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  cursor: text;
 }
 .oo-ui-capsuleItemWidget:focus {
-       outline: none;
-       border-color: #087ecc;
+  outline: none;
+  border-color: #087ecc;
 }
 .oo-ui-capsuleItemWidget.oo-ui-widget-disabled {
-       opacity: 0.5;
-       -webkit-transform: translate3d(0, 0, 0);
-       box-shadow: none;
-       color: #333;
-       background: #eee;
-       border-color: #ccc;
+  opacity: 0.5;
+  -webkit-transform: translate3d(0, 0, 0);
+  box-shadow: none;
+  color: #333;
+  background: #eee;
+  border-color: #ccc;
 }
 .oo-ui-capsuleItemWidget > .oo-ui-buttonElement {
-       margin-top: -1.25em;
-       padding-left: 0.3em;
+  margin-top: -1.25em;
+  padding-left: 0.3em;
 }
 .oo-ui-searchWidget-query {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
 }
 .oo-ui-searchWidget-query .oo-ui-textInputWidget {
-       width: 100%;
+  width: 100%;
 }
 .oo-ui-searchWidget-results {
-       position: absolute;
-       bottom: 0;
-       left: 0;
-       right: 0;
-       overflow-x: hidden;
-       overflow-y: auto;
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  overflow-x: hidden;
+  overflow-y: auto;
 }
 .oo-ui-searchWidget-query {
-       height: 4em;
-       padding: 0 1em;
-       box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.2);
+  height: 4em;
+  padding: 0 1em;
+  box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.2);
 }
 .oo-ui-searchWidget-query .oo-ui-textInputWidget {
-       margin: 0.75em 0;
+  margin: 0.75em 0;
 }
 .oo-ui-searchWidget-results {
-       top: 4em;
-       padding: 1em;
-       line-height: 0;
+  top: 4em;
+  padding: 1em;
+  line-height: 0;
 }
 .oo-ui-numberInputWidget {
-       display: inline-block;
-       position: relative;
-       max-width: 50em;
+  display: inline-block;
+  position: relative;
+  max-width: 50em;
 }
 .oo-ui-numberInputWidget-buttoned .oo-ui-buttonWidget,
 .oo-ui-numberInputWidget-buttoned .oo-ui-textInputWidget {
-       display: table-cell;
+  display: table-cell;
 }
 .oo-ui-numberInputWidget-buttoned .oo-ui-buttonElement-button {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-numberInputWidget-field {
-       display: table;
-       table-layout: fixed;
-       width: 100%;
+  display: table;
+  table-layout: fixed;
+  width: 100%;
 }
 .oo-ui-numberInputWidget-field > .oo-ui-buttonWidget {
-       width: 2.25em;
+  width: 2.25em;
 }
 .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;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+  border-right-width: 0;
 }
 .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;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+  border-left-width: 0;
 }
 .oo-ui-numberInputWidget-buttoned .oo-ui-textInputWidget input {
-       border-radius: 0;
+  border-radius: 0;
 }
index 126b591..bf50532 100644 (file)
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:06Z
+ * Date: 2016-11-09T00:52:42Z
  */
 .oo-ui-draggableElement-handle,
 .oo-ui-draggableElement-handle.oo-ui-widget {
-       cursor: move;
-       cursor: url(images/grab.cur );
-       cursor: -webkit-grab;
-       cursor:    -moz-grab;
-       cursor:         grab;
+  cursor: move;
+  cursor: url(images/grab.cur );
+  cursor: -webkit-grab;
+  cursor:    -moz-grab;
+  cursor:         grab;
 }
 .oo-ui-draggableElement-handle:active {
-       cursor: url(images/grabbing.cur );
-       cursor: -webkit-grabbing;
-       cursor:    -moz-grabbing;
-       cursor:         grabbing;
+  cursor: url(images/grabbing.cur );
+  cursor: -webkit-grabbing;
+  cursor:    -moz-grabbing;
+  cursor:         grabbing;
 }
 .oo-ui-draggableElement-handle.oo-ui-widget-disabled,
 .oo-ui-widget-disabled .oo-ui-draggableElement-handle {
-       cursor: default;
+  cursor: default;
 }
 .oo-ui-draggableElement-placeholder {
-       opacity: 0.2;
+  opacity: 0.2;
 }
 .oo-ui-draggableGroupElement-horizontal .oo-ui-draggableElement {
-       display: inline-block;
+  display: inline-block;
 }
 .oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous > .oo-ui-panelLayout-scrollable {
-       overflow-y: hidden;
+  overflow-y: hidden;
 }
 .oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
-       width: 100%;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  width: 100%;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-scrollable {
-       overflow-y: auto;
+  overflow-y: auto;
 }
 .oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout-padded {
-       padding: 2em;
+  padding: 2em;
 }
 .oo-ui-bookletLayout-outlinePanel-editable > .oo-ui-outlineSelectWidget {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 3em;
-       overflow-y: auto;
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 3em;
+  overflow-y: auto;
 }
 .oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
-       position: absolute;
-       bottom: 0;
-       left: 0;
-       right: 0;
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
 }
 .oo-ui-bookletLayout-stackLayout > .oo-ui-panelLayout {
-       padding: 1.5em;
+  padding: 1.5em;
 }
 .oo-ui-bookletLayout-outlinePanel {
-       border-right: 1px solid #ddd;
+  border-right: 1px solid #ddd;
 }
 .oo-ui-bookletLayout-outlinePanel > .oo-ui-outlineControlsWidget {
-       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
+  box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
 }
 .oo-ui-indexLayout > .oo-ui-menuLayout-menu {
-       height: 3em;
+  height: 3em;
 }
 .oo-ui-indexLayout > .oo-ui-menuLayout-content {
-       top: 3em;
+  top: 3em;
 }
 .oo-ui-indexLayout-stackLayout > .oo-ui-panelLayout {
-       padding: 1.5em;
+  padding: 1.5em;
 }
 .oo-ui-indexLayout > .oo-ui-menuLayout-menu {
-       height: 2.75em;
+  height: 2.75em;
 }
 .oo-ui-indexLayout > .oo-ui-menuLayout-content {
-       top: 2.75em;
+  top: 2.75em;
 }
 .oo-ui-menuLayout {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 0;
-       /* stylelint-disable declaration-no-important */
-       /* stylelint-enable declaration-no-important */
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  /* stylelint-disable declaration-no-important */
+  /* stylelint-enable declaration-no-important */
 }
 .oo-ui-menuLayout-menu,
 .oo-ui-menuLayout-content {
-       position: absolute;
-       -webkit-transition: all 200ms ease;
-          -moz-transition: all 200ms ease;
-               transition: all 200ms ease;
+  position: absolute;
+  -webkit-transition: all 200ms ease;
+     -moz-transition: all 200ms ease;
+          transition: all 200ms ease;
 }
 .oo-ui-menuLayout-menu {
-       height: 18em;
-       width: 18em;
+  height: 18em;
+  width: 18em;
 }
 .oo-ui-menuLayout-content {
-       top: 18em;
-       left: 18em;
-       right: 18em;
-       bottom: 18em;
+  top: 18em;
+  left: 18em;
+  right: 18em;
+  bottom: 18em;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-menu {
-       width: 0 !important;
-       height: 0 !important;
-       overflow: hidden;
+  width: 0 !important;
+  height: 0 !important;
+  overflow: hidden;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-hideMenu > .oo-ui-menuLayout-content {
-       top: 0 !important;
-       left: 0 !important;
-       right: 0 !important;
-       bottom: 0 !important;
+  top: 0 !important;
+  left: 0 !important;
+  right: 0 !important;
+  bottom: 0 !important;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-menu {
-       width: auto !important;
-       left: 0;
-       top: 0;
-       right: 0;
+  width: auto !important;
+  left: 0;
+  top: 0;
+  right: 0;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-top > .oo-ui-menuLayout-content {
-       right: 0 !important;
-       bottom: 0 !important;
-       left: 0 !important;
+  right: 0 !important;
+  bottom: 0 !important;
+  left: 0 !important;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-menu {
-       height: auto !important;
-       top: 0;
-       right: 0;
-       bottom: 0;
+  height: auto !important;
+  top: 0;
+  right: 0;
+  bottom: 0;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-after > .oo-ui-menuLayout-content {
-       bottom: 0 !important;
-       left: 0 !important;
-       top: 0 !important;
+  bottom: 0 !important;
+  left: 0 !important;
+  top: 0 !important;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-menu {
-       width: auto !important;
-       right: 0;
-       bottom: 0;
-       left: 0;
+  width: auto !important;
+  right: 0;
+  bottom: 0;
+  left: 0;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-bottom > .oo-ui-menuLayout-content {
-       left: 0 !important;
-       top: 0 !important;
-       right: 0 !important;
+  left: 0 !important;
+  top: 0 !important;
+  right: 0 !important;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-menu {
-       height: auto !important;
-       bottom: 0;
-       left: 0;
-       top: 0;
+  height: auto !important;
+  bottom: 0;
+  left: 0;
+  top: 0;
 }
 .oo-ui-menuLayout.oo-ui-menuLayout-showMenu.oo-ui-menuLayout-before > .oo-ui-menuLayout-content {
-       top: 0 !important;
-       right: 0 !important;
-       bottom: 0 !important;
+  top: 0 !important;
+  right: 0 !important;
+  bottom: 0 !important;
 }
 .oo-ui-stackLayout-continuous > .oo-ui-panelLayout {
-       display: block;
-       position: relative;
+  display: block;
+  position: relative;
 }
 .oo-ui-buttonSelectWidget {
-       display: inline-block;
-       white-space: nowrap;
-       border-radius: 2px;
-       margin-right: 0.5em;
+  display: inline-block;
+  white-space: nowrap;
+  border-radius: 2px;
+  margin-right: 0.5em;
+  z-index: 0;
+  position: relative;
 }
 .oo-ui-buttonSelectWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-buttonSelectWidget:focus {
-       outline: 0;
+  outline: 0;
 }
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
-       border-radius: 0;
-       margin-left: -1px;
+  border-radius: 0;
+  margin-left: -1px;
 }
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonElement-button {
-       border-bottom-left-radius: 2px;
-       border-top-left-radius: 2px;
-       margin-left: 0;
+  border-bottom-left-radius: 2px;
+  border-top-left-radius: 2px;
+  margin-left: 0;
 }
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:last-child .oo-ui-buttonElement-button {
-       border-bottom-right-radius: 2px;
-       border-top-right-radius: 2px;
+  border-bottom-right-radius: 2px;
+  border-top-right-radius: 2px;
 }
 .oo-ui-buttonSelectWidget.oo-ui-widget-enabled:focus .oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected .oo-ui-buttonElement-button {
-       border-color: #36c;
-       box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
+}
+.oo-ui-buttonSelectWidget.oo-ui-widget-enabled .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonSelectWidget.oo-ui-widget-enabled .oo-ui-buttonElement.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active {
+  z-index: 1;
+}
+.oo-ui-buttonSelectWidget.oo-ui-widget-enabled .oo-ui-buttonElement.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+  z-index: 3;
+}
+.oo-ui-buttonSelectWidget.oo-ui-widget-enabled .oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
+  z-index: -1;
 }
 .oo-ui-buttonOptionWidget {
-       display: inline-block;
-       padding: 0;
+  display: inline-block;
+  padding: 0;
 }
 .oo-ui-buttonOptionWidget.oo-ui-buttonElement-active .oo-ui-buttonElement-button {
-       cursor: default;
+  cursor: default;
 }
 .oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       position: static;
-       display: inline-block;
-       vertical-align: middle;
+  position: static;
+  display: inline-block;
+  vertical-align: middle;
 }
 .oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected,
 .oo-ui-buttonOptionWidget.oo-ui-optionWidget-pressed,
 .oo-ui-buttonOptionWidget.oo-ui-optionWidget-highlighted {
-       background-color: transparent;
+  background-color: transparent;
 }
 .oo-ui-toggleButtonWidget {
-       margin-right: 0.5em;
+  margin-right: 0.5em;
 }
 .oo-ui-toggleButtonWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-toggleSwitchWidget {
-       position: relative;
-       display: inline-block;
-       vertical-align: middle;
-       overflow: hidden;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       -webkit-transform: translateZ(0);
-          -moz-transform: translateZ(0);
-           -ms-transform: translateZ(0);
-               transform: translateZ(0);
-       background-color: #f8f9fa;
-       width: 3.5em;
-       min-height: 26px;
-       height: 2em;
-       border: 1px solid #72777d;
-       border-radius: 1em;
-       margin-right: 0.5em;
-       -webkit-transition: background-color 250ms, border-color 250ms;
-          -moz-transition: background-color 250ms, border-color 250ms;
-               transition: background-color 250ms, border-color 250ms;
+  position: relative;
+  display: inline-block;
+  vertical-align: middle;
+  overflow: hidden;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  -webkit-transform: translateZ(0);
+     -moz-transform: translateZ(0);
+      -ms-transform: translateZ(0);
+          transform: translateZ(0);
+  background-color: #f8f9fa;
+  width: 3.5em;
+  min-height: 26px;
+  height: 2em;
+  border: 1px solid #72777d;
+  border-radius: 1em;
+  margin-right: 0.5em;
+  -webkit-transition: background-color 250ms, border-color 250ms;
+     -moz-transition: background-color 250ms, border-color 250ms;
+          transition: background-color 250ms, border-color 250ms;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled {
-       cursor: pointer;
+  cursor: pointer;
 }
 .oo-ui-toggleSwitchWidget-grip {
-       position: absolute;
-       display: block;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  position: absolute;
+  display: block;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-toggleSwitchWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-toggleSwitchWidget:before {
-       content: '';
-       display: block;
-       position: absolute;
-       top: 1px;
-       left: 1px;
-       bottom: 1px;
-       right: 1px;
-       border: 1px solid transparent;
-       border-radius: 1em;
-       z-index: 1;
-       -webkit-transition: border-color 250ms;
-          -moz-transition: border-color 250ms;
-               transition: border-color 250ms;
+  content: '';
+  display: block;
+  position: absolute;
+  top: 1px;
+  left: 1px;
+  bottom: 1px;
+  right: 1px;
+  border: 1px solid transparent;
+  border-radius: 1em;
+  z-index: 1;
+  -webkit-transition: border-color 250ms;
+     -moz-transition: border-color 250ms;
+          transition: border-color 250ms;
 }
 .oo-ui-toggleSwitchWidget-grip {
-       top: 0.3125em;
-       min-width: 16px;
-       width: 1.25em;
-       min-height: 16px;
-       height: 1.25em;
-       border-radius: 1.25em;
-       -webkit-transition: background-color 250ms, left 100ms, margin-left 100ms;
-          -moz-transition: background-color 250ms, left 100ms, margin-left 100ms;
-               transition: background-color 250ms, left 100ms, margin-left 100ms;
+  top: 0.3125em;
+  min-width: 16px;
+  width: 1.25em;
+  min-height: 16px;
+  height: 1.25em;
+  border-radius: 1.25em;
+  -webkit-transition: background-color 250ms, left 100ms, margin-left 100ms;
+     -moz-transition: background-color 250ms, left 100ms, margin-left 100ms;
+          transition: background-color 250ms, left 100ms, margin-left 100ms;
 }
 .oo-ui-toggleSwitchWidget-glow {
-       display: none;
+  display: none;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-grip {
-       left: 0.4em;
-       margin-left: 0;
+  left: 0.4em;
+  margin-left: 0;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
-       left: 1.9em;
-       margin-left: -2px;
+  left: 1.9em;
+  margin-left: -2px;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled .oo-ui-toggleSwitchWidget-grip {
-       background-color: #f8f9fa;
-       border: 1px solid #72777d;
+  background-color: #f8f9fa;
+  border: 1px solid #72777d;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover {
-       background-color: #fff;
-       border-color: #447ff5;
+  background-color: #fff;
+  border-color: #447ff5;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover .oo-ui-toggleSwitchWidget-grip {
-       background-color: #fff;
-       border-color: #447ff5;
+  background-color: #fff;
+  border-color: #447ff5;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active,
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active:hover {
-       background-color: #36c;
-       border-color: #2a4b8d;
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active:hover,
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active:focus {
+  background-color: #2a4b8d;
+  border-color: #2a4b8d;
+  box-shadow: inset 0 0 0 1px #2a4b8d;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active .oo-ui-toggleSwitchWidget-grip,
-.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active:hover .oo-ui-toggleSwitchWidget-grip {
-       background-color: #fff;
-       border-color: #fff;
-       box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active:hover .oo-ui-toggleSwitchWidget-grip,
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:active:focus .oo-ui-toggleSwitchWidget-grip {
+  background-color: #fff;
+  border-color: #fff;
+  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus {
-       border-color: #36c;
-       box-shadow: inset 0 0 0 1px #36c;
-       outline: 0;
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c;
+  outline: 0;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:focus .oo-ui-toggleSwitchWidget-grip {
-       border-color: #36c;
+  border-color: #36c;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on {
-       background-color: #2a4b8d;
-       border-color: #2a4b8d;
+  background-color: #36c;
+  border-color: #36c;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
-       background-color: #fff;
-       border-color: #fff;
-       box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
+  background-color: #fff;
+  border-color: #fff;
+  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on:hover {
-       background-color: #36c;
-       border-color: #36c;
+  background-color: #447ff5;
+  border-color: #447ff5;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on:active,
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on:active:hover {
-       background-color: #2a4b8d;
-       border-color: #2a4b8d;
+  background-color: #2a4b8d;
+  border-color: #2a4b8d;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on:focus {
-       border-color: #36c;
+  border-color: #36c;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled.oo-ui-toggleWidget-on:focus:before {
-       border-color: #fff;
+  border-color: #fff;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
-       background-color: #c8ccd1;
-       border-color: #c8ccd1;
-       outline: 0;
+  background-color: #c8ccd1;
+  border-color: #c8ccd1;
+  outline: 0;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-disabled.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-grip {
-       border: 1px solid #fff;
-       box-shadow: inset 0 0 0 1px #fff;
+  border: 1px solid #fff;
+  box-shadow: inset 0 0 0 1px #fff;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-disabled.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
-       background-color: #fff;
+  background-color: #fff;
 }
 .oo-ui-selectFileWidget {
-       display: inline-block;
-       vertical-align: middle;
-       width: 100%;
-       max-width: 50em;
-       margin-right: 0.5em;
+  display: inline-block;
+  vertical-align: middle;
+  width: 100%;
+  max-width: 50em;
+  margin-right: 0.5em;
 }
 .oo-ui-selectFileWidget-selectButton {
-       display: table-cell;
+  display: table-cell;
 }
 .oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-       position: relative;
-       overflow: hidden;
+  position: relative;
+  overflow: hidden;
 }
 .oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button > [type='file'] {
-       position: absolute;
-       top: 0;
-       bottom: 0;
-       left: 0;
-       right: 0;
-       width: 100%;
-       height: 100%;
-       opacity: 0;
-       z-index: 1;
-       cursor: pointer;
-       padding-top: 100px;
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  width: 100%;
+  height: 100%;
+  opacity: 0;
+  z-index: 1;
+  cursor: pointer;
+  padding-top: 100px;
 }
 .oo-ui-selectFileWidget-selectButton.oo-ui-widget-disabled > .oo-ui-buttonElement-button > [type='file'] {
-       display: none;
+  display: none;
 }
 .oo-ui-selectFileWidget-info {
-       width: 100%;
-       display: table-cell;
-       vertical-align: middle;
-       position: relative;
-       overflow: hidden;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  width: 100%;
+  display: table-cell;
+  vertical-align: middle;
+  position: relative;
+  overflow: hidden;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
 .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-       position: absolute;
+  position: absolute;
 }
 .oo-ui-widget-disabled .oo-ui-selectFileWidget-info {
-       cursor: default;
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  cursor: default;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-selectFileWidget-label {
-       position: absolute;
-       top: 0;
-       bottom: 0;
-       left: 0;
-       right: 0;
-       text-overflow: ellipsis;
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  text-overflow: ellipsis;
 }
 .oo-ui-selectFileWidget-clearButton {
-       position: absolute;
-       z-index: 2;
+  position: absolute;
+  z-index: 2;
 }
 .oo-ui-selectFileWidget-dropTarget {
-       position: relative;
-       cursor: default;
-       height: 8.815em;
+  position: relative;
+  cursor: default;
+  height: 8.815em;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-dropLabel,
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton,
 .oo-ui-selectFileWidget-dropTarget .oo-ui-iconElement-icon {
-       display: none;
+  display: none;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail {
-       width: 7.815em;
-       position: absolute;
-       top: 0.5em;
-       bottom: 0.5em;
-       left: 0.5em;
-       background-position: center center;
-       background-repeat: no-repeat;
-       background-size: contain;
+  width: 7.815em;
+  position: absolute;
+  top: 0.5em;
+  bottom: 0.5em;
+  left: 0.5em;
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-size: contain;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail.oo-ui-pendingElement-pending {
-       background-repeat: repeat;
-       background-size: auto;
+  background-repeat: repeat;
+  background-size: auto;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail > .oo-ui-selectFileWidget-noThumbnail-icon {
-       opacity: 0.4;
-       height: 7.815em;
-       width: 7.815em;
+  opacity: 0.4;
+  height: 7.815em;
+  width: 7.815em;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
-       display: block;
-       height: 100%;
-       width: auto;
-       margin-left: 8.815em;
-       border: 0;
+  display: block;
+  height: 100%;
+  width: auto;
+  margin-left: 8.815em;
+  border: 0;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
-       display: block;
-       position: relative;
-       top: inherit;
+  display: block;
+  position: relative;
+  top: inherit;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-fileName {
-       display: block;
-       padding-top: 0.5em;
-       padding-right: 2.375em;
+  display: block;
+  padding-top: 0.5em;
+  padding-right: 2.375em;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-clearButton {
-       right: 0.5em;
+  right: 0.5em;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-thumbnail,
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
-       display: none;
+  display: none;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton {
-       display: block;
-       margin: 2.2em 1em 1em;
+  display: block;
+  margin: 2.2em 1em 1em;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget,
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
-       text-align: center;
+  text-align: center;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info,
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-info {
-       margin: 0;
+  margin: 0;
 }
 .oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-clearButton,
 .oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-clearButton {
-       display: none;
+  display: none;
+}
+.oo-ui-selectFileWidget-empty.oo-ui-widget-enabled .oo-ui-selectFileWidget-label {
+  cursor: default;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-widget-enabled .oo-ui-selectFileWidget-dropLabel {
-       display: block;
+  display: block;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: 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;
+  cursor: no-drop;
 }
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
-       height: auto;
+  height: auto;
 }
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
-       padding: 1em;
+  padding: 1em;
 }
 .oo-ui-selectFileWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-       border-radius: 0 2px 2px 0;
+  border-radius: 0 2px 2px 0;
 }
 .oo-ui-selectFileWidget-info {
-       height: 2.4em;
-       background-color: #fff;
-       border: 1px solid #9aa0a7;
-       border-radius: 2px 0 0 2px;
-       border-width: 1px 0 1px 1px;
+  height: 2.4em;
+  background-color: #fff;
+  border: 1px solid #a2a9b1;
+  border-radius: 2px 0 0 2px;
+  border-width: 1px 0 1px 1px;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon {
-       left: 0;
-       top: 0;
-       height: 2.3em;
-       margin-left: 0.5em;
+  left: 0;
+  top: 0;
+  height: 2.3em;
+  margin-left: 0.5em;
 }
 .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-       top: 0;
-       right: 0;
-       height: 2.3em;
-       margin-right: 0.775em;
+  top: 0;
+  right: 0;
+  height: 2.3em;
+  margin-right: 0.775em;
 }
 .oo-ui-selectFileWidget-label {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       display: block;
-       right: 2.375em;
-       line-height: 2.3;
-       margin: 0;
-       overflow: hidden;
-       white-space: nowrap;
-       text-overflow: ellipsis;
-       padding-left: 0.5em;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  display: block;
+  right: 2.375em;
+  margin: 0;
+  padding-left: 0.5em;
+  line-height: 2.3;
+  white-space: nowrap;
+}
+.oo-ui-selectFileWidget-fileName {
+  display: block;
+  overflow: hidden;
+  text-overflow: ellipsis;
 }
 .oo-ui-selectFileWidget-clearButton {
-       top: 0;
-       right: 0;
-       min-width: 24px;
-       width: 1.875em;
-       margin-right: 0;
+  top: 0;
+  right: 0;
+  min-width: 24px;
+  width: 1.875em;
+  margin-right: 0;
 }
 .oo-ui-selectFileWidget-clearButton .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       height: 2.3em;
+  height: 2.3em;
 }
 .oo-ui-selectFileWidget-empty .oo-ui-selectFileWidget-label {
-       color: #72777d;
+  color: #72777d;
 }
 .oo-ui-selectFileWidget.oo-ui-iconElement .oo-ui-selectFileWidget-label {
-       left: 2.875em;
+  left: 2.875em;
 }
 .oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-label {
-       right: 4.4625em;
-       padding-left: 0;
+  right: 4.4625em;
+  padding-left: 0;
 }
 .oo-ui-selectFileWidget.oo-ui-indicatorElement .oo-ui-selectFileWidget-clearButton {
-       right: 2.0875em;
+  right: 2.0875em;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-indicatorElement .oo-ui-selectFileWidget-label,
 .oo-ui-selectFileWidget-notsupported.oo-ui-indicatorElement .oo-ui-selectFileWidget-label {
-       right: 2em;
+  right: 2em;
 }
 .oo-ui-selectFileWidget-supported.oo-ui-widget-enabled.oo-ui-selectFileWidget-canDrop.oo-ui-selectFileWidget-dropTarget {
-       background-color: #eaf3ff;
+  background-color: #eaf3ff;
 }
 .oo-ui-selectFileWidget-dropTarget {
-       background-color: #fff;
-       border: 1px solid #9aa0a7;
-       vertical-align: middle;
-       overflow: hidden;
-       border-radius: 2px;
+  background-color: #fff;
+  border: 1px solid #a2a9b1;
+  vertical-align: middle;
+  overflow: hidden;
+  border-radius: 2px;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-selectButton > .oo-ui-buttonElement-button {
-       border-radius: 2px;
+  border-radius: 2px;
 }
 .oo-ui-selectFileWidget-dropTarget .oo-ui-selectFileWidget-label {
-       line-height: 1.4;
-       overflow: inherit;
-       white-space: normal;
+  line-height: 1.4;
+  overflow: inherit;
+  white-space: normal;
 }
 .oo-ui-selectFileWidget-empty.oo-ui-widget-enabled.oo-ui-selectFileWidget-dropTarget {
-       background-color: #eee;
-       border-style: dashed;
+  background-color: #eee;
+  border-style: dashed;
 }
 .oo-ui-selectFileWidget.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
 .oo-ui-selectFileWidget-empty.oo-ui-widget-disabled.oo-ui-selectFileWidget-dropTarget,
 .oo-ui-selectFileWidget-notsupported.oo-ui-selectFileWidget-dropTarget {
-       background-color: #eaecf0;
-       border-color: #c8ccd1;
+  background-color: #eaecf0;
+  border-color: #c8ccd1;
 }
 .oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info,
 .oo-ui-selectFileWidget-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info,
 .oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info {
-       background-color: #eaecf0;
-       color: #72777d;
-       border-color: #c8ccd1;
-       text-shadow: 0 1px 1px #fff;
+  background-color: #eaecf0;
+  color: #72777d;
+  border-color: #c8ccd1;
+  text-shadow: 0 1px 1px #fff;
 }
 .oo-ui-selectFileWidget.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-iconElement-icon,
 .oo-ui-selectFileWidget-empty.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-empty.oo-ui-widget-disabled .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator,
 .oo-ui-selectFileWidget-notsupported .oo-ui-selectFileWidget-info > .oo-ui-indicatorElement-indicator {
-       opacity: 0.51;
+  opacity: 0.51;
 }
 .oo-ui-widget-disabled .oo-ui-selectFileWidget-dropLabel {
-       display: none;
+  display: none;
 }
 .oo-ui-outlineOptionWidget {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
-       font-size: 1.1em;
-       padding: 0.75em;
-       -webkit-transition: background-color 100ms, color 100ms;
-          -moz-transition: background-color 100ms, color 100ms;
-               transition: background-color 100ms, color 100ms;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+  font-size: 1.1em;
+  padding: 0.75em;
+  -webkit-transition: background-color 100ms, color 100ms;
+     -moz-transition: background-color 100ms, color 100ms;
+          transition: background-color 100ms, color 100ms;
 }
 .oo-ui-outlineOptionWidget.oo-ui-optionWidget-highlighted {
-       background-color: #eaecf0;
-       color: #000;
+  background-color: #eaecf0;
+  color: #000;
 }
 .oo-ui-outlineOptionWidget.oo-ui-optionWidget-selected {
-       background-color: #eaf3ff;
-       color: #36c;
+  background-color: #eaf3ff;
+  color: #36c;
 }
 .oo-ui-outlineOptionWidget.oo-ui-optionWidget-pressed {
-       background-color: rgba(41, 98, 204, 0.1);
-       color: #36c;
+  background-color: rgba(41, 98, 204, 0.1);
+  color: #36c;
 }
 .oo-ui-outlineOptionWidget .oo-ui-iconElement-icon {
-       font-size: 90.90909%;
+  font-size: 90.90909%;
 }
 .oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
-       padding-right: 1.5em;
+  padding-right: 1.5em;
 }
 .oo-ui-outlineOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       opacity: 0.5;
+  opacity: 0.5;
 }
 .oo-ui-outlineOptionWidget-level-0 {
-       padding-left: 3.5em;
+  padding-left: 3.5em;
 }
 .oo-ui-outlineOptionWidget-level-0 .oo-ui-iconElement-icon {
-       left: 1em;
+  left: 1em;
 }
 .oo-ui-outlineOptionWidget-level-1 {
-       padding-left: 5em;
+  padding-left: 5em;
 }
 .oo-ui-outlineOptionWidget-level-1 .oo-ui-iconElement-icon {
-       left: 2.5em;
+  left: 2.5em;
 }
 .oo-ui-outlineOptionWidget-level-2 {
-       padding-left: 6.5em;
+  padding-left: 6.5em;
 }
 .oo-ui-outlineOptionWidget-level-2 .oo-ui-iconElement-icon {
-       left: 4em;
+  left: 4em;
 }
 .oo-ui-outlineOptionWidget.oo-ui-flaggedElement-important {
-       font-weight: bold;
+  font-weight: bold;
 }
 .oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
-       opacity: 0.5;
+  opacity: 0.5;
 }
 .oo-ui-outlineOptionWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
-       color: #777;
+  color: #777;
 }
 .oo-ui-outlineControlsWidget {
-       height: 3em;
-       background-color: #fff;
+  height: 3em;
+  background-color: #fff;
 }
 .oo-ui-outlineControlsWidget-items,
 .oo-ui-outlineControlsWidget-movers {
-       float: left;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  float: left;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-       float: left;
-       background-position: right center;
+  float: left;
+  background-position: right center;
 }
 .oo-ui-outlineControlsWidget-items {
-       float: left;
+  float: left;
 }
 .oo-ui-outlineControlsWidget-items .oo-ui-buttonWidget {
-       float: left;
+  float: left;
 }
 .oo-ui-outlineControlsWidget-movers {
-       float: right;
+  float: right;
 }
 .oo-ui-outlineControlsWidget-movers .oo-ui-buttonWidget {
-       float: right;
+  float: right;
 }
 .oo-ui-outlineControlsWidget-items,
 .oo-ui-outlineControlsWidget-movers {
-       height: 2em;
-       margin: 0.5em 0.5em 0.5em 0;
-       padding: 0;
+  height: 2em;
+  margin: 0.5em 0.5em 0.5em 0;
+  padding: 0;
 }
 .oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-       width: 1.5em;
-       height: 2em;
-       margin: 0.5em 0 0.5em 0.5em;
-       opacity: 0.2;
+  width: 1.5em;
+  height: 2em;
+  margin: 0.5em 0 0.5em 0.5em;
+  opacity: 0.2;
 }
 .oo-ui-tabSelectWidget {
-       text-align: left;
-       white-space: nowrap;
-       overflow: hidden;
-       background-color: #ddd;
+  text-align: left;
+  white-space: nowrap;
+  overflow: hidden;
+  background-color: #ddd;
 }
 .oo-ui-tabOptionWidget {
-       display: inline-block;
-       vertical-align: bottom;
-       padding: 0.35em 1em;
-       margin: 0.5em 0 0 0.75em;
-       border: 1px solid transparent;
-       border-bottom: 0;
-       border-top-left-radius: 2px;
-       border-top-right-radius: 2px;
-       color: #222;
-       font-weight: bold;
+  display: inline-block;
+  vertical-align: bottom;
+  padding: 0.35em 1em;
+  margin: 0.5em 0 0 0.75em;
+  border: 1px solid transparent;
+  border-bottom: 0;
+  border-top-left-radius: 2px;
+  border-top-right-radius: 2px;
+  color: #222;
+  font-weight: bold;
 }
 .oo-ui-tabOptionWidget.oo-ui-widget-enabled:hover {
-       background-color: rgba(255, 255, 255, 0.3);
+  background-color: rgba(255, 255, 255, 0.3);
 }
 .oo-ui-tabOptionWidget.oo-ui-widget-enabled:active {
-       background-color: rgba(255, 255, 255, 0.8);
+  background-color: rgba(255, 255, 255, 0.8);
 }
 .oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
-       padding-right: 1.5em;
+  padding-right: 1.5em;
 }
 .oo-ui-tabOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-       opacity: 0.5;
+  opacity: 0.5;
 }
 .oo-ui-selectWidget-pressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
 .oo-ui-selectWidget-depressed .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected,
 .oo-ui-tabOptionWidget.oo-ui-optionWidget-selected:hover {
-       background-color: #fff;
-       color: #333;
+  background-color: #fff;
+  color: #333;
 }
 .oo-ui-capsuleMultiselectWidget {
-       display: inline-block;
-       position: relative;
-       width: 100%;
-       max-width: 50em;
+  display: inline-block;
+  position: relative;
+  width: 100%;
+  max-width: 50em;
 }
 .oo-ui-capsuleMultiselectWidget-handle {
-       width: 100%;
-       display: block;
-       position: relative;
+  width: 100%;
+  display: block;
+  position: relative;
 }
 .oo-ui-capsuleMultiselectWidget-content {
-       position: relative;
+  position: relative;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-content > input {
-       display: none;
+  display: none;
 }
 .oo-ui-capsuleMultiselectWidget-group {
-       display: inline;
+  display: inline;
 }
 .oo-ui-capsuleMultiselectWidget-handle {
-       min-height: 2.4em;
-       margin-right: 0.5em;
-       padding: 0.15em 0.25em;
-       border: 1px solid #9aa0a7;
-       border-radius: 2px;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  min-height: 2.4em;
+  margin-right: 0.5em;
+  padding: 0.15em 0.25em;
+  border: 1px solid #a2a9b1;
+  border-radius: 2px;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-capsuleMultiselectWidget-handle:last-child {
-       margin-right: 0;
-}
-.oo-ui-capsuleMultiselectWidget-handle:hover {
-       border-color: #72777d;
+  margin-right: 0;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator,
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon {
-       position: absolute;
+  position: absolute;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input {
-       border: 0;
-       line-height: 1.675;
-       margin: 0 0 0 0.2em;
-       padding: 0;
-       font-size: inherit;
-       font-family: inherit;
-       background-color: transparent;
-       color: #000;
-       vertical-align: middle;
+  border: 0;
+  line-height: 1.675;
+  margin: 0 0 0 0.2em;
+  padding: 0;
+  font-size: inherit;
+  font-family: inherit;
+  background-color: transparent;
+  color: #000;
+  vertical-align: middle;
 }
 .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-capsuleMultiselectWidget-content > input:focus {
-       outline: 0;
+  outline: 0;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle {
-       padding-right: 2.4875em;
+  padding-right: 2.4875em;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-indicatorElement .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
-       right: 0;
-       top: 0;
-       margin: 0.775em;
+  right: 0;
+  top: 0;
+  margin: 0.775em;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-iconElement .oo-ui-capsuleMultiselectWidget-handle {
-       padding-left: 2.475em;
+  padding-left: 2.475em;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-iconElement .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon {
-       left: 0;
-       top: 0;
-       margin: 0.3em;
+  left: 0;
+  top: 0;
+  margin: 0.3em;
 }
 .oo-ui-capsuleMultiselectWidget .oo-ui-popupWidget {
-       width: 100%;
-       margin-top: -1px;
+  width: 100%;
+  margin-top: -1px;
 }
 .oo-ui-capsuleMultiselectWidget .oo-ui-popupWidget-popup {
-       min-width: 100%;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       border-width: 0 1px;
-       border-radius: 0 0 2px 2px;
+  min-width: 100%;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  border-width: 0 1px;
+  border-radius: 0 0 2px 2px;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-enabled .oo-ui-capsuleMultiselectWidget-handle {
-       background-color: #fff;
-       cursor: text;
-       -webkit-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
-          -moz-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
-               transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+  background-color: #fff;
+  cursor: text;
+  -webkit-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+     -moz-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
+          transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-enabled:hover .oo-ui-capsuleMultiselectWidget-handle {
-       border-color: #a2a9b1;
+  border-color: #72777d;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-enabled.oo-ui-capsuleMultiselectWidget-open .oo-ui-capsuleMultiselectWidget-handle {
-       border-color: #36c;
-       outline: 0;
-       box-shadow: inset 0 0 0 1px #36c;
+  border-color: #36c;
+  outline: 0;
+  box-shadow: inset 0 0 0 1px #36c;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-handle {
-       color: #72777d;
-       text-shadow: 0 1px 1px #fff;
-       border-color: #c8ccd1;
-       background-color: #eaecf0;
+  color: #72777d;
+  text-shadow: 0 1px 1px #fff;
+  border-color: #c8ccd1;
+  background-color: #eaecf0;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-iconElement-icon {
-       opacity: 0.51;
+  opacity: 0.51;
 }
 .oo-ui-capsuleMultiselectWidget.oo-ui-widget-disabled .oo-ui-capsuleMultiselectWidget-handle > .oo-ui-indicatorElement-indicator {
-       opacity: 0.15;
+  opacity: 0.15;
 }
 .oo-ui-capsuleItemWidget {
-       position: relative;
-       display: inline-block;
-       cursor: default;
-       white-space: nowrap;
-       width: auto;
-       max-width: 100%;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
-       vertical-align: middle;
-       height: 1.7em;
-       line-height: 1.7;
-       background-color: #eee;
-       color: #222;
-       margin: 0.1em;
-       border: 1px solid #9aa0a7;
-       border-radius: 2px;
-       padding: 0 0.4em;
+  position: relative;
+  display: inline-block;
+  cursor: default;
+  white-space: nowrap;
+  width: auto;
+  max-width: 100%;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  vertical-align: middle;
+  height: 1.7em;
+  line-height: 1.7;
+  background-color: #eee;
+  color: #222;
+  margin: 0.1em;
+  border: 1px solid #a2a9b1;
+  border-radius: 2px;
+  padding: 0 0.4em;
 }
 .oo-ui-capsuleItemWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       display: inline-block;
-       text-overflow: ellipsis;
-       overflow: hidden;
+  display: inline-block;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  cursor: text;
 }
 .oo-ui-capsuleItemWidget:focus {
-       outline: 0;
-       border-color: #36c;
-       box-shadow: inset 0 0 0 1px #36c;
+  outline: 0;
+  border-color: #36c;
+  box-shadow: inset 0 0 0 1px #36c;
 }
 .oo-ui-capsuleItemWidget.oo-ui-widget-disabled {
-       background-color: #eaecf0;
-       color: #72777d;
-       border-color: #c8ccd1;
-       text-shadow: 0 1px 1px #fff;
+  background-color: #eaecf0;
+  color: #72777d;
+  border-color: #c8ccd1;
+  text-shadow: 0 1px 1px #fff;
 }
 .oo-ui-capsuleItemWidget > .oo-ui-buttonElement {
-       display: none;
+  display: none;
 }
 .oo-ui-capsuleItemWidget.oo-ui-widget-enabled {
-       padding-right: 1.5375em;
+  padding-right: 1.5375em;
 }
 .oo-ui-capsuleItemWidget.oo-ui-widget-enabled > .oo-ui-buttonElement {
-       display: block;
-       position: absolute;
-       top: 0;
-       right: 0;
-       bottom: 0;
+  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%;
+  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;
+  position: absolute;
+  top: 0;
+  right: 0.3em;
+  bottom: 0;
+  height: auto;
 }
 .oo-ui-searchWidget-query {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
 }
 .oo-ui-searchWidget-query .oo-ui-textInputWidget {
-       width: 100%;
+  width: 100%;
 }
 .oo-ui-searchWidget-results {
-       position: absolute;
-       bottom: 0;
-       left: 0;
-       right: 0;
-       overflow-x: hidden;
-       overflow-y: auto;
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  overflow-x: hidden;
+  overflow-y: auto;
 }
 .oo-ui-searchWidget-query {
-       height: 4em;
-       padding: 0 1em;
-       border-bottom: 1px solid #9aa0a7;
+  height: 4em;
+  padding: 0 1em;
+  border-bottom: 1px solid #a2a9b1;
 }
 .oo-ui-searchWidget-query .oo-ui-textInputWidget {
-       margin: 0.75em 0;
+  margin: 0.75em 0;
 }
 .oo-ui-searchWidget-results {
-       top: 4em;
-       padding: 1em;
-       line-height: 0;
+  top: 4em;
+  padding: 1em;
+  line-height: 0;
 }
 .oo-ui-numberInputWidget {
-       display: inline-block;
-       position: relative;
-       max-width: 50em;
+  display: inline-block;
+  position: relative;
+  max-width: 50em;
 }
 .oo-ui-numberInputWidget-buttoned .oo-ui-buttonWidget,
 .oo-ui-numberInputWidget-buttoned .oo-ui-textInputWidget {
-       display: table-cell;
+  display: table-cell;
 }
 .oo-ui-numberInputWidget-buttoned .oo-ui-buttonElement-button {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-numberInputWidget-field {
-       display: table;
-       table-layout: fixed;
-       width: 100%;
+  display: table;
+  table-layout: fixed;
+  width: 100%;
 }
 .oo-ui-numberInputWidget-buttoned .oo-ui-buttonWidget {
-       width: 2.5em;
+  width: 2.5em;
 }
 .oo-ui-numberInputWidget-buttoned .oo-ui-buttonElement-button {
-       display: block;
-       padding-left: 0;
-       padding-right: 0;
+  display: block;
+  min-height: 2.5em;
+  padding-left: 0;
+  padding-right: 0;
 }
 .oo-ui-numberInputWidget-buttoned .oo-ui-textInputWidget input {
-       border-radius: 0;
+  border-radius: 0;
 }
 .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;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+  border-right-width: 0;
 }
 .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;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+  border-left-width: 0;
 }
index 62195df..6962c92 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:02Z
+ * Date: 2016-11-09T00:52:37Z
  */
 ( function ( OO ) {
 
@@ -85,7 +85,7 @@ OO.ui.mixin.DraggableElement.static.cancelButtonMouseDownEvents = false;
  * Respond to mousedown event.
  *
  * @private
- * @param {jQuery.Event} e jQuery event
+ * @param {jQuery.Event} e Drag event
  */
 OO.ui.mixin.DraggableElement.prototype.onDragMouseDown = function ( e ) {
        this.wasHandleUsed =
@@ -99,7 +99,8 @@ OO.ui.mixin.DraggableElement.prototype.onDragMouseDown = function ( e ) {
  * Respond to dragstart event.
  *
  * @private
- * @param {jQuery.Event} e jQuery event
+ * @param {jQuery.Event} e Drag event
+ * @return {boolean} False if the event is cancelled
  * @fires dragstart
  */
 OO.ui.mixin.DraggableElement.prototype.onDragStart = function ( e ) {
@@ -149,7 +150,7 @@ OO.ui.mixin.DraggableElement.prototype.onDragEnd = function () {
  * Handle drop event.
  *
  * @private
- * @param {jQuery.Event} e jQuery event
+ * @param {jQuery.Event} e Drop event
  * @fires drop
  */
 OO.ui.mixin.DraggableElement.prototype.onDrop = function ( e ) {
@@ -161,6 +162,7 @@ OO.ui.mixin.DraggableElement.prototype.onDrop = function ( e ) {
  * In order for drag/drop to work, the dragover event must
  * return false and stop propogation.
  *
+ * @param {jQuery.Event} e Drag event
  * @private
  */
 OO.ui.mixin.DraggableElement.prototype.onDragOver = function ( e ) {
@@ -3103,13 +3105,10 @@ OO.ui.OutlineOptionWidget.prototype.getLevel = function () {
  */
 OO.ui.OutlineOptionWidget.prototype.setPressed = function ( state ) {
        OO.ui.OutlineOptionWidget.parent.prototype.setPressed.call( this, state );
-       if ( this.constructor.static.pressable ) {
-               this.pressed = !!state;
-               if ( this.pressed ) {
-                       this.setFlags( 'progressive' );
-               } else if ( !this.selected ) {
-                       this.clearFlags();
-               }
+       if ( this.pressed ) {
+               this.setFlags( 'progressive' );
+       } else if ( !this.selected ) {
+               this.clearFlags();
        }
        return this;
 };
@@ -3147,13 +3146,10 @@ OO.ui.OutlineOptionWidget.prototype.setRemovable = function ( removable ) {
  */
 OO.ui.OutlineOptionWidget.prototype.setSelected = function ( state ) {
        OO.ui.OutlineOptionWidget.parent.prototype.setSelected.call( this, state );
-       if ( this.constructor.static.selectable ) {
-               this.selected = !!state;
-               if ( this.selected ) {
-                       this.setFlags( 'progressive' );
-               } else {
-                       this.clearFlags();
-               }
+       if ( this.selected ) {
+               this.setFlags( 'progressive' );
+       } else {
+               this.clearFlags();
        }
        return this;
 };
@@ -3496,6 +3492,8 @@ OO.ui.CapsuleItemWidget.prototype.onClick = function () {
 
 /**
  * Handle keyDown event for the entire capsule
+ *
+ * @param {jQuery.Event} e Key down event
  */
 OO.ui.CapsuleItemWidget.prototype.onKeyDown = function ( e ) {
        var element = this.getElementGroup();
@@ -3573,6 +3571,7 @@ OO.ui.CapsuleItemWidget.prototype.focus = function () {
  *
  * @constructor
  * @param {Object} [config] Configuration options
+ * @cfg {string} [placeholder] Placeholder text
  * @cfg {boolean} [allowArbitrary=false] Allow data items to be added even if not present in the menu.
  * @cfg {Object} [menu] (required) Configuration options to pass to the
  *  {@link OO.ui.MenuSelectWidget menu select widget}.
@@ -3599,8 +3598,11 @@ OO.ui.CapsuleMultiselectWidget = function OoUiCapsuleMultiselectWidget( config )
        }, config );
 
        // Properties (must be set before mixin constructor calls)
-       this.$input = config.popup ? null : $( '<input>' );
        this.$handle = $( '<div>' );
+       this.$input = config.popup ? null : $( '<input>' );
+       if ( config.placeholder !== undefined && config.placeholder !== '' ) {
+               this.$input.attr( 'placeholder', config.placeholder );
+       }
 
        // Mixin constructors
        OO.ui.mixin.GroupElement.call( this, config );
@@ -3676,7 +3678,6 @@ OO.ui.CapsuleMultiselectWidget = function OoUiCapsuleMultiselectWidget( config )
                        role: 'combobox',
                        'aria-autocomplete': 'list'
                } );
-               this.updateInputSize();
        }
        if ( config.data ) {
                this.setItemsFromData( config.data );
@@ -3695,6 +3696,14 @@ OO.ui.CapsuleMultiselectWidget = function OoUiCapsuleMultiselectWidget( config )
                this.$content.append( this.$input );
                this.$overlay.append( this.menu.$element );
        }
+
+       // Input size needs to be calculated after everything else is rendered
+       setTimeout( function () {
+               if ( this.$input ) {
+                       this.updateInputSize();
+               }
+       }.bind( this ) );
+
        this.onMenuItemsChange();
 };
 
@@ -3911,9 +3920,12 @@ OO.ui.CapsuleMultiselectWidget.prototype.addItems = function ( items ) {
  * @param {Object} item
  */
 OO.ui.CapsuleMultiselectWidget.prototype.editItem = function ( item ) {
+       this.addItemFromLabel( this.$input.val() );
+       this.clearInput();
        this.$input.val( item.label );
        this.updateInputSize();
        this.focus();
+       this.menu.updateItemVisibility(); // Hack, we shouldn't be calling this method directly
        this.removeItems( [ item ] );
 };
 
@@ -4149,11 +4161,31 @@ OO.ui.CapsuleMultiselectWidget.prototype.onKeyDown = function ( e ) {
  */
 OO.ui.CapsuleMultiselectWidget.prototype.updateInputSize = function () {
        var $lastItem, direction, contentWidth, currentWidth, bestWidth;
-       if ( !this.isDisabled() ) {
+       if ( this.$input && !this.isDisabled() ) {
                this.$input.css( 'width', '1em' );
                $lastItem = this.$group.children().last();
                direction = OO.ui.Element.static.getDir( this.$handle );
-               contentWidth = this.$input[ 0 ].scrollWidth;
+
+               // Get the width of the input with the placeholder text as
+               // the value and save it so that we don't keep recalculating
+               if (
+                       this.contentWidthWithPlaceholder === undefined &&
+                       this.$input.val() === '' &&
+                       this.$input.attr( 'placeholder' ) !== undefined
+               ) {
+                       this.$input.val( this.$input.attr( 'placeholder' ) );
+                       this.contentWidthWithPlaceholder = this.$input[ 0 ].scrollWidth;
+                       this.$input.val( '' );
+
+               }
+
+               // Always keep the input wide enough for the placeholder text
+               contentWidth = Math.max(
+                       this.$input[ 0 ].scrollWidth,
+                       // undefined arguments in Math.max lead to NaN
+                       ( this.contentWidthWithPlaceholder === undefined ) ?
+                               0 : this.contentWidthWithPlaceholder
+               );
                currentWidth = this.$input.width();
 
                if ( contentWidth < currentWidth ) {
@@ -4161,13 +4193,14 @@ OO.ui.CapsuleMultiselectWidget.prototype.updateInputSize = function () {
                        return;
                }
 
-               if ( !$lastItem.length ) {
+               if ( $lastItem.length === 0 ) {
                        bestWidth = this.$content.innerWidth();
                } else {
                        bestWidth = direction === 'ltr' ?
                                this.$content.innerWidth() - $lastItem.position().left - $lastItem.outerWidth() :
                                $lastItem.position().left;
                }
+
                // Some safety margin for sanity, because I *really* don't feel like finding out where the few
                // pixels this is off by are coming from.
                bestWidth -= 10;
index 3cff8f7..6258b84 100644 (file)
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:06Z
+ * Date: 2016-11-09T00:52:42Z
  */
 .oo-ui-actionWidget.oo-ui-pendingElement-pending {
-       background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
+  background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
 }
 .oo-ui-window {
-       background-color: transparent;
-       background-image: none;
+  background-color: transparent;
+  background-image: none;
 }
 .oo-ui-window-frame {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+}
+.oo-ui-window-content {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
 }
 .oo-ui-window-content:focus {
-       outline: 0;
+  outline: 0;
 }
 .oo-ui-window-head,
 .oo-ui-window-foot {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-window-body {
-       margin: 0;
-       padding: 0;
-       background: none;
+  margin: 0;
+  padding: 0;
+  background: none;
 }
 .oo-ui-window-overlay {
-       position: absolute;
-       top: 0;
-       /* @noflip */
-       left: 0;
+  position: absolute;
+  top: 0;
+  /* @noflip */
+  left: 0;
 }
 .oo-ui-dialog-content > .oo-ui-window-head,
 .oo-ui-dialog-content > .oo-ui-window-body,
 .oo-ui-dialog-content > .oo-ui-window-foot {
-       position: absolute;
-       left: 0;
-       right: 0;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  position: absolute;
+  left: 0;
+  right: 0;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-dialog-content > .oo-ui-window-head {
-       overflow: hidden;
-       z-index: 1;
-       top: 0;
+  overflow: hidden;
+  z-index: 1;
+  top: 0;
 }
 .oo-ui-dialog-content > .oo-ui-window-body {
-       overflow: auto;
-       z-index: 2;
-       top: 0;
-       bottom: 0;
+  overflow: auto;
+  z-index: 2;
+  top: 0;
+  bottom: 0;
 }
 .oo-ui-dialog-content > .oo-ui-window-foot {
-       z-index: 3;
-       bottom: 0;
+  z-index: 3;
+  bottom: 0;
 }
 .oo-ui-dialog-content > .oo-ui-window-body {
-       box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
+  box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget {
+  position: relative;
+  text-align: center;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
+  display: block;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
+  position: relative;
+  top: auto;
+  bottom: auto;
 }
 .oo-ui-messageDialog-actions-horizontal {
-       display: table;
-       table-layout: fixed;
-       width: 100%;
+  display: table;
+  table-layout: fixed;
+  width: 100%;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-       display: table-cell;
-       width: 1%;
+  display: table-cell;
+  width: 1%;
 }
 .oo-ui-messageDialog-actions-vertical {
-       display: block;
+  display: block;
 }
 .oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-       display: block;
-       overflow: hidden;
-       text-overflow: ellipsis;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget {
-       position: relative;
-       text-align: center;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
-       display: block;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
-       position: relative;
-       top: auto;
-       bottom: auto;
-       display: inline;
-       white-space: nowrap;
+  display: block;
+  overflow: hidden;
+  text-overflow: ellipsis;
 }
 .oo-ui-messageDialog-content .oo-ui-window-body {
-       box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
+  box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
 }
 .oo-ui-messageDialog-title,
 .oo-ui-messageDialog-message {
-       display: block;
-       text-align: center;
+  display: block;
+  text-align: center;
 }
 .oo-ui-messageDialog-title.oo-ui-labelElement,
 .oo-ui-messageDialog-message.oo-ui-labelElement {
-       padding-top: 0.5em;
+  padding-top: 0.5em;
 }
 .oo-ui-messageDialog-title {
-       font-size: 1.5em;
-       line-height: 1em;
-       color: #000;
+  font-size: 1.5em;
+  line-height: 1em;
+  color: #000;
 }
 .oo-ui-messageDialog-message {
-       font-size: 0.9em;
-       line-height: 1.25em;
-       color: #666;
+  font-size: 0.9em;
+  line-height: 1.25em;
+  color: #666;
 }
 .oo-ui-messageDialog-message-verbose {
-       font-size: 1.1em;
-       line-height: 1.5em;
-       text-align: left;
+  font-size: 1.1em;
+  line-height: 1.5em;
+  text-align: left;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-       border-right: 1px solid #e5e5e5;
-       margin: 0;
+  border-right: 1px solid #e5e5e5;
+  margin: 0;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
-       border-right-width: 0;
+  border-right-width: 0;
 }
 .oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-       border-bottom: 1px solid #e5e5e5;
-       margin: 0;
+  border-bottom: 1px solid #e5e5e5;
+  margin: 0;
 }
 .oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
-       border-bottom-width: 0;
+  border-bottom-width: 0;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget {
-       height: 3.4em;
-       margin-right: 0;
+  height: 3.4em;
+  margin-right: 0;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       text-align: center;
-       line-height: 3.4em;
+  text-align: center;
+  line-height: 3.4em;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget:hover {
-       background-color: rgba(0, 0, 0, 0.05);
+  background-color: rgba(0, 0, 0, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
-       background-color: rgba(0, 0, 0, 0.1);
+  background-color: rgba(0, 0, 0, 0.1);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
-       background-color: rgba(8, 126, 204, 0.05);
+  background-color: rgba(8, 126, 204, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
-       background-color: rgba(8, 126, 204, 0.1);
+  background-color: rgba(8, 126, 204, 0.1);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
-       font-weight: bold;
+  font-weight: bold;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
-       background-color: rgba(118, 171, 54, 0.05);
+  background-color: rgba(118, 171, 54, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
-       background-color: rgba(118, 171, 54, 0.1);
+  background-color: rgba(118, 171, 54, 0.1);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
-       background-color: rgba(212, 83, 83, 0.05);
+  background-color: rgba(212, 83, 83, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
-       background-color: rgba(212, 83, 83, 0.1);
+  background-color: rgba(212, 83, 83, 0.1);
 }
 .oo-ui-processDialog-location {
-       overflow: hidden;
-       text-overflow: ellipsis;
-       white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 .oo-ui-processDialog-title {
-       display: inline;
-       padding: 0;
+  display: inline;
+  padding: 0;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget {
-       white-space: nowrap;
+  white-space: nowrap;
 }
 .oo-ui-processDialog-actions-safe,
 .oo-ui-processDialog-actions-primary {
-       position: absolute;
-       top: 0;
-       bottom: 0;
+  position: absolute;
+  top: 0;
+  bottom: 0;
 }
 .oo-ui-processDialog-actions-safe {
-       left: 0;
+  left: 0;
 }
 .oo-ui-processDialog-actions-primary {
-       right: 0;
+  right: 0;
 }
 .oo-ui-processDialog-errors {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 0;
-       z-index: 2;
-       overflow-x: hidden;
-       overflow-y: auto;
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 2;
+  overflow-x: hidden;
+  overflow-y: auto;
 }
 .oo-ui-processDialog-content .oo-ui-window-head {
-       height: 3.4em;
+  height: 3.4em;
 }
 .oo-ui-processDialog-content .oo-ui-window-body {
-       top: 3.4em;
-       box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
+  top: 3.4em;
+  box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
 }
 .oo-ui-processDialog-navigation {
-       position: relative;
-       height: 3.4em;
-       padding: 0 1em;
+  position: relative;
+  height: 3.4em;
+  padding: 0 1em;
 }
 .oo-ui-processDialog-location {
-       padding: 0.75em 0;
-       height: 1.875em;
-       cursor: default;
-       text-align: center;
+  padding: 0.75em 0;
+  height: 1.875em;
+  cursor: default;
+  text-align: center;
 }
 .oo-ui-processDialog-title {
-       font-weight: bold;
-       line-height: 1.875em;
+  font-weight: bold;
+  line-height: 1.875em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-buttonElement-button {
-       min-width: 1.875em;
-       min-height: 1.875em;
+  min-width: 1.875em;
+  min-height: 1.875em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-labelElement-label,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-labelElement-label,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-labelElement-label {
-       line-height: 1.875em;
+  line-height: 1.875em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-       margin-top: -0.125em;
+  margin-top: -0.125em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed {
-       margin: 0.75em;
+  margin: 0.75em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
-       padding: 0 1em;
-       vertical-align: middle;
-       margin: -1px;
+  padding: 0 1em;
+  vertical-align: middle;
+  margin: -1px;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless {
-       margin: 0;
+  margin: 0;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button {
-       padding: 0.75em 1em;
-       vertical-align: middle;
+  padding: 0.75em 1em;
+  vertical-align: middle;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget:hover,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget:hover {
-       background-color: rgba(0, 0, 0, 0.05);
+  background-color: rgba(0, 0, 0, 0.05);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget:active,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget:active {
-       background-color: rgba(0, 0, 0, 0.1);
+  background-color: rgba(0, 0, 0, 0.1);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
-       background-color: rgba(8, 126, 204, 0.05);
+  background-color: rgba(8, 126, 204, 0.05);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
-       background-color: rgba(8, 126, 204, 0.1);
+  background-color: rgba(8, 126, 204, 0.1);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
-       font-weight: bold;
+  font-weight: bold;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
-       background-color: rgba(118, 171, 54, 0.05);
+  background-color: rgba(118, 171, 54, 0.05);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
-       background-color: rgba(118, 171, 54, 0.1);
+  background-color: rgba(118, 171, 54, 0.1);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
-       background-color: rgba(212, 83, 83, 0.05);
+  background-color: rgba(212, 83, 83, 0.05);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
-       background-color: rgba(212, 83, 83, 0.1);
+  background-color: rgba(212, 83, 83, 0.1);
 }
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-processDialog > .oo-ui-window-frame {
-       min-height: 5em;
+  min-height: 5em;
 }
 .oo-ui-processDialog-errors {
-       background-color: rgba(255, 255, 255, 0.9);
-       padding: 3em 3em 1.5em 3em;
-       text-align: center;
+  background-color: rgba(255, 255, 255, 0.9);
+  padding: 3em 3em 1.5em 3em;
+  text-align: center;
 }
 .oo-ui-processDialog-errors .oo-ui-buttonWidget {
-       margin: 2em 1em 2em 1em;
+  margin: 2em 1em 2em 1em;
 }
 .oo-ui-processDialog-errors-title {
-       font-size: 1.5em;
-       color: #000;
-       margin-bottom: 2em;
+  font-size: 1.5em;
+  color: #000;
+  margin-bottom: 2em;
 }
 .oo-ui-processDialog-error {
-       text-align: left;
-       margin: 1em;
-       padding: 1em;
-       border: 1px solid #ff9e9e;
-       background-color: #fff7f7;
-       border-radius: 0.25em;
+  text-align: left;
+  margin: 1em;
+  padding: 1em;
+  border: 1px solid #ff9e9e;
+  background-color: #fff7f7;
+  border-radius: 0.25em;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog {
-       position: fixed;
-       width: 0;
-       height: 0;
-       overflow: hidden;
-       z-index: 4;
+  position: fixed;
+  width: 0;
+  height: 0;
+  overflow: hidden;
+  z-index: 4;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-active {
-       width: auto;
-       height: auto;
-       top: 0;
-       right: 0;
-       bottom: 0;
-       left: 0;
-       padding: 1em;
+  width: auto;
+  height: auto;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  padding: 1em;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
-       position: absolute;
-       right: 0;
-       left: 0;
-       margin: auto;
-       overflow: hidden;
-       max-width: 100%;
-       max-height: 100%;
+  position: absolute;
+  right: 0;
+  left: 0;
+  margin: auto;
+  overflow: hidden;
+  max-width: 100%;
+  max-height: 100%;
 }
 .oo-ui-windowManager-fullscreen > .oo-ui-dialog > .oo-ui-window-frame {
-       width: 100%;
-       height: 100%;
-       top: 0;
-       bottom: 0;
+  width: 100%;
+  height: 100%;
+  top: 0;
+  bottom: 0;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog {
-       background-color: rgba(255, 255, 255, 0.5);
-       opacity: 0;
-       -webkit-transition: opacity 250ms ease;
-          -moz-transition: opacity 250ms ease;
-               transition: opacity 250ms ease;
+  background-color: rgba(255, 255, 255, 0.5);
+  opacity: 0;
+  -webkit-transition: opacity 250ms ease;
+     -moz-transition: opacity 250ms ease;
+          transition: opacity 250ms ease;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
-       background-color: #fff;
-       opacity: 0;
-       -webkit-transform: scale(0.5);
-          -moz-transform: scale(0.5);
-           -ms-transform: scale(0.5);
-               transform: scale(0.5);
-       -webkit-transition: all 250ms ease;
-          -moz-transition: all 250ms ease;
-               transition: all 250ms ease;
+  background-color: #fff;
+  opacity: 0;
+  -webkit-transform: scale(0.5);
+     -moz-transform: scale(0.5);
+      -ms-transform: scale(0.5);
+          transform: scale(0.5);
+  -webkit-transition: all 250ms ease;
+     -moz-transition: all 250ms ease;
+          transition: all 250ms ease;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup {
-       opacity: 1;
+  opacity: 1;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
-       opacity: 1;
-       -webkit-transform: scale(1);
-          -moz-transform: scale(1);
-           -ms-transform: scale(1);
-               transform: scale(1);
+  opacity: 1;
+  -webkit-transform: scale(1);
+     -moz-transform: scale(1);
+      -ms-transform: scale(1);
+          transform: scale(1);
 }
 .oo-ui-windowManager-modal.oo-ui-windowManager-floating > .oo-ui-dialog > .oo-ui-window-frame {
-       top: 1em;
-       bottom: 1em;
-       max-height: 100%;
-       max-height: calc(100% - 2em);
-       border: 1px solid #ccc;
-       border-radius: 0.5em;
-       box-shadow: 0 0.2em 1em rgba(0, 0, 0, 0.3);
+  top: 1em;
+  bottom: 1em;
+  max-height: 100%;
+  max-height: calc(100% - 2em);
+  border: 1px solid #ccc;
+  border-radius: 0.5em;
+  box-shadow: 0 0.2em 1em rgba(0, 0, 0, 0.3);
 }
index 2c115f9..359c469 100644 (file)
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:06Z
+ * Date: 2016-11-09T00:52:42Z
  */
 .oo-ui-window {
-       background: transparent;
+  background: transparent;
 }
 .oo-ui-window-frame {
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+}
+.oo-ui-window-content {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
 }
 .oo-ui-window-content:focus {
-       outline: 0;
+  outline: 0;
 }
 .oo-ui-window-head,
 .oo-ui-window-foot {
-       -webkit-touch-callout: none;
-       -webkit-user-select: none;
-          -moz-user-select: none;
-           -ms-user-select: none;
-               user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
 }
 .oo-ui-window-body {
-       margin: 0;
-       padding: 0;
-       background: none;
+  margin: 0;
+  padding: 0;
+  background: none;
 }
 .oo-ui-window-overlay {
-       position: absolute;
-       top: 0;
-       /* @noflip */
-       left: 0;
+  position: absolute;
+  top: 0;
+  /* @noflip */
+  left: 0;
 }
 .oo-ui-dialog-content > .oo-ui-window-head,
 .oo-ui-dialog-content > .oo-ui-window-body,
 .oo-ui-dialog-content > .oo-ui-window-foot {
-       position: absolute;
-       left: 0;
-       right: 0;
-       -webkit-box-sizing: border-box;
-          -moz-box-sizing: border-box;
-               box-sizing: border-box;
+  position: absolute;
+  left: 0;
+  right: 0;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
 }
 .oo-ui-dialog-content > .oo-ui-window-head {
-       overflow: hidden;
-       z-index: 1;
-       top: 0;
+  overflow: hidden;
+  z-index: 1;
+  top: 0;
 }
 .oo-ui-dialog-content > .oo-ui-window-body {
-       overflow: auto;
-       z-index: 2;
-       top: 0;
-       bottom: 0;
+  overflow: auto;
+  z-index: 2;
+  top: 0;
+  bottom: 0;
 }
 .oo-ui-dialog-content > .oo-ui-window-foot {
-       z-index: 3;
-       bottom: 0;
+  z-index: 3;
+  bottom: 0;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget {
+  position: relative;
+  text-align: center;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
+  display: block;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
+  position: relative;
+  top: auto;
+  bottom: auto;
 }
 .oo-ui-messageDialog-actions-horizontal {
-       display: table;
-       table-layout: fixed;
-       width: 100%;
+  display: table;
+  table-layout: fixed;
+  width: 100%;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-       display: table-cell;
-       width: 1%;
+  display: table-cell;
+  width: 1%;
 }
 .oo-ui-messageDialog-actions-vertical {
-       display: block;
+  display: block;
 }
 .oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-       display: block;
-       overflow: hidden;
-       text-overflow: ellipsis;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget {
-       position: relative;
-       text-align: center;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
-       display: block;
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
-       position: relative;
-       top: auto;
-       bottom: auto;
-       display: inline;
-       white-space: nowrap;
+  display: block;
+  overflow: hidden;
+  text-overflow: ellipsis;
 }
 .oo-ui-messageDialog-content > .oo-ui-window-foot {
-       outline: 1px solid #aaa;
+  outline: 1px solid #a2a9b1;
 }
 .oo-ui-messageDialog-title,
 .oo-ui-messageDialog-message {
-       display: block;
-       text-align: center;
+  display: block;
+  text-align: center;
 }
 .oo-ui-messageDialog-title.oo-ui-labelElement,
 .oo-ui-messageDialog-message.oo-ui-labelElement {
-       padding-top: 0.5em;
+  padding-top: 0.5em;
 }
 .oo-ui-messageDialog-title {
-       font-size: 1.5em;
-       line-height: 1;
-       color: #000;
+  font-size: 1.5em;
+  line-height: 1;
+  color: #000;
 }
 .oo-ui-messageDialog-message {
-       font-size: 0.9em;
-       line-height: 1.25;
-       color: #222;
+  font-size: 0.9em;
+  line-height: 1.25;
+  color: #222;
 }
 .oo-ui-messageDialog-message-verbose {
-       font-size: 1.1em;
-       line-height: 1.5;
-       text-align: left;
+  font-size: 1.1em;
+  line-height: 1.5;
+  text-align: left;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-       border-right: 1px solid #9aa0a7;
-       margin: 0;
+  border-right: 1px solid #a2a9b1;
+  margin: 0;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
-       border-right-width: 0;
+  border-right-width: 0;
 }
 .oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-       border-bottom: 1px solid #9aa0a7;
-       margin: 0;
+  border-bottom: 1px solid #a2a9b1;
+  margin: 0;
 }
 .oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
-       border-bottom-width: 0;
+  border-bottom-width: 0;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget {
-       min-height: 3.4em;
-       margin-right: 0;
+  min-height: 3.4em;
+  margin-right: 0;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget:last-child {
-       margin-right: 0;
+  margin-right: 0;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
+  border-radius: 0;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-labelElement .oo-ui-labelElement-label {
-       line-height: 3.4;
-       text-align: center;
+  line-height: 3.4;
+  text-align: center;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget:hover {
-       background-color: rgba(0, 0, 0, 0.05);
+  background-color: rgba(0, 0, 0, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
-       background-color: rgba(0, 0, 0, 0.1);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover {
-       background-color: rgba(8, 126, 204, 0.05);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active {
-       background-color: rgba(8, 126, 204, 0.1);
-}
-.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
-       font-weight: bold;
+  background-color: rgba(0, 0, 0, 0.1);
 }
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:hover,
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
-       background-color: rgba(8, 126, 204, 0.05);
+  background-color: rgba(8, 126, 204, 0.05);
 }
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive:active,
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
-       background-color: rgba(8, 126, 204, 0.1);
+  background-color: rgba(8, 126, 204, 0.1);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label,
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive .oo-ui-labelElement-label {
+  font-weight: bold;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
-       background-color: rgba(212, 83, 83, 0.05);
+  background-color: rgba(212, 83, 83, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
-       background-color: rgba(212, 83, 83, 0.1);
+  background-color: rgba(212, 83, 83, 0.1);
 }
 .oo-ui-processDialog-location {
-       overflow: hidden;
-       text-overflow: ellipsis;
-       white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 .oo-ui-processDialog-title {
-       display: inline;
-       padding: 0;
+  display: inline;
+  padding: 0;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget {
-       white-space: nowrap;
+  white-space: nowrap;
 }
 .oo-ui-processDialog-actions-safe,
 .oo-ui-processDialog-actions-primary {
-       position: absolute;
-       top: 0;
-       bottom: 0;
+  position: absolute;
+  top: 0;
+  bottom: 0;
 }
 .oo-ui-processDialog-actions-safe {
-       left: 0;
+  left: 0;
 }
 .oo-ui-processDialog-actions-primary {
-       right: 0;
+  right: 0;
 }
 .oo-ui-processDialog-errors {
-       position: absolute;
-       top: 0;
-       left: 0;
-       right: 0;
-       bottom: 0;
-       z-index: 2;
-       overflow-x: hidden;
-       overflow-y: auto;
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 2;
+  overflow-x: hidden;
+  overflow-y: auto;
 }
 .oo-ui-processDialog-content .oo-ui-window-head {
-       height: 3.4em;
+  height: 3.4em;
 }
 .oo-ui-processDialog-content .oo-ui-window-body {
-       top: 3.4em;
-       outline: 1px solid rgba(0, 0, 0, 0.2);
+  top: 3.4em;
+  outline: 1px solid rgba(0, 0, 0, 0.2);
 }
 .oo-ui-processDialog-navigation {
-       position: relative;
-       height: 3.4em;
-       padding: 0 1em;
+  position: relative;
+  height: 3.4em;
+  padding: 0 1em;
 }
 .oo-ui-processDialog-location {
-       padding: 0.75em 0;
-       height: 1.875em;
-       cursor: default;
-       text-align: center;
+  padding: 0.75em 0;
+  height: 1.875em;
+  cursor: default;
+  text-align: center;
 }
 .oo-ui-processDialog-title {
-       font-weight: bold;
-       line-height: 1.875em;
+  font-weight: bold;
+  line-height: 1.875em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed {
-       margin: 0.5em;
+  margin: 0.5em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless {
-       margin: 0;
+  margin: 0;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-buttonElement-button {
-       padding: 0.75em 1em;
-       vertical-align: middle;
+  padding: 0.75em 1em;
+  vertical-align: middle;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-labelElement-label,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-labelElement-label,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-frameless .oo-ui-labelElement-label {
-       line-height: 1.875em;
+  line-height: 1.875em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless:hover,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless:hover {
-       background-color: rgba(0, 0, 0, 0.05);
+  background-color: rgba(0, 0, 0, 0.05);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless:active,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless:active {
-       background-color: rgba(0, 0, 0, 0.1);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:hover {
-       background-color: rgba(8, 126, 204, 0.05);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive:active {
-       background-color: rgba(8, 126, 204, 0.1);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-labelElement-label {
-       font-weight: bold;
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover {
-       background-color: rgba(118, 171, 54, 0.05);
-}
-.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active,
-.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active {
-       background-color: rgba(118, 171, 54, 0.1);
+  background-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover,
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:hover {
+  background-color: rgba(8, 126, 204, 0.05);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active,
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive:active {
+  background-color: rgba(8, 126, 204, 0.1);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-progressive .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive .oo-ui-labelElement-label {
+  font-weight: bold;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:hover,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:hover {
-       background-color: rgba(212, 83, 83, 0.05);
+  background-color: rgba(212, 83, 83, 0.05);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:active,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive:active {
-       background-color: rgba(212, 83, 83, 0.1);
+  background-color: rgba(212, 83, 83, 0.1);
 }
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement {
-       margin-right: 0;
+  margin-right: 0;
 }
 .oo-ui-processDialog > .oo-ui-window-frame {
-       min-height: 5em;
+  min-height: 5em;
 }
 .oo-ui-processDialog-errors {
-       background-color: rgba(255, 255, 255, 0.9);
-       padding: 3em 3em 1.5em 3em;
-       text-align: center;
+  background-color: rgba(255, 255, 255, 0.9);
+  padding: 3em 3em 1.5em 3em;
+  text-align: center;
 }
 .oo-ui-processDialog-errors .oo-ui-buttonWidget {
-       margin: 2em 1em 2em 1em;
+  margin: 2em 1em 2em 1em;
 }
 .oo-ui-processDialog-errors-title {
-       font-size: 1.5em;
-       color: #000;
-       margin-bottom: 2em;
+  font-size: 1.5em;
+  color: #000;
+  margin-bottom: 2em;
 }
 .oo-ui-processDialog-error {
-       text-align: left;
-       margin: 1em;
-       padding: 1em;
-       border: 1px solid #ff9e9e;
-       background-color: #fff7f7;
-       border-radius: 2px;
+  text-align: left;
+  margin: 1em;
+  padding: 1em;
+  border: 1px solid #ff9e9e;
+  background-color: #fff7f7;
+  border-radius: 2px;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog {
-       position: fixed;
-       width: 0;
-       height: 0;
-       overflow: hidden;
-       z-index: 4;
+  position: fixed;
+  width: 0;
+  height: 0;
+  overflow: hidden;
+  z-index: 4;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-active {
-       width: auto;
-       height: auto;
-       top: 0;
-       right: 0;
-       bottom: 0;
-       left: 0;
-       padding: 1em;
+  width: auto;
+  height: auto;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  padding: 1em;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
-       position: absolute;
-       right: 0;
-       left: 0;
-       margin: auto;
-       overflow: hidden;
-       max-width: 100%;
-       max-height: 100%;
+  position: absolute;
+  right: 0;
+  left: 0;
+  margin: auto;
+  overflow: hidden;
+  max-width: 100%;
+  max-height: 100%;
 }
 .oo-ui-windowManager-fullscreen > .oo-ui-dialog > .oo-ui-window-frame {
-       width: 100%;
-       height: 100%;
-       top: 0;
-       bottom: 0;
+  width: 100%;
+  height: 100%;
+  top: 0;
+  bottom: 0;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog {
-       background-color: rgba(255, 255, 255, 0.5);
-       opacity: 0;
-       -webkit-transition: opacity 250ms;
-          -moz-transition: opacity 250ms;
-               transition: opacity 250ms;
+  background-color: rgba(255, 255, 255, 0.5);
+  opacity: 0;
+  -webkit-transition: opacity 250ms;
+     -moz-transition: opacity 250ms;
+          transition: opacity 250ms;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
-       background-color: #fff;
-       opacity: 0;
-       -webkit-transform: scale(0.5);
-          -moz-transform: scale(0.5);
-           -ms-transform: scale(0.5);
-               transform: scale(0.5);
-       -webkit-transition: all 250ms;
-          -moz-transition: all 250ms;
-               transition: all 250ms;
+  background-color: #fff;
+  opacity: 0;
+  -webkit-transform: scale(0.5);
+     -moz-transform: scale(0.5);
+      -ms-transform: scale(0.5);
+          transform: scale(0.5);
+  -webkit-transition: all 250ms;
+     -moz-transition: all 250ms;
+          transition: all 250ms;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup {
-       opacity: 1;
+  opacity: 1;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
-       opacity: 1;
-       -webkit-transform: scale(1);
-          -moz-transform: scale(1);
-           -ms-transform: scale(1);
-               transform: scale(1);
+  opacity: 1;
+  -webkit-transform: scale(1);
+     -moz-transform: scale(1);
+      -ms-transform: scale(1);
+          transform: scale(1);
 }
 .oo-ui-windowManager-modal.oo-ui-windowManager-floating > .oo-ui-dialog > .oo-ui-window-frame {
-       top: 1em;
-       bottom: 1em;
-       max-height: 100%;
-       max-height: calc(100% - 2em);
-       border: 1px solid #a2a9b1;
-       border-radius: 2px;
-       box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
+  top: 1em;
+  bottom: 1em;
+  max-height: 100%;
+  max-height: calc(100% - 2em);
+  border: 1px solid #a2a9b1;
+  border-radius: 2px;
+  box-shadow: 0 0.15em 0 0 rgba(0, 0, 0, 0.15);
 }
index 8ef5ea5..8b614c6 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.17.9
+ * OOjs UI v0.18.0
  * 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-09-13T18:30:02Z
+ * Date: 2016-11-09T00:52:37Z
  */
 ( function ( OO ) {
 
@@ -804,7 +804,6 @@ OO.ui.Error.prototype.getMessageText = function () {
  *  that must be resolved before proceeding, or a function to execute. See #createStep for more information. see #createStep for more information
  * @param {Object} [context=null] Execution context of the function. The context is ignored if the step is
  *  a number or promise.
- * @return {Object} Step object, with `callback` and `context` properties
  */
 OO.ui.Process = function ( step, context ) {
        // Properties
@@ -1026,6 +1025,7 @@ OO.ui.WindowManager = function OoUiWindowManager( config ) {
        this.preparingToClose = null;
        this.currentWindow = null;
        this.globalEvents = false;
+       this.$returnFocusTo = null;
        this.$ariaHidden = null;
        this.onWindowResizeTimeout = null;
        this.onWindowResizeHandler = this.onWindowResize.bind( this );
@@ -1142,6 +1142,7 @@ OO.ui.WindowManager.prototype.afterWindowResize = function () {
 /**
  * Check if window is opening.
  *
+ * @param {OO.ui.Window} win Window to check
  * @return {boolean} Window is opening
  */
 OO.ui.WindowManager.prototype.isOpening = function ( win ) {
@@ -1151,6 +1152,7 @@ OO.ui.WindowManager.prototype.isOpening = function ( win ) {
 /**
  * Check if window is closing.
  *
+ * @param {OO.ui.Window} win Window to check
  * @return {boolean} Window is closing
  */
 OO.ui.WindowManager.prototype.isClosing = function ( win ) {
@@ -1160,6 +1162,7 @@ OO.ui.WindowManager.prototype.isClosing = function ( win ) {
 /**
  * Check if window is opened.
  *
+ * @param {OO.ui.Window} win Window to check
  * @return {boolean} Window is opened
  */
 OO.ui.WindowManager.prototype.isOpened = function ( win ) {
@@ -1283,6 +1286,7 @@ OO.ui.WindowManager.prototype.getCurrentWindow = function () {
  *
  * @param {OO.ui.Window|string} win Window object or symbolic name of window to open
  * @param {Object} [data] Window opening data
+ * @param {jQuery} [data.$returnFocusTo] Element to which the window will return focus when closed.
  * @return {jQuery.Promise} An `opening` promise resolved when the window is done opening.
  *  See {@link #event-opening 'opening' event}  for more information about `opening` promises.
  * @fires opening
@@ -1290,6 +1294,7 @@ OO.ui.WindowManager.prototype.getCurrentWindow = function () {
 OO.ui.WindowManager.prototype.openWindow = function ( win, data ) {
        var manager = this,
                opening = $.Deferred();
+       data = data || {};
 
        // Argument handling
        if ( typeof win === 'string' ) {
@@ -1319,6 +1324,7 @@ OO.ui.WindowManager.prototype.openWindow = function ( win, data ) {
                                manager.toggleGlobalEvents( true );
                                manager.toggleAriaIsolation( true );
                        }
+                       manager.$returnFocusTo = data.$returnFocusTo || $( document.activeElement );
                        manager.currentWindow = win;
                        manager.opening = opening;
                        manager.preparingToOpen = null;
@@ -1412,6 +1418,7 @@ OO.ui.WindowManager.prototype.closeWindow = function ( win, data ) {
                                                                manager.toggleGlobalEvents( false );
                                                                manager.toggleAriaIsolation( false );
                                                        }
+                                                       manager.$returnFocusTo[ 0 ].focus();
                                                        manager.closing = null;
                                                        manager.currentWindow = null;
                                                        closing.resolve( data );
@@ -1448,6 +1455,9 @@ OO.ui.WindowManager.prototype.addWindows = function ( windows ) {
                        if ( typeof name !== 'string' ) {
                                throw new Error( 'Cannot add window' );
                        }
+                       if ( !name ) {
+                               OO.ui.warnDeprecation( 'OO.ui.WindowManager#addWindows: Windows must have a `name` static property defined.' );
+                       }
                        list[ name ] = windows[ i ];
                }
        } else if ( OO.isPlainObject( windows ) ) {
@@ -1514,6 +1524,7 @@ OO.ui.WindowManager.prototype.clearWindows = function () {
  *
  * Fullscreen mode will be used if the dialog is too wide to fit in the screen.
  *
+ * @param {OO.ui.Window} win Window to update, should be the current window
  * @chainable
  */
 OO.ui.WindowManager.prototype.updateWindowSize = function ( win ) {
@@ -1852,17 +1863,20 @@ OO.ui.Window.prototype.getSizeProperties = function () {
 OO.ui.Window.prototype.withoutSizeTransitions = function ( callback ) {
        // Temporarily resize the frame so getBodyHeight() can use scrollHeight measurements.
        // Disable transitions first, otherwise we'll get values from when the window was animating.
-       var oldTransition,
-               styleObj = this.$frame[ 0 ].style;
-       oldTransition = styleObj.transition || styleObj.OTransition || styleObj.MsTransition ||
-               styleObj.MozTransition || styleObj.WebkitTransition;
-       styleObj.transition = styleObj.OTransition = styleObj.MsTransition =
-               styleObj.MozTransition = styleObj.WebkitTransition = 'none';
+       // We need to build the transition CSS properties using these specific properties since
+       // Firefox doesn't return anything useful when asked just for 'transition'.
+       var oldTransition = this.$frame.css( 'transition-property' ) + ' ' +
+               this.$frame.css( 'transition-duration' ) + ' ' +
+               this.$frame.css( 'transition-timing-function' ) + ' ' +
+               this.$frame.css( 'transition-delay' );
+
+       this.$frame.css( 'transition', 'none' );
        callback();
-       // Force reflow to make sure the style changes done inside callback really are not transitioned
+
+       // Force reflow to make sure the style changes done inside callback
+       // really are not transitioned
        this.$frame.height();
-       styleObj.transition = styleObj.OTransition = styleObj.MsTransition =
-               styleObj.MozTransition = styleObj.WebkitTransition = oldTransition;
+       this.$frame.css( 'transition', oldTransition );
 };
 
 /**
index 703911b..809cd02 100644 (file)
@@ -7,10 +7,6 @@
                "imageGallery": { "file": {
                        "ltr": "images/icons/imageGallery-ltr.svg",
                        "rtl": "images/icons/imageGallery-rtl.svg"
-               } },
-               "photoGallery": { "file": {
-                       "ltr": "images/icons/imageGallery-ltr.svg",
-                       "rtl": "images/icons/imageGallery-rtl.svg"
                } }
        }
 }
index 82fbd14..e8b2911 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/bigger-ltr.png and b/resources/lib/oojs-ui/themes/apex/images/icons/bigger-ltr.png differ
index 6d95fc6..fffbcdd 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
-    <g id="up">
-        <path id="arrow" d="M15.5 9h7L19 3z"/>
-    </g>
+    <path id="big-a" d="M14.334 6h1.372l4.48 12H18.48l-1.493-4h-4l-1.507 4H9.814zm2.28 7l-1.617-4.333L13.363 13h3.25z"/>
+    <path id="small-a" d="M6.172 12h.686l2.24 6h-.853L7.5 16H5.497l-.753 2h-.833zm1.14 3.5l-.81-2.166-.816 2.166h1.625z"/>
+    <path id="arrow" d="M9 9H4l2.5-3z"/>
 </svg>
index 64d1cf1..2f5e05d 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/bigger-rtl.png and b/resources/lib/oojs-ui/themes/apex/images/icons/bigger-rtl.png differ
index 807cdd9..7b903c4 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
-    <g id="up">
-        <path id="arrow" d="M1.5 9h7L5 3z"/>
-    </g>
+    <path id="big-a" d="M9.666 6H8.294l-4.48 12H5.52l1.493-4h4l1.507 4h1.666zm-2.28 7l1.617-4.333L10.637 13h-3.25z"/>
+    <path id="small-a" d="M17.828 12h-.686l-2.24 6h.853l.747-2h2l.753 2h.833zm-1.14 3.5l.81-2.167.816 2.167H16.69z"/>
+    <path id="arrow" d="M15 9h5l-2.5-3z"/>
 </svg>
index f5e89ba..a9b29d8 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/smaller-ltr.png and b/resources/lib/oojs-ui/themes/apex/images/icons/smaller-ltr.png differ
index 82d16af..9431252 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
-    <g id="down">
-        <path id="arrow" d="M22 3l-3.5 6L15 3z"/>
-    </g>
+    <path id="big-a" d="M9.666 6H8.294l-4.48 12H5.52l1.493-4h4l1.507 4h1.666zm-2.28 7l1.617-4.333L10.637 13h-3.25z"/>
+    <path id="small-a" d="M17.828 12h-.686l-2.24 6h.853l.747-2h2l.753 2h.833zm-1.14 3.5l.81-2.167.816 2.167H16.69z"/>
+    <path id="arrow" d="M15 6h5l-2.5 3z"/>
 </svg>
index e07c7b0..006bd2b 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/smaller-rtl.png and b/resources/lib/oojs-ui/themes/apex/images/icons/smaller-rtl.png differ
index 7466f48..d2d2858 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
-    <g id="down">
-        <path id="arrow" d="M9 3L5.5 9 2 3z"/>
-    </g>
+    <path id="big-a" d="M14.334 6h1.372l4.48 12H18.48l-1.493-4h-4l-1.507 4H9.814zm2.28 7l-1.617-4.333L13.363 13h3.25z"/>
+    <path id="small-a" d="M6.172 12h.686l2.24 6h-.853L7.5 16H5.497l-.753 2h-.833zm1.14 3.5l-.81-2.166-.816 2.166h1.625z"/>
+    <path id="arrow" d="M9 6H4l2.5 3z"/>
 </svg>
index 3911956..8c7b845 100644 (file)
                        "ltr": "images/icons/imageGallery-ltr.svg",
                        "rtl": "images/icons/imageGallery-rtl.svg"
                } },
-               "photoGallery": { "file": {
-                       "ltr": "images/icons/imageGallery-ltr.svg",
-                       "rtl": "images/icons/imageGallery-rtl.svg"
-               } },
                "play": { "file": {
                        "ltr": "images/icons/play-ltr.svg",
                        "rtl": "images/icons/play-rtl.svg"
index 97f77f4..ad247d3 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-ltr-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-ltr-invert.png differ
index 26f9653..b5ce7e7 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
-    <path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
-    <g id="up">
-        <path id="arrow" d="M15.5 9h7L19 3z"/>
-    </g>
+    <path id="big-a" d="M14.334 6h1.372l4.48 12H18.48l-1.493-4h-4l-1.507 4H9.814zm2.28 7l-1.617-4.333L13.363 13h3.25z"/>
+    <path id="small-a" d="M6.172 12h.686l2.24 6h-.853L7.5 16H5.497l-.753 2h-.833zm1.14 3.5l-.81-2.166-.816 2.166h1.625z"/>
+    <path id="arrow" d="M9 9H4l2.5-3z"/>
 </svg>
index 183aaeb..af290b9 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-ltr-progressive.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-ltr-progressive.png differ
index fedf787..e1f33d8 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
-    <path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
-    <g id="up">
-        <path id="arrow" d="M15.5 9h7L19 3z"/>
-    </g>
+    <path id="big-a" d="M14.334 6h1.372l4.48 12H18.48l-1.493-4h-4l-1.507 4H9.814zm2.28 7l-1.617-4.333L13.363 13h3.25z"/>
+    <path id="small-a" d="M6.172 12h.686l2.24 6h-.853L7.5 16H5.497l-.753 2h-.833zm1.14 3.5l-.81-2.166-.816 2.166h1.625z"/>
+    <path id="arrow" d="M9 9H4l2.5-3z"/>
 </svg>
index 82fbd14..e8b2911 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-ltr.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-ltr.png differ
index 6d95fc6..fffbcdd 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
-    <g id="up">
-        <path id="arrow" d="M15.5 9h7L19 3z"/>
-    </g>
+    <path id="big-a" d="M14.334 6h1.372l4.48 12H18.48l-1.493-4h-4l-1.507 4H9.814zm2.28 7l-1.617-4.333L13.363 13h3.25z"/>
+    <path id="small-a" d="M6.172 12h.686l2.24 6h-.853L7.5 16H5.497l-.753 2h-.833zm1.14 3.5l-.81-2.166-.816 2.166h1.625z"/>
+    <path id="arrow" d="M9 9H4l2.5-3z"/>
 </svg>
index 628de3d..f40c303 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-rtl-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-rtl-invert.png differ
index aeb562c..8ed760b 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
-    <path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
-    <g id="up">
-        <path id="arrow" d="M1.5 9h7L5 3z"/>
-    </g>
+    <path id="big-a" d="M9.666 6H8.294l-4.48 12H5.52l1.493-4h4l1.507 4h1.666zm-2.28 7l1.617-4.333L10.637 13h-3.25z"/>
+    <path id="small-a" d="M17.828 12h-.686l-2.24 6h.853l.747-2h2l.753 2h.833zm-1.14 3.5l.81-2.167.816 2.167H16.69z"/>
+    <path id="arrow" d="M15 9h5l-2.5-3z"/>
 </svg>
index 47af038..a5095a1 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-rtl-progressive.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-rtl-progressive.png differ
index 6c7b5fc..34ec7c0 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
-    <path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
-    <g id="up">
-        <path id="arrow" d="M1.5 9h7L5 3z"/>
-    </g>
+    <path id="big-a" d="M9.666 6H8.294l-4.48 12H5.52l1.493-4h4l1.507 4h1.666zm-2.28 7l1.617-4.333L10.637 13h-3.25z"/>
+    <path id="small-a" d="M17.828 12h-.686l-2.24 6h.853l.747-2h2l.753 2h.833zm-1.14 3.5l.81-2.167.816 2.167H16.69z"/>
+    <path id="arrow" d="M15 9h5l-2.5-3z"/>
 </svg>
index 64d1cf1..2f5e05d 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-rtl.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/bigger-rtl.png differ
index 807cdd9..7b903c4 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z" id="a"/>
-    <g id="up">
-        <path id="arrow" d="M1.5 9h7L5 3z"/>
-    </g>
+    <path id="big-a" d="M9.666 6H8.294l-4.48 12H5.52l1.493-4h4l1.507 4h1.666zm-2.28 7l1.617-4.333L10.637 13h-3.25z"/>
+    <path id="small-a" d="M17.828 12h-.686l-2.24 6h.853l.747-2h2l.753 2h.833zm-1.14 3.5l.81-2.167.816 2.167H16.69z"/>
+    <path id="arrow" d="M15 9h5l-2.5-3z"/>
 </svg>
index 84b1bcd..1b597da 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-ltr-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-ltr-invert.png differ
index 0eb2bfa..b29f718 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
-    <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
-    <g id="down">
-        <path id="arrow" d="M22 3l-3.5 6L15 3z"/>
-    </g>
+    <path id="big-a" d="M9.666 6H8.294l-4.48 12H5.52l1.493-4h4l1.507 4h1.666zm-2.28 7l1.617-4.333L10.637 13h-3.25z"/>
+    <path id="small-a" d="M17.828 12h-.686l-2.24 6h.853l.747-2h2l.753 2h.833zm-1.14 3.5l.81-2.167.816 2.167H16.69z"/>
+    <path id="arrow" d="M15 6h5l-2.5 3z"/>
 </svg>
index ba4fcef..2878f23 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-ltr-progressive.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-ltr-progressive.png differ
index b3c6452..9b7962e 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
-    <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
-    <g id="down">
-        <path id="arrow" d="M22 3l-3.5 6L15 3z"/>
-    </g>
+    <path id="big-a" d="M9.666 6H8.294l-4.48 12H5.52l1.493-4h4l1.507 4h1.666zm-2.28 7l1.617-4.333L10.637 13h-3.25z"/>
+    <path id="small-a" d="M17.828 12h-.686l-2.24 6h.853l.747-2h2l.753 2h.833zm-1.14 3.5l.81-2.167.816 2.167H16.69z"/>
+    <path id="arrow" d="M15 6h5l-2.5 3z"/>
 </svg>
index f5e89ba..a9b29d8 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-ltr.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-ltr.png differ
index 82d16af..9431252 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
-    <g id="down">
-        <path id="arrow" d="M22 3l-3.5 6L15 3z"/>
-    </g>
+    <path id="big-a" d="M9.666 6H8.294l-4.48 12H5.52l1.493-4h4l1.507 4h1.666zm-2.28 7l1.617-4.333L10.637 13h-3.25z"/>
+    <path id="small-a" d="M17.828 12h-.686l-2.24 6h.853l.747-2h2l.753 2h.833zm-1.14 3.5l.81-2.167.816 2.167H16.69z"/>
+    <path id="arrow" d="M15 6h5l-2.5 3z"/>
 </svg>
index c9cdd77..f94184a 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-rtl-invert.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-rtl-invert.png differ
index a87f7ba..171b31d 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
-    <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
-    <g id="down">
-        <path id="arrow" d="M9 3L5.5 9 2 3z"/>
-    </g>
+    <path id="big-a" d="M14.334 6h1.372l4.48 12H18.48l-1.493-4h-4l-1.507 4H9.814zm2.28 7l-1.617-4.333L13.363 13h3.25z"/>
+    <path id="small-a" d="M6.172 12h.686l2.24 6h-.853L7.5 16H5.497l-.753 2h-.833zm1.14 3.5l-.81-2.166-.816 2.166h1.625z"/>
+    <path id="arrow" d="M9 6H4l2.5 3z"/>
 </svg>
index 03a4bcc..99abfdb 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-rtl-progressive.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-rtl-progressive.png differ
index 64d103c..23c0b09 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
-    <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
-    <g id="down">
-        <path id="arrow" d="M9 3L5.5 9 2 3z"/>
-    </g>
+    <path id="big-a" d="M14.334 6h1.372l4.48 12H18.48l-1.493-4h-4l-1.507 4H9.814zm2.28 7l-1.617-4.333L13.363 13h3.25z"/>
+    <path id="small-a" d="M6.172 12h.686l2.24 6h-.853L7.5 16H5.497l-.753 2h-.833zm1.14 3.5l-.81-2.166-.816 2.166h1.625z"/>
+    <path id="arrow" d="M9 6H4l2.5 3z"/>
 </svg>
index e07c7b0..006bd2b 100644 (file)
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-rtl.png and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/smaller-rtl.png differ
index 7466f48..d2d2858 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path id="a" d="M12.666 6h-1.372l-4.48 12H8.52l1.493-4h4l1.507 4h1.666l-4.52-12zm-2.28 7l1.617-4.333L13.637 13h-3.25z"/>
-    <g id="down">
-        <path id="arrow" d="M9 3L5.5 9 2 3z"/>
-    </g>
+    <path id="big-a" d="M14.334 6h1.372l4.48 12H18.48l-1.493-4h-4l-1.507 4H9.814zm2.28 7l-1.617-4.333L13.363 13h3.25z"/>
+    <path id="small-a" d="M6.172 12h.686l2.24 6h-.853L7.5 16H5.497l-.753 2h-.833zm1.14 3.5l-.81-2.166-.816 2.166h1.625z"/>
+    <path id="arrow" d="M9 6H4l2.5 3z"/>
 </svg>
index e52d6a7..f25944c 100644 (file)
  */
 ( function ( $, mw ) {
 
-// Cached access key modifiers for used browser
-var cachedAccessKeyModifiers,
-
-       // Whether to use 'test-' instead of correct prefix (used for testing)
-       useTestPrefix = false,
-
-       // tag names which can have a label tag
-       // https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Form-associated_content
-       labelable = 'button, input, textarea, keygen, meter, output, progress, select';
-
-/**
- * Find the modifier keys that need to be pressed together with the accesskey to trigger the input.
- *
- * The result is dependant on the ua paramater or the current platform.
- * For browsers that support accessKeyLabel, #getAccessKeyLabel never calls here.
- * Valid key values that are returned can be: ctrl, alt, option, shift, esc
- *
- * @private
- * @param {Object} [ua] An object with a 'userAgent' and 'platform' property.
- * @return {Array} Array with 0 or more of the string values: ctrl, option, alt, shift, esc
- */
-function getAccessKeyModifiers( ua ) {
-       // use cached prefix if possible
-       if ( !ua && cachedAccessKeyModifiers ) {
-               return cachedAccessKeyModifiers;
-       }
+       // Cached access key modifiers for used browser
+       var cachedAccessKeyModifiers,
+
+               // Whether to use 'test-' instead of correct prefix (used for testing)
+               useTestPrefix = false,
+
+               // tag names which can have a label tag
+               // https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Form-associated_content
+               labelable = 'button, input, textarea, keygen, meter, output, progress, select';
+
+       /**
+        * Find the modifier keys that need to be pressed together with the accesskey to trigger the input.
+        *
+        * The result is dependant on the ua paramater or the current platform.
+        * For browsers that support accessKeyLabel, #getAccessKeyLabel never calls here.
+        * Valid key values that are returned can be: ctrl, alt, option, shift, esc
+        *
+        * @private
+        * @param {Object} [ua] An object with a 'userAgent' and 'platform' property.
+        * @return {Array} Array with 0 or more of the string values: ctrl, option, alt, shift, esc
+        */
+       function getAccessKeyModifiers( ua ) {
+               var profile, accessKeyModifiers;
+
+               // use cached prefix if possible
+               if ( !ua && cachedAccessKeyModifiers ) {
+                       return cachedAccessKeyModifiers;
+               }
 
-       var profile = $.client.profile( ua ),
+               profile = $.client.profile( ua );
                accessKeyModifiers = [ 'alt' ];
 
-       // Classic Opera on any platform
-       if ( profile.name === 'opera' && profile.versionNumber < 15 ) {
-               accessKeyModifiers = [ 'shift', 'esc' ];
-
-       // Chrome and modern Opera on any platform
-       } else if ( profile.name === 'chrome' || profile.name === 'opera' ) {
-               accessKeyModifiers = (
-                       profile.platform === 'mac'
-                               // Chrome on Mac
-                               ? [ 'ctrl', 'option' ]
-                               // Chrome on Windows or Linux
-                               // (both alt- and alt-shift work, but alt with E, D, F etc does not
-                               // work since they are browser shortcuts)
-                               : [ 'alt', 'shift' ]
-               );
-
-       // Non-Windows Safari with webkit_version > 526
-       } else if ( profile.platform !== 'win'
-               && profile.name === 'safari'
-               && profile.layoutVersion > 526
-       ) {
-               accessKeyModifiers = [ 'ctrl', 'alt' ];
-
-       // Safari/Konqueror on any platform, or any browser on Mac
-       // (but not Safari on Windows)
-       } else if ( !( profile.platform === 'win' && profile.name === 'safari' )
-               && ( profile.name === 'safari'
-               || profile.platform === 'mac'
-               || profile.name === 'konqueror' )
-       ) {
-               accessKeyModifiers = [ 'ctrl' ];
-
-       // Firefox/Iceweasel 2.x and later
-       } else if ( ( profile.name === 'firefox' || profile.name === 'iceweasel' )
-               && profile.versionBase > '1'
-       ) {
-               accessKeyModifiers = [ 'alt', 'shift' ];
-       }
+               // Classic Opera on any platform
+               if ( profile.name === 'opera' && profile.versionNumber < 15 ) {
+                       accessKeyModifiers = [ 'shift', 'esc' ];
+
+               // Chrome and modern Opera on any platform
+               } else if ( profile.name === 'chrome' || profile.name === 'opera' ) {
+                       accessKeyModifiers = (
+                               profile.platform === 'mac' ?
+                                       // Chrome on Mac
+                                       [ 'ctrl', 'option' ] :
+                                       // Chrome on Windows or Linux
+                                       // (both alt- and alt-shift work, but alt with E, D, F etc does not
+                                       // work since they are browser shortcuts)
+                                       [ 'alt', 'shift' ]
+                       );
+
+               // Non-Windows Safari with webkit_version > 526
+               } else if ( profile.platform !== 'win' &&
+                       profile.name === 'safari' &&
+                       profile.layoutVersion > 526
+               ) {
+                       accessKeyModifiers = [ 'ctrl', 'alt' ];
+
+               // Safari/Konqueror on any platform, or any browser on Mac
+               // (but not Safari on Windows)
+               } else if (
+                       !( profile.platform === 'win' && profile.name === 'safari' ) &&
+                       (
+                               profile.name === 'safari' ||
+                               profile.platform === 'mac' ||
+                               profile.name === 'konqueror'
+                       )
+               ) {
+                       accessKeyModifiers = [ 'ctrl' ];
+
+               // Firefox/Iceweasel 2.x and later
+               } else if (
+                       ( profile.name === 'firefox' || profile.name === 'iceweasel' ) &&
+                       profile.versionBase > '1'
+               ) {
+                       accessKeyModifiers = [ 'alt', 'shift' ];
+               }
 
-       // cache modifiers
-       if ( !ua ) {
-               cachedAccessKeyModifiers = accessKeyModifiers;
+               // cache modifiers
+               if ( !ua ) {
+                       cachedAccessKeyModifiers = accessKeyModifiers;
+               }
+               return accessKeyModifiers;
        }
-       return accessKeyModifiers;
-}
 
-/**
- * Get the access key label for an element.
- *
- * Will use native accessKeyLabel if available (currently only in Firefox 8+),
- * falls back to #getAccessKeyModifiers.
- *
- * @private
- * @param {HTMLElement} element Element to get the label for
- * @return {string} Access key label
- */
-function getAccessKeyLabel( element ) {
-       // abort early if no access key
-       if ( !element.accessKey ) {
-               return '';
-       }
-       // use accessKeyLabel if possible
-       // http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#dom-accesskeylabel
-       if ( !useTestPrefix && element.accessKeyLabel ) {
-               return element.accessKeyLabel;
+       /**
+        * Get the access key label for an element.
+        *
+        * Will use native accessKeyLabel if available (currently only in Firefox 8+),
+        * falls back to #getAccessKeyModifiers.
+        *
+        * @private
+        * @param {HTMLElement} element Element to get the label for
+        * @return {string} Access key label
+        */
+       function getAccessKeyLabel( element ) {
+               // abort early if no access key
+               if ( !element.accessKey ) {
+                       return '';
+               }
+               // use accessKeyLabel if possible
+               // https://html.spec.whatwg.org/multipage/interaction.html#dom-accesskeylabel
+               if ( !useTestPrefix && element.accessKeyLabel ) {
+                       return element.accessKeyLabel;
+               }
+               return ( useTestPrefix ? 'test' : getAccessKeyModifiers().join( '-' ) ) + '-' + element.accessKey;
        }
-       return ( useTestPrefix ? 'test' : getAccessKeyModifiers().join( '-' ) ) + '-' + element.accessKey;
-}
-
-/**
- * Update the title for an element (on the element with the access key or it's label) to show
- * the correct access key label.
- *
- * @private
- * @param {HTMLElement} element Element with the accesskey
- * @param {HTMLElement} titleElement Element with the title to update (may be the same as `element`)
- */
-function updateTooltipOnElement( element, titleElement ) {
-       var oldTitle, parts, regexp, newTitle, accessKeyLabel;
 
-       oldTitle = titleElement.title;
-       if ( !oldTitle ) {
-               // don't add a title if the element didn't have one before
-               return;
-       }
+       /**
+        * Update the title for an element (on the element with the access key or it's label) to show
+        * the correct access key label.
+        *
+        * @private
+        * @param {HTMLElement} element Element with the accesskey
+        * @param {HTMLElement} titleElement Element with the title to update (may be the same as `element`)
+        */
+       function updateTooltipOnElement( element, titleElement ) {
+               var oldTitle, parts, regexp, newTitle, accessKeyLabel;
+
+               oldTitle = titleElement.title;
+               if ( !oldTitle ) {
+                       // don't add a title if the element didn't have one before
+                       return;
+               }
 
-       parts = ( mw.msg( 'word-separator' ) + mw.msg( 'brackets' ) ).split( '$1' );
-       regexp = new RegExp( $.map( parts, mw.RegExp.escape ).join( '.*?' ) + '$' );
-       newTitle = oldTitle.replace( regexp, '' );
-       accessKeyLabel = getAccessKeyLabel( element );
+               parts = ( mw.msg( 'word-separator' ) + mw.msg( 'brackets' ) ).split( '$1' );
+               regexp = new RegExp( $.map( parts, mw.RegExp.escape ).join( '.*?' ) + '$' );
+               newTitle = oldTitle.replace( regexp, '' );
+               accessKeyLabel = getAccessKeyLabel( element );
 
-       if ( accessKeyLabel ) {
-               // Should be build the same as in Linker::titleAttrib
-               newTitle += mw.msg( 'word-separator' ) + mw.msg( 'brackets', accessKeyLabel );
-       }
-       if ( oldTitle !== newTitle ) {
-               titleElement.title = newTitle;
+               if ( accessKeyLabel ) {
+                       // Should be build the same as in Linker::titleAttrib
+                       newTitle += mw.msg( 'word-separator' ) + mw.msg( 'brackets', accessKeyLabel );
+               }
+               if ( oldTitle !== newTitle ) {
+                       titleElement.title = newTitle;
+               }
        }
-}
 
-/**
- * Update the title for an element to show the correct access key label.
- *
- * @private
- * @param {HTMLElement} element Element with the accesskey
- */
-function updateTooltip( element ) {
-       var id, $element, $label, $labelParent;
-       updateTooltipOnElement( element, element );
-
-       // update associated label if there is one
-       $element = $( element );
-       if ( $element.is( labelable ) ) {
-               // Search it using 'for' attribute
-               id = element.id.replace( /"/g, '\\"' );
-               if ( id ) {
-                       $label = $( 'label[for="' + id + '"]' );
-                       if ( $label.length === 1 ) {
-                               updateTooltipOnElement( element, $label[ 0 ] );
+       /**
+        * Update the title for an element to show the correct access key label.
+        *
+        * @private
+        * @param {HTMLElement} element Element with the accesskey
+        */
+       function updateTooltip( element ) {
+               var id, $element, $label, $labelParent;
+               updateTooltipOnElement( element, element );
+
+               // update associated label if there is one
+               $element = $( element );
+               if ( $element.is( labelable ) ) {
+                       // Search it using 'for' attribute
+                       id = element.id.replace( /"/g, '\\"' );
+                       if ( id ) {
+                               $label = $( 'label[for="' + id + '"]' );
+                               if ( $label.length === 1 ) {
+                                       updateTooltipOnElement( element, $label[ 0 ] );
+                               }
                        }
-               }
 
-               // Search it as parent, because the form control can also be inside the label element itself
-               $labelParent = $element.parents( 'label' );
-               if ( $labelParent.length === 1 ) {
-                       updateTooltipOnElement( element, $labelParent[ 0 ] );
+                       // Search it as parent, because the form control can also be inside the label element itself
+                       $labelParent = $element.parents( 'label' );
+                       if ( $labelParent.length === 1 ) {
+                               updateTooltipOnElement( element, $labelParent[ 0 ] );
+                       }
                }
        }
-}
-
-/**
- * Update the titles for all elements in a jQuery selection.
- *
- * @return {jQuery}
- * @chainable
- */
-$.fn.updateTooltipAccessKeys = function () {
-       return this.each( function () {
-               updateTooltip( this );
-       } );
-};
 
-/**
- * getAccessKeyModifiers
- *
- * @method updateTooltipAccessKeys_getAccessKeyModifiers
- * @inheritdoc #getAccessKeyModifiers
- */
-$.fn.updateTooltipAccessKeys.getAccessKeyModifiers = getAccessKeyModifiers;
-
-/**
- * getAccessKeyLabel
- *
- * @method updateTooltipAccessKeys_getAccessKeyLabel
- * @inheritdoc #getAccessKeyLabel
- */
-$.fn.updateTooltipAccessKeys.getAccessKeyLabel = getAccessKeyLabel;
-
-/**
- * getAccessKeyPrefix
- *
- * @method updateTooltipAccessKeys_getAccessKeyPrefix
- * @deprecated since 1.27 Use #getAccessKeyModifiers
- */
-$.fn.updateTooltipAccessKeys.getAccessKeyPrefix = function ( ua ) {
-       return getAccessKeyModifiers( ua ).join( '-' ) + '-';
-};
-
-/**
- * Switch test mode on and off.
- *
- * @method updateTooltipAccessKeys_setTestMode
- * @param {boolean} mode New mode
- */
-$.fn.updateTooltipAccessKeys.setTestMode = function ( mode ) {
-       useTestPrefix = mode;
-};
-
-/**
- * @class jQuery
- * @mixins jQuery.plugin.accessKeyLabel
- */
+       /**
+        * Update the titles for all elements in a jQuery selection.
+        *
+        * @return {jQuery}
+        * @chainable
+        */
+       $.fn.updateTooltipAccessKeys = function () {
+               return this.each( function () {
+                       updateTooltip( this );
+               } );
+       };
+
+       /**
+        * getAccessKeyModifiers
+        *
+        * @method updateTooltipAccessKeys_getAccessKeyModifiers
+        * @inheritdoc #getAccessKeyModifiers
+        */
+       $.fn.updateTooltipAccessKeys.getAccessKeyModifiers = getAccessKeyModifiers;
+
+       /**
+        * getAccessKeyLabel
+        *
+        * @method updateTooltipAccessKeys_getAccessKeyLabel
+        * @inheritdoc #getAccessKeyLabel
+        */
+       $.fn.updateTooltipAccessKeys.getAccessKeyLabel = getAccessKeyLabel;
+
+       /**
+        * getAccessKeyPrefix
+        *
+        * @method updateTooltipAccessKeys_getAccessKeyPrefix
+        * @deprecated since 1.27 Use #getAccessKeyModifiers
+        * @param {Object} [ua] An object with a 'userAgent' and 'platform' property.
+        * @return {string}
+        */
+       $.fn.updateTooltipAccessKeys.getAccessKeyPrefix = function ( ua ) {
+               return getAccessKeyModifiers( ua ).join( '-' ) + '-';
+       };
+
+       /**
+        * Switch test mode on and off.
+        *
+        * @method updateTooltipAccessKeys_setTestMode
+        * @param {boolean} mode New mode
+        */
+       $.fn.updateTooltipAccessKeys.setTestMode = function ( mode ) {
+               useTestPrefix = mode;
+       };
+
+       /**
+        * @class jQuery
+        * @mixins jQuery.plugin.accessKeyLabel
+        */
 
 }( jQuery, mediaWiki ) );
index fd7e8d1..8716b69 100644 (file)
  */
 ( function ( $ ) {
 
-var
-       // Cache ellipsed substrings for every string-width-position combination
-       cache = {},
+       var
+               // Cache ellipsed substrings for every string-width-position combination
+               cache = {},
 
-       // Use a separate cache when match highlighting is enabled
-       matchTextCache = {};
+               // Use a separate cache when match highlighting is enabled
+               matchTextCache = {};
 
-// Due to <https://github.com/jscs-dev/jscs-jsdoc/issues/136>
-// jscs:disable jsDoc
-/**
- * Automatically truncate the plain text contents of an element and add an ellipsis
- *
- * @param {Object} options
- * @param {'left'|'center'|'right'} [options.position='center'] Where to remove text.
- * @param {boolean} [options.tooltip=false] Whether to show a tooltip with the remainder
- * of the text.
- * @param {boolean} [options.restoreText=false] Whether to save the text for restoring
- * later.
- * @param {boolean} [options.hasSpan=false] Whether the element is already a container,
- * or if the library should create a new container for it.
- * @param {string|null} [options.matchText=null] Text to highlight, e.g. search terms.
- * @return {jQuery}
- * @chainable
- */
-$.fn.autoEllipsis = function ( options ) {
-       options = $.extend( {
-               position: 'center',
-               tooltip: false,
-               restoreText: false,
-               hasSpan: false,
-               matchText: null
-       }, options );
+       // Due to <https://github.com/jscs-dev/jscs-jsdoc/issues/136>
+       // jscs:disable jsDoc
+       /**
       * Automatically truncate the plain text contents of an element and add an ellipsis
       *
       * @param {Object} options
       * @param {'left'|'center'|'right'} [options.position='center'] Where to remove text.
       * @param {boolean} [options.tooltip=false] Whether to show a tooltip with the remainder
       * of the text.
       * @param {boolean} [options.restoreText=false] Whether to save the text for restoring
       * later.
       * @param {boolean} [options.hasSpan=false] Whether the element is already a container,
       * or if the library should create a new container for it.
       * @param {string|null} [options.matchText=null] Text to highlight, e.g. search terms.
       * @return {jQuery}
       * @chainable
       */
+       $.fn.autoEllipsis = function ( options ) {
+               options = $.extend( {
+                       position: 'center',
+                       tooltip: false,
+                       restoreText: false,
+                       hasSpan: false,
+                       matchText: null
+               }, options );
 
-       return this.each( function () {
-               var $trimmableText,
-                       text, trimmableText, w, pw,
-                       l, r, i, side, m,
-                       // container element - used for measuring against
-                       $container = $( this );
+               return this.each( function () {
+                       var $trimmableText,
+                               text, trimmableText, w, pw,
+                               l, r, i, side, m,
+                               // container element - used for measuring against
+                               $container = $( this );
 
-               if ( options.restoreText ) {
-                       if ( !$container.data( 'autoEllipsis.originalText' ) ) {
-                               $container.data( 'autoEllipsis.originalText', $container.text() );
-                       } else {
-                               $container.text( $container.data( 'autoEllipsis.originalText' ) );
+                       if ( options.restoreText ) {
+                               if ( !$container.data( 'autoEllipsis.originalText' ) ) {
+                                       $container.data( 'autoEllipsis.originalText', $container.text() );
+                               } else {
+                                       $container.text( $container.data( 'autoEllipsis.originalText' ) );
+                               }
                        }
-               }
 
-               // trimmable text element - only the text within this element will be trimmed
-               if ( options.hasSpan ) {
-                       $trimmableText = $container.children( options.selector );
-               } else {
-                       $trimmableText = $( '<span>' )
-                               .css( 'whiteSpace', 'nowrap' )
-                               .text( $container.text() );
-                       $container
-                               .empty()
-                               .append( $trimmableText );
-               }
+                       // trimmable text element - only the text within this element will be trimmed
+                       if ( options.hasSpan ) {
+                               $trimmableText = $container.children( options.selector );
+                       } else {
+                               $trimmableText = $( '<span>' )
+                                       .css( 'whiteSpace', 'nowrap' )
+                                       .text( $container.text() );
+                               $container
+                                       .empty()
+                                       .append( $trimmableText );
+                       }
 
-               text = $container.text();
-               trimmableText = $trimmableText.text();
-               w = $container.width();
-               pw = 0;
+                       text = $container.text();
+                       trimmableText = $trimmableText.text();
+                       w = $container.width();
+                       pw = 0;
 
-               // Try cache
-               if ( options.matchText ) {
-                       if ( !( text in matchTextCache ) ) {
-                               matchTextCache[ text ] = {};
-                       }
-                       if ( !( options.matchText in matchTextCache[ text ] ) ) {
-                               matchTextCache[ text ][ options.matchText ] = {};
-                       }
-                       if ( !( w in matchTextCache[ text ][ options.matchText ] ) ) {
-                               matchTextCache[ text ][ options.matchText ][ w ] = {};
-                       }
-                       if ( options.position in matchTextCache[ text ][ options.matchText ][ w ] ) {
-                               $container.html( matchTextCache[ text ][ options.matchText ][ w ][ options.position ] );
-                               if ( options.tooltip ) {
-                                       $container.attr( 'title', text );
+                       // Try cache
+                       if ( options.matchText ) {
+                               if ( !( text in matchTextCache ) ) {
+                                       matchTextCache[ text ] = {};
                                }
-                               return;
-                       }
-               } else {
-                       if ( !( text in cache ) ) {
-                               cache[ text ] = {};
-                       }
-                       if ( !( w in cache[ text ] ) ) {
-                               cache[ text ][ w ] = {};
-                       }
-                       if ( options.position in cache[ text ][ w ] ) {
-                               $container.html( cache[ text ][ w ][ options.position ] );
-                               if ( options.tooltip ) {
-                                       $container.attr( 'title', text );
+                               if ( !( options.matchText in matchTextCache[ text ] ) ) {
+                                       matchTextCache[ text ][ options.matchText ] = {};
+                               }
+                               if ( !( w in matchTextCache[ text ][ options.matchText ] ) ) {
+                                       matchTextCache[ text ][ options.matchText ][ w ] = {};
+                               }
+                               if ( options.position in matchTextCache[ text ][ options.matchText ][ w ] ) {
+                                       $container.html( matchTextCache[ text ][ options.matchText ][ w ][ options.position ] );
+                                       if ( options.tooltip ) {
+                                               $container.attr( 'title', text );
+                                       }
+                                       return;
+                               }
+                       } else {
+                               if ( !( text in cache ) ) {
+                                       cache[ text ] = {};
+                               }
+                               if ( !( w in cache[ text ] ) ) {
+                                       cache[ text ][ w ] = {};
+                               }
+                               if ( options.position in cache[ text ][ w ] ) {
+                                       $container.html( cache[ text ][ w ][ options.position ] );
+                                       if ( options.tooltip ) {
+                                               $container.attr( 'title', text );
+                                       }
+                                       return;
                                }
-                               return;
                        }
-               }
 
-               if ( $trimmableText.width() + pw > w ) {
-                       switch ( options.position ) {
-                               case 'right':
-                                       // Use binary search-like technique for efficiency
-                                       l = 0;
-                                       r = trimmableText.length;
-                                       do {
-                                               m = Math.ceil( ( l + r ) / 2 );
-                                               $trimmableText.text( trimmableText.slice( 0, m ) + '...' );
-                                               if ( $trimmableText.width() + pw > w ) {
-                                                       // Text is too long
-                                                       r = m - 1;
-                                               } else {
-                                                       l = m;
+                       if ( $trimmableText.width() + pw > w ) {
+                               switch ( options.position ) {
+                                       case 'right':
+                                               // Use binary search-like technique for efficiency
+                                               l = 0;
+                                               r = trimmableText.length;
+                                               do {
+                                                       m = Math.ceil( ( l + r ) / 2 );
+                                                       $trimmableText.text( trimmableText.slice( 0, m ) + '...' );
+                                                       if ( $trimmableText.width() + pw > w ) {
+                                                               // Text is too long
+                                                               r = m - 1;
+                                                       } else {
+                                                               l = m;
+                                                       }
+                                               } while ( l < r );
+                                               $trimmableText.text( trimmableText.slice( 0, l ) + '...' );
+                                               break;
+                                       case 'center':
+                                               // TODO: Use binary search like for 'right'
+                                               i = [ Math.round( trimmableText.length / 2 ), Math.round( trimmableText.length / 2 ) ];
+                                               // Begin with making the end shorter
+                                               side = 1;
+                                               while ( $trimmableText.outerWidth() + pw > w && i[ 0 ] > 0 ) {
+                                                       $trimmableText.text( trimmableText.slice( 0, i[ 0 ] ) + '...' + trimmableText.slice( i[ 1 ] ) );
+                                                       // Alternate between trimming the end and begining
+                                                       if ( side === 0 ) {
+                                                               // Make the begining shorter
+                                                               i[ 0 ]--;
+                                                               side = 1;
+                                                       } else {
+                                                               // Make the end shorter
+                                                               i[ 1 ]++;
+                                                               side = 0;
+                                                       }
                                                }
-                                       } while ( l < r );
-                                       $trimmableText.text( trimmableText.slice( 0, l ) + '...' );
-                                       break;
-                               case 'center':
-                                       // TODO: Use binary search like for 'right'
-                                       i = [ Math.round( trimmableText.length / 2 ), Math.round( trimmableText.length / 2 ) ];
-                                       // Begin with making the end shorter
-                                       side = 1;
-                                       while ( $trimmableText.outerWidth() + pw > w && i[ 0 ] > 0 ) {
-                                               $trimmableText.text( trimmableText.slice( 0, i[ 0 ] ) + '...' + trimmableText.slice( i[ 1 ] ) );
-                                               // Alternate between trimming the end and begining
-                                               if ( side === 0 ) {
-                                                       // Make the begining shorter
-                                                       i[ 0 ]--;
-                                                       side = 1;
-                                               } else {
-                                                       // Make the end shorter
-                                                       i[ 1 ]++;
-                                                       side = 0;
+                                               break;
+                                       case 'left':
+                                               // TODO: Use binary search like for 'right'
+                                               r = 0;
+                                               while ( $trimmableText.outerWidth() + pw > w && r < trimmableText.length ) {
+                                                       $trimmableText.text( '...' + trimmableText.slice( r ) );
+                                                       r++;
                                                }
-                                       }
-                                       break;
-                               case 'left':
-                                       // TODO: Use binary search like for 'right'
-                                       r = 0;
-                                       while ( $trimmableText.outerWidth() + pw > w && r < trimmableText.length ) {
-                                               $trimmableText.text( '...' + trimmableText.slice( r ) );
-                                               r++;
-                                       }
-                                       break;
+                                               break;
+                               }
+                       }
+                       if ( options.tooltip ) {
+                               $container.attr( 'title', text );
+                       }
+                       if ( options.matchText ) {
+                               $container.highlightText( options.matchText );
+                               matchTextCache[ text ][ options.matchText ][ w ][ options.position ] = $container.html();
+                       } else {
+                               cache[ text ][ w ][ options.position ] = $container.html();
                        }
-               }
-               if ( options.tooltip ) {
-                       $container.attr( 'title', text );
-               }
-               if ( options.matchText ) {
-                       $container.highlightText( options.matchText );
-                       matchTextCache[ text ][ options.matchText ][ w ][ options.position ] = $container.html();
-               } else {
-                       cache[ text ][ w ][ options.position ] = $container.html();
-               }
 
-       } );
-};
-// jscs:enable jsDoc
+               } );
+       };
+       // jscs:enable jsDoc
 
-/**
- * @class jQuery
- * @mixins jQuery.plugin.autoEllipsis
- */
+       /**
       * @class jQuery
       * @mixins jQuery.plugin.autoEllipsis
       */
 
 }( jQuery ) );
index dd71a2b..567bec8 100644 (file)
@@ -3,6 +3,17 @@
  */
 ( function ( $ ) {
 
+       var eventKeys = [
+               'keyup.byteLimit',
+               'keydown.byteLimit',
+               'change.byteLimit',
+               'mouseup.byteLimit',
+               'cut.byteLimit',
+               'paste.byteLimit',
+               'focus.byteLimit',
+               'blur.byteLimit'
+       ].join( ' ' );
+
        /**
         * Utility function to trim down a string, based on byteLimit
         * and given a safe start position. It supports insertion anywhere
                };
        };
 
-       var eventKeys = [
-               'keyup.byteLimit',
-               'keydown.byteLimit',
-               'change.byteLimit',
-               'mouseup.byteLimit',
-               'cut.byteLimit',
-               'paste.byteLimit',
-               'focus.byteLimit',
-               'blur.byteLimit'
-       ].join( ' ' );
-
        /**
         * Enforces a byte limit on an input field, so that UTF-8 entries are counted as well,
         * when, for example, a database field has a byte limit rather than a character limit.
                                // maxLength is a strange property. Removing or setting the property to
                                // undefined directly doesn't work. Instead, it can only be unset internally
                                // by the browser when removing the associated attribute (Firefox/Chrome).
-                               // http://code.google.com/p/chromium/issues/detail?id=136004
+                               // https://bugs.chromium.org/p/chromium/issues/detail?id=136004
                                $el.removeAttr( 'maxlength' );
 
                        } else {
                        // changed while text is being entered and keyup/change will not be fired yet
                        // (such as holding down a single key, fires keydown, and after each keydown,
                        // we can trim the previous one).
-                       // See http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order for
+                       // See https://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order for
                        // the order and characteristics of the key events.
                        $el.on( eventKeys, function () {
                                var res = $.trimByteLength(
index a3cc8fc..70dc105 100644 (file)
@@ -10,7 +10,6 @@
 ( function ( $ ) {
 
        function getColor( elem, attr ) {
-               /*jshint boss:true */
                var color;
 
                do {
@@ -22,6 +21,7 @@
                        }
 
                        attr = 'backgroundColor';
+               // eslint-disable-next-line no-cond-assign
                } while ( elem = elem.parentNode );
 
                return $.colorUtil.getRGB( color );
index c14f2c8..c53ec3b 100644 (file)
@@ -23,7 +23,6 @@
                 * @return {Array}
                 */
                getRGB: function ( color ) {
-                       /*jshint boss:true */
                        var result;
 
                        // Check if we're already dealing with an array of colors
@@ -32,6 +31,7 @@
                        }
 
                        // Look for rgb(num,num,num)
+                       // eslint-disable-next-line no-cond-assign
                        if ( result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec( color ) ) {
                                return [
                                        parseInt( result[ 1 ], 10 ),
@@ -41,6 +41,7 @@
                        }
 
                        // Look for rgb(num%,num%,num%)
+                       // eslint-disable-next-line no-cond-assign
                        if ( result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec( color ) ) {
                                return [
                                        parseFloat( result[ 1 ] ) * 2.55,
@@ -50,6 +51,7 @@
                        }
 
                        // Look for #a0b1c2
+                       // eslint-disable-next-line no-cond-assign
                        if ( result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec( color ) ) {
                                return [
                                        parseInt( result[ 1 ], 16 ),
@@ -59,6 +61,7 @@
                        }
 
                        // Look for #fff
+                       // eslint-disable-next-line no-cond-assign
                        if ( result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec( color ) ) {
                                return [
                                        parseInt( result[ 1 ] + result[ 1 ], 16 ),
@@ -68,6 +71,7 @@
                        }
 
                        // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
+                       // eslint-disable-next-line no-cond-assign
                        if ( result = /rgba\(0, 0, 0, 0\)/.exec( color ) ) {
                                return $.colorUtil.colors.transparent;
                        }
                 * @return {number[]} The HSL representation
                 */
                rgbToHsl: function ( r, g, b ) {
+                       var d, h, s, l, min, max;
+
                        r = r / 255;
                        g = g / 255;
                        b = b / 255;
 
-                       var d,
-                               max = Math.max( r, g, b ),
-                               min = Math.min( r, g, b ),
-                               h,
-                               s,
-                               l = ( max + min ) / 2;
+                       max = Math.max( r, g, b );
+                       min = Math.min( r, g, b );
+                       l = ( max + min ) / 2;
 
                        if ( max === min ) {
                                // achromatic
index 1ecce6c..7931c81 100644 (file)
@@ -12,6 +12,7 @@
                return data;
        };
 
+       // eslint-disable-next-line valid-jsdoc
        /**
         * Enable inline confirmation for given clickable element (like `<a />` or `<button />`).
         *
index f9db72f..0bfa8f3 100644 (file)
@@ -19,6 +19,9 @@
        $.expandableField = {
                /**
                 * Expand the field, make the callback
+                *
+                * @param {jQuery.Event} e Event
+                * @param {Object} context
                 */
                expandField: function ( e, context ) {
                        context.config.beforeExpand.call( context.data.$field, context );
@@ -29,6 +32,9 @@
                },
                /**
                 * Condense the field, make the callback
+                *
+                * @param {jQuery.Event} e Event
+                * @param {Object} context
                 */
                condenseField: function ( e, context ) {
                        context.config.beforeCondense.call( context.data.$field, context );
index 7d308f8..7a7109c 100644 (file)
  */
 ( function ( $ ) {
 
-/**
- * Get reported or approximate device pixel ratio.
- *
- * - 1.0 means 1 CSS pixel is 1 hardware pixel
- * - 2.0 means 1 CSS pixel is 2 hardware pixels
- * - etc.
- *
- * Uses `window.devicePixelRatio` if available, or CSS media queries on IE.
- *
- * @static
- * @inheritable
- * @return {number} Device pixel ratio
- */
-$.devicePixelRatio = function () {
-       if ( window.devicePixelRatio !== undefined ) {
-               // Most web browsers:
-               // * WebKit/Blink (Safari, Chrome, Android browser, etc)
-               // * Opera
-               // * Firefox 18+
-               // * Microsoft Edge (Windows 10)
-               return window.devicePixelRatio;
-       } else if ( window.msMatchMedia !== undefined ) {
-               // Windows 8 desktops / tablets, probably Windows Phone 8
-               //
-               // IE 10/11 doesn't report pixel ratio directly, but we can get the
-               // screen DPI and divide by 96. We'll bracket to [1, 1.5, 2.0] for
-               // simplicity, but you may get different values depending on zoom
-               // factor, size of screen and orientation in Metro IE.
-               if ( window.msMatchMedia( '(min-resolution: 192dpi)' ).matches ) {
+       /**
+        * Get reported or approximate device pixel ratio.
+        *
+        * - 1.0 means 1 CSS pixel is 1 hardware pixel
+        * - 2.0 means 1 CSS pixel is 2 hardware pixels
+        * - etc.
+        *
+        * Uses `window.devicePixelRatio` if available, or CSS media queries on IE.
+        *
+        * @static
+        * @inheritable
+        * @return {number} Device pixel ratio
+        */
+       $.devicePixelRatio = function () {
+               if ( window.devicePixelRatio !== undefined ) {
+                       // Most web browsers:
+                       // * WebKit/Blink (Safari, Chrome, Android browser, etc)
+                       // * Opera
+                       // * Firefox 18+
+                       // * Microsoft Edge (Windows 10)
+                       return window.devicePixelRatio;
+               } else if ( window.msMatchMedia !== undefined ) {
+                       // Windows 8 desktops / tablets, probably Windows Phone 8
+                       //
+                       // IE 10/11 doesn't report pixel ratio directly, but we can get the
+                       // screen DPI and divide by 96. We'll bracket to [1, 1.5, 2.0] for
+                       // simplicity, but you may get different values depending on zoom
+                       // factor, size of screen and orientation in Metro IE.
+                       if ( window.msMatchMedia( '(min-resolution: 192dpi)' ).matches ) {
+                               return 2;
+                       } else if ( window.msMatchMedia( '(min-resolution: 144dpi)' ).matches ) {
+                               return 1.5;
+                       } else {
+                               return 1;
+                       }
+               } else {
+                       // Legacy browsers...
+                       // Assume 1 if unknown.
+                       return 1;
+               }
+       };
+
+       /**
+        * Bracket a given device pixel ratio to one of [1, 1.5, 2].
+        *
+        * This is useful for grabbing images on the fly with sizes based on the display
+        * density, without causing slowdown and extra thumbnail renderings on devices
+        * that are slightly different from the most common sizes.
+        *
+        * The bracketed ratios match the default 'srcset' output on MediaWiki thumbnails,
+        * so will be consistent with default renderings.
+        *
+        * @static
+        * @inheritable
+        * @param {number} baseRatio Base ratio
+        * @return {number} Device pixel ratio
+        */
+       $.bracketDevicePixelRatio = function ( baseRatio ) {
+               if ( baseRatio > 1.5 ) {
                        return 2;
-               } else if ( window.msMatchMedia( '(min-resolution: 144dpi)' ).matches ) {
+               } else if ( baseRatio > 1 ) {
                        return 1.5;
                } else {
                        return 1;
                }
-       } else {
-               // Legacy browsers...
-               // Assume 1 if unknown.
-               return 1;
-       }
-};
-
-/**
- * Bracket a given device pixel ratio to one of [1, 1.5, 2].
- *
- * This is useful for grabbing images on the fly with sizes based on the display
- * density, without causing slowdown and extra thumbnail renderings on devices
- * that are slightly different from the most common sizes.
- *
- * The bracketed ratios match the default 'srcset' output on MediaWiki thumbnails,
- * so will be consistent with default renderings.
- *
- * @static
- * @inheritable
- * @return {number} Device pixel ratio
- */
-$.bracketDevicePixelRatio = function ( baseRatio ) {
-       if ( baseRatio > 1.5 ) {
-               return 2;
-       } else if ( baseRatio > 1 ) {
-               return 1.5;
-       } else {
-               return 1;
-       }
-};
+       };
 
-/**
- * Get reported or approximate device pixel ratio, bracketed to [1, 1.5, 2].
- *
- * This is useful for grabbing images on the fly with sizes based on the display
- * density, without causing slowdown and extra thumbnail renderings on devices
- * that are slightly different from the most common sizes.
- *
- * The bracketed ratios match the default 'srcset' output on MediaWiki thumbnails,
- * so will be consistent with default renderings.
- *
- * - 1.0 means 1 CSS pixel is 1 hardware pixel
- * - 1.5 means 1 CSS pixel is 1.5 hardware pixels
- * - 2.0 means 1 CSS pixel is 2 hardware pixels
- *
- * @static
- * @inheritable
- * @return {number} Device pixel ratio
- */
-$.bracketedDevicePixelRatio = function () {
-       return $.bracketDevicePixelRatio( $.devicePixelRatio() );
-};
+       /**
       * Get reported or approximate device pixel ratio, bracketed to [1, 1.5, 2].
       *
       * This is useful for grabbing images on the fly with sizes based on the display
       * density, without causing slowdown and extra thumbnail renderings on devices
       * that are slightly different from the most common sizes.
       *
       * The bracketed ratios match the default 'srcset' output on MediaWiki thumbnails,
       * so will be consistent with default renderings.
       *
       * - 1.0 means 1 CSS pixel is 1 hardware pixel
       * - 1.5 means 1 CSS pixel is 1.5 hardware pixels
       * - 2.0 means 1 CSS pixel is 2 hardware pixels
       *
       * @static
       * @inheritable
       * @return {number} Device pixel ratio
       */
+       $.bracketedDevicePixelRatio = function () {
+               return $.bracketDevicePixelRatio( $.devicePixelRatio() );
+       };
 
-/**
- * Implement responsive images based on srcset attributes, if browser has no
- * native srcset support.
- *
- * @return {jQuery} This selection
- * @chainable
- */
-$.fn.hidpi = function () {
-       var $target = this,
-               // TODO add support for dpi media query checks on Firefox, IE
-               devicePixelRatio = $.devicePixelRatio(),
-               testImage = new Image();
+       /**
       * Implement responsive images based on srcset attributes, if browser has no
       * native srcset support.
       *
       * @return {jQuery} This selection
       * @chainable
       */
+       $.fn.hidpi = function () {
+               var $target = this,
+                       // TODO add support for dpi media query checks on Firefox, IE
+                       devicePixelRatio = $.devicePixelRatio(),
+                       testImage = new Image();
 
-       if ( devicePixelRatio > 1 && testImage.srcset === undefined ) {
-               // No native srcset support.
-               $target.find( 'img' ).each( function () {
-                       var $img = $( this ),
-                               srcset = $img.attr( 'srcset' ),
-                               match;
-                       if ( typeof srcset === 'string' && srcset !== '' ) {
-                               match = $.matchSrcSet( devicePixelRatio, srcset );
-                               if ( match !== null ) {
-                                       $img.attr( 'src', match );
+               if ( devicePixelRatio > 1 && testImage.srcset === undefined ) {
+                       // No native srcset support.
+                       $target.find( 'img' ).each( function () {
+                               var $img = $( this ),
+                                       srcset = $img.attr( 'srcset' ),
+                                       match;
+                               if ( typeof srcset === 'string' && srcset !== '' ) {
+                                       match = $.matchSrcSet( devicePixelRatio, srcset );
+                                       if ( match !== null ) {
+                                               $img.attr( 'src', match );
+                                       }
                                }
-                       }
-               } );
-       }
+                       } );
+               }
 
-       return $target;
-};
+               return $target;
+       };
 
-/**
- * Match a srcset entry for the given device pixel ratio
- *
- * Exposed for testing.
- *
- * @private
- * @static
- * @param {number} devicePixelRatio
- * @param {string} srcset
- * @return {Mixed} null or the matching src string
- */
-$.matchSrcSet = function ( devicePixelRatio, srcset ) {
-       var candidates,
-               candidate,
-               bits,
-               src,
-               i,
-               ratioStr,
-               ratio,
-               selectedRatio = 1,
-               selectedSrc = null;
-       candidates = srcset.split( / *, */ );
-       for ( i = 0; i < candidates.length; i++ ) {
-               candidate = candidates[ i ];
-               bits = candidate.split( / +/ );
-               src = bits[ 0 ];
-               if ( bits.length > 1 && bits[ 1 ].charAt( bits[ 1 ].length - 1 ) === 'x' ) {
-                       ratioStr = bits[ 1 ].slice( 0, -1 );
-                       ratio = parseFloat( ratioStr );
-                       if ( ratio <= devicePixelRatio && ratio > selectedRatio ) {
-                               selectedRatio = ratio;
-                               selectedSrc = src;
+       /**
+        * Match a srcset entry for the given device pixel ratio
+        *
+        * Exposed for testing.
+        *
+        * @private
+        * @static
+        * @param {number} devicePixelRatio
+        * @param {string} srcset
+        * @return {Mixed} null or the matching src string
+        */
+       $.matchSrcSet = function ( devicePixelRatio, srcset ) {
+               var candidates,
+                       candidate,
+                       bits,
+                       src,
+                       i,
+                       ratioStr,
+                       ratio,
+                       selectedRatio = 1,
+                       selectedSrc = null;
+               candidates = srcset.split( / *, */ );
+               for ( i = 0; i < candidates.length; i++ ) {
+                       candidate = candidates[ i ];
+                       bits = candidate.split( / +/ );
+                       src = bits[ 0 ];
+                       if ( bits.length > 1 && bits[ 1 ].charAt( bits[ 1 ].length - 1 ) === 'x' ) {
+                               ratioStr = bits[ 1 ].slice( 0, -1 );
+                               ratio = parseFloat( ratioStr );
+                               if ( ratio <= devicePixelRatio && ratio > selectedRatio ) {
+                                       selectedRatio = ratio;
+                                       selectedSrc = src;
+                               }
                        }
                }
-       }
-       return selectedSrc;
-};
+               return selectedSrc;
+       };
 
-/**
- * @class jQuery
- * @mixins jQuery.plugin.hidpi
- */
+       /**
       * @class jQuery
       * @mixins jQuery.plugin.hidpi
       */
 
 }( jQuery ) );
index e37f19b..3feca81 100644 (file)
                                        // replace the matched node, with our span-wrapped clone of the matched node
                                        middlebit.parentNode.replaceChild( spannode, middlebit );
                                }
-                       } else if ( node.nodeType === Node.ELEMENT_NODE
+                       } else if (
+                               node.nodeType === Node.ELEMENT_NODE &&
                                // element with childnodes, and not a script, style or an element we created
-                               && node.childNodes
-                               && !/(script|style)/i.test( node.tagName )
-                               && !( node.tagName.toLowerCase() === 'span'
-                                       && node.className.match( /\bhighlight/ )
+                               node.childNodes &&
+                               !/(script|style)/i.test( node.tagName ) &&
+                               !(
+                                       node.tagName.toLowerCase() === 'span' &&
+                                       node.className.match( /\bhighlight/ )
                                )
                        ) {
                                for ( i = 0; i < node.childNodes.length; ++i ) {
index f5932b2..05b3891 100644 (file)
  */
 ( function ( $, mw ) {
 
-/**
- * Gets a localized message, using parameters from options if present.
- *
- * @ignore
- * @param {Object} options
- * @param {string} key
- * @return {string} Localized message
- */
-function msg( options, key ) {
-       var args = options.params[ key ] || [];
-       // Format: mw.msg( key [, p1, p2, ...] )
-       args.unshift( options.prefix + ( options.keys[ key ] || key ) );
-       return mw.msg.apply( mw, args );
-}
+       /**
       * Gets a localized message, using parameters from options if present.
       *
       * @ignore
       * @param {Object} options
       * @param {string} key
       * @return {string} Localized message
       */
+       function msg( options, key ) {
+               var args = options.params[ key ] || [];
+               // Format: mw.msg( key [, p1, p2, ...] )
+               args.unshift( options.prefix + ( options.keys[ key ] || key ) );
+               return mw.msg.apply( mw, args );
+       }
 
-/**
- * Localizes a DOM selection by replacing <html:msg /> elements with localized text and adding
- * localized title and alt attributes to elements with title-msg and alt-msg attributes
- * respectively.
- *
- * Call on a selection of HTML which contains `<html:msg key="message-key" />` elements or elements
- * with title-msg="message-key", alt-msg="message-key" or placeholder-msg="message-key" attributes.
- * `<html:msg />` elements will be replaced with localized text, *-msg attributes will be replaced
- * with attributes that do not have the "-msg" suffix and contain a localized message.
- *
- * Example:
- *     // Messages: { 'title': 'Awesome', 'desc': 'Cat doing backflip' 'search' contains 'Search' }
- *     var html = '\
- *         <p>\
- *             <html:msg key="title" />\
- *             <img src="something.jpg" title-msg="title" alt-msg="desc" />\
- *             <input type="text" placeholder-msg="search" />\
- *         </p>';
- *     $( 'body' ).append( $( html ).localize() );
- *
- * Appends something like this to the body...
- *     <p>
- *         Awesome
- *         <img src="something.jpg" title="Awesome" alt="Cat doing backflip" />
- *         <input type="text" placeholder="Search" />
- *     </p>
- *
- * Arguments can be passed into uses of a message using the params property of the options object
- * given to .localize(). Multiple messages can be given parameters, because the params property is
- * an object keyed by the message key to apply the parameters to, each containing an array of
- * parameters to use. The limitation is that you can not use different parameters to individual uses
- * of a message in the same selection being localized - they will all recieve the same parameters.
- *
- * Example:
- *     // Messages: { 'easy-as': 'Easy as $1 $2 $3.' }
- *     var html = '<p><html:msg key="easy-as" /></p>';
- *     $( 'body' ).append( $( html ).localize( { 'params': { 'easy-as': ['a', 'b', 'c'] } } ) );
- *
- * Appends something like this to the body...
- *     <p>Easy as a, b, c</p>
- *
- * Raw HTML content can be used, instead of it being escaped as text. To do this, just use the raw
- * attribute on a msg element.
- *
- * Example:
- *     // Messages: { 'hello': '<b><i>Hello</i> $1!</b>' }
- *     var html = '\
- *         <p>\
- *             <!-- escaped: --><html:msg key="hello" />\
- *             <!-- raw: --><html:msg key="hello" raw />\
- *         </p>';
- *     $( 'body' ).append( $( html ).localize( { 'params': { 'hello': ['world'] } } ) );
- *
- * Appends something like this to the body...
- *     <p>
- *         <!-- escaped: -->&lt;b&gt;&lt;i&gt;Hello&lt;/i&gt; world!&lt;/b&gt;
- *         <!-- raw: --><b><i>Hello</i> world!</b>
- *     </p>
- *
- * Message keys can also be remapped, allowing the same generic template to be used with a variety
- * of messages. This is important for improving re-usability of templates.
- *
- * Example:
- *     // Messages: { 'good-afternoon': 'Good afternoon' }
- *     var html = '<p><html:msg key="greeting" /></p>';
- *     $( 'body' ).append( $( html ).localize( { 'keys': { 'greeting': 'good-afternoon' } } ) );
- *
- * Appends something like this to the body...
- *     <p>Good afternoon</p>
- *
- * Message keys can also be prefixed globally, which is handy when writing extensions, where by
- * convention all messages are prefixed with the extension's name.
- *
- * Example:
- *     // Messages: { 'teleportation-warning': 'You may not get there all in one piece.' }
- *     var html = '<p><html:msg key="warning" /></p>';
- *     $( 'body' ).append( $( html ).localize( { 'prefix': 'teleportation-' } ) );
- *
- * Appends something like this to the body...
- *     <p>You may not get there all in one piece.</p>
- *
- * @param {Object} options Map of options to be used while localizing
- * @param {string} options.prefix String to prepend to all message keys
- * @param {Object} options.keys Message key aliases, used for remapping keys to a template
- * @param {Object} options.params Lists of parameters to use with certain message keys
- * @return {jQuery}
- * @chainable
- */
-$.fn.localize = function ( options ) {
-       var $target = this,
-               attributes = [ 'title', 'alt', 'placeholder' ];
+       /**
       * Localizes a DOM selection by replacing <html:msg /> elements with localized text and adding
       * localized title and alt attributes to elements with title-msg and alt-msg attributes
       * respectively.
       *
       * Call on a selection of HTML which contains `<html:msg key="message-key" />` elements or elements
       * with title-msg="message-key", alt-msg="message-key" or placeholder-msg="message-key" attributes.
       * `<html:msg />` elements will be replaced with localized text, *-msg attributes will be replaced
       * with attributes that do not have the "-msg" suffix and contain a localized message.
       *
       * Example:
       *     // Messages: { 'title': 'Awesome', 'desc': 'Cat doing backflip' 'search' contains 'Search' }
       *     var html = '\
       *         <p>\
       *             <html:msg key="title" />\
       *             <img src="something.jpg" title-msg="title" alt-msg="desc" />\
       *             <input type="text" placeholder-msg="search" />\
       *         </p>';
       *     $( 'body' ).append( $( html ).localize() );
       *
       * Appends something like this to the body...
       *     <p>
       *         Awesome
       *         <img src="something.jpg" title="Awesome" alt="Cat doing backflip" />
       *         <input type="text" placeholder="Search" />
       *     </p>
       *
       * Arguments can be passed into uses of a message using the params property of the options object
       * given to .localize(). Multiple messages can be given parameters, because the params property is
       * an object keyed by the message key to apply the parameters to, each containing an array of
       * parameters to use. The limitation is that you can not use different parameters to individual uses
       * of a message in the same selection being localized - they will all recieve the same parameters.
       *
       * Example:
       *     // Messages: { 'easy-as': 'Easy as $1 $2 $3.' }
       *     var html = '<p><html:msg key="easy-as" /></p>';
       *     $( 'body' ).append( $( html ).localize( { 'params': { 'easy-as': ['a', 'b', 'c'] } } ) );
       *
       * Appends something like this to the body...
       *     <p>Easy as a, b, c</p>
       *
       * Raw HTML content can be used, instead of it being escaped as text. To do this, just use the raw
       * attribute on a msg element.
       *
       * Example:
       *     // Messages: { 'hello': '<b><i>Hello</i> $1!</b>' }
       *     var html = '\
       *         <p>\
       *             <!-- escaped: --><html:msg key="hello" />\
       *             <!-- raw: --><html:msg key="hello" raw />\
       *         </p>';
       *     $( 'body' ).append( $( html ).localize( { 'params': { 'hello': ['world'] } } ) );
       *
       * Appends something like this to the body...
       *     <p>
       *         <!-- escaped: -->&lt;b&gt;&lt;i&gt;Hello&lt;/i&gt; world!&lt;/b&gt;
       *         <!-- raw: --><b><i>Hello</i> world!</b>
       *     </p>
       *
       * Message keys can also be remapped, allowing the same generic template to be used with a variety
       * of messages. This is important for improving re-usability of templates.
       *
       * Example:
       *     // Messages: { 'good-afternoon': 'Good afternoon' }
       *     var html = '<p><html:msg key="greeting" /></p>';
       *     $( 'body' ).append( $( html ).localize( { 'keys': { 'greeting': 'good-afternoon' } } ) );
       *
       * Appends something like this to the body...
       *     <p>Good afternoon</p>
       *
       * Message keys can also be prefixed globally, which is handy when writing extensions, where by
       * convention all messages are prefixed with the extension's name.
       *
       * Example:
       *     // Messages: { 'teleportation-warning': 'You may not get there all in one piece.' }
       *     var html = '<p><html:msg key="warning" /></p>';
       *     $( 'body' ).append( $( html ).localize( { 'prefix': 'teleportation-' } ) );
       *
       * Appends something like this to the body...
       *     <p>You may not get there all in one piece.</p>
       *
       * @param {Object} options Map of options to be used while localizing
       * @param {string} options.prefix String to prepend to all message keys
       * @param {Object} options.keys Message key aliases, used for remapping keys to a template
       * @param {Object} options.params Lists of parameters to use with certain message keys
       * @return {jQuery}
       * @chainable
       */
+       $.fn.localize = function ( options ) {
+               var $target = this,
+                       attributes = [ 'title', 'alt', 'placeholder' ];
 
-       // Extend options
-       options = $.extend( {
-               prefix: '',
-               keys: {},
-               params: {}
-       }, options );
+               // Extend options
+               options = $.extend( {
+                       prefix: '',
+                       keys: {},
+                       params: {}
+               }, options );
 
-       // Elements
-       // Ok, so here's the story on this selector. In IE 6/7, searching for 'msg' turns up the
-       // 'html:msg', but searching for 'html:msg' doesn't. In later IE and other browsers, searching
-       // for 'html:msg' turns up the 'html:msg', but searching for 'msg' doesn't. So searching for
-       // both 'msg' and 'html:msg' seems to get the job done. This feels pretty icky, though.
-       $target.find( 'msg,html\\:msg' ).each( function () {
-               var $el = $( this );
-               // Escape by default
-               if ( $el.attr( 'raw' ) ) {
-                       $el.html( msg( options, $el.attr( 'key' ) ) );
-               } else {
-                       $el.text( msg( options, $el.attr( 'key' ) ) );
-               }
-               // Remove wrapper
-               $el.replaceWith( $el.html() );
-       } );
-
-       // Attributes
-       // Note: there's no way to prevent escaping of values being injected into attributes, this is
-       // on purpose, not a design flaw.
-       $.each( attributes, function ( i, attr ) {
-               var msgAttr = attr + '-msg';
-               $target.find( '[' + msgAttr + ']' ).each( function () {
+               // Elements
+               // Ok, so here's the story on this selector. In IE 6/7, searching for 'msg' turns up the
+               // 'html:msg', but searching for 'html:msg' doesn't. In later IE and other browsers, searching
+               // for 'html:msg' turns up the 'html:msg', but searching for 'msg' doesn't. So searching for
+               // both 'msg' and 'html:msg' seems to get the job done. This feels pretty icky, though.
+               $target.find( 'msg,html\\:msg' ).each( function () {
                        var $el = $( this );
-                       $el.attr( attr, msg( options, $el.attr( msgAttr ) ) ).removeAttr( msgAttr );
+                       // Escape by default
+                       if ( $el.attr( 'raw' ) ) {
+                               $el.html( msg( options, $el.attr( 'key' ) ) );
+                       } else {
+                               $el.text( msg( options, $el.attr( 'key' ) ) );
+                       }
+                       // Remove wrapper
+                       $el.replaceWith( $el.html() );
                } );
-       } );
 
-       // HTML, Text for elements which cannot have children e.g. OPTION
-       $target.find( '[data-msg-text]' ).each( function () {
-               var $el = $( this );
-               $el.text( msg( options, $el.attr( 'data-msg-text' ) ) );
-       } );
+               // Attributes
+               // Note: there's no way to prevent escaping of values being injected into attributes, this is
+               // on purpose, not a design flaw.
+               $.each( attributes, function ( i, attr ) {
+                       var msgAttr = attr + '-msg';
+                       $target.find( '[' + msgAttr + ']' ).each( function () {
+                               var $el = $( this );
+                               $el.attr( attr, msg( options, $el.attr( msgAttr ) ) ).removeAttr( msgAttr );
+                       } );
+               } );
 
-       $target.find( '[data-msg-html]' ).each( function () {
-               var $el = $( this );
-               $el.html( msg( options, $el.attr( 'data-msg-html' ) ) );
-       } );
+               // HTML, Text for elements which cannot have children e.g. OPTION
+               $target.find( '[data-msg-text]' ).each( function () {
+                       var $el = $( this );
+                       $el.text( msg( options, $el.attr( 'data-msg-text' ) ) );
+               } );
+
+               $target.find( '[data-msg-html]' ).each( function () {
+                       var $el = $( this );
+                       $el.html( msg( options, $el.attr( 'data-msg-html' ) ) );
+               } );
 
-       return $target;
-};
+               return $target;
+       };
 
-// Let IE know about the msg tag before it's used...
-document.createElement( 'msg' );
+       // Let IE know about the msg tag before it's used...
+       document.createElement( 'msg' );
 
-/**
- * @class jQuery
- * @mixins jQuery.plugin.localize
- */
+       /**
       * @class jQuery
       * @mixins jQuery.plugin.localize
       */
 
 }( jQuery, mediaWiki ) );
index ac60e8f..eef3846 100644 (file)
                        };
                        // Default toggle link. Only build it when needed to avoid jQuery memory leaks (event data).
                        buildDefaultToggleLink = function () {
-                               return $( '<a href="#"></a>' )
+                               return $( '<a>' )
+                                       .attr( {
+                                               role: 'button',
+                                               tabindex: 0
+                                       } )
                                        .text( collapseText )
                                        .wrap( '<span class="mw-collapsible-toggle"></span>' )
                                                .parent()
index 27ceb2b..f9675fa 100644 (file)
                        return false;
                },
                compareArray: function ( arrThis, arrAgainst ) {
+                       var i;
                        if ( arrThis.length !== arrAgainst.length ) {
                                return false;
                        }
-                       for ( var i = 0; i < arrThis.length; i++ ) {
+                       for ( i = 0; i < arrThis.length; i++ ) {
                                if ( $.isArray( arrThis[ i ] ) ) {
                                        if ( !$.compareArray( arrThis[ i ], arrAgainst[ i ] ) ) {
                                                return false;
                return str.replace( /([\\{}()|.?*+\-\^$\[\]])/g, '\\$1' );
        }, 'Use mediawiki.RegExp instead.' );
 
-} )( jQuery, mediaWiki );
+}( jQuery, mediaWiki ) );
index c472ac7..ae9c943 100644 (file)
@@ -35,7 +35,7 @@
        function args( elem ) {
                // Return an object of element attributes
                var newAttrs = {},
-                               rinlinejQuery = /^jQuery\d+$/;
+                       rinlinejQuery = /^jQuery\d+$/;
                $.each( elem.attributes, function ( i, attr ) {
                        if ( attr.specified && !rinlinejQuery.test( attr.name ) ) {
                                newAttrs[ attr.name ] = attr.value;
@@ -46,7 +46,7 @@
 
        function clearPlaceholder( event, value ) {
                var input = this,
-                               $input = $( input );
+                       $input = $( input );
                if ( input.value === $input.attr( 'placeholder' ) && $input.hasClass( 'placeholder' ) ) {
                        if ( $input.data( 'placeholder-password' ) ) {
                                $input = $input.hide().next().show().attr( 'id', $input.removeAttr( 'id' ).data( 'placeholder-id' ) );
@@ -68,9 +68,9 @@
 
        function setPlaceholder() {
                var $replacement,
-                               input = this,
-                               $input = $( input ),
-                               id = this.id;
+                       input = this,
+                       $input = $( input ),
+                       id = this.id;
                if ( !input.value ) {
                        if ( input.type === 'password' ) {
                                if ( !$input.data( 'placeholder-textinput' ) ) {
 
        function changePlaceholder( text ) {
                var hasArgs = arguments.length,
-                               $input = this;
+                       $input = this;
                if ( hasArgs ) {
                        if ( $input.attr( 'placeholder' ) !== text ) {
                                $input.prop( 'placeholder', text );
index 8d263fb..4353dd7 100644 (file)
@@ -17,9 +17,9 @@
 
        var util,
                hasOwn = Object.prototype.hasOwnProperty,
-               log = ( window.console && window.console.log )
-                       ? function () { return window.console.log.apply( window.console, arguments ); }
-                       function () {};
+               log = ( window.console && window.console.log ) ?
+                       function () { return window.console.log.apply( window.console, arguments ); } :
+                       function () {};
 
        // Simplified version of a few jQuery methods, except that they don't
        // call other jQuery methods. Required to be able to run the CompletenessTest
                } );
 
                QUnit.done( function () {
+                       var toolbar, testResults, cntTotal, cntCalled, cntMissing;
+
                        that.populateMissingTests();
                        log( 'CompletenessTest/populateMissingTests', that );
 
-                       var toolbar, testResults, cntTotal, cntCalled, cntMissing;
-
                        cntTotal = util.keys( that.injectionTracker ).length;
                        cntCalled = util.keys( that.methodCallTracker ).length;
                        cntMissing = util.keys( that.missingTests ).length;
 
                        // Hard ignores
                        if ( this.ignoreFn( currVal, this, currPathArray ) ) {
-                               return null;
+                               return;
                        }
 
                        // Handle the lazy limit
                        this.lazyCounter++;
                        if ( this.lazyCounter > this.lazyLimit ) {
                                log( 'CompletenessTest.fn.walkTheObject> Limit reached: ' + this.lazyCounter, currPathArray );
-                               return null;
+                               return;
                        }
 
                        // Functions
                        // Make the spy inherit from the original so that its static methods are also
                        // visible in the spy (e.g. when we inject a check into mw.log, mw.log.warn
                        // must remain accessible).
-                       // XXX: https://github.com/jshint/jshint/issues/2656
-                       /*jshint ignore:start */
-                       /*jshint proto:true */
                        spy.__proto__ = val;
-                       /*jshint ignore:end */
 
                        // Objects are by reference, members (unless objects) are not.
                        obj[ key ] = spy;
index af5a97d..9079cc0 100644 (file)
@@ -59,6 +59,8 @@
                 * @return {jQuery}
                 */
                createSpinner: function ( opts ) {
+                       var $spinner;
+
                        if ( opts !== undefined && $.type( opts ) !== 'object' ) {
                                opts = {
                                        id: opts
@@ -67,7 +69,7 @@
 
                        opts = $.extend( {}, defaults, opts );
 
-                       var $spinner = $( '<div>' ).addClass( 'mw-spinner' ).attr( 'title', '...' );
+                       $spinner = $( '<div>' ).addClass( 'mw-spinner' ).attr( 'title', '...' );
                        if ( opts.id !== undefined ) {
                                $spinner.attr( 'id', 'mw-spinner-' + opts.id );
                        }
index 884ecb6..f3e4e09 100644 (file)
                                                        $results.empty();
                                                        expWidth = -1;
                                                        for ( i = 0; i < context.config.suggestions.length; i++ ) {
-                                                               /*jshint loopfunc:true */
                                                                text = context.config.suggestions[ i ];
                                                                $result = $( '<div>' )
                                                                        .addClass( 'suggestions-result' )
                                                        46, // delete
                                                        8   // backspace
                                                ];
-                                               if ( context.data.keypressedCount === 0
-                                                       && e.which === context.data.keypressed
-                                                       && $.inArray( e.which, allowed ) !== -1
+                                               if ( context.data.keypressedCount === 0 &&
+                                                       e.which === context.data.keypressed &&
+                                                       $.inArray( e.which, allowed ) !== -1
                                                ) {
                                                        $.suggestions.keypress( e, context, context.data.keypressed );
                                                }
index 62be0d8..4da05e6 100644 (file)
         * in default (ascending) order when their header cell is clicked the next time.
         *
         * @param {jQuery} $headers
-        * @param {number[][]} sortList
-        * @param {number[][]} headerToColumns
+        * @param {Array} sortList 2D number array
+        * @param {Array} headerToColumns 2D number array
         */
        function setHeadersOrder( $headers, sortList, headerToColumns ) {
                // Loop through all headers to retrieve the indices of the columns the header spans across:
        }
 
        function setHeadersCss( table, $headers, list, css, msg, columnToHeader ) {
+               var i, len;
                // Remove all header information and reset titles to default message
                $headers.removeClass( css[ 0 ] ).removeClass( css[ 1 ] ).attr( 'title', msg[ 1 ] );
 
-               for ( var i = 0; i < list.length; i++ ) {
+               for ( i = 0, len = list.length; i < len; i++ ) {
                        $headers
                                .eq( columnToHeader[ list[ i ][ 0 ] ] )
                                .addClass( css[ list[ i ][ 1 ] ] )
        }
 
        function buildCollationTable() {
+               var key, keys = [];
                ts.collationTable = mw.config.get( 'tableSorterCollation' );
                ts.collationRegex = null;
                if ( ts.collationTable ) {
-                       var key,
-                               keys = [];
-
                        // Build array of key names
                        for ( key in ts.collationTable ) {
                                // Check hasOwn to be safe
        /* Public scope */
 
        $.tablesorter = {
-                       defaultOptions: {
-                               cssHeader: 'headerSort',
-                               cssAsc: 'headerSortUp',
-                               cssDesc: 'headerSortDown',
-                               cssChildRow: 'expand-child',
-                               sortMultiSortKey: 'shiftKey',
-                               unsortableClass: 'unsortable',
-                               parsers: [],
-                               cancelSelection: true,
-                               sortList: [],
-                               headerList: [],
-                               headerToColumns: [],
-                               columnToHeader: [],
-                               columns: 0
-                       },
-
-                       dateRegex: [],
-                       monthNames: {},
-
-                       /**
-                        * @param {jQuery} $tables
-                        * @param {Object} [settings]
-                        */
-                       construct: function ( $tables, settings ) {
-                               return $tables.each( function ( i, table ) {
-                                       // Declare and cache.
-                                       var $headers, cache, config, sortCSS, sortMsg,
-                                               $table = $( table ),
-                                               firstTime = true;
-
-                                       // Quit if no tbody
-                                       if ( !table.tBodies ) {
+               defaultOptions: {
+                       cssHeader: 'headerSort',
+                       cssAsc: 'headerSortUp',
+                       cssDesc: 'headerSortDown',
+                       cssChildRow: 'expand-child',
+                       sortMultiSortKey: 'shiftKey',
+                       unsortableClass: 'unsortable',
+                       parsers: [],
+                       cancelSelection: true,
+                       sortList: [],
+                       headerList: [],
+                       headerToColumns: [],
+                       columnToHeader: [],
+                       columns: 0
+               },
+
+               dateRegex: [],
+               monthNames: {},
+
+               /**
+                * @param {jQuery} $tables
+                * @param {Object} [settings]
+                * @return {jQuery}
+                */
+               construct: function ( $tables, settings ) {
+                       return $tables.each( function ( i, table ) {
+                               // Declare and cache.
+                               var $headers, cache, config, sortCSS, sortMsg,
+                                       $table = $( table ),
+                                       firstTime = true;
+
+                               // Quit if no tbody
+                               if ( !table.tBodies ) {
+                                       return;
+                               }
+                               if ( !table.tHead ) {
+                                       // No thead found. Look for rows with <th>s and
+                                       // move them into a <thead> tag or a <tfoot> tag
+                                       emulateTHeadAndFoot( $table );
+
+                                       // Still no thead? Then quit
+                                       if ( !table.tHead ) {
                                                return;
                                        }
-                                       if ( !table.tHead ) {
-                                               // No thead found. Look for rows with <th>s and
-                                               // move them into a <thead> tag or a <tfoot> tag
-                                               emulateTHeadAndFoot( $table );
+                               }
+                               $table.addClass( 'jquery-tablesorter' );
 
-                                               // Still no thead? Then quit
-                                               if ( !table.tHead ) {
-                                                       return;
-                                               }
-                                       }
-                                       $table.addClass( 'jquery-tablesorter' );
-
-                                       // Merge and extend
-                                       config = $.extend( {}, $.tablesorter.defaultOptions, settings );
-
-                                       // Save the settings where they read
-                                       $.data( table, 'tablesorter', { config: config } );
-
-                                       // Get the CSS class names, could be done elsewhere
-                                       sortCSS = [ config.cssAsc, config.cssDesc ];
-                                       // Messages tell the the user what the *next* state will be
-                                       // so are in reverse order to the CSS classes.
-                                       sortMsg = [ mw.msg( 'sort-descending' ), mw.msg( 'sort-ascending' ) ];
-
-                                       // Build headers
-                                       $headers = buildHeaders( table, sortMsg );
-
-                                       // Grab and process locale settings.
-                                       buildTransformTable();
-                                       buildDateTable();
-
-                                       // Precaching regexps can bring 10 fold
-                                       // performance improvements in some browsers.
-                                       cacheRegexs();
-
-                                       function setupForFirstSort() {
-                                               firstTime = false;
-
-                                               // Defer buildCollationTable to first sort. As user and site scripts
-                                               // may customize tableSorterCollation but load after $.ready(), other
-                                               // scripts may call .tablesorter() before they have done the
-                                               // tableSorterCollation customizations.
-                                               buildCollationTable();
-
-                                               // Legacy fix of .sortbottoms
-                                               // Wrap them inside a tfoot (because that's what they actually want to be)
-                                               // and put the <tfoot> at the end of the <table>
-                                               var $tfoot,
-                                                       $sortbottoms = $table.find( '> tbody > tr.sortbottom' );
-                                               if ( $sortbottoms.length ) {
-                                                       $tfoot = $table.children( 'tfoot' );
-                                                       if ( $tfoot.length ) {
-                                                               $tfoot.eq( 0 ).prepend( $sortbottoms );
-                                                       } else {
-                                                               $table.append( $( '<tfoot>' ).append( $sortbottoms ) );
-                                                       }
-                                               }
+                               // Merge and extend
+                               config = $.extend( {}, $.tablesorter.defaultOptions, settings );
 
-                                               explodeRowspans( $table );
-                                               manageColspans( $table );
+                               // Save the settings where they read
+                               $.data( table, 'tablesorter', { config: config } );
 
-                                               // Try to auto detect column type, and store in tables config
-                                               config.parsers = buildParserCache( table, $headers );
-                                       }
+                               // Get the CSS class names, could be done elsewhere
+                               sortCSS = [ config.cssAsc, config.cssDesc ];
+                               // Messages tell the the user what the *next* state will be
+                               // so are in reverse order to the CSS classes.
+                               sortMsg = [ mw.msg( 'sort-descending' ), mw.msg( 'sort-ascending' ) ];
 
-                                       // Apply event handling to headers
-                                       // this is too big, perhaps break it out?
-                                       $headers.on( 'keypress click', function ( e ) {
-                                               var cell, $cell, columns, newSortList, i,
-                                                       totalRows,
-                                                       j, s, o;
-
-                                               if ( e.type === 'click' && e.target.nodeName.toLowerCase() === 'a' ) {
-                                                       // The user clicked on a link inside a table header.
-                                                       // Do nothing and let the default link click action continue.
-                                                       return true;
-                                               }
+                               // Build headers
+                               $headers = buildHeaders( table, sortMsg );
 
-                                               if ( e.type === 'keypress' && e.which !== 13 ) {
-                                                       // Only handle keypresses on the "Enter" key.
-                                                       return true;
-                                               }
+                               // Grab and process locale settings.
+                               buildTransformTable();
+                               buildDateTable();
 
-                                               if ( firstTime ) {
-                                                       setupForFirstSort();
+                               // Precaching regexps can bring 10 fold
+                               // performance improvements in some browsers.
+                               cacheRegexs();
+
+                               function setupForFirstSort() {
+                                       var $tfoot, $sortbottoms;
+
+                                       firstTime = false;
+
+                                       // Defer buildCollationTable to first sort. As user and site scripts
+                                       // may customize tableSorterCollation but load after $.ready(), other
+                                       // scripts may call .tablesorter() before they have done the
+                                       // tableSorterCollation customizations.
+                                       buildCollationTable();
+
+                                       // Legacy fix of .sortbottoms
+                                       // Wrap them inside a tfoot (because that's what they actually want to be)
+                                       // and put the <tfoot> at the end of the <table>
+                                       $sortbottoms = $table.find( '> tbody > tr.sortbottom' );
+                                       if ( $sortbottoms.length ) {
+                                               $tfoot = $table.children( 'tfoot' );
+                                               if ( $tfoot.length ) {
+                                                       $tfoot.eq( 0 ).prepend( $sortbottoms );
+                                               } else {
+                                                       $table.append( $( '<tfoot>' ).append( $sortbottoms ) );
                                                }
+                                       }
 
-                                               // Build the cache for the tbody cells
-                                               // to share between calculations for this sort action.
-                                               // Re-calculated each time a sort action is performed due to possiblity
-                                               // that sort values change. Shouldn't be too expensive, but if it becomes
-                                               // too slow an event based system should be implemented somehow where
-                                               // cells get event .change() and bubbles up to the <table> here
-                                               cache = buildCache( table );
-
-                                               totalRows = ( $table[ 0 ].tBodies[ 0 ] && $table[ 0 ].tBodies[ 0 ].rows.length ) || 0;
-                                               if ( totalRows > 0 ) {
-                                                       cell = this;
-                                                       $cell = $( cell );
-
-                                                       // Get current column sort order
-                                                       $cell.data( {
-                                                               order: $cell.data( 'count' ) % 2,
-                                                               count: $cell.data( 'count' ) + 1
-                                                       } );
+                                       explodeRowspans( $table );
+                                       manageColspans( $table );
 
-                                                       cell = this;
-                                                       // Get current column index
-                                                       columns = config.headerToColumns[ $cell.data( 'headerIndex' ) ];
-                                                       newSortList = $.map( columns, function ( c ) {
-                                                               // jQuery "helpfully" flattens the arrays...
-                                                               return [ [ c, $cell.data( 'order' ) ] ];
-                                                       } );
-                                                       // Index of first column belonging to this header
-                                                       i = columns[ 0 ];
+                                       // Try to auto detect column type, and store in tables config
+                                       config.parsers = buildParserCache( table, $headers );
+                               }
 
-                                                       if ( !e[ config.sortMultiSortKey ] ) {
-                                                               // User only wants to sort on one column set
-                                                               // Flush the sort list and add new columns
-                                                               config.sortList = newSortList;
-                                                       } else {
-                                                               // Multi column sorting
-                                                               // It is not possible for one column to belong to multiple headers,
-                                                               // so this is okay - we don't need to check for every value in the columns array
-                                                               if ( isValueInArray( i, config.sortList ) ) {
-                                                                       // The user has clicked on an already sorted column.
-                                                                       // Reverse the sorting direction for all tables.
-                                                                       for ( j = 0; j < config.sortList.length; j++ ) {
-                                                                               s = config.sortList[ j ];
-                                                                               o = config.headerList[ config.columnToHeader[ s[ 0 ] ] ];
-                                                                               if ( isValueInArray( s[ 0 ], newSortList ) ) {
-                                                                                       $( o ).data( 'count', s[ 1 ] + 1 );
-                                                                                       s[ 1 ] = $( o ).data( 'count' ) % 2;
-                                                                               }
+                               // Apply event handling to headers
+                               // this is too big, perhaps break it out?
+                               $headers.on( 'keypress click', function ( e ) {
+                                       var cell, $cell, columns, newSortList, i,
+                                               totalRows,
+                                               j, s, o;
+
+                                       if ( e.type === 'click' && e.target.nodeName.toLowerCase() === 'a' ) {
+                                               // The user clicked on a link inside a table header.
+                                               // Do nothing and let the default link click action continue.
+                                               return true;
+                                       }
+
+                                       if ( e.type === 'keypress' && e.which !== 13 ) {
+                                               // Only handle keypresses on the "Enter" key.
+                                               return true;
+                                       }
+
+                                       if ( firstTime ) {
+                                               setupForFirstSort();
+                                       }
+
+                                       // Build the cache for the tbody cells
+                                       // to share between calculations for this sort action.
+                                       // Re-calculated each time a sort action is performed due to possiblity
+                                       // that sort values change. Shouldn't be too expensive, but if it becomes
+                                       // too slow an event based system should be implemented somehow where
+                                       // cells get event .change() and bubbles up to the <table> here
+                                       cache = buildCache( table );
+
+                                       totalRows = ( $table[ 0 ].tBodies[ 0 ] && $table[ 0 ].tBodies[ 0 ].rows.length ) || 0;
+                                       if ( totalRows > 0 ) {
+                                               cell = this;
+                                               $cell = $( cell );
+
+                                               // Get current column sort order
+                                               $cell.data( {
+                                                       order: $cell.data( 'count' ) % 2,
+                                                       count: $cell.data( 'count' ) + 1
+                                               } );
+
+                                               cell = this;
+                                               // Get current column index
+                                               columns = config.headerToColumns[ $cell.data( 'headerIndex' ) ];
+                                               newSortList = $.map( columns, function ( c ) {
+                                                       // jQuery "helpfully" flattens the arrays...
+                                                       return [ [ c, $cell.data( 'order' ) ] ];
+                                               } );
+                                               // Index of first column belonging to this header
+                                               i = columns[ 0 ];
+
+                                               if ( !e[ config.sortMultiSortKey ] ) {
+                                                       // User only wants to sort on one column set
+                                                       // Flush the sort list and add new columns
+                                                       config.sortList = newSortList;
+                                               } else {
+                                                       // Multi column sorting
+                                                       // It is not possible for one column to belong to multiple headers,
+                                                       // so this is okay - we don't need to check for every value in the columns array
+                                                       if ( isValueInArray( i, config.sortList ) ) {
+                                                               // The user has clicked on an already sorted column.
+                                                               // Reverse the sorting direction for all tables.
+                                                               for ( j = 0; j < config.sortList.length; j++ ) {
+                                                                       s = config.sortList[ j ];
+                                                                       o = config.headerList[ config.columnToHeader[ s[ 0 ] ] ];
+                                                                       if ( isValueInArray( s[ 0 ], newSortList ) ) {
+                                                                               $( o ).data( 'count', s[ 1 ] + 1 );
+                                                                               s[ 1 ] = $( o ).data( 'count' ) % 2;
                                                                        }
-                                                               } else {
-                                                                       // Add columns to sort list array
-                                                                       config.sortList = config.sortList.concat( newSortList );
                                                                }
+                                                       } else {
+                                                               // Add columns to sort list array
+                                                               config.sortList = config.sortList.concat( newSortList );
                                                        }
+                                               }
 
-                                                       // Reset order/counts of cells not affected by sorting
-                                                       setHeadersOrder( $headers, config.sortList, config.headerToColumns );
+                                               // Reset order/counts of cells not affected by sorting
+                                               setHeadersOrder( $headers, config.sortList, config.headerToColumns );
 
-                                                       // Set CSS for headers
-                                                       setHeadersCss( $table[ 0 ], $headers, config.sortList, sortCSS, sortMsg, config.columnToHeader );
-                                                       appendToTable(
-                                                               $table[ 0 ], multisort( $table[ 0 ], config.sortList, cache )
-                                                       );
+                                               // Set CSS for headers
+                                               setHeadersCss( $table[ 0 ], $headers, config.sortList, sortCSS, sortMsg, config.columnToHeader );
+                                               appendToTable(
+                                                       $table[ 0 ], multisort( $table[ 0 ], config.sortList, cache )
+                                               );
 
-                                                       // Stop normal event by returning false
-                                                       return false;
-                                               }
+                                               // Stop normal event by returning false
+                                               return false;
+                                       }
 
-                                       // Cancel selection
-                                       } ).mousedown( function () {
-                                               if ( config.cancelSelection ) {
-                                                       this.onselectstart = function () {
-                                                               return false;
-                                                       };
+                               // Cancel selection
+                               } ).mousedown( function () {
+                                       if ( config.cancelSelection ) {
+                                               this.onselectstart = function () {
                                                        return false;
-                                               }
-                                       } );
+                                               };
+                                               return false;
+                                       }
+                               } );
 
-                                       /**
-                                        * Sorts the table. If no sorting is specified by passing a list of sort
-                                        * objects, the table is sorted according to the initial sorting order.
-                                        * Passing an empty array will reset sorting (basically just reset the headers
-                                        * making the table appear unsorted).
-                                        *
-                                        * @param {Array} [sortList] List of sort objects.
-                                        */
-                                       $table.data( 'tablesorter' ).sort = function ( sortList ) {
-
-                                               if ( firstTime ) {
-                                                       setupForFirstSort();
-                                               }
+                               /**
+                                * Sorts the table. If no sorting is specified by passing a list of sort
+                                * objects, the table is sorted according to the initial sorting order.
+                                * Passing an empty array will reset sorting (basically just reset the headers
+                                * making the table appear unsorted).
+                                *
+                                * @param {Array} [sortList] List of sort objects.
+                                */
+                               $table.data( 'tablesorter' ).sort = function ( sortList ) {
+
+                                       if ( firstTime ) {
+                                               setupForFirstSort();
+                                       }
 
-                                               if ( sortList === undefined ) {
-                                                       sortList = config.sortList;
-                                               } else if ( sortList.length > 0 ) {
-                                                       sortList = convertSortList( sortList );
-                                               }
+                                       if ( sortList === undefined ) {
+                                               sortList = config.sortList;
+                                       } else if ( sortList.length > 0 ) {
+                                               sortList = convertSortList( sortList );
+                                       }
 
-                                               // Set each column's sort count to be able to determine the correct sort
-                                               // order when clicking on a header cell the next time
-                                               setHeadersOrder( $headers, sortList, config.headerToColumns );
+                                       // Set each column's sort count to be able to determine the correct sort
+                                       // order when clicking on a header cell the next time
+                                       setHeadersOrder( $headers, sortList, config.headerToColumns );
 
-                                               // re-build the cache for the tbody cells
-                                               cache = buildCache( table );
+                                       // re-build the cache for the tbody cells
+                                       cache = buildCache( table );
 
-                                               // set css for headers
-                                               setHeadersCss( table, $headers, sortList, sortCSS, sortMsg, config.columnToHeader );
+                                       // set css for headers
+                                       setHeadersCss( table, $headers, sortList, sortCSS, sortMsg, config.columnToHeader );
 
-                                               // sort the table and append it to the dom
-                                               appendToTable( table, multisort( table, sortList, cache ) );
-                                       };
+                                       // sort the table and append it to the dom
+                                       appendToTable( table, multisort( table, sortList, cache ) );
+                               };
 
-                                       // sort initially
-                                       if ( config.sortList.length > 0 ) {
-                                               config.sortList = convertSortList( config.sortList );
-                                               $table.data( 'tablesorter' ).sort();
-                                       }
+                               // sort initially
+                               if ( config.sortList.length > 0 ) {
+                                       config.sortList = convertSortList( config.sortList );
+                                       $table.data( 'tablesorter' ).sort();
+                               }
 
-                               } );
-                       },
+                       } );
+               },
 
-                       addParser: function ( parser ) {
-                               if ( !getParserById( parser.id ) ) {
-                                       parsers.push( parser );
-                               }
-                       },
-
-                       formatDigit: function ( s ) {
-                               var out, c, p, i;
-                               if ( ts.transformTable !== false ) {
-                                       out = '';
-                                       for ( p = 0; p < s.length; p++ ) {
-                                               c = s.charAt( p );
-                                               if ( c in ts.transformTable ) {
-                                                       out += ts.transformTable[ c ];
-                                               } else {
-                                                       out += c;
-                                               }
+               addParser: function ( parser ) {
+                       if ( !getParserById( parser.id ) ) {
+                               parsers.push( parser );
+                       }
+               },
+
+               formatDigit: function ( s ) {
+                       var out, c, p, i;
+                       if ( ts.transformTable !== false ) {
+                               out = '';
+                               for ( p = 0; p < s.length; p++ ) {
+                                       c = s.charAt( p );
+                                       if ( c in ts.transformTable ) {
+                                               out += ts.transformTable[ c ];
+                                       } else {
+                                               out += c;
                                        }
-                                       s = out;
                                }
-                               i = parseFloat( s.replace( /[, ]/g, '' ).replace( '\u2212', '-' ) );
-                               return isNaN( i ) ? 0 : i;
-                       },
+                               s = out;
+                       }
+                       i = parseFloat( s.replace( /[, ]/g, '' ).replace( '\u2212', '-' ) );
+                       return isNaN( i ) ? 0 : i;
+               },
 
-                       formatFloat: function ( s ) {
-                               var i = parseFloat( s );
-                               return isNaN( i ) ? 0 : i;
-                       },
+               formatFloat: function ( s ) {
+                       var i = parseFloat( s );
+                       return isNaN( i ) ? 0 : i;
+               },
 
-                       formatInt: function ( s ) {
-                               var i = parseInt( s, 10 );
-                               return isNaN( i ) ? 0 : i;
-                       },
+               formatInt: function ( s ) {
+                       var i = parseInt( s, 10 );
+                       return isNaN( i ) ? 0 : i;
+               },
 
-                       clearTableBody: function ( table ) {
-                               $( table.tBodies[ 0 ] ).empty();
-                       },
+               clearTableBody: function ( table ) {
+                       $( table.tBodies[ 0 ] ).empty();
+               },
 
-                       getParser: function ( id ) {
-                               buildTransformTable();
-                               buildDateTable();
-                               cacheRegexs();
-                               buildCollationTable();
+               getParser: function ( id ) {
+                       buildTransformTable();
+                       buildDateTable();
+                       cacheRegexs();
+                       buildCollationTable();
 
-                               return getParserById( id );
-                       },
+                       return getParserById( id );
+               },
 
-                       getParsers: function () {  // for table diagnosis
-                               return parsers;
-                       }
-               };
+               getParsers: function () {  // for table diagnosis
+                       return parsers;
+               }
+       };
 
        // Shortcut
        ts = $.tablesorter;
                        return true;
                },
                format: function ( s ) {
+                       var tsc;
                        s = $.trim( s.toLowerCase() );
                        if ( ts.collationRegex ) {
-                               var tsc = ts.collationTable;
+                               tsc = ts.collationTable;
                                s = s.replace( ts.collationRegex, function ( match ) {
                                        var r = tsc[ match ] ? tsc[ match ] : tsc[ match.toUpperCase() ];
                                        return r.toLowerCase();
                                if ( !matches ) {
                                        return $.tablesorter.formatFloat( 0 );
                                }
-                               isodate = new Date( matches[ 2 ]  + '/' + matches[ 3 ] + '/' + matches[ 1 ] );
+                               isodate = new Date( matches[ 2 ] + '/' + matches[ 3 ] + '/' + matches[ 1 ] );
                        } else {
                                matches = s.match( ts.rgx.isoDate[ 0 ] );
                                if ( !matches ) {
index 5e93ba6..c897302 100644 (file)
 
                /**
                 * Helper function to get an IE TextRange object for an element
+                *
+                * @param {HTMLElement} element
+                * @return {TextRange}
                 */
-               function rangeForElementIE( e ) {
-                       if ( e.nodeName.toLowerCase() === 'input' ) {
-                               return e.createTextRange();
+               function rangeForElementIE( element ) {
+                       var sel;
+                       if ( element.nodeName.toLowerCase() === 'input' ) {
+                               return element.createTextRange();
                        } else {
-                               var sel = document.body.createTextRange();
-                               sel.moveToElementText( e );
+                               sel = document.body.createTextRange();
+                               sel.moveToElementText( element );
                                return sel;
                        }
                }
@@ -47,6 +51,8 @@
                 * Helper function for IE for activating the textarea. Called only in the
                 * IE-specific code paths below; makes use of IE-specific non-standard
                 * function setActive() if possible to avoid screen flicker.
+                *
+                * @param {HTMLElement} element
                 */
                function activateElementOnIE( element ) {
                        if ( element.setActive ) {
                fn = {
                        /**
                         * Get the contents of the textarea
+                        *
+                        * @return {string}
                         */
                        getContents: function () {
                                return this.val();
                        },
                        /**
                         * Set the contents of the textarea, replacing anything that was there before
+                        *
+                        * @param {string} content
                         */
                        setContents: function ( content ) {
                                this.val( content );
@@ -72,6 +82,8 @@
                        /**
                         * Get the currently selected text in this textarea. Will focus the textarea
                         * in some browsers (IE/Opera)
+                        *
+                        * @return {string}
                         */
                        getSelection: function () {
                                var retval, range,
                         * Inserts text at the beginning and end of a text selection, optionally
                         * inserting text at the caret when selection is empty.
                         *
+                        * @param {Object} options Options
                         * FIXME document the options parameters
+                        * @return {jQuery}
                         */
                        encapsulateSelection: function ( options ) {
                                return this.each( function () {
                                         * Do the splitlines stuff.
                                         *
                                         * Wrap each line of the selected text with pre and post
+                                        *
+                                        * @param {string} selText Selected text
+                                        * @param {string} pre Text before
+                                        * @param {string} post Text after
+                                        * @return {string} Wrapped text
                                         */
                                        function doSplitLines( selText, pre, post ) {
                                                var i,
                         *
                         * Will focus the textarea in some browsers (IE/Opera)
                         *
+                        * @param {Object} options Options
                         * FIXME document the options parameters
+                        * @return {number} Position
                         */
                        getCaretPosition: function ( options ) {
                                function getCaret( e ) {
                                        var caretPos = 0,
                                                endPos = 0,
                                                preText, rawPreText, periText,
-                                               rawPeriText, postText, rawPostText,
+                                               rawPeriText, postText,
                                                // IE Support
                                                preFinished,
                                                periFinished,
                                                // Load the text values we need to compare
                                                preText = rawPreText = preRange.text;
                                                periText = rawPeriText = periRange.text;
-                                               postText = rawPostText = postRange.text;
+                                               postText = postRange.text;
 
                                                /*
                                                 * Check each range for trimmed newlines by shrinking the range by 1
                                                                        postFinished = true;
                                                                } else {
                                                                        postRange.moveEnd( 'character', -1 );
-                                                                       if ( postRange.text === postText ) {
-                                                                               rawPostText += '\r\n';
-                                                                       } else {
+                                                                       if ( postRange.text !== postText ) {
                                                                                postFinished = true;
                                                                        }
                                                                }
                                return getCaret( this.get( 0 ) );
                        },
                        /**
+                        * @param {Object} options options
                         * FIXME document the options parameters
+                        * @return {jQuery}
                         */
                        setSelection: function ( options ) {
                                return this.each( function () {
                         * Scroll a textarea to the current cursor position. You can set the cursor
                         * position with setSelection()
                         *
-                        * @param {boolean} options Whether to force a scroll even if the caret position
-                        *  is already visible. Defaults to false
-                        *
-                        * FIXME document the options parameters (function body suggests options.force is a boolean, not options itself)
+                        * @param {Object} options options
+                        * @cfg {boolean} [force=false] Whether to force a scroll even if the caret position
+                        *  is already visible.
+                        * FIXME document the options parameters
+                        * @return {jQuery}
                         */
                        scrollToCaretPosition: function ( options ) {
                                function getLineLength( e ) {
index 3b19b35..f26c336 100644 (file)
                                        $( '<span>' ).addClass( 'comment' ).html(
                                                // There is no equivalent to rawParams
                                                mw.message( 'parentheses' ).escaped()
-                                                       .replace( '$1', parse.parsedsummary )
+                                                       // .replace() use $ as start of a pattern.
+                                                       // $$ is the pattern for '$'.
+                                                       // The inner .replace() duplicates any $ and
+                                                       // the outer .replace() simplifies the $$.
+                                                       .replace( '$1', parse.parsedsummary.replace( /\$/g, '$$$$' ) )
                                        )
                                );
                        }
index 6c63957..c8d3fad 100644 (file)
@@ -1,6 +1,7 @@
 /*!
  * Scripts for pre-emptive edit preparing on action=edit
  */
+/* eslint-disable no-use-before-define */
 ( function ( mw, $ ) {
        if ( !mw.config.get( 'wgAjaxEditStash' ) ) {
                return;
                        if (
                                // Reverts may involve use (undo) links; stash as they review the diff.
                                // Since the form has a pre-filled summary, stash the edit immediately.
-                               mw.util.getParamValue( 'undo' ) !== null
+                               mw.util.getParamValue( 'undo' ) !== null ||
                                // Pressing "show changes" and "preview" also signify that the user will
                                // probably save the page soon
-                               || $.inArray( $form.find( '#mw-edit-mode' ).val(), [ 'preview', 'diff' ] ) > -1
+                               $.inArray( $form.find( '#mw-edit-mode' ).val(), [ 'preview', 'diff' ] ) > -1
                        ) {
                                checkStash();
                        }
index 077d5e3..b3b0af2 100644 (file)
@@ -10,6 +10,7 @@ jQuery( function ( $ ) {
         * @ignore
         * @context {Element} input
         * @param {jQuery.Event} e
+        * @return {boolean} False to cancel the default event
         */
        function updateDiffRadios() {
                var nextState = 'before',
index 2be29f0..7439754 100644 (file)
@@ -4,11 +4,12 @@
 ( function ( mw, $ ) {
        $( function () {
                mw.util.$content.dblclick( function ( e ) {
+                       var $a;
                        // Recheck preference so extensions can do a hack to disable this code.
                        if ( parseInt( mw.user.options.get( 'editondblclick' ), 10 ) ) {
                                e.preventDefault();
                                // Trigger native HTMLElement click instead of opening URL (bug 43052)
-                               var $a = $( '#ca-edit a' );
+                               $a = $( '#ca-edit a' );
                                // Not every page has an edit link (bug 57713)
                                if ( $a.length ) {
                                        $a.get( 0 ).click();
index 4c75e33..a3a82d5 100644 (file)
 
                $link = $( '<a>' )
                .text( showText )
-               .attr( 'href', '#' )
-               .click( function () {
-                       if ( $table.hasClass( 'collapsed' ) ) {
-                               $( this ).text( hideText );
-                       } else {
-                               $( this ).text( showText );
+               .attr( {
+                       role: 'button',
+                       tabindex: 0
+               } )
+               .on( 'click keypress', function ( e ) {
+                       if (
+                               e.type === 'click' ||
+                               e.type === 'keypress' && e.which === 13
+                       ) {
+                               if ( $table.hasClass( 'collapsed' ) ) {
+                                       $( this ).text( hideText );
+                               } else {
+                                       $( this ).text( showText );
+                               }
+                               $table.toggleClass( 'expanded collapsed' );
                        }
-                       $table.toggleClass( 'expanded collapsed' );
-                       return false;
                } );
 
                $col.append( $link );
index 29a5a79..39a122d 100644 (file)
@@ -28,7 +28,7 @@
                }
 
                // Note that this will update the hash in a modern browser, retaining back behaviour
-               history.replaceState( /*data=*/ history.state, /*title=*/ document.title, /*url=*/ canonical );
+               history.replaceState( /* data= */ history.state, /* title= */ document.title, /* url= */ canonical );
                if ( shouldChangeFragment ) {
                        // Specification for history.replaceState() doesn't require browser to scroll,
                        // so scroll to be sure (see also T110501). Support for IE9 and IE10.
index a4c911a..e136211 100644 (file)
@@ -3,7 +3,6 @@
  */
 
 mediaWiki.language.convertGrammar = function ( word, form ) {
-       /*jshint onecase:true */
        var grammarForms = mediaWiki.language.getData( 'ga', 'grammarForms' );
        if ( grammarForms && grammarForms[ form ] ) {
                return grammarForms[ form ][ word ];
index 945f02f..5bf8c4d 100644 (file)
@@ -21,7 +21,7 @@ mediaWiki.language.convertGrammar = function ( word, form ) {
                        }
 
                        // Add a hyphen (maqaf) before numbers and non-Hebrew letters
-                       if ( word.slice( 0, 1 ) < 'א' ||  word.slice( 0, 1 ) > 'ת' ) {
+                       if ( word.slice( 0, 1 ) < 'א' || word.slice( 0, 1 ) > 'ת' ) {
                                word = '־' + word;
                        }
        }
index 935d466..bb6f61d 100644 (file)
@@ -3,7 +3,6 @@
  */
 
 mediaWiki.language.convertGrammar = function ( word, form ) {
-       /*jshint onecase:true */
        var grammarForms = mediaWiki.language.getData( 'hy', 'grammarForms' );
        if ( grammarForms && grammarForms[ form ] ) {
                return grammarForms[ form ][ word ];
index ccc68f1..09d7c0b 100644 (file)
@@ -2,82 +2,37 @@
  * Russian (Русский) language functions
  */
 
-// These tests were originally made for names of Wikimedia
-// websites, so they don't currently cover all the possible
-// cases.
-
 mediaWiki.language.convertGrammar = function ( word, form ) {
-       /*global $ */
        'use strict';
 
-       var grammarForms = mediaWiki.language.getData( 'ru', 'grammarForms' );
-       if ( grammarForms && grammarForms[ form ] ) {
-               return grammarForms[ form ][ word ];
+       var forms, transformations, i, rule, sourcePattern, regexp, replacement;
+
+       forms = mediaWiki.language.getData( 'ru', 'grammarForms' );
+       if ( forms && forms[ form ] ) {
+               return forms[ form ][ word ];
+       }
+
+       transformations = mediaWiki.language.getData( 'ru', 'grammarTransformations' );
+
+       if ( !transformations[ form ] ) {
+               return word;
        }
-       switch ( form ) {
-               case 'genitive': // родительный падеж
-                       if ( word.slice( -1 ) === 'ь' ) {
-                               word = word.slice( 0, -1 ) + 'я';
-                       } else if ( word.slice( -2 ) === 'ия' ) {
-                               word = word.slice( 0, -2 ) + 'ии';
-                       } else if ( word.slice( -2 ) === 'ка' ) {
-                               word = word.slice( 0, -2 ) + 'ки';
-                       } else if ( word.slice( -2 ) === 'ти' ) {
-                               word = word.slice( 0, -2 ) + 'тей';
-                       } else if ( word.slice( -2 ) === 'ды' ) {
-                               word = word.slice( 0, -2 ) + 'дов';
-                       } else if ( word.slice( -1 ) === 'д' ) {
-                               word = word.slice( 0, -1 ) + 'да';
-                       } else if ( word.slice( -3 ) === 'ные' ) {
-                               word = word.slice( 0, -3 ) + 'ных';
-                       } else if ( word.slice( -3 ) === 'ник' ) {
-                               word = word.slice( 0, -3 ) + 'ника';
-                       }
-                       break;
-               case 'prepositional': // предложный падеж
-                       if ( word.slice( -1 ) === 'ь' ) {
-                               word = word.slice( 0, -1 ) + 'е';
-                       } else if ( word.slice( -2 ) === 'ия' ) {
-                               word = word.slice( 0, -2 ) + 'ии';
-                       } else if ( word.slice( -2 ) === 'ка' ) {
-                               word = word.slice( 0, -2 ) + 'ке';
-                       } else if ( word.slice( -2 ) === 'ти' ) {
-                               word = word.slice( 0, -2 ) + 'тях';
-                       } else if ( word.slice( -2 ) === 'ды' ) {
-                               word = word.slice( 0, -2 ) + 'дах';
-                       } else if ( word.slice( -1 ) === 'д' ) {
-                               word = word.slice( 0, -1 ) + 'де';
-                       } else if ( word.slice( -3 ) === 'ные' ) {
-                               word = word.slice( 0, -3 ) + 'ных';
-                       } else if ( word.slice( -3 ) === 'ник' ) {
-                               word = word.slice( 0, -3 ) + 'нике';
-                       }
-                       break;
-               case 'languagegen': // язык в родительном падеже ("(с) русского")
-                       if ( word.slice( -3 ) === 'кий' ) {
-                               word = word.slice( 0, -2 ) + 'ого';
-                       } else if ( $.inArray( word, [ 'иврит', 'идиш' ] ) > -1 ) {
-                               word = word + 'а';
-                       }
-                       break;
-               case 'languageprep': // язык в предложном падеже ("(на) русском")
-                       if ( word.slice( -3 ) === 'кий' ) {
-                               word = word.slice( 0, -2 ) + 'ом';
-                       } else if ( $.inArray( word, [ 'иврит', 'идиш' ] ) > -1 ) {
-                               word = word + 'е';
-                       }
-                       break;
-               case 'languageadverb': // наречие с названием языка ("по-русски")
-                       if ( word.slice( -3 ) === 'кий' ) {
-                               word = 'по-' + word.slice( 0, -1 );
-                       } else if ( $.inArray( word, [ 'иврит', 'идиш' ] ) > -1 ) {
-                               word = 'на ' + word + 'е';
-                       } else if ( $.inArray( word, [ 'идо', 'урду', 'хинди', 'эсперанто' ] ) > -1 ) {
-                               word = 'на ' + word;
-                       } else {
-                               word = 'на языке ' + word;
-                       }
-                       break;
+
+       for ( i = 0; i < transformations[ form ].length; i++ ) {
+               rule = transformations[ form ][ i ];
+               sourcePattern = rule[ 0 ];
+
+               if ( sourcePattern === '@metadata' ) {
+                       continue;
+               }
+
+               regexp = new RegExp( sourcePattern );
+               replacement = rule[ 1 ];
+
+               if ( word.match( regexp ) ) {
+                       return word.replace( regexp, replacement );
+               }
        }
+
        return word;
 };
index cf3ef79..fc2af3d 100644 (file)
  */
 ( function ( mw, $ ) {
 
-/**
- * @class mw.language
- */
-$.extend( mw.language, {
-
        /**
-        * Process the PLURAL template substitution
-        *
-        * @private
-        * @param {Object} template Template object
-        * @param {string} template.title
-        * @param {Array} template.parameters
-        * @return {string}
+        * @class mw.language
         */
-       procPLURAL: function ( template ) {
-               if ( template.title && template.parameters && mw.language.convertPlural ) {
-                       // Check if we have forms to replace
-                       if ( template.parameters.length === 0 ) {
-                               return '';
+       $.extend( mw.language, {
+
+               /**
+                * Process the PLURAL template substitution
+                *
+                * @private
+                * @param {Object} template Template object
+                * @param {string} template.title
+                * @param {Array} template.parameters
+                * @return {string}
+                */
+               procPLURAL: function ( template ) {
+                       var count;
+                       if ( template.title && template.parameters && mw.language.convertPlural ) {
+                               // Check if we have forms to replace
+                               if ( template.parameters.length === 0 ) {
+                                       return '';
+                               }
+                               // Restore the count into a Number ( if it got converted earlier )
+                               count = mw.language.convertNumber( template.title, true );
+                               // Do convertPlural call
+                               return mw.language.convertPlural( parseInt( count, 10 ), template.parameters );
                        }
-                       // Restore the count into a Number ( if it got converted earlier )
-                       var count = mw.language.convertNumber( template.title, true );
-                       // Do convertPlural call
-                       return mw.language.convertPlural( parseInt( count, 10 ), template.parameters );
-               }
-               // Could not process plural return first form or nothing
-               if ( template.parameters[ 0 ] ) {
-                       return template.parameters[ 0 ];
-               }
-               return '';
-       },
+                       // Could not process plural return first form or nothing
+                       if ( template.parameters[ 0 ] ) {
+                               return template.parameters[ 0 ];
+                       }
+                       return '';
+               },
 
-       /**
-        * Plural form transformations, needed for some languages.
-        *
-        * @param {number} count Non-localized quantifier
-        * @param {Array} forms List of plural forms
-        * @param {Object} [explicitPluralForms] List of explicit plural forms
-        * @return {string} Correct form for quantifier in this language
-        */
-       convertPlural: function ( count, forms, explicitPluralForms ) {
-               var pluralRules,
-                       pluralFormIndex = 0;
+               /**
+                * Plural form transformations, needed for some languages.
+                *
+                * @param {number} count Non-localized quantifier
+                * @param {Array} forms List of plural forms
+                * @param {Object} [explicitPluralForms] List of explicit plural forms
+                * @return {string} Correct form for quantifier in this language
+                */
+               convertPlural: function ( count, forms, explicitPluralForms ) {
+                       var pluralRules,
+                               pluralFormIndex = 0;
 
-               if ( explicitPluralForms && ( explicitPluralForms[ count ] !== undefined ) ) {
-                       return explicitPluralForms[ count ];
-               }
+                       if ( explicitPluralForms && ( explicitPluralForms[ count ] !== undefined ) ) {
+                               return explicitPluralForms[ count ];
+                       }
 
-               if ( !forms || forms.length === 0 ) {
-                       return '';
-               }
+                       if ( !forms || forms.length === 0 ) {
+                               return '';
+                       }
 
-               pluralRules = mw.language.getData( mw.config.get( 'wgUserLanguage' ), 'pluralRules' );
-               if ( !pluralRules ) {
-                       // default fallback.
-                       return ( count === 1 ) ? forms[ 0 ] : forms[ 1 ];
-               }
-               pluralFormIndex = mw.cldr.getPluralForm( count, pluralRules );
-               pluralFormIndex = Math.min( pluralFormIndex, forms.length - 1 );
-               return forms[ pluralFormIndex ];
-       },
+                       pluralRules = mw.language.getData( mw.config.get( 'wgUserLanguage' ), 'pluralRules' );
+                       if ( !pluralRules ) {
+                               // default fallback.
+                               return ( count === 1 ) ? forms[ 0 ] : forms[ 1 ];
+                       }
+                       pluralFormIndex = mw.cldr.getPluralForm( count, pluralRules );
+                       pluralFormIndex = Math.min( pluralFormIndex, forms.length - 1 );
+                       return forms[ pluralFormIndex ];
+               },
 
-       /**
-        * Pads an array to a specific length by copying the last one element.
-        *
-        * @private
-        * @param {Array} forms Number of forms given to convertPlural
-        * @param {number} count Number of forms required
-        * @return {Array} Padded array of forms
-        */
-       preConvertPlural: function ( forms, count ) {
-               while ( forms.length < count ) {
-                       forms.push( forms[ forms.length - 1 ] );
-               }
-               return forms;
-       },
+               /**
+                * Pads an array to a specific length by copying the last one element.
+                *
+                * @private
+                * @param {Array} forms Number of forms given to convertPlural
+                * @param {number} count Number of forms required
+                * @return {Array} Padded array of forms
+                */
+               preConvertPlural: function ( forms, count ) {
+                       while ( forms.length < count ) {
+                               forms.push( forms[ forms.length - 1 ] );
+                       }
+                       return forms;
+               },
 
-       /**
-        * Provides an alternative text depending on specified gender.
-        *
-        * Usage in message text: `{{gender:[gender|user object]|masculine|feminine|neutral}}`.
-        * If second or third parameter are not specified, masculine is used.
-        *
-        * These details may be overridden per language.
-        *
-        * @param {string} gender 'male', 'female', or anything else for neutral.
-        * @param {Array} forms List of gender forms
-        * @return {string}
-        */
-       gender: function ( gender, forms ) {
-               if ( !forms || forms.length === 0 ) {
-                       return '';
-               }
-               forms = mw.language.preConvertPlural( forms, 2 );
-               if ( gender === 'male' ) {
-                       return forms[ 0 ];
-               }
-               if ( gender === 'female' ) {
-                       return forms[ 1 ];
-               }
-               return ( forms.length === 3 ) ? forms[ 2 ] : forms[ 0 ];
-       },
+               /**
+                * Provides an alternative text depending on specified gender.
+                *
+                * Usage in message text: `{{gender:[gender|user object]|masculine|feminine|neutral}}`.
+                * If second or third parameter are not specified, masculine is used.
+                *
+                * These details may be overridden per language.
+                *
+                * @param {string} gender 'male', 'female', or anything else for neutral.
+                * @param {Array} forms List of gender forms
+                * @return {string}
+                */
+               gender: function ( gender, forms ) {
+                       if ( !forms || forms.length === 0 ) {
+                               return '';
+                       }
+                       forms = mw.language.preConvertPlural( forms, 2 );
+                       if ( gender === 'male' ) {
+                               return forms[ 0 ];
+                       }
+                       if ( gender === 'female' ) {
+                               return forms[ 1 ];
+                       }
+                       return ( forms.length === 3 ) ? forms[ 2 ] : forms[ 0 ];
+               },
 
-       /**
-        * Grammatical transformations, needed for inflected languages.
-        * Invoked by putting `{{grammar:form|word}}` in a message.
-        *
-        * The rules can be defined in $wgGrammarForms global or computed
-        * dynamically by overriding this method per language.
-        *
-        * @param {string} word
-        * @param {string} form
-        * @return {string}
-        */
-       convertGrammar: function ( word, form ) {
-               var grammarForms = mw.language.getData( mw.config.get( 'wgUserLanguage' ), 'grammarForms' );
-               if ( grammarForms && grammarForms[ form ] ) {
-                       return grammarForms[ form ][ word ] || word;
-               }
-               return word;
-       },
+               /**
+                * Grammatical transformations, needed for inflected languages.
+                * Invoked by putting `{{grammar:form|word}}` in a message.
+                *
+                * The rules can be defined in $wgGrammarForms global or computed
+                * dynamically by overriding this method per language.
+                *
+                * @param {string} word
+                * @param {string} form
+                * @return {string}
+                */
+               convertGrammar: function ( word, form ) {
+                       var grammarForms = mw.language.getData( mw.config.get( 'wgUserLanguage' ), 'grammarForms' );
+                       if ( grammarForms && grammarForms[ form ] ) {
+                               return grammarForms[ form ][ word ] || word;
+                       }
+                       return word;
+               },
 
-       /**
-        * Turn a list of string into a simple list using commas and 'and'.
-        *
-        * See Language::listToText in languages/Language.php
-        *
-        * @param {string[]} list
-        * @return {string}
-        */
-       listToText: function ( list ) {
-               var text = '',
-                       i = 0;
+               /**
+                * Turn a list of string into a simple list using commas and 'and'.
+                *
+                * See Language::listToText in languages/Language.php
+                *
+                * @param {string[]} list
+                * @return {string}
+                */
+               listToText: function ( list ) {
+                       var text = '',
+                               i = 0;
 
-               for ( ; i < list.length; i++ ) {
-                       text += list[ i ];
-                       if ( list.length - 2 === i ) {
-                               text += mw.msg( 'and' ) + mw.msg( 'word-separator' );
-                       } else if ( list.length - 1 !== i ) {
-                               text += mw.msg( 'comma-separator' );
+                       for ( ; i < list.length; i++ ) {
+                               text += list[ i ];
+                               if ( list.length - 2 === i ) {
+                                       text += mw.msg( 'and' ) + mw.msg( 'word-separator' );
+                               } else if ( list.length - 1 !== i ) {
+                                       text += mw.msg( 'comma-separator' );
+                               }
                        }
-               }
-               return text;
-       },
+                       return text;
+               },
 
-       setSpecialCharacters: function ( data ) {
-               this.specialCharacters = data;
-       }
-} );
+               setSpecialCharacters: function ( data ) {
+                       this.specialCharacters = data;
+               }
+       } );
 
 }( mediaWiki, jQuery ) );
index 268985f..1192650 100644 (file)
         * @return {string}
         */
        function replicate( str, num ) {
+               var buf = [];
+
                if ( num <= 0 || !str ) {
                        return '';
                }
 
-               var buf = [];
                while ( num-- ) {
                        buf.push( str );
                }
         * @return {string}
         */
        function pad( text, size, ch, end ) {
+               var out, padStr;
+
                if ( !ch ) {
                        ch = '0';
                }
 
-               var out = String( text ),
-                       padStr = replicate( ch, Math.ceil( ( size - out.length ) / ch.length ) );
+               out = String( text );
+               padStr = replicate( ch, Math.ceil( ( size - out.length ) / ch.length ) );
 
                return end ? out + padStr : padStr + out;
        }
         * @return {string}
         */
        function commafyNumber( value, pattern, options ) {
-               options = options || {
-                       group: ',',
-                       decimal: '.'
-               };
-
-               if ( isNaN( value ) ) {
-                       return value;
-               }
-
                var padLength,
                        patternDigits,
                        index,
                        groupSize2 = 0,
                        pieces = [];
 
+               options = options || {
+                       group: ',',
+                       decimal: '.'
+               };
+
+               if ( isNaN( value ) ) {
+                       return value;
+               }
+
                if ( patternParts[ 1 ] ) {
                        // Pad fractional with trailing zeros
                        padLength = ( patternParts[ 1 ] && patternParts[ 1 ].lastIndexOf( '0' ) + 1 );
index d387a2d..ec94df3 100644 (file)
  * Hide all the elements irrelevant for printing
  */
 .noprint,
-div#jump-to-nav,
+#jump-to-nav,
 .mw-jump,
-div.top,
-div#column-one,
+#column-one,
 .mw-editsection,
 .mw-editsection-like,
 #footer-places,
@@ -21,12 +20,12 @@ div#column-one,
 .usermessage,
 .patrollink,
 .ns-0 .mw-redirectedfrom,
-div.magnify,
+.magnify,
 #mw-navigation,
 #siteNotice,
 /* Deprecated, changed in core */
-div#f-poweredbyico,
-div#f-copyrightico,
+#f-poweredbyico,
+#f-copyrightico,
 li#about,
 li#disclaimer,
 li#mobileview,
@@ -228,7 +227,7 @@ div.floatleft p {
        font-style: italic;
 }
 
-div.center {
+.center {
        text-align: center;
 }
 
@@ -246,7 +245,7 @@ div.thumb {
 div.thumbinner {
        background-color: #fff;
        border: 1pt solid #ccc;
-       padding: 3px !important;
+       padding: 3px;
        font-size: 94%;
        text-align: center;
        /* new block formatting context,
@@ -262,7 +261,7 @@ html .thumbcaption {
        border: none;
        text-align: left;
        line-height: 1.4em;
-       padding: 3px !important;
+       padding: 3px;
        font-size: 94%;
 }
 
@@ -325,10 +324,6 @@ table.listing td {
        border-collapse: collapse;
 }
 
-a.sortheader {
-       margin: 0 0.3em;
-}
-
 /**
  * Categories
  */
index 7ccf59e..4daf77f 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 /* For clarity, explicitly state some recommendations from
- * http://www.w3.org/TR/CSS21/sample.html to make sure the editsection links scale right
+ * https://www.w3.org/TR/CSS21/sample.html to make sure the editsection links scale right
  */
 
 h1 {
index 6226c90..aa49ae1 100644 (file)
 ( function ( mw, $ ) {
 
-var ProtectionForm = window.ProtectionForm = {
-       /**
-        * Set up the protection chaining interface (i.e. "unlock move permissions" checkbox)
-        * on the protection form
-        */
-       init: function () {
-               var $cell = $( '<td>' ),
-                       $row = $( '<tr>' ).append( $cell );
-
-               if ( !$( '#mwProtectSet' ).length ) {
-                       return false;
-               }
-
-               if ( mw.config.get( 'wgCascadeableLevels' ) !== undefined ) {
-                       $( 'form#mw-Protect-Form' ).submit( this.toggleUnchainedInputs.bind( ProtectionForm, true ) );
-               }
-               this.getExpirySelectors().each( function () {
-                       $( this ).change( ProtectionForm.updateExpiryList.bind( ProtectionForm, this ) );
-               } );
-               this.getExpiryInputs().each( function () {
-                       $( this ).on( 'keyup change', ProtectionForm.updateExpiry.bind( ProtectionForm, this ) );
-               } );
-               this.getLevelSelectors().each( function () {
-                       $( this ).change( ProtectionForm.updateLevels.bind( ProtectionForm, this ) );
-               } );
-
-               $( '#mwProtectSet > tbody > tr:first' ).after( $row );
-
-               // If there is only one protection type, there is nothing to chain
-               if ( $( '[id ^= mw-protect-table-]' ).length > 1 ) {
-                       $cell.append(
-                               $( '<input>' )
-                                       .attr( { id: 'mwProtectUnchained', type: 'checkbox' } )
-                                       .click( this.onChainClick.bind( this ) )
-                                       .prop( 'checked', !this.areAllTypesMatching() ),
-                               document.createTextNode( ' ' ),
-                               $( '<label>' )
-                                       .attr( 'for', 'mwProtectUnchained' )
-                                       .text( mw.msg( 'protect-unchain-permissions' ) )
-                       );
-
-                       this.toggleUnchainedInputs( !this.areAllTypesMatching() );
-               }
-
-               $( '#mwProtect-reason' ).byteLimit( 180 );
-
-               this.updateCascadeCheckbox();
-       },
-
-       /**
-        * Sets the disabled attribute on the cascade checkbox depending on the current selected levels
-        */
-       updateCascadeCheckbox: function () {
-               this.getLevelSelectors().each( function () {
-                       if ( !ProtectionForm.isCascadeableLevel( $( this ).val() ) ) {
-                               $( '#mwProtect-cascade' ).prop( { checked: false, disabled: true } );
+       var ProtectionForm = window.ProtectionForm = {
+               /**
+                * Set up the protection chaining interface (i.e. "unlock move permissions" checkbox)
+                * on the protection form
+                *
+                * @return {boolean}
+                */
+               init: function () {
+                       var $cell = $( '<td>' ),
+                               $row = $( '<tr>' ).append( $cell );
+
+                       if ( !$( '#mwProtectSet' ).length ) {
                                return false;
-                       } else {
-                               $( '#mwProtect-cascade' ).prop( 'disabled', false );
                        }
-               } );
-       },
-
-       /**
-        * Checks if a certain protection level is cascadeable.
-        *
-        * @param {string} level
-        * @return {boolean}
-        */
-       isCascadeableLevel: function ( level ) {
-               return $.inArray( level, mw.config.get( 'wgCascadeableLevels' ) ) !== -1;
-       },
-
-       /**
-        * When protection levels are locked together, update the rest
-        * when one action's level changes
-        *
-        * @param {Element} source Level selector that changed
-        */
-       updateLevels: function ( source ) {
-               if ( !this.isUnchained() ) {
-                       this.setAllSelectors( source.selectedIndex );
-               }
-               this.updateCascadeCheckbox();
-       },
-
-       /**
-        * When protection levels are locked together, update the
-        * expiries when one changes
-        *
-        * @param {Element} source expiry input that changed
-        */
-
-       updateExpiry: function ( source ) {
-               if ( !this.isUnchained() ) {
+
+                       if ( mw.config.get( 'wgCascadeableLevels' ) !== undefined ) {
+                               $( 'form#mw-Protect-Form' ).submit( this.toggleUnchainedInputs.bind( ProtectionForm, true ) );
+                       }
+                       this.getExpirySelectors().each( function () {
+                               $( this ).change( ProtectionForm.updateExpiryList.bind( ProtectionForm, this ) );
+                       } );
                        this.getExpiryInputs().each( function () {
-                               this.value = source.value;
+                               $( this ).on( 'keyup change', ProtectionForm.updateExpiry.bind( ProtectionForm, this ) );
                        } );
-               }
-               if ( this.isUnchained() ) {
-                       $( '#' + source.id.replace( /^mwProtect-(\w+)-expires$/, 'mwProtectExpirySelection-$1' ) ).val( 'othertime' );
-               } else {
-                       this.getExpirySelectors().each( function () {
-                               this.value = 'othertime';
+                       this.getLevelSelectors().each( function () {
+                               $( this ).change( ProtectionForm.updateLevels.bind( ProtectionForm, this ) );
                        } );
-               }
-       },
-
-       /**
-        * When protection levels are locked together, update the
-        * expiry lists when one changes and clear the custom inputs
-        *
-        * @param {Element} source Expiry selector that changed
-        */
-       updateExpiryList: function ( source ) {
-               if ( !this.isUnchained() ) {
-                       this.getExpirySelectors().each( function () {
-                               this.value = source.value;
+
+                       $( '#mwProtectSet > tbody > tr:first' ).after( $row );
+
+                       // If there is only one protection type, there is nothing to chain
+                       if ( $( '[id ^= mw-protect-table-]' ).length > 1 ) {
+                               $cell.append(
+                                       $( '<input>' )
+                                               .attr( { id: 'mwProtectUnchained', type: 'checkbox' } )
+                                               .click( this.onChainClick.bind( this ) )
+                                               .prop( 'checked', !this.areAllTypesMatching() ),
+                                       document.createTextNode( ' ' ),
+                                       $( '<label>' )
+                                               .attr( 'for', 'mwProtectUnchained' )
+                                               .text( mw.msg( 'protect-unchain-permissions' ) )
+                               );
+
+                               this.toggleUnchainedInputs( !this.areAllTypesMatching() );
+                       }
+
+                       $( '#mwProtect-reason' ).byteLimit( 180 );
+
+                       this.updateCascadeCheckbox();
+                       return true;
+               },
+
+               /**
+                * Sets the disabled attribute on the cascade checkbox depending on the current selected levels
+                */
+               updateCascadeCheckbox: function () {
+                       this.getLevelSelectors().each( function () {
+                               if ( !ProtectionForm.isCascadeableLevel( $( this ).val() ) ) {
+                                       $( '#mwProtect-cascade' ).prop( { checked: false, disabled: true } );
+                                       return false;
+                               } else {
+                                       $( '#mwProtect-cascade' ).prop( 'disabled', false );
+                               }
                        } );
-                       this.getExpiryInputs().each( function () {
-                               this.value = '';
+               },
+
+               /**
+                * Checks if a certain protection level is cascadeable.
+                *
+                * @param {string} level
+                * @return {boolean}
+                */
+               isCascadeableLevel: function ( level ) {
+                       return $.inArray( level, mw.config.get( 'wgCascadeableLevels' ) ) !== -1;
+               },
+
+               /**
+                * When protection levels are locked together, update the rest
+                * when one action's level changes
+                *
+                * @param {Element} source Level selector that changed
+                */
+               updateLevels: function ( source ) {
+                       if ( !this.isUnchained() ) {
+                               this.setAllSelectors( source.selectedIndex );
+                       }
+                       this.updateCascadeCheckbox();
+               },
+
+               /**
+                * When protection levels are locked together, update the
+                * expiries when one changes
+                *
+                * @param {Element} source expiry input that changed
+                */
+
+               updateExpiry: function ( source ) {
+                       if ( !this.isUnchained() ) {
+                               this.getExpiryInputs().each( function () {
+                                       this.value = source.value;
+                               } );
+                       }
+                       if ( this.isUnchained() ) {
+                               $( '#' + source.id.replace( /^mwProtect-(\w+)-expires$/, 'mwProtectExpirySelection-$1' ) ).val( 'othertime' );
+                       } else {
+                               this.getExpirySelectors().each( function () {
+                                       this.value = 'othertime';
+                               } );
+                       }
+               },
+
+               /**
+                * When protection levels are locked together, update the
+                * expiry lists when one changes and clear the custom inputs
+                *
+                * @param {Element} source Expiry selector that changed
+                */
+               updateExpiryList: function ( source ) {
+                       if ( !this.isUnchained() ) {
+                               this.getExpirySelectors().each( function () {
+                                       this.value = source.value;
+                               } );
+                               this.getExpiryInputs().each( function () {
+                                       this.value = '';
+                               } );
+                       }
+               },
+
+               /**
+                * Update chain status and enable/disable various bits of the UI
+                * when the user changes the "unlock move permissions" checkbox
+                */
+               onChainClick: function () {
+                       this.toggleUnchainedInputs( this.isUnchained() );
+                       if ( !this.isUnchained() ) {
+                               this.setAllSelectors( this.getMaxLevel() );
+                       }
+                       this.updateCascadeCheckbox();
+               },
+
+               /**
+                * Returns true if the named attribute in all objects in the given array are matching
+                *
+                * @param {Object[]} objects
+                * @param {string} attrName
+                * @return {boolean}
+                */
+               matchAttribute: function ( objects, attrName ) {
+                       return $.map( objects, function ( object ) {
+                               return object[ attrName ];
+                       } ).filter( function ( item, index, a ) {
+                               return index === a.indexOf( item );
+                       } ).length === 1;
+               },
+
+               /**
+                * Are all actions protected at the same level, with the same expiry time?
+                *
+                * @return {boolean}
+                */
+               areAllTypesMatching: function () {
+                       return this.matchAttribute( this.getLevelSelectors(), 'selectedIndex' ) &&
+                               this.matchAttribute( this.getExpirySelectors(), 'selectedIndex' ) &&
+                               this.matchAttribute( this.getExpiryInputs(), 'value' );
+               },
+
+               /**
+                * Is protection chaining off?
+                *
+                * @return {boolean}
+                */
+               isUnchained: function () {
+                       var element = document.getElementById( 'mwProtectUnchained' );
+                       return element ?
+                               element.checked :
+                               true; // No control, so we need to let the user set both levels
+               },
+
+               /**
+                * Find the highest protection level in any selector
+                *
+                * @return {number}
+                */
+               getMaxLevel: function () {
+                       return Math.max.apply( Math, this.getLevelSelectors().map( function () {
+                               return this.selectedIndex;
+                       } ) );
+               },
+
+               /**
+                * Protect all actions at the specified level
+                *
+                * @param {number} index Protection level
+                */
+               setAllSelectors: function ( index ) {
+                       this.getLevelSelectors().each( function () {
+                               this.selectedIndex = index;
                        } );
+               },
+
+               /**
+                * Get a list of all protection selectors on the page
+                *
+                * @return {jQuery}
+                */
+               getLevelSelectors: function () {
+                       return $( 'select[id ^= mwProtect-level-]' );
+               },
+
+               /**
+                * Get a list of all expiry inputs on the page
+                *
+                * @return {jQuery}
+                */
+               getExpiryInputs: function () {
+                       return $( 'input[id ^= mwProtect-][id $= -expires]' );
+               },
+
+               /**
+                * Get a list of all expiry selector lists on the page
+                *
+                * @return {jQuery}
+                */
+               getExpirySelectors: function () {
+                       return $( 'select[id ^= mwProtectExpirySelection-]' );
+               },
+
+               /**
+                * Enable/disable protection selectors and expiry inputs
+                *
+                * @param {boolean} val Enable?
+                */
+               toggleUnchainedInputs: function ( val ) {
+                       var setDisabled = function () { this.disabled = !val; };
+                       this.getLevelSelectors().slice( 1 ).each( setDisabled );
+                       this.getExpiryInputs().slice( 1 ).each( setDisabled );
+                       this.getExpirySelectors().slice( 1 ).each( setDisabled );
                }
-       },
-
-       /**
-        * Update chain status and enable/disable various bits of the UI
-        * when the user changes the "unlock move permissions" checkbox
-        */
-       onChainClick: function () {
-               this.toggleUnchainedInputs( this.isUnchained() );
-               if ( !this.isUnchained() ) {
-                       this.setAllSelectors( this.getMaxLevel() );
-               }
-               this.updateCascadeCheckbox();
-       },
-
-       /**
-        * Returns true if the named attribute in all objects in the given array are matching
-        *
-        * @param {Object[]} objects
-        * @param {string} attrName
-        * @return {boolean}
-        */
-       matchAttribute: function ( objects, attrName ) {
-               return $.map( objects, function ( object ) {
-                       return object[ attrName ];
-               } ).filter( function ( item, index, a ) {
-                       return index === a.indexOf( item );
-               } ).length === 1;
-       },
-
-       /**
-        * Are all actions protected at the same level, with the same expiry time?
-        *
-        * @return {boolean}
-        */
-       areAllTypesMatching: function () {
-               return this.matchAttribute( this.getLevelSelectors(), 'selectedIndex' )
-                       && this.matchAttribute( this.getExpirySelectors(), 'selectedIndex' )
-                       && this.matchAttribute( this.getExpiryInputs(), 'value' );
-       },
-
-       /**
-        * Is protection chaining off?
-        *
-        * @return {boolean}
-        */
-       isUnchained: function () {
-               var element = document.getElementById( 'mwProtectUnchained' );
-               return element
-                       ? element.checked
-                       : true; // No control, so we need to let the user set both levels
-       },
-
-       /**
-        * Find the highest protection level in any selector
-        *
-        * @return {number}
-        */
-       getMaxLevel: function () {
-               return Math.max.apply( Math, this.getLevelSelectors().map( function () {
-                       return this.selectedIndex;
-               } ) );
-       },
-
-       /**
-        * Protect all actions at the specified level
-        *
-        * @param {number} index Protection level
-        */
-       setAllSelectors: function ( index ) {
-               this.getLevelSelectors().each( function () {
-                       this.selectedIndex = index;
-               } );
-       },
-
-       /**
-        * Get a list of all protection selectors on the page
-        *
-        * @return {jQuery}
-        */
-       getLevelSelectors: function () {
-               return $( 'select[id ^= mwProtect-level-]' );
-       },
-
-       /**
-        * Get a list of all expiry inputs on the page
-        *
-        * @return {jQuery}
-        */
-       getExpiryInputs: function () {
-               return $( 'input[id ^= mwProtect-][id $= -expires]' );
-       },
-
-       /**
-        * Get a list of all expiry selector lists on the page
-        *
-        * @return {jQuery}
-        */
-       getExpirySelectors: function () {
-               return $( 'select[id ^= mwProtectExpirySelection-]' );
-       },
-
-       /**
-        * Enable/disable protection selectors and expiry inputs
-        *
-        * @param {boolean} val Enable?
-        */
-       toggleUnchainedInputs: function ( val ) {
-               var setDisabled = function () { this.disabled = !val; };
-               this.getLevelSelectors().slice( 1 ).each( setDisabled );
-               this.getExpiryInputs().slice( 1 ).each( setDisabled );
-               this.getExpirySelectors().slice( 1 ).each( setDisabled );
-       }
-};
-
-$( ProtectionForm.init.bind( ProtectionForm ) );
+       };
+
+       $( ProtectionForm.init.bind( ProtectionForm ) );
 
 }( mediaWiki, jQuery ) );
index cb4919f..1522de1 100644 (file)
@@ -105,6 +105,25 @@ span.comment {
        clear: both;
 }
 
+/* Edit font preference */
+/* TODO: for 'default' on non-textareas we could compute the default font of textarea in the client */
+.mw-editfont-default:not( textarea ) {
+       font-family: monospace;
+}
+
+/* Keep this rule separate from the :not rule above so it still works in older browsers */
+.mw-editfont-monospace {
+       font-family: monospace;
+}
+
+.mw-editfont-sans-serif {
+       font-family: sans-serif;
+}
+
+.mw-editfont-serif {
+       font-family: serif;
+}
+
 /**
  * rev_deleted stuff
  */
index 38271a0..8062849 100644 (file)
 
        /**
         * @deprecated since 1.17 Use mw.loader instead. Warnings added in 1.25.
+        * @param {string} url
+        * @return {HTMLElement} Script tag
         */
        function importScriptURI( url ) {
+               var s;
                if ( loadedScripts[ url ] ) {
                        return null;
                }
                loadedScripts[ url ] = true;
-               var s = document.createElement( 'script' );
+               s = document.createElement( 'script' );
                s.setAttribute( 'src', url );
                document.getElementsByTagName( 'head' )[ 0 ].appendChild( s );
                return s;
 
        /**
         * @deprecated since 1.17 Use mw.loader instead. Warnings added in 1.25.
+        * @param {string} url
+        * @param {string} media
+        * @return {HTMLElement} Link tag
         */
        function importStylesheetURI( url, media ) {
                var l = document.createElement( 'link' );
index 780b372..1bfa3a3 100644 (file)
 // ----------------------------------------------------------------------------
 
 .button-colors( @bgColor, @highlightColor, @activeColor ) {
-       background: @bgColor;
+       background-color: @bgColor;
+       color: @colorButtonText;
+       border: 1px solid @colorFieldBorder;
+
+       // Make sure that `color` isn't inheriting from user-agent styles
+       &:visited {
+               color: @colorButtonText;
+       }
 
        &:hover {
                background-color: @highlightColor;
+               color: @colorGray4;
+               border-color: @colorGray10;
        }
 
        &:focus {
-               border-color: @colorWhite;
-               box-shadow: inset 0 0 0 1px @bgColor, inset 0 0 0 2px @colorWhite;
-               outline-width: 0;
-
-               // Remove the inner border and padding in Firefox.
-               &::-moz-focus-inner {
-                       border-color: transparent;
-                       padding: 0;
-               }
+               background-color: @highlightColor;
+               // Make sure that `color` isn't inheriting from user-agent styles
+               color: @colorButtonText;
+               border-color: @colorProgressive;
+               box-shadow: inset 0 0 0 1px @colorProgressive, inset 0 0 0 2px #fff;
        }
 
        &:active,
        &.is-on,
        &.mw-ui-checked {
                background-color: @activeColor;
+               color: @colorGray1;
+               border-color: @colorGray7;
                box-shadow: none;
        }
-}
-
-.button-colors( @bgColor, @highlightColor, @activeColor ) when ( lightness( @bgColor ) >= 70% ) {
-       color: @colorButtonText;
-       border: 1px solid @colorFieldBorder;
-
-       &:hover,
-       &:active,
-       &:visited {
-               // make sure that is isn't inheriting from a general rule
-               color: @colorButtonText;
-       }
-
-       &:focus {
-               background-color: @highlightColor;
-       }
 
        &:disabled {
-               color: @colorDisabledText;
+               background-color: @colorGray12;
+               color: #fff;
+               border-color: @colorGray12;
 
-               // make sure disabled buttons don't have hover and active states
+               // Make sure disabled buttons don't have hover and active states
                &:hover,
                &:active {
-                       background: @bgColor;
+                       background-color: @colorGray12;
+                       color: #fff;
                        box-shadow: none;
+                       border-color: @colorGray12;
                }
        }
 }
 
-.button-colors( @bgColor, @highlightColor, @activeColor ) when ( lightness( @bgColor ) < 70% ) {
+.button-colors-primary( @bgColor, @highlightColor, @activeColor ) {
+       background-color: @bgColor;
        color: #fff;
        // border of the same color as background so that light background and
        // dark background buttons are the same height and width
        border: 1px solid @bgColor;
-       text-shadow: 0 1px rgba(0, 0, 0, .1);
+       text-shadow: 0 1px rgba( 0, 0, 0, 0.1 );
+
+       &:hover {
+               background-color: @highlightColor;
+               border-color: @highlightColor;
+       }
+
+       &:focus {
+               box-shadow: inset 0 0 0 1px @bgColor, inset 0 0 0 2px #fff;
+       }
+
+       &:active,
+       &.is-on,
+       &.mw-ui-checked {
+               background-color: @activeColor;
+               border-color: @activeColor;
+               box-shadow: none;
+       }
 
        &:disabled {
-               background-color: @colorGray13;
-               border-color: @colorGray13;
+               background-color: @colorGray12;
+               color: #fff;
+               border-color: @colorGray12;
 
-               // make sure disabled buttons don't have hover and active states
+               // Make sure disabled buttons don't have hover and active states
                &:hover,
                &:active,
                &.mw-ui-checked {
+                       background-color: @colorGray12;
+                       color: #fff;
+                       border-color: @colorGray12;
                        box-shadow: none;
                }
        }
 
 .button-colors-quiet( @textColor, @highlightColor, @activeColor ) {
        // Quiet buttons all start gray, and reveal
-       // constructive/progressive/destructive color on hover and active.
+       // progressive/destructive color on hover and active.
        color: @colorButtonText;
 
        &:hover {
index 77e80b0..676ecca 100644 (file)
@@ -6,16 +6,16 @@
 @colorGray2: #222;
 @colorGray3: #333;
 @colorGray4: #444;
-@colorGray5: #555;
+@colorGray5: #54595d;
 @colorGray6: #666;
 @colorGray7: #72777d;
 @colorGray8: #888;
 @colorGray9: #999;
-@colorGray10: #aaa;
+@colorGray10: #a2a9b1;
 @colorGray11: #bbb;
-@colorGray12: #ccc;
+@colorGray12: #c8ccd1;
 @colorGray13: #ddd;
-@colorGray14: #eee;
+@colorGray14: #eaecf0;
 @colorGray15: #f8f9fa; // lightest
 
 // Semantic background colors
@@ -50,7 +50,7 @@
 @colorWarningText: #705000;
 
 // UI colors
-@colorFieldBorder: #9aa0a7;
+@colorFieldBorder: #a2a9b1;
 @colorShadow: @colorGray14;
 @colorPlaceholder: @colorGray10;
 @colorNeutral: @colorGray7;
index 68fb2aa..558fd4c 100644 (file)
@@ -1,4 +1,3 @@
-/*global OO */
 ( function ( mw, $ ) {
        /**
         * Factory for MessagePoster objects. This provides a pluggable to way to script the action
index d9cdf5a..d4c93fd 100644 (file)
@@ -89,7 +89,7 @@ table.toc td {
        display: table-cell;
        /*
        Text decorations are not propagated to the contents of inline blocks and inline tables,
-       according to <http://www.w3.org/TR/css-text-decor-3/#line-decoration>, and 'display: table-cell'
+       according to <https://www.w3.org/TR/css-text-decor-3/#line-decoration>, and 'display: table-cell'
        generates an inline table when used without any parent table-rows and tables.
        */
        text-decoration: inherit;
@@ -99,8 +99,8 @@ table.toc td {
 .tocnumber {
        padding-left: 0;
        padding-right: 0.5em;
+       color: #222;
 }
-
 /* @noflip */
 .mw-content-ltr .tocnumber {
        padding-left: 0;
index 7b0b071..9c52b2a 100644 (file)
@@ -13,6 +13,10 @@ a {
        background: none;
 }
 
+a:not( [href] ) {
+       cursor: pointer; /* Always cursor:pointer even without href */
+}
+
 a:visited {
        color: #0b0080;
 }
index 2517605..99f6c13 100644 (file)
        z-index: 100;
 }
 
+.mw-apisandbox-fullscreen .mw-apisandbox-container {
+       border-width: 1px 0 0 0;
+       border-radius: 0;
+}
+
 .mw-apisandbox-spacer {
        display: inline-block;
        height: 1px;
index 5c3715d..217bd92 100644 (file)
@@ -1,4 +1,4 @@
-/*global OO */
+/* eslint-disable no-use-before-define */
 ( function ( $, mw, OO ) {
        'use strict';
        var ApiSandbox, Util, WidgetMethods, Validators,
@@ -10,7 +10,8 @@
                suppressErrors = true,
                updatingBooklet = false,
                pages = {},
-               moduleInfoCache = {};
+               moduleInfoCache = {},
+               baseRequestParams;
 
        WidgetMethods = {
                textInputWidget: {
                        },
                        apiCheckValid: function () {
                                var that = this;
-                               return this.isValid().done( function ( ok ) {
+                               return this.getValidity().then( function () {
+                                       return $.Deferred().resolve( true ).promise();
+                               }, function () {
+                                       return $.Deferred().resolve( false ).promise();
+                               } ).done( function ( ok ) {
                                        ok = ok || suppressErrors;
                                        that.setIcon( ok ? null : 'alert' );
                                        that.setIconTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
                },
 
                dateTimeInputWidget: {
-                       isValid: function () {
-                               var ok = !Util.apiBool( this.paramInfo.required ) || this.getApiValue() !== '';
-                               return $.Deferred().resolve( ok ).promise();
+                       getValidity: function () {
+                               if ( !Util.apiBool( this.paramInfo.required ) || this.getApiValue() !== '' ) {
+                                       return $.Deferred().resolve().promise();
+                               } else {
+                                       return $.Deferred().reject().promise();
+                               }
                        }
                },
 
                                        } );
                                        widget.setIcon = widget.input.setIcon.bind( widget.input );
                                        widget.setIconTitle = widget.input.setIconTitle.bind( widget.input );
-                                       widget.isValid = widget.input.isValid.bind( widget.input );
+                                       widget.getValidity = widget.input.getValidity.bind( widget.input );
                                        widget.paramInfo = pi;
                                        $.extend( widget, WidgetMethods.textInputWidget );
                                        if ( Util.apiBool( pi.enforcerange ) ) {
                                        break;
 
                                case 'limit':
-                                       widget = new OO.ui.NumberInputWidget( {
-                                               required: Util.apiBool( pi.required ),
-                                               isInteger: true
+                                       widget = new OO.ui.TextInputWidget( {
+                                               required: Util.apiBool( pi.required )
                                        } );
-                                       widget.setIcon = widget.input.setIcon.bind( widget.input );
-                                       widget.setIconTitle = widget.input.setIconTitle.bind( widget.input );
-                                       widget.isValid = widget.input.isValid.bind( widget.input );
-                                       widget.input.setValidation( function ( value ) {
-                                               return value === 'max' || widget.validateNumber( value );
+                                       widget.setValidation( function ( value ) {
+                                               var n, pi = this.paramInfo;
+
+                                               if ( value === 'max' ) {
+                                                       return true;
+                                               } else {
+                                                       n = +value;
+                                                       return !isNaN( n ) && isFinite( n ) &&
+                                                               // eslint-disable-next-line no-bitwise
+                                                               ( n | 0 ) === n &&
+                                                               n >= pi.min && n <= pi.apiSandboxMax;
+                                               }
                                        } );
+                                       pi.min = pi.min || 0;
+                                       pi.apiSandboxMax = mw.config.get( 'apihighlimits' ) ? pi.highmax : pi.max;
                                        widget.paramInfo = pi;
                                        $.extend( widget, WidgetMethods.textInputWidget );
-                                       widget.setRange( pi.min || 0, mw.config.get( 'apihighlimits' ) ? pi.highmax : pi.max );
                                        multiMode = 'enter';
                                        break;
 
                init: function () {
                        var $toolbar;
 
+                       ApiSandbox.isFullscreen = false;
+
                        $content = $( '#mw-apisandbox' );
 
                        windowManager = new OO.ui.WindowManager();
                                        fullscreenButton.$element,
                                        new OO.ui.ButtonWidget( {
                                                label: mw.message( 'apisandbox-submit' ).text(),
-                                               flags: [ 'primary', 'constructive' ]
+                                               flags: [ 'primary', 'progressive' ]
                                        } ).on( 'click', ApiSandbox.sendRequest ).$element,
                                        new OO.ui.ButtonWidget( {
                                                label: mw.message( 'apisandbox-reset' ).text(),
                 * Toggle "fullscreen" mode
                 */
                toggleFullscreen: function () {
-                       var $body = $( document.body );
+                       var $body = $( document.body ),
+                               $ui = $( '#mw-apisandbox-ui' );
 
-                       $body.toggleClass( 'mw-apisandbox-fullscreen' );
-                       if ( $body.hasClass( 'mw-apisandbox-fullscreen' ) ) {
+                       ApiSandbox.isFullscreen = !ApiSandbox.isFullscreen;
+
+                       $body.toggleClass( 'mw-apisandbox-fullscreen', ApiSandbox.isFullscreen );
+                       $ui.toggleClass( 'mw-body-content', ApiSandbox.isFullscreen );
+                       if ( ApiSandbox.isFullscreen ) {
                                fullscreenButton.setLabel( mw.message( 'apisandbox-unfullscreen' ).text() );
                                fullscreenButton.setTitle( mw.message( 'apisandbox-unfullscreen-tooltip' ).text() );
-                               $body.append( $( '#mw-apisandbox-ui' ) );
+                               $body.append( $ui );
                        } else {
                                fullscreenButton.setLabel( mw.message( 'apisandbox-fullscreen' ).text() );
                                fullscreenButton.setTitle( mw.message( 'apisandbox-fullscreen-tooltip' ).text() );
-                               $content.append( $( '#mw-apisandbox-ui' ) );
+                               $content.append( $ui );
                        }
                        ApiSandbox.resizePanel();
                },
                        var height = $( window ).height(),
                                contentTop = $content.offset().top;
 
-                       if ( $( document.body ).hasClass( 'mw-apisandbox-fullscreen' ) ) {
+                       if ( ApiSandbox.isFullscreen ) {
                                height -= panel.$element.offset().top - $( '#mw-apisandbox-ui' ).offset().top;
                                panel.$element.height( height - 1 );
                        } else {
 
                /**
                 * Update the current query when the page hash changes
+                *
+                * @return {boolean} Successful
                 */
                loadFromHash: function () {
                        var params, m, re,
 
                /**
                 * Submit button handler
+                *
+                * @param {Object} [params] Use this set of params instead of those in the form fields.
+                *   The form fields will be updated to match.
                 */
-               sendRequest: function () {
+               sendRequest: function ( params ) {
                        var page, subpages, i, query, $result, $focus,
                                progress, $progressText, progressLoading,
                                deferreds = [],
-                               params = {},
+                               paramsAreForced = !!params,
                                displayParams = {},
                                checkPages = [ pages.main ];
 
 
                        suppressErrors = false;
 
+                       // save widget state in params (or load from it if we are forced)
+                       if ( paramsAreForced ) {
+                               ApiSandbox.updateUI( params );
+                       }
+                       params = {};
                        while ( checkPages.length ) {
                                page = checkPages.shift();
                                deferreds.push( page.apiCheckValid() );
                                }
                        }
 
+                       if ( !paramsAreForced ) {
+                               // forced params means we are continuing a query; the base query should be preserved
+                               baseRequestParams = $.extend( {}, params );
+                       }
+
                        $.when.apply( $, deferreds ).done( function () {
                                if ( $.inArray( false, arguments ) !== -1 ) {
                                        windowManager.openWindow( 'errorAlert', {
                                                        );
                                        } )
                                        .done( function ( data, jqXHR ) {
-                                               var m, loadTime, button,
+                                               var m, loadTime, button, clear,
                                                        ct = jqXHR.getResponseHeader( 'Content-Type' );
 
                                                $result.empty();
                                                        if ( data.modules.length ) {
                                                                mw.loader.load( data.modules );
                                                        }
+                                                       if ( data.status && data.status !== 200 ) {
+                                                               $( '<div>' )
+                                                                       .addClass( 'api-pretty-header api-pretty-status' )
+                                                                       .append(
+                                                                               mw.message( 'api-format-prettyprint-status', data.status, data.statustext ).parse()
+                                                                       )
+                                                                       .appendTo( $result );
+                                                       }
                                                        $result.append( Util.parseHTML( data.html ) );
                                                        loadTime = data.time;
                                                } else if ( ( m = data.match( /<pre[ >][\s\S]*<\/pre>/ ) ) ) {
                                                                .text( data )
                                                                .appendTo( $result );
                                                }
+                                               if ( paramsAreForced || data[ 'continue' ] ) {
+                                                       $result.append(
+                                                               $( '<div>' ).append(
+                                                                       new OO.ui.ButtonWidget( {
+                                                                               label: mw.message( 'apisandbox-continue' ).text()
+                                                                       } ).on( 'click', function () {
+                                                                               ApiSandbox.sendRequest( $.extend( {}, baseRequestParams, data[ 'continue' ] ) );
+                                                                       } ).setDisabled( !data[ 'continue' ] ).$element,
+                                                                       ( clear = new OO.ui.ButtonWidget( {
+                                                                               label: mw.message( 'apisandbox-continue-clear' ).text()
+                                                                       } ).on( 'click', function () {
+                                                                               ApiSandbox.updateUI( baseRequestParams );
+                                                                               clear.setDisabled( true );
+                                                                               booklet.setPage( '|results|' );
+                                                                       } ).setDisabled( !paramsAreForced ) ).$element,
+                                                                       new OO.ui.PopupButtonWidget( {
+                                                                               framed: false,
+                                                                               icon: 'info',
+                                                                               popup: {
+                                                                                       $content: $( '<div>' ).append( mw.message( 'apisandbox-continue-help' ).parse() ),
+                                                                                       padded: true
+                                                                               }
+                                                                       } ).$element
+                                                               )
+                                                       );
+                                               }
                                                if ( typeof loadTime === 'number' ) {
                                                        $result.append(
                                                                $( '<div>' ).append(
                                                                if ( pi.parameters[ i ].highmax !== undefined ) {
                                                                        dl.append( $( '<dd>', {
                                                                                addClass: 'info',
-                                                                               append: Util.parseHTML( mw.message(
-                                                                                       'api-help-param-limit2', pi.parameters[ i ].max, pi.parameters[ i ].highmax
-                                                                               ).parse() )
+                                                                               append: [
+                                                                                       Util.parseHTML( mw.message(
+                                                                                               'api-help-param-limit2', pi.parameters[ i ].max, pi.parameters[ i ].highmax
+                                                                                       ).parse() ),
+                                                                                       ' ',
+                                                                                       Util.parseHTML( mw.message( 'apisandbox-param-limit' ).parse() )
+                                                                               ]
                                                                        } ) );
                                                                } else {
                                                                        dl.append( $( '<dd>', {
                                                                                addClass: 'info',
-                                                                               append: Util.parseHTML( mw.message(
-                                                                                       'api-help-param-limit', pi.parameters[ i ].max
-                                                                               ).parse() )
+                                                                               append: [
+                                                                                       Util.parseHTML( mw.message(
+                                                                                               'api-help-param-limit', pi.parameters[ i ].max
+                                                                                       ).parse() ),
+                                                                                       ' ',
+                                                                                       Util.parseHTML( mw.message( 'apisandbox-param-limit' ).parse() )
+                                                                               ]
                                                                        } ) );
                                                                }
                                                                break;
                                                // Don't grey out the label when the field is disabled,
                                                // it makes it too hard to read and our "disabled"
                                                // isn't really disabled.
+                                               widgetField.onFieldDisable( false );
                                                widgetField.onFieldDisable = doNothing;
 
                                                if ( Util.apiBool( pi.parameters[ i ].deprecated ) ) {
                                                        dynamicParamNameWidget,
                                                        new OO.ui.ButtonWidget( {
                                                                icon: 'add',
-                                                               flags: 'constructive'
+                                                               flags: 'progressive'
                                                        } ).on( 'click', addDynamicParamWidget ),
                                                        {
                                                                label: mw.message( 'apisandbox-dynamic-parameters-add-label' ).text(),
index 69a2a67..3e6e684 100644 (file)
@@ -6,9 +6,10 @@
                var $tagList = $( '#mw-edittags-tag-list' );
                if ( $tagList.length ) {
                        $tagList.chosen( {
-                               /*jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
+                               /* eslint-disable camelcase */
                                placeholder_text_multiple: mw.msg( 'tags-edit-chosen-placeholder' ),
                                no_results_text: mw.msg( 'tags-edit-chosen-no-results' )
+                               /* eslint-enable camelcase */
                        } );
                }
 
index a523d5b..5191f92 100644 (file)
@@ -31,7 +31,7 @@
 }
 .searchresult {
        font-size: 95%;
-       width: 38em;
+       max-width: 38em;
 }
 .mw-search-results {
        margin-left: 0;
index dd48367..f818096 100644 (file)
@@ -5,8 +5,11 @@
  * @class mw.special.upload
  * @singleton
  */
+
+/* eslint-disable no-use-before-define */
+/* global Uint8Array */
+
 ( function ( mw, $ ) {
-       /*jshint latedef:false */
        var uploadWarning, uploadLicense,
                ajaxUploadDestCheck = mw.config.get( 'wgAjaxUploadDestCheck' ),
                $license = $( '#wpLicense' );
        $( function () {
                /**
                 * Is the FileAPI available with sufficient functionality?
+                *
+                * @return {boolean}
                 */
                function hasFileAPI() {
                        return window.FileReader !== undefined;
                        }, mw.config.get( 'wgFileCanRotate' ) ? function ( data ) {
                                try {
                                        meta = mw.libs.jpegmeta( data, file.fileName );
-                                       // jscs:disable requireCamelCaseOrUpperCaseIdentifiers, disallowDanglingUnderscores
+                                       // eslint-disable-next-line no-underscore-dangle, camelcase
                                        meta._binary_data = null;
-                                       // jscs:enable
                                } catch ( e ) {
                                        meta = null;
                                }
 
                /**
                 * Check if the file does not exceed the maximum size
+                *
+                * @param {File} file
+                * @return {boolean}
                 */
                function checkMaxUploadSize( file ) {
                        var maxSize, $error;
                if ( hasFileAPI() ) {
                        // Update thumbnail when the file selection control is updated.
                        $( '#wpUploadFile' ).change( function () {
+                               var file;
                                clearPreview();
                                if ( this.files && this.files.length ) {
                                        // Note: would need to be updated to handle multiple files.
-                                       var file = this.files[ 0 ];
+                                       file = this.files[ 0 ];
 
                                        if ( !checkMaxUploadSize( file ) ) {
                                                return;
index bb26c0f..e9fc024 100644 (file)
         *  current cursor position.
         * @param {string} [button.imageId] `id` attribute of the button HTML element. Can be
         *  used to define the image with CSS if it's not provided as `imageFile`.
+        * @param {string} [speedTip]
+        * @param {string} [tagOpen]
+        * @param {string} [tagClose]
+        * @param {string} [sampleText]
+        * @param {string} [imageId]
         */
        function insertButton( button, speedTip, tagOpen, tagClose, sampleText, imageId ) {
                var $button;
index 5bb69b8..4c4e129 100644 (file)
@@ -6,15 +6,14 @@
 .mixin-mw-ui-anchor-styles( @mainColor ) {
        color: @mainColor;
 
-       // Hover state
        &:hover {
                color: lighten( @mainColor, @colorLightenPercentage );
        }
-       // Focus and active states
+
        &:focus,
        &:active {
                color: darken( @mainColor, @colorDarkenPercentage );
-               outline: none; // outline fix
+               outline: 0;
        }
 
        // Quiet mode is gray at first
 /*
 Anchors
 
-The anchor base type can be applied to A elements when a basic context styling needs to be given to a link, without
-having to assign it as a button type. mw-ui-anchor only changes the text color, and should not be used in combination
-with other base classes, such as mw-ui-button.
+The anchor base type can be applied to `a` elements when a basic context styling needs to be given to a link, without
+having to assign it as a button type. `.mw-ui-anchor` only changes the text color, and should not be used in combination
+with other base classes, such as `.mw-ui-button`.
+
 
 Markup:
 <a href="#" class="mw-ui-anchor mw-ui-progressive">Progressive</a>
-<a href="#" class="mw-ui-anchor mw-ui-constructive">Constructive</a>
 <a href="#" class="mw-ui-anchor mw-ui-destructive">Destructive</a>
 
 .mw-ui-quiet - Quiet until interaction.
@@ -46,13 +45,14 @@ Styleguide 6.2.
                .mixin-mw-ui-anchor-styles( @colorProgressive );
        }
 
-       &.mw-ui-constructive {
-               .mixin-mw-ui-anchor-styles( @colorConstructive );
-       }
-
        &.mw-ui-destructive {
                .mixin-mw-ui-anchor-styles( @colorDestructive );
        }
+
+       //`.mw-ui-constructive` is deprecated; consolidated with `progressive`, see T110555
+       &.mw-ui-constructive {
+               .mixin-mw-ui-anchor-styles( @colorConstructive );
+       }
 }
 
 /*
index 5931efb..85795f4 100644 (file)
@@ -14,7 +14,7 @@
 
 // Neutral button styling
 //
-// These are the main actions on the page/workflow. The page should have only one of progressive, constructive and desctructive buttons, the rest being quiet.
+// These are the main actions on the page/workflow. The page should have only one of progressive and destructive buttons, the rest being quiet.
 //
 // Markup:
 // <div>
        vertical-align: middle;
 
        // Content styling
-       .button-colors( #fff, @colorGray12, @colorGray7 );
+       .button-colors( @colorGray15, #fff, #d9d9d9 );
        text-align: center;
        font-weight: bold;
 
        // Interaction styling
        cursor: pointer;
 
+       &:focus {
+               outline-width: 0;
+
+               // Remove the inner border and padding in Firefox.
+               &::-moz-focus-inner {
+                       border-color: transparent;
+                       padding: 0;
+               }
+       }
+
+       // `:not()` is used exclusively for `transition`s as both are not supported by IE < 9
+       &:not( :disabled ) {
+               .transition( ~'background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms' );
+       }
+
        &:disabled {
                text-shadow: none;
                cursor: default;
@@ -78,9 +93,6 @@
        //   <button class="mw-ui-button mw-ui-progressive mw-ui-big">.mw-ui-progressive</button>
        // </div>
        // <div>
-       //   <button class="mw-ui-button mw-ui-constructive mw-ui-big">.mw-ui-constructive</button>
-       // </div>
-       // <div>
        //   <button class="mw-ui-button mw-ui-destructive mw-ui-big">.mw-ui-destructive</button>
        // </div>
        //
        //   <button class="mw-ui-button mw-ui-progressive mw-ui-block">.mw-ui-progressive</button>
        // </div>
        // <div>
-       //   <button class="mw-ui-button mw-ui-constructive mw-ui-block">.mw-ui-constructive</button>
-       // </div>
-       // <div>
        //   <button class="mw-ui-button mw-ui-destructive mw-ui-block">.mw-ui-destructive</button>
        // </div>
        //
        // Progressive buttons
        //
        // Use progressive buttons for actions which lead to a next step in the process.
-       // .mw-ui-primary is deprecated, kept for compatibility.
+       // .mw-ui-constructive is deprecated; consolidated with `progressive`, see T110555
        //
        // Markup:
        // <div>
        //
        // Styleguide 2.1.1.
        &.mw-ui-progressive,
-       &.mw-ui-primary {
-               .button-colors( @colorProgressive, @colorProgressiveHighlight, @colorProgressiveActive );
-
-               &.mw-ui-quiet {
-                       .button-colors-quiet( @colorProgressive, @colorProgressiveHighlight, @colorProgressiveActive );
-               }
-       }
-
-       // Constructive buttons (deprecated, consolidated with `progressive` – see T110555)
-       //
-       // Use constructive buttons for actions which result in a final action in the process that results
-       // in a change of state.
-       // e.g. save changes button
-       //
-       // Markup:
-       // <div>
-       //   <button class="mw-ui-button mw-ui-constructive">.mw-ui-constructive</button>
-       // </div>
-       // <div>
-       //   <button class="mw-ui-button mw-ui-constructive" disabled>.mw-ui-constructive</button>
-       // </div>
-       //
-       // Styleguide 2.1.2.
        &.mw-ui-constructive {
-               .button-colors( @colorProgressive, @colorProgressiveHighlight, @colorProgressiveActive );
+               .button-colors-primary( @colorProgressive, @colorProgressiveHighlight, @colorProgressiveActive );
 
                &.mw-ui-quiet {
                        .button-colors-quiet( @colorProgressive, @colorProgressiveHighlight, @colorProgressiveActive );
        //   <button class="mw-ui-button mw-ui-destructive" disabled>.mw-ui-destructive</button>
        // </div>
        //
-       // Styleguide 2.1.3.
+       // Styleguide 2.1.2.
        &.mw-ui-destructive {
-               .button-colors( @colorDestructive, @colorDestructiveHighlight, @colorDestructiveActive );
+               .button-colors-primary( @colorDestructive, @colorDestructiveHighlight, @colorDestructiveActive );
 
                &.mw-ui-quiet {
                        .button-colors-quiet( @colorDestructive, @colorDestructiveHighlight, @colorDestructiveActive );
 
        // Quiet buttons
        //
-       // Use quiet buttons when they are less important and alongside other constructive, progressive or destructive buttons. It should be used for an action that exits the user from the current view/workflow.
+       // Use quiet buttons when they are less important and alongside other progressive or destructive buttons. It should be used for an action that exits the user from the current view/workflow.
        // Its use is  not recommended on mobile/tablet due to lack of hover state.
        //
        // Markup:
        //   <button class="mw-ui-button mw-ui-quiet">.mw-ui-button</button>
        // </div>
        // <div>
-       //   <button class="mw-ui-button mw-ui-constructive mw-ui-quiet">.mw-ui-constructive</button>
-       // </div>
-       // <div>
-       //   <button class="mw-ui-button mw-ui-constructive mw-ui-quiet" disabled>.mw-ui-constructive</button>
-       // </div>
-       // <div>
        //   <button class="mw-ui-button mw-ui-destructive mw-ui-quiet">.mw-ui-destructive</button>
        // </div>
        // <div>
        //   <button class="mw-ui-button mw-ui-progressive mw-ui-quiet" disabled>.mw-ui-progressive</button>
        // </div>
        //
-       // Styleguide 2.1.4.
+       // Styleguide 2.1.3.
        &.mw-ui-quiet {
                background: transparent;
                border: 0;
index aedec5b..2327efc 100644 (file)
@@ -30,7 +30,7 @@
 //     <input class="mw-ui-input" value="input">
 //   </div>
 //   <div class="mw-ui-vform-field">
-//     <button class="mw-ui-button mw-ui-constructive">Button in vform</button>
+//     <button class="mw-ui-button mw-ui-progressive">Button in vform</button>
 //   </div>
 // </form>
 //
index 76fee23..8bddb3a 100644 (file)
@@ -4,11 +4,6 @@
 @import "mediawiki.ui/variables";
 @import "mediawiki.ui/mixins";
 
-// Placeholder text styling helper
-.field-placeholder-styling() {
-       font-style: italic;
-       font-weight: normal;
-}
 // Text inputs
 //
 // Apply the mw-ui-input class to input and textarea fields.
 //
 // Styleguide 1.1.
 .mw-ui-input {
+       background-color: #fff;
        .box-sizing( border-box );
        display: block;
        width: 100%;
        border: 1px solid @colorFieldBorder;
        border-radius: @borderRadius;
        padding: 0.3em 0.3em 0.3em 0.6em;
+       // necessary for smooth transition
+       box-shadow: inset 0 0 0 0.1em #fff;
        font-family: inherit;
        font-size: inherit;
        line-height: inherit;
        vertical-align: middle;
 
-       // Placeholder text styling must be set individually for each browser @winter
-       &::-webkit-input-placeholder { // webkit
-               .field-placeholder-styling;
+       // Normalize & style placeholder text, see T139034
+       // Placeholder styles can't be grouped, otherwise they're ignored as invalid.
+
+       // Placeholder mixin
+       .mixin-placeholder() {
+               color: @colorGray7;
+               font-style: italic;
+       }
+       // Firefox 4-18
+       &:-moz-placeholder { // stylelint-disable-line selector-no-vendor-prefix
+               .mixin-placeholder;
+               opacity: 1;
+       }
+       // Firefox 19-
+       &::-moz-placeholder { // stylelint-disable-line selector-no-vendor-prefix
+               .mixin-placeholder;
+               opacity: 1;
        }
-       &::-moz-placeholder { // FF 4-18
-               .field-placeholder-styling;
+       // Internet Explorer 10-11
+       &:-ms-input-placeholder { // stylelint-disable-line selector-no-vendor-prefix
+               .mixin-placeholder;
        }
-       &:-moz-placeholder { // FF >= 19
-               .field-placeholder-styling;
+       // WebKit, Blink, Edge
+       // Don't set `opacity < 1`, see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/3901363/
+       &::-webkit-input-placeholder { // stylelint-disable-line selector-no-vendor-prefix
+               .mixin-placeholder;
        }
-       &:-ms-input-placeholder { // IE >= 10
-               .field-placeholder-styling;
+       // W3C Standard Selectors Level 4
+       &:placeholder-shown {
+               .mixin-placeholder;
        }
 
-       // Remove red outline from inputs which have required field and invalid content.
-       // This is a Firefox only issue
+       // Firefox: Remove red outline when `required` attribute set and invalid content.
        // See https://developer.mozilla.org/en-US/docs/Web/CSS/:invalid
-       // This should be above :focus so focus behaviour takes preference
+       // This should come before `:focus` so latter rules take preference.
        &:invalid {
                box-shadow: none;
        }
 
+       &:hover {
+               border-color: @colorGray7;
+       }
+
        &:focus {
                border-color: @colorProgressive;
                box-shadow: inset 0 0 0 1px @colorProgressive;
                outline: 0;
        }
 
+       // `:not()` is used exclusively for `transition`s as both are not supported by IE < 9.
+       &:not( :disabled ) {
+               .transition( ~'color 100ms, border-color 100ms, box-shadow 100ms' );
+       }
+
        &:disabled {
                border-color: @colorGray14;
                color: @colorGray12;
                // Correct the odd appearance in Chrome and Safari 5
                -webkit-appearance: textfield;
 
-               // Remove proprietary clear button in IE 10-11
+               // Remove proprietary clear button in IE 10-11, Edge 12+
                &::-ms-clear {
                        display: none;
                }
@@ -99,7 +123,7 @@ textarea.mw-ui-input {
 //
 // Markup:
 // <input class="mw-ui-input mw-ui-input-inline">
-// <button class="mw-ui-button mw-ui-constructive">Submit</button>
+// <button class="mw-ui-button mw-ui-progressive">Submit</button>
 //
 // Styleguide 1.2.
 input[type="number"],
index cc27e9e..5551745 100644 (file)
@@ -16,10 +16,10 @@ Text
 Context classes may be used on elements with only plain-text content with the mw-ui-text base. When the context classes
 are used on interactive and block-level elements, the appropriate alternative base type classes should also be used. For
 example, mw-ui-anchor with A, or mw-ui-button with buttons.
+'Constructive' is deprecated and merged with 'Progressive'.
 
 Markup:
 <span class="mw-ui-text mw-ui-progressive">Progressive</span>
-<span class="mw-ui-text mw-ui-constructive">Constructive</span>
 <span class="mw-ui-text mw-ui-destructive">Destructive</span>
 
 Styleguide 6.1.
@@ -28,11 +28,9 @@ Styleguide 6.1.
 .mw-ui-text {
        // The selector order is like this on purpose; IE 6 ignores the second selector,
        // so we don't want to accidentally apply this color on all mw-ui-CONTEXT classes
-       .mw-ui-progressive& {
-               color: @colorProgressive;
-       }
+       .mw-ui-progressive&,
        .mw-ui-constructive& {
-               color: @colorConstructive;
+               color: @colorProgressive;
        }
        .mw-ui-destructive& {
                color: @colorDestructive;
index 31b1cd5..54a5a85 100644 (file)
                return this.selected;
        };
 
+       // eslint-disable-next-line valid-jsdoc
        /**
         * Set the selected dates
         *
                return this.focusedDate;
        };
 
+       // eslint-disable-next-line valid-jsdoc
        /**
         * Set the currently-focused date
         *
         *
         * @protected
         * @param {jQuery.Event} e Key down event
+        * @return {boolean} False to cancel the default event
         */
        mw.widgets.datetime.CalendarWidget.prototype.onKeyDown = function ( e ) {
                var focusedDate = this.getFocusedDate();
index 1c54234..1793849 100644 (file)
         *  Defaults to the current date and time (with 0 milliseconds).
         */
        mw.widgets.datetime.DateTimeFormatter = function MwWidgetsDatetimeDateTimeFormatter( config ) {
-               var statick = this.constructor[ 'static' ];
-
-               statick.setupDefaults();
+               this.constructor.static.setupDefaults();
 
                config = $.extend( {
                        format: '@default',
                        local: false,
-                       fullZones: statick.fullZones,
-                       shortZones: statick.shortZones
+                       fullZones: this.constructor.static.fullZones,
+                       shortZones: this.constructor.static.shortZones
                }, config );
 
                // Mixin constructors
                OO.EventEmitter.call( this );
 
                // Properties
-               if ( statick.formats[ config.format ] ) {
-                       this.format = statick.formats[ config.format ];
+               if ( this.constructor.static.formats[ config.format ] ) {
+                       this.format = this.constructor.static.formats[ config.format ];
                } else {
                        this.format = config.format;
                }
@@ -70,7 +68,7 @@
         * @inheritable
         * @property {Object}
         */
-       mw.widgets.datetime.DateTimeFormatter[ 'static' ].formats = {};
+       mw.widgets.datetime.DateTimeFormatter.static.formats = {};
 
        /**
         * Default time zone indicators
@@ -79,7 +77,7 @@
         * @inheritable
         * @property {string[]}
         */
-       mw.widgets.datetime.DateTimeFormatter[ 'static' ].fullZones = null;
+       mw.widgets.datetime.DateTimeFormatter.static.fullZones = null;
 
        /**
         * Default abbreviated time zone indicators
@@ -88,9 +86,9 @@
         * @inheritable
         * @property {string[]}
         */
-       mw.widgets.datetime.DateTimeFormatter[ 'static' ].shortZones = null;
+       mw.widgets.datetime.DateTimeFormatter.static.shortZones = null;
 
-       mw.widgets.datetime.DateTimeFormatter[ 'static' ].setupDefaults = function () {
+       mw.widgets.datetime.DateTimeFormatter.static.setupDefaults = function () {
                if ( !this.fullZones ) {
                        this.fullZones = [
                                mw.msg( 'timezone-utc' ),
                return this.local;
        };
 
+       // eslint-disable-next-line valid-jsdoc
        /**
         * Toggle whether dates are in local time or UTC
         *
         *  - 'clip': "Jan 32" => "Jan 31", "Feb 32" => "Feb 28" (or 29), "Feb 0" => "Feb 1", etc.
         * @return {Date} Adjusted date
         */
-       mw.widgets.datetime.DateTimeFormatter.prototype.adjustComponent = function ( date /*, component, delta, mode */ ) {
+       mw.widgets.datetime.DateTimeFormatter.prototype.adjustComponent = function ( date /* , component, delta, mode */ ) {
                // Should be overridden by subclass
                return date;
        };
index 91f797d..e9bedf5 100644 (file)
                        calendar: {}
                }, config );
 
+               // See InputWidget#reusePreInfuseDOM about config.$input
+               if ( config.$input ) {
+                       config.$input.addClass( 'oo-ui-element-hidden' );
+               }
+
                if ( $.isPlainObject( config.formatter ) && config.formatter.format === undefined ) {
                        config.formatter.format = '@' + config.type;
                }
                        } );
                }
 
-               // Our form input *should* be type="hidden". But if we're infusing from
-               // PHP, it's not.
-               if ( this.$input.attr( 'type' ) !== 'hidden' ) {
-                       try {
-                               this.$input.attr( 'type', 'hidden' );
-                       } catch ( e ) {
-                       }
-                       // IE <= 8, and IE 9 in quirks mode, doesn't allow changing the
-                       // type, so just hide the field with CSS. IE 9 in quirks mode
-                       // doesn't even throw an error, so do that unconditionally. Sigh.
-                       this.$input.css( 'display', 'none' );
-               }
-
                // Initialization
                this.setTabIndex( -1 );
 
 
        /* Static properties */
 
-       mw.widgets.datetime.DateTimeInputWidget[ 'static' ].supportsSimpleLabel = false;
+       mw.widgets.datetime.DateTimeInputWidget.static.supportsSimpleLabel = false;
 
        /* Events */
 
         * @private
         * @param {jQuery} $field
         * @param {jQuery.Event} e Key down event
+        * @return {boolean} False to cancel the default event
         */
        mw.widgets.datetime.DateTimeInputWidget.prototype.onFieldKeyDown = function ( $field, e ) {
                var spec = $field.data( 'mw-widgets-datetime-dateTimeInputWidget-fieldSpec' );
         * @private
         * @param {jQuery} $field
         * @param {jQuery.Event} e Change event
+        * @return {boolean} False to cancel the default event
         */
        mw.widgets.datetime.DateTimeInputWidget.prototype.onFieldWheel = function ( $field, e ) {
                var delta = 0,
index fbf3238..b280ead 100644 (file)
@@ -32,7 +32,7 @@
        /**
         * @inheritdoc
         */
-       mw.widgets.datetime.DiscordianDateTimeFormatter[ 'static' ].formats = {
+       mw.widgets.datetime.DiscordianDateTimeFormatter.static.formats = {
                '@time': '${hour|0}:${minute|0}:${second|0}',
                '@date': '$!{dow|full}${not-intercalary|1|, }${season|full}${not-intercalary|1| }${day|#}, ${year|#}',
                '@datetime': '$!{dow|full}${not-intercalary|1|, }${season|full}${not-intercalary|1| }${day|#}, ${year|#} ${hour|0}:${minute|0}:${second|0} $!{zone|short}',
index f60b34b..9e9b15f 100644 (file)
         * @cfg {number} [weekStartsOn=0] What day the week starts on: 0 is Sunday, 1 is Monday, 6 is Saturday.
         */
        mw.widgets.datetime.ProlepticGregorianDateTimeFormatter = function MwWidgetsDatetimeProlepticGregorianDateTimeFormatter( config ) {
-               var statick = this.constructor[ 'static' ];
-
-               statick.setupDefaults();
+               this.constructor.static.setupDefaults();
 
                config = $.extend( {
                        weekStartsOn: 0,
-                       hour12Periods: statick.hour12Periods
+                       hour12Periods: this.constructor.static.hour12Periods
                }, config );
 
                if ( config.fullMonthNames && !config.shortMonthNames ) {
                        }.bind( this ) );
                }
                config = $.extend( {
-                       fullMonthNames: statick.fullMonthNames,
-                       shortMonthNames: statick.shortMonthNames,
-                       fullDayNames: statick.fullDayNames,
-                       shortDayNames: statick.shortDayNames,
-                       dayLetters: statick.dayLetters
+                       fullMonthNames: this.constructor.static.fullMonthNames,
+                       shortMonthNames: this.constructor.static.shortMonthNames,
+                       fullDayNames: this.constructor.static.fullDayNames,
+                       shortDayNames: this.constructor.static.shortDayNames,
+                       dayLetters: this.constructor.static.dayLetters
                }, config );
 
                // Parent constructor
@@ -89,7 +87,7 @@
        /**
         * @inheritdoc
         */
-       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].formats = {
+       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.formats = {
                '@time': '${hour|0}:${minute|0}:${second|0}',
                '@date': '$!{dow|short} ${day|#} ${month|short} ${year|#}',
                '@datetime': '$!{dow|short} ${day|#} ${month|short} ${year|#} ${hour|0}:${minute|0}:${second|0} $!{zone|short}',
         * @inheritable
         * @property {Object}
         */
-       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].fullMonthNames = null;
+       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.fullMonthNames = null;
 
        /**
         * Default abbreviated month names.
         * @inheritable
         * @property {Object}
         */
-       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].shortMonthNames = null;
+       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.shortMonthNames = null;
 
        /**
         * Default full day of week names.
         * @inheritable
         * @property {Object}
         */
-       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].fullDayNames = null;
+       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.fullDayNames = null;
 
        /**
         * Default abbreviated day of week names.
         * @inheritable
         * @property {Object}
         */
-       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].shortDayNames = null;
+       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.shortDayNames = null;
 
        /**
         * Default day letters.
         * @inheritable
         * @property {string[]}
         */
-       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].dayLetters = null;
+       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.dayLetters = null;
 
        /**
         * Default AM/PM indicators
         * @inheritable
         * @property {string[]}
         */
-       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].hour12Periods = null;
+       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.hour12Periods = null;
 
-       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].setupDefaults = function () {
-               mw.widgets.datetime.DateTimeFormatter[ 'static' ].setupDefaults.call( this );
+       mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.setupDefaults = function () {
+               mw.widgets.datetime.DateTimeFormatter.static.setupDefaults.call( this );
 
                if ( this.fullMonthNames && !this.shortMonthNames ) {
                        this.shortMonthNames = {};
index 3daa70a..57a3d9c 100644 (file)
@@ -4,7 +4,7 @@
  * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
  * @license The MIT License (MIT); see LICENSE.txt
  */
-/*global moment */
+/* global moment */
 ( function ( $, mw ) {
 
        /**
                selected = moment( this.getDate(), this.getDateFormat() );
 
                switch ( this.displayLayer ) {
-               case 'month':
-                       this.labelButton.setLabel( this.moment.format( 'MMMM YYYY' ) );
-                       this.upButton.toggle( true );
-
-                       // First week displayed is the first week spanned by the month, unless it begins on Monday, in
-                       // which case first week displayed is the previous week. This makes the calendar "balanced"
-                       // and also neatly handles 28-day February sometimes spanning only 4 weeks.
-                       currentDay = moment( this.moment ).startOf( 'month' ).subtract( 1, 'day' ).startOf( 'week' );
-
-                       // Day-of-week labels. Localisation-independent: works with weeks starting on Saturday, Sunday
-                       // or Monday.
-                       for ( i = 0; i < 7; i++ ) {
-                               items.push(
-                                       $( '<div>' )
-                                               .addClass( 'mw-widget-calendarWidget-day-heading' )
-                                               .text( currentDay.format( 'dd' ) )
-                               );
-                               currentDay.add( 1, 'day' );
-                       }
-                       currentDay.subtract( 7, 'days' );
-
-                       // Actual calendar month. Always displays 6 weeks, for consistency (months can span 4 to 6
-                       // weeks).
-                       for ( i = 0; i < 42; i++ ) {
-                               items.push(
-                                       $( '<div>' )
-                                               .addClass( 'mw-widget-calendarWidget-item mw-widget-calendarWidget-day' )
-                                               .toggleClass( 'mw-widget-calendarWidget-day-additional', !currentDay.isSame( this.moment, 'month' ) )
-                                               .toggleClass( 'mw-widget-calendarWidget-day-today', currentDay.isSame( today, 'day' ) )
-                                               .toggleClass( 'mw-widget-calendarWidget-item-selected', currentDay.isSame( selected, 'day' ) )
-                                               .text( currentDay.format( 'D' ) )
-                                               .data( 'date', currentDay.date() )
-                                               .data( 'month', currentDay.month() )
-                                               .data( 'year', currentDay.year() )
-                               );
-                               currentDay.add( 1, 'day' );
-                       }
-                       break;
-
-               case 'year':
-                       this.labelButton.setLabel( this.moment.format( 'YYYY' ) );
-                       this.upButton.toggle( true );
-
-                       currentMonth = moment( this.moment ).startOf( 'year' );
-                       for ( i = 0; i < 12; i++ ) {
-                               items.push(
-                                       $( '<div>' )
-                                               .addClass( 'mw-widget-calendarWidget-item mw-widget-calendarWidget-month' )
-                                               .toggleClass( 'mw-widget-calendarWidget-item-selected', currentMonth.isSame( selected, 'month' ) )
-                                               .text( currentMonth.format( 'MMMM' ) )
-                                               .data( 'month', currentMonth.month() )
-                               );
-                               currentMonth.add( 1, 'month' );
-                       }
-                       // Shuffle the array to display months in columns rather than rows.
-                       items = [
-                               items[ 0 ], items[ 6 ],      //  | January  | July      |
-                               items[ 1 ], items[ 7 ],      //  | February | August    |
-                               items[ 2 ], items[ 8 ],      //  | March    | September |
-                               items[ 3 ], items[ 9 ],      //  | April    | October   |
-                               items[ 4 ], items[ 10 ],     //  | May      | November  |
-                               items[ 5 ], items[ 11 ]      //  | June     | December  |
-                       ];
-                       break;
-
-               case 'duodecade':
-                       this.labelButton.setLabel( null );
-                       this.upButton.toggle( false );
-
-                       currentYear = moment( { year: Math.floor( this.moment.year() / 20 ) * 20 } );
-                       for ( i = 0; i < 20; i++ ) {
-                               items.push(
-                                       $( '<div>' )
-                                               .addClass( 'mw-widget-calendarWidget-item mw-widget-calendarWidget-year' )
-                                               .toggleClass( 'mw-widget-calendarWidget-item-selected', currentYear.isSame( selected, 'year' ) )
-                                               .text( currentYear.format( 'YYYY' ) )
-                                               .data( 'year', currentYear.year() )
-                               );
-                               currentYear.add( 1, 'year' );
-                       }
-                       break;
+                       case 'month':
+                               this.labelButton.setLabel( this.moment.format( 'MMMM YYYY' ) );
+                               this.upButton.toggle( true );
+
+                               // First week displayed is the first week spanned by the month, unless it begins on Monday, in
+                               // which case first week displayed is the previous week. This makes the calendar "balanced"
+                               // and also neatly handles 28-day February sometimes spanning only 4 weeks.
+                               currentDay = moment( this.moment ).startOf( 'month' ).subtract( 1, 'day' ).startOf( 'week' );
+
+                               // Day-of-week labels. Localisation-independent: works with weeks starting on Saturday, Sunday
+                               // or Monday.
+                               for ( i = 0; i < 7; i++ ) {
+                                       items.push(
+                                               $( '<div>' )
+                                                       .addClass( 'mw-widget-calendarWidget-day-heading' )
+                                                       .text( currentDay.format( 'dd' ) )
+                                       );
+                                       currentDay.add( 1, 'day' );
+                               }
+                               currentDay.subtract( 7, 'days' );
+
+                               // Actual calendar month. Always displays 6 weeks, for consistency (months can span 4 to 6
+                               // weeks).
+                               for ( i = 0; i < 42; i++ ) {
+                                       items.push(
+                                               $( '<div>' )
+                                                       .addClass( 'mw-widget-calendarWidget-item mw-widget-calendarWidget-day' )
+                                                       .toggleClass( 'mw-widget-calendarWidget-day-additional', !currentDay.isSame( this.moment, 'month' ) )
+                                                       .toggleClass( 'mw-widget-calendarWidget-day-today', currentDay.isSame( today, 'day' ) )
+                                                       .toggleClass( 'mw-widget-calendarWidget-item-selected', currentDay.isSame( selected, 'day' ) )
+                                                       .text( currentDay.format( 'D' ) )
+                                                       .data( 'date', currentDay.date() )
+                                                       .data( 'month', currentDay.month() )
+                                                       .data( 'year', currentDay.year() )
+                                       );
+                                       currentDay.add( 1, 'day' );
+                               }
+                               break;
+
+                       case 'year':
+                               this.labelButton.setLabel( this.moment.format( 'YYYY' ) );
+                               this.upButton.toggle( true );
+
+                               currentMonth = moment( this.moment ).startOf( 'year' );
+                               for ( i = 0; i < 12; i++ ) {
+                                       items.push(
+                                               $( '<div>' )
+                                                       .addClass( 'mw-widget-calendarWidget-item mw-widget-calendarWidget-month' )
+                                                       .toggleClass( 'mw-widget-calendarWidget-item-selected', currentMonth.isSame( selected, 'month' ) )
+                                                       .text( currentMonth.format( 'MMMM' ) )
+                                                       .data( 'month', currentMonth.month() )
+                                       );
+                                       currentMonth.add( 1, 'month' );
+                               }
+                               // Shuffle the array to display months in columns rather than rows.
+                               items = [
+                                       items[ 0 ], items[ 6 ],      //  | January  | July      |
+                                       items[ 1 ], items[ 7 ],      //  | February | August    |
+                                       items[ 2 ], items[ 8 ],      //  | March    | September |
+                                       items[ 3 ], items[ 9 ],      //  | April    | October   |
+                                       items[ 4 ], items[ 10 ],     //  | May      | November  |
+                                       items[ 5 ], items[ 11 ]      //  | June     | December  |
+                               ];
+                               break;
+
+                       case 'duodecade':
+                               this.labelButton.setLabel( null );
+                               this.upButton.toggle( false );
+
+                               currentYear = moment( { year: Math.floor( this.moment.year() / 20 ) * 20 } );
+                               for ( i = 0; i < 20; i++ ) {
+                                       items.push(
+                                               $( '<div>' )
+                                                       .addClass( 'mw-widget-calendarWidget-item mw-widget-calendarWidget-year' )
+                                                       .toggleClass( 'mw-widget-calendarWidget-item-selected', currentYear.isSame( selected, 'year' ) )
+                                                       .text( currentYear.format( 'YYYY' ) )
+                                                       .data( 'year', currentYear.year() )
+                                       );
+                                       currentYear.add( 1, 'year' );
+                               }
+                               break;
                }
 
                this.$body.append.apply( this.$body, items );
         */
        mw.widgets.CalendarWidget.prototype.onPrevButtonClick = function () {
                switch ( this.displayLayer ) {
-               case 'month':
-                       this.moment.subtract( 1, 'month' );
-                       break;
-               case 'year':
-                       this.moment.subtract( 1, 'year' );
-                       break;
-               case 'duodecade':
-                       this.moment.subtract( 20, 'years' );
-                       break;
+                       case 'month':
+                               this.moment.subtract( 1, 'month' );
+                               break;
+                       case 'year':
+                               this.moment.subtract( 1, 'year' );
+                               break;
+                       case 'duodecade':
+                               this.moment.subtract( 20, 'years' );
+                               break;
                }
                this.updateUI( 'previous' );
        };
         */
        mw.widgets.CalendarWidget.prototype.onNextButtonClick = function () {
                switch ( this.displayLayer ) {
-               case 'month':
-                       this.moment.add( 1, 'month' );
-                       break;
-               case 'year':
-                       this.moment.add( 1, 'year' );
-                       break;
-               case 'duodecade':
-                       this.moment.add( 20, 'years' );
-                       break;
+                       case 'month':
+                               this.moment.add( 1, 'month' );
+                               break;
+                       case 'year':
+                               this.moment.add( 1, 'year' );
+                               break;
+                       case 'duodecade':
+                               this.moment.add( 20, 'years' );
+                               break;
                }
                this.updateUI( 'next' );
        };
         * what gets clicked.
         *
         * @private
+        * @param {jQuery.Event} e Click event
         */
        mw.widgets.CalendarWidget.prototype.onBodyClick = function ( e ) {
                var
         *
         * @private
         * @param {jQuery.Event} e Mouse click event
+        * @return {boolean} False to cancel the default event
         */
        mw.widgets.CalendarWidget.prototype.onClick = function ( e ) {
                if ( !this.isDisabled() && e.which === 1 ) {
         *
         * @private
         * @param {jQuery.Event} e Key down event
+        * @return {boolean} False to cancel the default event
         */
        mw.widgets.CalendarWidget.prototype.onKeyDown = function ( e ) {
                var
-                       /*jshint -W024*/
                        dir = OO.ui.Element.static.getDir( this.$element ),
-                       /*jshint +W024*/
                        nextDirectionKey = dir === 'ltr' ? OO.ui.Keys.RIGHT : OO.ui.Keys.LEFT,
                        prevDirectionKey = dir === 'ltr' ? OO.ui.Keys.LEFT : OO.ui.Keys.RIGHT,
                        changed = true;
 
                if ( !this.isDisabled() ) {
                        switch ( e.which ) {
-                       case prevDirectionKey:
-                               this.moment.subtract( 1, this.precision === 'month' ? 'month' : 'day' );
-                               break;
-                       case nextDirectionKey:
-                               this.moment.add( 1, this.precision === 'month' ? 'month' : 'day' );
-                               break;
-                       case OO.ui.Keys.UP:
-                               this.moment.subtract( 1, this.precision === 'month' ? 'month' : 'week' );
-                               break;
-                       case OO.ui.Keys.DOWN:
-                               this.moment.add( 1, this.precision === 'month' ? 'month' : 'week' );
-                               break;
-                       case OO.ui.Keys.PAGEUP:
-                               this.moment.subtract( 1, this.precision === 'month' ? 'year' : 'month' );
-                               break;
-                       case OO.ui.Keys.PAGEDOWN:
-                               this.moment.add( 1, this.precision === 'month' ? 'year' : 'month' );
-                               break;
-                       default:
-                               changed = false;
-                               break;
+                               case prevDirectionKey:
+                                       this.moment.subtract( 1, this.precision === 'month' ? 'month' : 'day' );
+                                       break;
+                               case nextDirectionKey:
+                                       this.moment.add( 1, this.precision === 'month' ? 'month' : 'day' );
+                                       break;
+                               case OO.ui.Keys.UP:
+                                       this.moment.subtract( 1, this.precision === 'month' ? 'month' : 'week' );
+                                       break;
+                               case OO.ui.Keys.DOWN:
+                                       this.moment.add( 1, this.precision === 'month' ? 'month' : 'week' );
+                                       break;
+                               case OO.ui.Keys.PAGEUP:
+                                       this.moment.subtract( 1, this.precision === 'month' ? 'year' : 'month' );
+                                       break;
+                               case OO.ui.Keys.PAGEDOWN:
+                                       this.moment.add( 1, this.precision === 'month' ? 'year' : 'month' );
+                                       break;
+                               default:
+                                       changed = false;
+                                       break;
                        }
 
                        if ( changed ) {
index 4d86cfd..488d9e0 100644 (file)
@@ -94,7 +94,8 @@
         * @extends mw.Title
         *
         * @constructor
-        * @inheritdoc
+        * @param {string} title
+        * @param {number} [namespace]
         */
        function ForeignTitle( title, namespace ) {
                // We only need to handle categories here... but we don't know the target language.
        };
 
        /**
-        * @class mw.widgets.CategoryCapsuleItemWidget
-        *
         * Category selector capsule item widget. Extends OO.ui.CapsuleItemWidget with the ability to link
         * to the given page, and to show its existence status (i.e., whether it is a redlink).
         *
+        * @class mw.widgets.CategoryCapsuleItemWidget
         * @uses mw.Api
         * @extends OO.ui.CapsuleItemWidget
         *
                this.$label.replaceWith( this.$link );
                this.setLabelElement( this.$link );
 
-               /*jshint -W024*/
                if ( !this.constructor.static.pageExistenceCaches[ this.apiUrl ] ) {
                        this.constructor.static.pageExistenceCaches[ this.apiUrl ] =
                                new PageExistenceCache( new mw.ForeignApi( this.apiUrl ) );
                        .done( function ( exists ) {
                                widget.setMissing( !exists );
                        } );
-               /*jshint +W024*/
        };
 
        /* Setup */
 
        /* Static Properties */
 
-       /*jshint -W024*/
        /**
         * Map of API URLs to PageExistenceCache objects.
         *
        mw.widgets.CategoryCapsuleItemWidget.static.pageExistenceCaches = {
                '': new PageExistenceCache()
        };
-       /*jshint +W024*/
 
        /* Methods */
 
index 267eebb..e0ec8e7 100644 (file)
                                        prop: 'categories',
                                        cllimit: this.limit,
                                        titles: 'Category:' + input
-                               } ).done( function ( res )  {
+                               } ).done( function ( res ) {
                                        var categories = [];
 
                                        $.each( res.query.pages, function ( index, page ) {
index ddae9b1..8f48ec3 100644 (file)
@@ -51,7 +51,6 @@
        OO.inheritClass( mw.widgets.ComplexTitleInputWidget, OO.ui.Widget );
 
        /* Static Methods */
-       /*jshint -W024*/
 
        /**
         * @inheritdoc
@@ -85,8 +84,6 @@
                return state;
        };
 
-       /*jshint +W024*/
-
        /* Methods */
 
        /**
index a9b5bc3..7f5e608 100644 (file)
@@ -4,7 +4,7 @@
  * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
  * @license The MIT License (MIT); see LICENSE.txt
  */
-/*global moment */
+/* global moment */
 ( function ( $, mw ) {
 
        /**
@@ -87,6 +87,8 @@
         *     calendar uses relative positioning.
         */
        mw.widgets.DateInputWidget = function MWWDateInputWidget( config ) {
+               var placeholderDateFormat, mustBeAfter, mustBeBefore;
+
                // Config initialization
                config = $.extend( {
                        precision: 'day',
                        }
                }
 
-               var placeholderDateFormat, mustBeAfter, mustBeBefore;
                if ( config.placeholderDateFormat ) {
                        placeholderDateFormat = config.placeholderDateFormat;
                } else if ( config.inputFormat ) {
                        .addClass( 'mw-widget-dateInputWidget' )
                        .append( this.$handle, this.textInput.$element, this.calendar.$element );
 
+               // config.overlay is the selector to be used for config.$overlay, specified from PHP
+               if ( config.overlay ) {
+                       config.$overlay = $( config.overlay );
+               }
+
                if ( config.$overlay ) {
                        this.calendar.setFloatableContainer( this.$element );
                        config.$overlay.append( this.calendar.$element );
                this.updateUI();
                this.textInput.toggle( false );
                this.calendar.toggle( false );
+
+               // Hide unused <input> from PHP after infusion is done
+               // See InputWidget#reusePreInfuseDOM about config.$input
+               if ( config.$input ) {
+                       config.$input.addClass( 'oo-ui-element-hidden' );
+               }
        };
 
        /* Inheritance */
         * @return {string} Format string
         */
        mw.widgets.DateInputWidget.prototype.getDisplayFormat = function () {
+               var localeData, llll, lll, ll, format;
+
                if ( this.displayFormat !== undefined ) {
                        return this.displayFormat;
                }
                        // We try to construct it as 'llll - (lll - ll)' and hope for the best.
                        // This seems to work well for many languages (maybe even all?).
 
-                       var localeData = moment.localeData( moment.locale() ),
-                               llll = localeData.longDateFormat( 'llll' ),
-                               lll = localeData.longDateFormat( 'lll' ),
-                               ll = localeData.longDateFormat( 'll' ),
-                               format = llll.replace( lll.replace( ll, '' ), '' );
+                       localeData = moment.localeData( moment.locale() );
+                       llll = localeData.longDateFormat( 'llll' );
+                       lll = localeData.longDateFormat( 'lll' );
+                       ll = localeData.longDateFormat( 'll' );
+                       format = llll.replace( lll.replace( ll, '' ), '' );
 
                        return format;
                }
         *
         * @private
         * @param {jQuery.Event} e Mouse click event
+        * @return {boolean} False to cancel the default event
         */
        mw.widgets.DateInputWidget.prototype.onClick = function ( e ) {
                if ( !this.isDisabled() && e.which === 1 ) {
         *
         * @private
         * @param {jQuery.Event} e Key press event
+        * @return {boolean} False to cancel the default event
         */
        mw.widgets.DateInputWidget.prototype.onKeyPress = function ( e ) {
                if ( !this.isDisabled() &&
         *
         * @private
         * @param {jQuery.Event} e Key press event
+        * @return {boolean} False to cancel the default event
         */
        mw.widgets.DateInputWidget.prototype.onCalendarKeyPress = function ( e ) {
                if ( !this.isDisabled() && e.which === OO.ui.Keys.ENTER ) {
         *
         * @private
         * @param {jQuery.Event} e Mouse click event
+        * @return {boolean} False to cancel the default event
         */
        mw.widgets.DateInputWidget.prototype.onCalendarClick = function ( e ) {
                if (
index c88395e..aa0c739 100644 (file)
@@ -36,6 +36,8 @@
 
        /**
         * @private
+        * @param {Object} [config] Configuration options
+        * @return {Object[]} Dropdown options
         */
        mw.widgets.NamespaceInputWidget.prototype.getNamespaceDropdownOptions = function ( config ) {
                var options,
index d816335..39bee7c 100755 (executable)
@@ -13,6 +13,7 @@
         * @extends mw.widgets.TitleInputWidget
         *
         * @constructor
+        * @param {Object} [config] Configuration options
         * @cfg {boolean} [pushPending=true] Visually mark the input field as "pending", while
         *  requesting suggestions.
         * @cfg {boolean} [performSearchOnClick=true] If true, the script will start a search when-
index 101a606..a78ad82 100644 (file)
@@ -15,6 +15,7 @@
         * @mixins OO.ui.mixin.LookupElement
         *
         * @constructor
+        * @param {Object} [config] Configuration options
         * @cfg {boolean} [suggestions=true] Display search suggestions
         * @cfg {RegExp|Function|string} [validate] Perform title validation
         */
index 96f9549..5ba9481 100644 (file)
@@ -15,6 +15,7 @@
         * @mixins mw.widgets.TitleWidget
         *
         * @constructor
+        * @param {Object} [config] Configuration options
         */
        mw.widgets.TitleSearchWidget = function MwWidgetsTitleSearchWidget( config ) {
                config = config || {};
index 1732407..e1e50ea 100644 (file)
@@ -7,14 +7,14 @@
 ( function ( $, mw ) {
 
        var interwikiPrefixesPromise = new mw.Api().get( {
-                       action: 'query',
-                       meta: 'siteinfo',
-                       siprop: 'interwikimap'
-               } ).then( function ( data ) {
-                       return $.map( data.query.interwikimap, function ( interwiki ) {
-                               return interwiki.prefix;
-                       } );
+               action: 'query',
+               meta: 'siteinfo',
+               siprop: 'interwikimap'
+       } ).then( function ( data ) {
+               return $.map( data.query.interwikimap, function ( interwiki ) {
+                       return interwiki.prefix;
                } );
+       } );
 
        /**
         * Mixin for title widgets
@@ -30,9 +30,9 @@
         * @cfg {boolean} [relative=true] If a namespace is set, display titles relative to it
         * @cfg {boolean} [suggestions=true] Display search suggestions
         * @cfg {boolean} [showRedirectTargets=true] Show the targets of redirects
-        * @cfg {boolean} [showRedlink] Show red link to exact match if it doesn't exist
         * @cfg {boolean} [showImages] Show page images
         * @cfg {boolean} [showDescriptions] Show page descriptions
+        * @cfg {boolean} [excludeCurrentPage] Exclude the current page from suggestions
         * @cfg {boolean} [validateTitle=true] Whether the input must be a valid title (if set to true,
         *  the widget will marks itself red for invalid inputs, including an empty query).
         * @cfg {Object} [cache] Result cache which implements a 'set' method, taking keyed values as an argument
@@ -51,9 +51,9 @@
                this.relative = config.relative !== undefined ? config.relative : true;
                this.suggestions = config.suggestions !== undefined ? config.suggestions : true;
                this.showRedirectTargets = config.showRedirectTargets !== false;
-               this.showRedlink = !!config.showRedlink;
                this.showImages = !!config.showImages;
                this.showDescriptions = !!config.showDescriptions;
+               this.excludeCurrentPage = !!config.excludeCurrentPage;
                this.validateTitle = config.validateTitle !== undefined ? config.validateTitle : true;
                this.cache = config.cache;
 
                                        }
                                        req = new mw.Api().get( params );
                                        promiseAbortObject.abort = req.abort.bind( req ); // TODO ew
-                                       return req;
+                                       return req.then( function ( ret ) {
+                                               if ( ret.query === undefined ) {
+                                                       ret = new mw.Api().get( { action: 'query', titles: query } );
+                                                       promiseAbortObject.abort = ret.abort.bind( ret );
+                                               }
+                                               return ret;
+                                       } );
                                }
                        } ).promise( promiseAbortObject );
                } else {
         */
        mw.widgets.TitleWidget.prototype.getOptionsFromData = function ( data ) {
                var i, len, index, pageExists, pageExistsExact, suggestionPage, page, redirect, redirects,
+                       currentPageName = new mw.Title( mw.config.get( 'wgRelevantPageName' ) ).getPrefixedText(),
                        items = [],
                        titles = [],
                        titleObj = mw.Title.newFromText( this.getQueryValue() ),
 
                for ( index in data.pages ) {
                        suggestionPage = data.pages[ index ];
+                       // When excludeCurrentPage is set, don't list the current page unless the user has type the full title
+                       if ( this.excludeCurrentPage && suggestionPage.title === currentPageName && suggestionPage.title !== titleObj.getPrefixedText() ) {
+                               continue;
+                       }
                        pageData[ suggestionPage.title ] = {
+                               known: suggestionPage.known !== undefined,
                                missing: suggestionPage.missing !== undefined,
                                redirect: suggestionPage.redirect !== undefined,
                                disambiguation: OO.getProp( suggestionPage, 'pageprops', 'disambiguation' ) !== undefined,
                        for ( i = 0, len = redirects.length; i < len; i++ ) {
                                pageData[ redirects[ i ] ] = {
                                        missing: false,
+                                       known: true,
                                        redirect: true,
                                        disambiguation: false,
                                        description: mw.msg( 'mw-widgets-titleinput-description-redirect', suggestionPage.title ),
                // If not found, run value through mw.Title to avoid treating a match as a
                // mismatch where normalisation would make them matching (bug 48476)
 
-               pageExistsExact = titles.indexOf( this.getQueryValue() ) !== -1;
+               pageExistsExact = (
+                       Object.prototype.hasOwnProperty.call( pageData, this.getQueryValue() ) &&
+                       (
+                               !pageData[ this.getQueryValue() ].missing ||
+                               pageData[ this.getQueryValue() ].known
+                       )
+               );
                pageExists = pageExistsExact || (
-                       titleObj && titles.indexOf( titleObj.getPrefixedText() ) !== -1
+                       titleObj &&
+                       Object.prototype.hasOwnProperty.call( pageData, titleObj.getPrefixedText() ) &&
+                       (
+                               !pageData[ titleObj.getPrefixedText() ].missing ||
+                               pageData[ titleObj.getPrefixedText() ].known
+                       )
                );
 
-               if ( !pageExists ) {
-                       pageData[ this.getQueryValue() ] = {
-                               missing: true, redirect: false, disambiguation: false,
-                               description: mw.msg( 'mw-widgets-titleinput-description-new-page' )
-                       };
-               }
-
                if ( this.cache ) {
                        this.cache.set( pageData );
                }
                if ( pageExists && !pageExistsExact ) {
                        titles.unshift( this.getQueryValue() );
                }
-               // Offer the exact text as a new page if the title is valid
-               if ( this.showRedlink && !pageExists && titleObj ) {
-                       titles.push( this.getQueryValue() );
-               }
+
                for ( i = 0, len = titles.length; i < len; i++ ) {
                        page = pageData[ titles[ i ] ] || {};
                        items.push( new mw.widgets.TitleOptionWidget( this.getOptionWidgetData( titles[ i ], page ) ) );
         * @return {Object} Data for option widget
         */
        mw.widgets.TitleWidget.prototype.getOptionWidgetData = function ( title, data ) {
-               var mwTitle = new mw.Title( title );
+               var mwTitle = new mw.Title( title ),
+                       description = data.description;
+               if ( data.missing && !description ) {
+                       description = mw.msg( 'mw-widgets-titleinput-description-new-page' );
+               }
                return {
-                       data: this.namespace !== null && this.relative
-                               ? mwTitle.getRelativeText( this.namespace )
-                               title,
+                       data: this.namespace !== null && this.relative ?
+                               mwTitle.getRelativeText( this.namespace ) :
+                               title,
                        url: mwTitle.getUrl(),
                        imageUrl: this.showImages ? data.imageUrl : null,
-                       description: this.showDescriptions ? data.description : null,
+                       description: this.showDescriptions ? description : null,
                        missing: data.missing,
                        redirect: data.redirect,
                        disambiguation: data.disambiguation,
index 164fd20..2b3a59f 100644 (file)
@@ -90,6 +90,7 @@
         *
         * @method
         * @param {Mixed} response Response from server
+        * @return {Object}
         */
        mw.widgets.UserInputWidget.prototype.getLookupCacheDataFromResponse = function ( response ) {
                return response.query.allusers || {};
index f51403f..1a3cdd5 100644 (file)
                this.apiUrl = String( url );
                this.anonymous = options && options.anonymous;
 
-               options = $.extend( /*deep=*/ true,
+               options = $.extend( /* deep=*/ true,
                        {
                                ajax: {
                                        url: this.apiUrl,
                                        xhrFields: {
-                                               withCredentials: this.anonymous ? false : true
+                                               withCredentials: !this.anonymous
                                        }
                                },
                                parameters: {
index b7579ff..b9e05c3 100644 (file)
                                } )
                                // AJAX success just means "200 OK" response, also check API error codes
                                .done( function ( result, textStatus, jqXHR ) {
+                                       var code;
                                        if ( result === undefined || result === null || result === '' ) {
                                                apiDeferred.reject( 'ok-but-empty',
                                                        'OK response but empty result (check HTTP headers?)',
                                                        jqXHR
                                                );
                                        } else if ( result.error ) {
-                                               var code = result.error.code === undefined ? 'unknown' : result.error.code;
+                                               code = result.error.code === undefined ? 'unknown' : result.error.code;
                                                apiDeferred.reject( code, result, result, jqXHR );
                                        } else {
                                                apiDeferred.resolve( result, jqXHR );
                 *
                 * @since 1.22
                 * @param {string} type Token type
+                * @param {string} [assert]
                 * @return {jQuery.Promise} Received token.
                 */
                getToken: function ( type, assert ) {
index bb3a913..21fad5e 100644 (file)
                        var basetimestamp, curtimestamp,
                                api = this;
                        return api.get( {
-                                       action: 'query',
-                                       prop: 'revisions',
-                                       rvprop: [ 'content', 'timestamp' ],
-                                       titles: String( title ),
-                                       formatversion: '2',
-                                       curtimestamp: true
-                               } )
+                               action: 'query',
+                               prop: 'revisions',
+                               rvprop: [ 'content', 'timestamp' ],
+                               titles: String( title ),
+                               formatversion: '2',
+                               curtimestamp: true
+                       } )
                                .then( function ( data ) {
                                        var page, revision;
                                        if ( !data.query || !data.query.pages ) {
index 418fd23..f38e88b 100644 (file)
                 * @return {string} return.done.data Parsed HTML of `wikitext`.
                 */
                parse: function ( content, additionalParams ) {
-                       var apiPromise, config = $.extend( {
-                               formatversion: 2,
-                               action: 'parse',
-                               contentmodel: 'wikitext'
-                       }, additionalParams );
+                       var apiPromise,
+                               config = $.extend( {
+                                       formatversion: 2,
+                                       action: 'parse',
+                                       contentmodel: 'wikitext'
+                               }, additionalParams );
 
                        if ( mw.Title && content instanceof mw.Title ) {
                                // Parse existing page
index 8169449..351ceb2 100644 (file)
@@ -34,7 +34,8 @@
         * @return {string}
         */
        function getFirstKey( obj ) {
-               for ( var key in obj ) {
+               var key;
+               for ( key in obj ) {
                        if ( obj.hasOwnProperty( key ) ) {
                                return key;
                        }
@@ -45,6 +46,7 @@
         * Get new iframe object for an upload.
         *
         * @private
+        * @param {string} id
         * @return {HTMLIframeElement}
         */
        function getNewIframe( id ) {
@@ -58,6 +60,8 @@
         * Shortcut for getting hidden inputs
         *
         * @private
+        * @param {string} name
+        * @param {string} val
         * @return {jQuery}
         */
        function getHiddenInput( name, val ) {
                 *
                 * @param {string} filekey
                 * @param {Object} data
+                * @return {jQuery.Promise}
                 */
                uploadFromStash: function ( filekey, data ) {
                        data.filekey = filekey;
index a2ff129..687b475 100644 (file)
@@ -12,6 +12,7 @@
         * @param {string|mw.Title|string[]|mw.Title[]} pages Full page name or instance of mw.Title, or an
         *  array thereof. If an array is passed, the return value passed to the promise will also be an
         *  array of appropriate objects.
+        * @param {Object} [addParams]
         * @return {jQuery.Promise}
         * @return {Function} return.done
         * @return {Object|Object[]} return.done.watch Object or list of objects (depends on the `pages`
index 0fbbcbe..5f60097 100644 (file)
@@ -4,8 +4,6 @@
  */
 ( function ( mw, $ ) {
 
-       /*jshint -W024*/
-
        /**
         * Helper function for hide-if to find the nearby form field.
         *
 
        mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
                $root.find( '.mw-htmlform-hide-if' ).each( function () {
-                       var v, i, fields, test, func, spec, self, modules, data,extraModules,
+                       var v, i, fields, test, func, spec, self, modules, data, extraModules,
                                $el = $( this );
 
                        modules = [];
index 37474f6..4f672fc 100644 (file)
@@ -10,6 +10,7 @@
         * Currently only supports passing 'hide-if' data.
         *
         * @ignore
+        * @param {Object} [config] Configuration options
         */
        mw.htmlform.Element = function ( config ) {
                // Configuration initialization
index a8786ef..37c0554 100644 (file)
@@ -18,8 +18,8 @@
                } );
                $oldContainer.find( 'input' ).each( function () {
                        var $oldInput = $( this ),
-                       checked = $oldInput.prop( 'checked' ),
-                       $option = $( '<option>' );
+                               checked = $oldInput.prop( 'checked' ),
+                               $option = $( '<option>' );
                        $option.prop( 'value', $oldInput.prop( 'value' ) );
                        if ( checked ) {
                                $option.prop( 'selected', true );
@@ -32,9 +32,9 @@
 
        function convertCheckboxesToMulti( $oldContainer, type ) {
                var $fieldLabel = $( '<td>' ),
-               $td = $( '<td>' ),
-               $fieldLabelText = $( '<label>' ),
-               $container;
+                       $td = $( '<td>' ),
+                       $fieldLabelText = $( '<label>' ),
+                       $container;
                if ( type === 'tr' ) {
                        addMulti( $oldContainer, $td );
                        $container = $( '<tr>' );
                return $container;
        }
 
+       function convertCheckboxesWidgetToCapsules( fieldLayout ) {
+               var checkboxesWidget, checkboxesOptions, capsulesOptions, capsulesWidget;
+
+               checkboxesWidget = fieldLayout.fieldWidget;
+               checkboxesOptions = checkboxesWidget.checkboxMultiselectWidget.getItems();
+               capsulesOptions = checkboxesOptions.map( function ( option ) {
+                       return new OO.ui.MenuOptionWidget( {
+                               data: option.getData(),
+                               label: option.getLabel()
+                       } );
+               } );
+               capsulesWidget = new OO.ui.CapsuleMultiselectWidget( {
+                       menu: {
+                               items: capsulesOptions
+                       }
+               } );
+               capsulesWidget.setItemsFromData( checkboxesWidget.getValue() );
+
+               // Data from CapsuleMultiselectWidget will not be submitted with the form, so keep the original
+               // CheckboxMultiselectInputWidget up-to-date.
+               capsulesWidget.on( 'change', function () {
+                       checkboxesWidget.setValue( capsulesWidget.getItemsData() );
+               } );
+
+               // Hide original widget and add new one in its place. This is a bit hacky, since the FieldLayout
+               // still thinks it's connected to the old widget.
+               checkboxesWidget.toggle( false );
+               checkboxesWidget.$element.after( capsulesWidget.$element );
+       }
+
        mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
-               if ( $root.find( '.mw-htmlform-dropdown' ).length ) {
-                       mw.loader.using( 'jquery.chosen', function () {
-                               $root.find( '.mw-htmlform-dropdown' ).each( function () {
-                                       var type = this.nodeName.toLowerCase(),
-                                               $converted = convertCheckboxesToMulti( $( this ), type );
-                                       $converted.find( '.htmlform-chzn-select' ).chosen( { width: 'auto' } );
-                               } );
+               var $dropdowns = $root.find( '.mw-htmlform-field-HTMLMultiSelectField.mw-htmlform-dropdown' );
+               if ( $dropdowns.length ) {
+                       $dropdowns.each( function () {
+                               var $el = $( this ),
+                                       data, modules, extraModules;
+                               if ( $el.is( '[data-ooui]' ) ) {
+                                       // Load 'oojs-ui-widgets' for CapsuleMultiselectWidget
+                                       modules = [ 'mediawiki.htmlform.ooui', 'oojs-ui-widgets' ];
+                                       data = $el.data( 'mw-modules' );
+                                       if ( data ) {
+                                               // We can trust this value, 'data-mw-*' attributes are banned from user content in Sanitizer
+                                               extraModules = data.split( ',' );
+                                               modules.push.apply( modules, extraModules );
+                                       }
+                                       mw.loader.using( modules, function () {
+                                               convertCheckboxesWidgetToCapsules( OO.ui.FieldLayout.static.infuse( $el ) );
+                                       } );
+                               } else {
+                                       mw.loader.using( 'jquery.chosen', function () {
+                                               var type = $el.is( 'tr' ) ? 'tr' : 'div',
+                                                       $converted = convertCheckboxesToMulti( $el, type );
+                                               $converted.find( '.htmlform-chzn-select' ).chosen( { width: 'auto' } );
+                                       } );
+                               }
                        } );
                }
        } );
index fc0fd6e..40f4f52 100644 (file)
@@ -18,8 +18,8 @@
 /* Flatlist styling for PHP widgets... */
 .mw-htmlform-flatlist .oo-ui-fieldLayout-align-inline,
 /* ...and for JS widgets */
-.mw-htmlform-flatlist .oo-ui-optionWidget,
-.mw-htmlform-flatlist .oo-ui-multioptionWidget {
+.mw-htmlform-flatlist .oo-ui-radioOptionWidget,
+.mw-htmlform-flatlist .oo-ui-checkboxMultioptionWidget {
        display: inline-block;
        margin-right: 1em;
 }
index 0f61d97..a5cf1d8 100644 (file)
@@ -1,4 +1,4 @@
-/*global moment */
+/* global moment, Uint8Array */
 ( function ( $, mw ) {
 
        /**
@@ -18,6 +18,9 @@
         * @class mw.ForeignStructuredUpload.BookletLayout
         * @uses mw.ForeignStructuredUpload
         * @extends mw.Upload.BookletLayout
+        *
+        * @constructor
+        * @param {Object} config Configuration options
         * @cfg {string} [target] Used to choose the target repository.
         *     If nothing is passed, the {@link mw.ForeignUpload#property-target default} is used.
         */
                } );
        };
 
+       /**
+        * @param {mw.Title} filename
+        * @return {jQuery.Promise} Resolves (on success) or rejects with OO.ui.Error
+        */
+       mw.ForeignStructuredUpload.BookletLayout.prototype.validateFilename = function ( filename ) {
+               return ( new mw.Api() ).get( {
+                       action: 'query',
+                       prop: 'info',
+                       titles: filename.getPrefixedDb(),
+                       formatversion: 2
+               } ).then(
+                       function ( result ) {
+                               // if the file already exists, reject right away, before
+                               // ever firing finishStashUpload()
+                               if ( !result.query.pages[ 0 ].missing ) {
+                                       return $.Deferred().reject( new OO.ui.Error(
+                                               $( '<p>' ).msg( 'fileexists', filename.getPrefixedDb() ),
+                                               { recoverable: false }
+                                       ) );
+                               }
+                       },
+                       function () {
+                               // API call failed - this could be a connection hiccup...
+                               // Let's just ignore this validation step and turn this
+                               // failure into a successful resolve ;)
+                               return $.Deferred().resolve();
+                       }
+               );
+       };
+
+       /**
+        * @inheritdoc
+        */
+       mw.ForeignStructuredUpload.BookletLayout.prototype.saveFile = function () {
+               var title = mw.Title.newFromText(
+                               this.getFilename(),
+                               mw.config.get( 'wgNamespaceIds' ).file
+                       );
+
+               return this.uploadPromise
+                       .then( this.validateFilename.bind( this, title ) )
+                       .then( mw.ForeignStructuredUpload.BookletLayout.parent.prototype.saveFile.bind( this ) );
+       };
+
        /* Getters */
 
        /**
                                }
 
                                try {
-                                       metadata = mw.libs.jpegmeta( this.result, file.name );
+                                       metadata = mw.libs.jpegmeta( fileStr, file.name );
                                } catch ( e ) {
                                        metadata = null;
                                }
index 3a0a94b..0c572d4 100644 (file)
@@ -1,8 +1,5 @@
 ( function ( mw, $, OO ) {
        /**
-        * @class mw.ForeignStructuredUpload
-        * @extends mw.ForeignUpload
-        *
         * Used to represent an upload in progress on the frontend.
         *
         * This subclass will upload to a wiki using a structured metadata
         * **TODO: This currently only supports uploads under CC-BY-SA 4.0,
         * and should really have support for more licenses.**
         *
-        * @inheritdoc
+        * @class mw.ForeignStructuredUpload
+        * @extends mw.ForeignUpload
+        *
+        * @constructor
+        * @param {string} [target]
+        * @param {Object} [apiconfig]
         */
        function ForeignStructuredUpload( target, apiconfig ) {
                this.date = undefined;
index 781c1df..08fc01d 100644 (file)
@@ -1,8 +1,5 @@
 ( function ( mw, OO, $ ) {
        /**
-        * @class mw.ForeignUpload
-        * @extends mw.Upload
-        *
         * Used to represent an upload in progress on the frontend.
         *
         * Subclassed to upload to a foreign API, with no other goodies. Use
@@ -12,6 +9,9 @@
         * an object, we assume you want the default, and treat it as apiconfig
         * instead.
         *
+        * @class mw.ForeignUpload
+        * @extends mw.Upload
+        *
         * @constructor
         * @param {string} [target] Used to set up the target
         *     wiki. If not remote, this class behaves identically to mw.Upload (unless further subclassed)
 
        /**
         * Override from mw.Upload to make sure the API info is found and allowed
+        *
+        * @inheritdoc
         */
        ForeignUpload.prototype.upload = function () {
                var upload = this;
 
        /**
         * Override from mw.Upload to make sure the API info is found and allowed
+        *
+        * @inheritdoc
         */
        ForeignUpload.prototype.uploadToStash = function () {
                var upload = this;
index e468768..9203e5e 100644 (file)
@@ -3,17 +3,15 @@
  * @author Timo Tijhof, 2011-2013
  * @since 1.18
  */
-( function ( mw, $ ) {
-       /*jshint latedef:false */
 
+/* eslint-disable no-use-before-define */
+
+( function ( mw, $ ) {
        /**
         * Parse titles into an object structure. Note that when using the constructor
         * directly, passing invalid titles will result in an exception. Use #newFromText to use the
         * logic directly and get null for invalid titles which is easier to work with.
         *
-        * @class mw.Title
-        */
-       /**
         * Note that in the constructor and #newFromText method, `namespace` is the **default** namespace
         * only, and can be overridden by a namespace prefix in `title`. If you do not want this behavior,
         * use #makeTitle. Compare:
@@ -30,7 +28,8 @@
         *     mw.Title.newFromText( 'Template:Foo', NS_TEMPLATE ).getPrefixedText(); // => 'Template:Foo'
         *     mw.Title.makeTitle( NS_TEMPLATE, 'Template:Foo' ).getPrefixedText();   // => 'Template:Template:Foo'
         *
-        * @method constructor
+        * @class mw.Title
+        * @constructor
         * @param {string} title Title of the page. If no second argument given,
         *  this will be searched for a namespace
         * @param {number} [namespace=NS_MAIN] If given, will used as default namespace for the given title
                this.title = parsed.title;
                this.ext = parsed.ext;
                this.fragment = parsed.fragment;
-
-               return this;
        }
 
        /* Private members */
 
+       // eslint-disable-next-line vars-on-top
        var
+               namespaceIds = mw.config.get( 'wgNamespaceIds' ),
 
-       namespaceIds = mw.config.get( 'wgNamespaceIds' ),
+               /**
+                * @private
+                * @static
+                * @property NS_MAIN
+                */
+               NS_MAIN = namespaceIds[ '' ],
 
-       /**
-        * @private
-        * @static
-        * @property NS_MAIN
-        */
-       NS_MAIN = namespaceIds[ '' ],
+               /**
+                * @private
+                * @static
+                * @property NS_TALK
+                */
+               NS_TALK = namespaceIds.talk,
 
-       /**
-        * @private
-        * @static
-        * @property NS_TALK
-        */
-       NS_TALK = namespaceIds.talk,
+               /**
+                * @private
+                * @static
+                * @property NS_SPECIAL
+                */
+               NS_SPECIAL = namespaceIds.special,
 
-       /**
-        * @private
-        * @static
-        * @property NS_SPECIAL
-        */
-       NS_SPECIAL = namespaceIds.special,
+               /**
+                * @private
+                * @static
+                * @property NS_MEDIA
+                */
+               NS_MEDIA = namespaceIds.media,
 
-       /**
-        * @private
-        * @static
-        * @property NS_MEDIA
-        */
-       NS_MEDIA = namespaceIds.media,
+               /**
+                * @private
+                * @static
+                * @property NS_FILE
+                */
+               NS_FILE = namespaceIds.file,
 
-       /**
-        * @private
-        * @static
-        * @property NS_FILE
-        */
-       NS_FILE = namespaceIds.file,
+               /**
+                * @private
+                * @static
+                * @property FILENAME_MAX_BYTES
+                */
+               FILENAME_MAX_BYTES = 240,
 
-       /**
-        * @private
-        * @static
-        * @property FILENAME_MAX_BYTES
-        */
-       FILENAME_MAX_BYTES = 240,
+               /**
+                * @private
+                * @static
+                * @property TITLE_MAX_BYTES
+                */
+               TITLE_MAX_BYTES = 255,
 
-       /**
-        * @private
-        * @static
-        * @property TITLE_MAX_BYTES
-        */
-       TITLE_MAX_BYTES = 255,
+               /**
+                * Get the namespace id from a namespace name (either from the localized, canonical or alias
+                * name).
+                *
+                * Example: On a German wiki this would return 6 for any of 'File', 'Datei', 'Image' or
+                * even 'Bild'.
+                *
+                * @private
+                * @static
+                * @method getNsIdByName
+                * @param {string} ns Namespace name (case insensitive, leading/trailing space ignored)
+                * @return {number|boolean} Namespace id or boolean false
+                */
+               getNsIdByName = function ( ns ) {
+                       var id;
+
+                       // Don't cast non-strings to strings, because null or undefined should not result in
+                       // returning the id of a potential namespace called "Null:" (e.g. on null.example.org/wiki)
+                       // Also, toLowerCase throws exception on null/undefined, because it is a String method.
+                       if ( typeof ns !== 'string' ) {
+                               return false;
+                       }
+                       // TODO: Should just use local var namespaceIds here but it
+                       // breaks test which modify the config
+                       id = mw.config.get( 'wgNamespaceIds' )[ ns.toLowerCase() ];
+                       if ( id === undefined ) {
+                               return false;
+                       }
+                       return id;
+               },
 
-       /**
-        * Get the namespace id from a namespace name (either from the localized, canonical or alias
-        * name).
-        *
-        * Example: On a German wiki this would return 6 for any of 'File', 'Datei', 'Image' or
-        * even 'Bild'.
-        *
-        * @private
-        * @static
-        * @method getNsIdByName
-        * @param {string} ns Namespace name (case insensitive, leading/trailing space ignored)
-        * @return {number|boolean} Namespace id or boolean false
-        */
-       getNsIdByName = function ( ns ) {
-               var id;
-
-               // Don't cast non-strings to strings, because null or undefined should not result in
-               // returning the id of a potential namespace called "Null:" (e.g. on null.example.org/wiki)
-               // Also, toLowerCase throws exception on null/undefined, because it is a String method.
-               if ( typeof ns !== 'string' ) {
-                       return false;
-               }
-               // TODO: Should just use local var namespaceIds here but it
-               // breaks test which modify the config
-               id = mw.config.get( 'wgNamespaceIds' )[ ns.toLowerCase() ];
-               if ( id === undefined ) {
-                       return false;
-               }
-               return id;
-       },
+               /**
+                * @private
+                * @method getNamespacePrefix_
+                * @param {number} namespace
+                * @return {string}
+                */
+               getNamespacePrefix = function ( namespace ) {
+                       return namespace === NS_MAIN ?
+                               '' :
+                               ( mw.config.get( 'wgFormattedNamespaces' )[ namespace ].replace( / /g, '_' ) + ':' );
+               },
 
-       /**
-        * @private
-        * @method getNamespacePrefix_
-        * @param {number} namespace
-        * @return {string}
-        */
-       getNamespacePrefix = function ( namespace ) {
-               return namespace === NS_MAIN ?
-                       '' :
-                       ( mw.config.get( 'wgFormattedNamespaces' )[ namespace ].replace( / /g, '_' ) + ':' );
-       },
-
-       rUnderscoreTrim = /^_+|_+$/g,
-
-       rSplit = /^(.+?)_*:_*(.*)$/,
-
-       // See MediaWikiTitleCodec.php#getTitleInvalidRegex
-       rInvalid = new RegExp(
-               '[^' + mw.config.get( 'wgLegalTitleChars' ) + ']' +
-               // URL percent encoding sequences interfere with the ability
-               // to round-trip titles -- you can't link to them consistently.
-               '|%[0-9A-Fa-f]{2}' +
-               // XML/HTML character references produce similar issues.
-               '|&[A-Za-z0-9\u0080-\uFFFF]+;' +
-               '|&#[0-9]+;' +
-               '|&#x[0-9A-Fa-f]+;'
-       ),
-
-       // From MediaWikiTitleCodec::splitTitleString() in PHP
-       // Note that this is not equivalent to /\s/, e.g. underscore is included, tab is not included.
-       rWhitespace = /[ _\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+/g,
-
-       // From MediaWikiTitleCodec::splitTitleString() in PHP
-       rUnicodeBidi = /[\u200E\u200F\u202A-\u202E]/g,
+               rUnderscoreTrim = /^_+|_+$/g,
 
-       /**
-        * Slightly modified from Flinfo. Credit goes to Lupo and Flominator.
-        * @private
-        * @static
-        * @property sanitationRules
-        */
-       sanitationRules = [
-               // "signature"
-               {
-                       pattern: /~{3}/g,
-                       replace: '',
-                       generalRule: true
-               },
-               // control characters
-               {
-                       pattern: /[\x00-\x1f\x7f]/g,
-                       replace: '',
-                       generalRule: true
-               },
-               // URL encoding (possibly)
-               {
-                       pattern: /%([0-9A-Fa-f]{2})/g,
-                       replace: '% $1',
-                       generalRule: true
-               },
-               // HTML-character-entities
-               {
-                       pattern: /&(([A-Za-z0-9\x80-\xff]+|#[0-9]+|#x[0-9A-Fa-f]+);)/g,
-                       replace: '& $1',
-                       generalRule: true
-               },
-               // slash, colon (not supported by file systems like NTFS/Windows, Mac OS 9 [:], ext4 [/])
-               {
-                       pattern: new RegExp( '[' + mw.config.get( 'wgIllegalFileChars', '' ) + ']', 'g' ),
-                       replace: '-',
-                       fileRule: true
-               },
-               // brackets, greater than
-               {
-                       pattern: /[\]\}>]/g,
-                       replace: ')',
-                       generalRule: true
-               },
-               // brackets, lower than
-               {
-                       pattern: /[\[\{<]/g,
-                       replace: '(',
-                       generalRule: true
-               },
-               // everything that wasn't covered yet
-               {
-                       pattern: new RegExp( rInvalid.source, 'g' ),
-                       replace: '-',
-                       generalRule: true
-               },
-               // directory structures
-               {
-                       pattern: /^(\.|\.\.|\.\/.*|\.\.\/.*|.*\/\.\/.*|.*\/\.\.\/.*|.*\/\.|.*\/\.\.)$/g,
-                       replace: '',
-                       generalRule: true
-               }
-       ],
+               rSplit = /^(.+?)_*:_*(.*)$/,
 
-       /**
-        * Internal helper for #constructor and #newFromText.
-        *
-        * Based on Title.php#secureAndSplit
-        *
-        * @private
-        * @static
-        * @method parse
-        * @param {string} title
-        * @param {number} [defaultNamespace=NS_MAIN]
-        * @return {Object|boolean}
-        */
-       parse = function ( title, defaultNamespace ) {
-               var namespace, m, id, i, fragment, ext;
+               // See MediaWikiTitleCodec.php#getTitleInvalidRegex
+               rInvalid = new RegExp(
+                       '[^' + mw.config.get( 'wgLegalTitleChars' ) + ']' +
+                       // URL percent encoding sequences interfere with the ability
+                       // to round-trip titles -- you can't link to them consistently.
+                       '|%[0-9A-Fa-f]{2}' +
+                       // XML/HTML character references produce similar issues.
+                       '|&[A-Za-z0-9\u0080-\uFFFF]+;' +
+                       '|&#[0-9]+;' +
+                       '|&#x[0-9A-Fa-f]+;'
+               ),
 
-               namespace = defaultNamespace === undefined ? NS_MAIN : defaultNamespace;
+               // From MediaWikiTitleCodec::splitTitleString() in PHP
+               // Note that this is not equivalent to /\s/, e.g. underscore is included, tab is not included.
+               rWhitespace = /[ _\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+/g,
 
-               title = title
-                       // Strip Unicode bidi override characters
-                       .replace( rUnicodeBidi, '' )
-                       // Normalise whitespace to underscores and remove duplicates
-                       .replace( rWhitespace, '_' )
-                       // Trim underscores
-                       .replace( rUnderscoreTrim, '' );
+               // From MediaWikiTitleCodec::splitTitleString() in PHP
+               rUnicodeBidi = /[\u200E\u200F\u202A-\u202E]/g,
+
+               /**
+                * Slightly modified from Flinfo. Credit goes to Lupo and Flominator.
+                * @private
+                * @static
+                * @property sanitationRules
+                */
+               sanitationRules = [
+                       // "signature"
+                       {
+                               pattern: /~{3}/g,
+                               replace: '',
+                               generalRule: true
+                       },
+                       // control characters
+                       {
+                               // eslint-disable-next-line no-control-regex
+                               pattern: /[\x00-\x1f\x7f]/g,
+                               replace: '',
+                               generalRule: true
+                       },
+                       // URL encoding (possibly)
+                       {
+                               pattern: /%([0-9A-Fa-f]{2})/g,
+                               replace: '% $1',
+                               generalRule: true
+                       },
+                       // HTML-character-entities
+                       {
+                               pattern: /&(([A-Za-z0-9\x80-\xff]+|#[0-9]+|#x[0-9A-Fa-f]+);)/g,
+                               replace: '& $1',
+                               generalRule: true
+                       },
+                       // slash, colon (not supported by file systems like NTFS/Windows, Mac OS 9 [:], ext4 [/])
+                       {
+                               pattern: new RegExp( '[' + mw.config.get( 'wgIllegalFileChars', '' ) + ']', 'g' ),
+                               replace: '-',
+                               fileRule: true
+                       },
+                       // brackets, greater than
+                       {
+                               pattern: /[\]\}>]/g,
+                               replace: ')',
+                               generalRule: true
+                       },
+                       // brackets, lower than
+                       {
+                               pattern: /[\[\{<]/g,
+                               replace: '(',
+                               generalRule: true
+                       },
+                       // everything that wasn't covered yet
+                       {
+                               pattern: new RegExp( rInvalid.source, 'g' ),
+                               replace: '-',
+                               generalRule: true
+                       },
+                       // directory structures
+                       {
+                               pattern: /^(\.|\.\.|\.\/.*|\.\.\/.*|.*\/\.\/.*|.*\/\.\.\/.*|.*\/\.|.*\/\.\.)$/g,
+                               replace: '',
+                               generalRule: true
+                       }
+               ],
+
+               /**
+                * Internal helper for #constructor and #newFromText.
+                *
+                * Based on Title.php#secureAndSplit
+                *
+                * @private
+                * @static
+                * @method parse
+                * @param {string} title
+                * @param {number} [defaultNamespace=NS_MAIN]
+                * @return {Object|boolean}
+                */
+               parse = function ( title, defaultNamespace ) {
+                       var namespace, m, id, i, fragment, ext;
+
+                       namespace = defaultNamespace === undefined ? NS_MAIN : defaultNamespace;
 
-               // Process initial colon
-               if ( title !== '' && title[ 0 ] === ':' ) {
-                       // Initial colon means main namespace instead of specified default
-                       namespace = NS_MAIN;
                        title = title
-                               // Strip colon
-                               .slice( 1 )
+                               // Strip Unicode bidi override characters
+                               .replace( rUnicodeBidi, '' )
+                               // Normalise whitespace to underscores and remove duplicates
+                               .replace( rWhitespace, '_' )
                                // Trim underscores
                                .replace( rUnderscoreTrim, '' );
-               }
 
-               if ( title === '' ) {
-                       return false;
-               }
+                       // Process initial colon
+                       if ( title !== '' && title[ 0 ] === ':' ) {
+                               // Initial colon means main namespace instead of specified default
+                               namespace = NS_MAIN;
+                               title = title
+                                       // Strip colon
+                                       .slice( 1 )
+                                       // Trim underscores
+                                       .replace( rUnderscoreTrim, '' );
+                       }
 
-               // Process namespace prefix (if any)
-               m = title.match( rSplit );
-               if ( m ) {
-                       id = getNsIdByName( m[ 1 ] );
-                       if ( id !== false ) {
-                               // Ordinary namespace
-                               namespace = id;
-                               title = m[ 2 ];
+                       if ( title === '' ) {
+                               return false;
+                       }
 
-                               // For Talk:X pages, make sure X has no "namespace" prefix
-                               if ( namespace === NS_TALK && ( m = title.match( rSplit ) ) ) {
-                                       // Disallow titles like Talk:File:x (subject should roundtrip: talk:file:x -> file:x -> file_talk:x)
-                                       if ( getNsIdByName( m[ 1 ] ) !== false ) {
-                                               return false;
+                       // Process namespace prefix (if any)
+                       m = title.match( rSplit );
+                       if ( m ) {
+                               id = getNsIdByName( m[ 1 ] );
+                               if ( id !== false ) {
+                                       // Ordinary namespace
+                                       namespace = id;
+                                       title = m[ 2 ];
+
+                                       // For Talk:X pages, make sure X has no "namespace" prefix
+                                       if ( namespace === NS_TALK && ( m = title.match( rSplit ) ) ) {
+                                               // Disallow titles like Talk:File:x (subject should roundtrip: talk:file:x -> file:x -> file_talk:x)
+                                               if ( getNsIdByName( m[ 1 ] ) !== false ) {
+                                                       return false;
+                                               }
                                        }
                                }
                        }
-               }
 
-               // Process fragment
-               i = title.indexOf( '#' );
-               if ( i === -1 ) {
-                       fragment = null;
-               } else {
-                       fragment = title
-                               // Get segment starting after the hash
-                               .slice( i + 1 )
-                               // Convert to text
-                               // NB: Must not be trimmed ("Example#_foo" is not the same as "Example#foo")
-                               .replace( /_/g, ' ' );
-
-                       title = title
-                               // Strip hash
-                               .slice( 0, i )
-                               // Trim underscores, again (strips "_" from "bar" in "Foo_bar_#quux")
-                               .replace( rUnderscoreTrim, '' );
-               }
+                       // Process fragment
+                       i = title.indexOf( '#' );
+                       if ( i === -1 ) {
+                               fragment = null;
+                       } else {
+                               fragment = title
+                                       // Get segment starting after the hash
+                                       .slice( i + 1 )
+                                       // Convert to text
+                                       // NB: Must not be trimmed ("Example#_foo" is not the same as "Example#foo")
+                                       .replace( /_/g, ' ' );
+
+                               title = title
+                                       // Strip hash
+                                       .slice( 0, i )
+                                       // Trim underscores, again (strips "_" from "bar" in "Foo_bar_#quux")
+                                       .replace( rUnderscoreTrim, '' );
+                       }
 
-               // Reject illegal characters
-               if ( title.match( rInvalid ) ) {
-                       return false;
-               }
+                       // Reject illegal characters
+                       if ( title.match( rInvalid ) ) {
+                               return false;
+                       }
 
-               // Disallow titles that browsers or servers might resolve as directory navigation
-               if (
-                       title.indexOf( '.' ) !== -1 && (
-                               title === '.' || title === '..' ||
-                               title.indexOf( './' ) === 0 ||
-                               title.indexOf( '../' ) === 0 ||
-                               title.indexOf( '/./' ) !== -1 ||
-                               title.indexOf( '/../' ) !== -1 ||
-                               title.slice( -2 ) === '/.' ||
-                               title.slice( -3 ) === '/..'
-                       )
-               ) {
-                       return false;
-               }
+                       // Disallow titles that browsers or servers might resolve as directory navigation
+                       if (
+                               title.indexOf( '.' ) !== -1 && (
+                                       title === '.' || title === '..' ||
+                                       title.indexOf( './' ) === 0 ||
+                                       title.indexOf( '../' ) === 0 ||
+                                       title.indexOf( '/./' ) !== -1 ||
+                                       title.indexOf( '/../' ) !== -1 ||
+                                       title.slice( -2 ) === '/.' ||
+                                       title.slice( -3 ) === '/..'
+                               )
+                       ) {
+                               return false;
+                       }
 
-               // Disallow magic tilde sequence
-               if ( title.indexOf( '~~~' ) !== -1 ) {
-                       return false;
-               }
+                       // Disallow magic tilde sequence
+                       if ( title.indexOf( '~~~' ) !== -1 ) {
+                               return false;
+                       }
 
-               // Disallow titles exceeding the TITLE_MAX_BYTES byte size limit (size of underlying database field)
-               // Except for special pages, e.g. [[Special:Block/Long name]]
-               // Note: The PHP implementation also asserts that even in NS_SPECIAL, the title should
-               // be less than 512 bytes.
-               if ( namespace !== NS_SPECIAL && $.byteLength( title ) > TITLE_MAX_BYTES ) {
-                       return false;
-               }
+                       // Disallow titles exceeding the TITLE_MAX_BYTES byte size limit (size of underlying database field)
+                       // Except for special pages, e.g. [[Special:Block/Long name]]
+                       // Note: The PHP implementation also asserts that even in NS_SPECIAL, the title should
+                       // be less than 512 bytes.
+                       if ( namespace !== NS_SPECIAL && $.byteLength( title ) > TITLE_MAX_BYTES ) {
+                               return false;
+                       }
 
-               // Can't make a link to a namespace alone.
-               if ( title === '' && namespace !== NS_MAIN ) {
-                       return false;
-               }
+                       // Can't make a link to a namespace alone.
+                       if ( title === '' && namespace !== NS_MAIN ) {
+                               return false;
+                       }
 
-               // Any remaining initial :s are illegal.
-               if ( title[ 0 ] === ':' ) {
-                       return false;
-               }
+                       // Any remaining initial :s are illegal.
+                       if ( title[ 0 ] === ':' ) {
+                               return false;
+                       }
 
-               // For backwards-compatibility with old mw.Title, we separate the extension from the
-               // rest of the title.
-               i = title.lastIndexOf( '.' );
-               if ( i === -1 || title.length <= i + 1 ) {
-                       // Extensions are the non-empty segment after the last dot
-                       ext = null;
-               } else {
-                       ext = title.slice( i + 1 );
-                       title = title.slice( 0, i );
-               }
+                       // For backwards-compatibility with old mw.Title, we separate the extension from the
+                       // rest of the title.
+                       i = title.lastIndexOf( '.' );
+                       if ( i === -1 || title.length <= i + 1 ) {
+                               // Extensions are the non-empty segment after the last dot
+                               ext = null;
+                       } else {
+                               ext = title.slice( i + 1 );
+                               title = title.slice( 0, i );
+                       }
 
-               return {
-                       namespace: namespace,
-                       title: title,
-                       ext: ext,
-                       fragment: fragment
-               };
-       },
+                       return {
+                               namespace: namespace,
+                               title: title,
+                               ext: ext,
+                               fragment: fragment
+                       };
+               },
 
-       /**
-        * Convert db-key to readable text.
-        *
-        * @private
-        * @static
-        * @method text
-        * @param {string} s
-        * @return {string}
-        */
-       text = function ( s ) {
-               if ( s !== null && s !== undefined ) {
-                       return s.replace( /_/g, ' ' );
-               } else {
-                       return '';
-               }
-       },
+               /**
+                * Convert db-key to readable text.
+                *
+                * @private
+                * @static
+                * @method text
+                * @param {string} s
+                * @return {string}
+                */
+               text = function ( s ) {
+                       if ( s !== null && s !== undefined ) {
+                               return s.replace( /_/g, ' ' );
+                       } else {
+                               return '';
+                       }
+               },
 
-       /**
-        * Sanitizes a string based on a rule set and a filter
-        *
-        * @private
-        * @static
-        * @method sanitize
-        * @param {string} s
-        * @param {Array} filter
-        * @return {string}
-        */
-       sanitize = function ( s, filter ) {
-               var i, ruleLength, rule, m, filterLength,
-                       rules = sanitationRules;
-
-               for ( i = 0, ruleLength = rules.length; i < ruleLength; ++i ) {
-                       rule = rules[ i ];
-                       for ( m = 0, filterLength = filter.length; m < filterLength; ++m ) {
-                               if ( rule[ filter[ m ] ] ) {
-                                       s = s.replace( rule.pattern, rule.replace );
+               /**
+                * Sanitizes a string based on a rule set and a filter
+                *
+                * @private
+                * @static
+                * @method sanitize
+                * @param {string} s
+                * @param {Array} filter
+                * @return {string}
+                */
+               sanitize = function ( s, filter ) {
+                       var i, ruleLength, rule, m, filterLength,
+                               rules = sanitationRules;
+
+                       for ( i = 0, ruleLength = rules.length; i < ruleLength; ++i ) {
+                               rule = rules[ i ];
+                               for ( m = 0, filterLength = filter.length; m < filterLength; ++m ) {
+                                       if ( rule[ filter[ m ] ] ) {
+                                               s = s.replace( rule.pattern, rule.replace );
+                                       }
                                }
                        }
-               }
-               return s;
-       },
-
-       /**
-        * Cuts a string to a specific byte length, assuming UTF-8
-        * or less, if the last character is a multi-byte one
-        *
-        * @private
-        * @static
-        * @method trimToByteLength
-        * @param {string} s
-        * @param {number} length
-        * @return {string}
-        */
-       trimToByteLength = function ( s, length ) {
-               var byteLength, chopOffChars, chopOffBytes;
-
-               // bytelength is always greater or equal to the length in characters
-               s = s.substr( 0, length );
-               while ( ( byteLength = $.byteLength( s ) ) > length ) {
-                       // Calculate how many characters can be safely removed
-                       // First, we need to know how many bytes the string exceeds the threshold
-                       chopOffBytes = byteLength - length;
-                       // A character in UTF-8 is at most 4 bytes
-                       // One character must be removed in any case because the
-                       // string is too long
-                       chopOffChars = Math.max( 1, Math.floor( chopOffBytes / 4 ) );
-                       s = s.substr( 0, s.length - chopOffChars );
-               }
-               return s;
-       },
+                       return s;
+               },
 
-       /**
-        * Cuts a file name to a specific byte length
-        *
-        * @private
-        * @static
-        * @method trimFileNameToByteLength
-        * @param {string} name without extension
-        * @param {string} extension file extension
-        * @return {string} The full name, including extension
-        */
-       trimFileNameToByteLength = function ( name, extension ) {
-               // There is a special byte limit for file names and ... remember the dot
-               return trimToByteLength( name, FILENAME_MAX_BYTES - extension.length - 1 ) + '.' + extension;
-       },
-
-       // Polyfill for ES5 Object.create
-       createObject = Object.create || ( function () {
-               return function ( o ) {
-                       function Title() {}
-                       if ( o !== Object( o ) ) {
-                               throw new Error( 'Cannot inherit from a non-object' );
+               /**
+                * Cuts a string to a specific byte length, assuming UTF-8
+                * or less, if the last character is a multi-byte one
+                *
+                * @private
+                * @static
+                * @method trimToByteLength
+                * @param {string} s
+                * @param {number} length
+                * @return {string}
+                */
+               trimToByteLength = function ( s, length ) {
+                       var byteLength, chopOffChars, chopOffBytes;
+
+                       // bytelength is always greater or equal to the length in characters
+                       s = s.substr( 0, length );
+                       while ( ( byteLength = $.byteLength( s ) ) > length ) {
+                               // Calculate how many characters can be safely removed
+                               // First, we need to know how many bytes the string exceeds the threshold
+                               chopOffBytes = byteLength - length;
+                               // A character in UTF-8 is at most 4 bytes
+                               // One character must be removed in any case because the
+                               // string is too long
+                               chopOffChars = Math.max( 1, Math.floor( chopOffBytes / 4 ) );
+                               s = s.substr( 0, s.length - chopOffChars );
                        }
-                       Title.prototype = o;
-                       return new Title();
-               };
-       }() );
+                       return s;
+               },
+
+               /**
+                * Cuts a file name to a specific byte length
+                *
+                * @private
+                * @static
+                * @method trimFileNameToByteLength
+                * @param {string} name without extension
+                * @param {string} extension file extension
+                * @return {string} The full name, including extension
+                */
+               trimFileNameToByteLength = function ( name, extension ) {
+                       // There is a special byte limit for file names and ... remember the dot
+                       return trimToByteLength( name, FILENAME_MAX_BYTES - extension.length - 1 ) + '.' + extension;
+               },
+
+               // Polyfill for ES5 Object.create
+               createObject = Object.create || ( function () {
+                       return function ( o ) {
+                               function Title() {}
+                               if ( o !== Object( o ) ) {
+                                       throw new Error( 'Cannot inherit from a non-object' );
+                               }
+                               Title.prototype = o;
+                               return new Title();
+                       };
+               }() );
 
        /* Static members */
 
                        }
                }
 
-               if ( namespace === NS_MEDIA
-                       || ( options.forUploading && ( namespace === NS_FILE ) )
+               if (
+                       namespace === NS_MEDIA ||
+                       ( options.forUploading && ( namespace === NS_FILE ) )
                ) {
 
                        title = sanitize( title, [ 'generalRule', 'fileRule' ] );
                pages: {},
 
                set: function ( titles, state ) {
+                       var i, len,
+                               pages = this.pages;
+
                        titles = $.isArray( titles ) ? titles : [ titles ];
                        state = state === undefined ? true : !!state;
-                       var i,
-                               pages = this.pages,
-                               len = titles.length;
 
-                       for ( i = 0; i < len; i++ ) {
+                       for ( i = 0, len = titles.length; i < len; i++ ) {
                                pages[ titles[ i ] ] = state;
                        }
                        return true;
index 1ea7e04..9d9c0a6 100644 (file)
@@ -29,6 +29,9 @@
         * @uses mw.Upload
         * @uses mw.Upload.BookletLayout
         * @extends OO.ui.ProcessDialog
+        *
+        * @constructor
+        * @param {Object} [config] Configuration options
         * @cfg {Function} [bookletClass=mw.Upload.BookletLayout] Booklet class to be
         *     used for the steps
         * @cfg {Object} [booklet] Booklet constructor configuration
@@ -57,7 +60,6 @@
         * @inheritdoc
         * @property title
         */
-       /*jshint -W024*/
        mw.Upload.Dialog.static.title = mw.msg( 'upload-dialog-title' );
 
        /**
@@ -84,7 +86,7 @@
                        modes: 'insert'
                },
                {
-                       flags: [ 'primary', 'constructive' ],
+                       flags: [ 'primary', 'progressive' ],
                        label: mw.msg( 'upload-dialog-button-save' ),
                        action: 'save',
                        modes: 'info'
@@ -97,8 +99,6 @@
                }
        ];
 
-       /*jshint +W024*/
-
        /* Methods */
 
        /**
         * @return {mw.Upload.BookletLayout} An upload booklet
         */
        mw.Upload.Dialog.prototype.createUploadBooklet = function () {
+               // eslint-disable-next-line new-cap
                return new this.bookletClass( $.extend( {
                        $overlay: this.$overlay
                }, this.bookletConfig ) );
index 23b0900..02df2a8 100644 (file)
@@ -2,8 +2,6 @@
        var UP;
 
        /**
-        * @class mw.Upload
-        *
         * Used to represent an upload in progress on the frontend.
         * Most of the functionality is implemented in mw.Api.plugin.upload,
         * but this model class will tie it together as well as let you perform
@@ -43,6 +41,8 @@
         *       } );
         *     } );
         *
+        * @class mw.Upload
+        *
         * @constructor
         * @param {Object|mw.Api} [apiconfig] A mw.Api object (or subclass), or configuration
         *     to pass to the constructor of mw.Api.
index 835b423..0c47dbe 100644 (file)
  * @class mw.Uri
  */
 
+/* eslint-disable no-use-before-define */
+
 ( function ( mw, $ ) {
+       var parser, properties;
+
        /**
         * Function that's useful when constructing the URI string -- we frequently encounter the pattern
         * of having to add something to the URI as we go, but only if it's present, and to include a
         * @static
         * @property {Object} parser
         */
-       var parser = {
+       parser = {
                strict: mw.template.get( 'mediawiki.Uri', 'strict.regexp' ).render(),
                loose: mw.template.get( 'mediawiki.Uri', 'loose.regexp' ).render()
-       },
+       };
 
        /**
         * The order here matches the order of captured matches in the `parser` property regexes.
         * @param {string|Function} documentLocation A full url, or function returning one.
         *  If passed a function, the return value may change over time and this will be honoured. (T74334)
         * @member mw
+        * @return {Function} Uri class
         */
        mw.UriRelative = function ( documentLocation ) {
                var getDefaultUri = ( function () {
index 4d0c135..e3a8f7b 100644 (file)
@@ -1,9 +1,5 @@
-/* jshint devel: true */
 ( function ( mw, $ ) {
        /**
-        * @method confirmCloseWindow
-        * @member mw
-        *
         * Prevent the closing of a window with a confirm message (the onbeforeunload event seems to
         * work in most browsers.)
         *
@@ -25,6 +21,8 @@
         *         // do whatever you wanted to do
         *     }
         *
+        * @method confirmCloseWindow
+        * @member mw
         * @param {Object} [options]
         * @param {string} [options.namespace] Namespace for the event registration
         * @param {string} [options.message]
                        }
                };
        };
-} )( mediaWiki, jQuery );
+}( mediaWiki, jQuery ) );
index 26c74a1..3c1a668 100644 (file)
                        }
 
                        bitDiv( 'phpversion' )
-                               .append( $( this.data.phpEngine === 'HHVM'
-                                       ? '<a href="http://hhvm.com/">HHVM</a>'
-                                       '<a href="https://php.net/">PHP</a>'
+                               .append( $( this.data.phpEngine === 'HHVM' ?
+                                       '<a href="http://hhvm.com/">HHVM</a>' :
+                                       '<a href="https://php.net/">PHP</a>'
                                ) )
                                .append( ': ' + this.data.phpVersion );
 
 
                /**
                 * Build the console panel
+                *
+                * @return {jQuery} Console panel
                 */
                buildConsoleTable: function () {
                        var $table, entryTypeText, i, length, entry;
                        $table = $( '<table id="mw-debug-querylist"></table>' );
 
                        $( '<tr>' )
-                               .append( $( '<th>#</th>' ).css( 'width', '4em' )    )
+                               .append( $( '<th>#</th>' ).css( 'width', '4em' ) )
                                .append( $( '<th>SQL</th>' ) )
-                               .append( $( '<th>Time</th>' ).css( 'width', '8em'  ) )
+                               .append( $( '<th>Time</th>' ).css( 'width', '8em' ) )
                                .append( $( '<th>Call</th>' ).css( 'width', '18em' ) )
                        .appendTo( $table );
 
index 46b8479..e86aff6 100644 (file)
                        /**
                         * Dumb window.onerror handler which forwards the errors via mw.track.
                         *
+                        * @param {string} errorMessage
+                        * @param {string} url
+                        * @param {number} lineNumber
+                        * @param {number} [columnNumber]
+                        * @param {Error|Mixed} [errorObject]
+                        * @return {boolean} True to prevent the default action
                         * @fires global_error
                         */
                        window.onerror = function ( errorMessage, url, lineNumber, columnNumber, errorObject ) {
index ad1069f..0c9ea97 100644 (file)
@@ -1,4 +1,3 @@
-/* jshint bitwise:false */
 ( function ( mw, $ ) {
 
        var CONTROL_BUCKET = 'control',
@@ -7,16 +6,17 @@
        /**
         * An implementation of Jenkins' one-at-a-time hash.
         *
-        * @see http://en.wikipedia.org/wiki/Jenkins_hash_function
+        * @see https://en.wikipedia.org/wiki/Jenkins_hash_function
         *
         * @param {string} string String to hash
         * @return {number} The hash as a 32-bit unsigned integer
         * @ignore
         *
         * @author Ori Livneh <ori@wikimedia.org>
-        * @see http://jsbin.com/kejewi/4/watch?js,console
+        * @see https://jsbin.com/kejewi/4/watch?js,console
         */
        function hashString( string ) {
+               /* eslint-disable no-bitwise */
                var hash = 0,
                        i = string.length;
 
@@ -30,6 +30,7 @@
                hash += ( hash << 15 );
 
                return hash >>> 0;
+               /* eslint-enable no-bitwise */
        }
 
        /**
index 170e124..6abdf83 100644 (file)
@@ -6,8 +6,6 @@
  * @author Moriel Schottlender, 2015
  * @since 1.19
  */
-/*jshint esversion:5 */
-/*global OO*/
 ( function ( mw, $ ) {
        /**
         * This is a way of getting simple feedback from users. It's useful
                                        ]
                                };
                                break;
-                       case 'error1':
-                       case 'error2':
-                       case 'error3':
-                       case 'error4':
-                               dialogConfig = {
-                                       title: mw.msg( 'feedback-error-title' ),
-                                       message: mw.msg( 'feedback-' + status ),
-                                       actions: [
-                                               {
-                                                       action: 'accept',
-                                                       label: mw.msg( 'feedback-close' ),
-                                                       flags: 'primary'
-                                               }
-                                       ]
-                               };
-                               break;
                }
 
                // Show the message dialog
                {
                        action: 'submit',
                        label: mw.msg( 'feedback-submit' ),
-                       flags: [ 'primary', 'constructive' ]
+                       flags: [ 'primary', 'progressive' ]
                },
                {
                        action: 'external',
                        label: mw.msg( 'feedback-external-bug-report-button' ),
-                       flags: 'constructive'
+                       flags: 'progressive'
                },
                {
                        action: 'cancel',
                                this.feedbackSubjectInput.getValue()
                        );
 
-               this.actions.setAbilities( { submit:  isValid } );
+               this.actions.setAbilities( { submit: isValid } );
        };
 
        /**
                                }, function () {
                                        fb.status = 'error4';
                                        mw.log.warn( 'Feedback report failed because MessagePoster could not be fetched' );
-                               } ).always( function () {
+                               } ).then( function () {
                                        fb.close();
+                               }, function () {
+                                       return fb.getErrorMessage();
                                } );
                        }, this );
                }
                return mw.Feedback.Dialog.parent.prototype.getActionProcess.call( this, action );
        };
 
+       /**
+        * Returns an error message for the current status.
+        *
+        * @private
+        *
+        * @return {OO.ui.Error}
+        */
+       mw.Feedback.Dialog.prototype.getErrorMessage = function () {
+               switch ( this.status ) {
+                       case 'error1':
+                       case 'error2':
+                       case 'error3':
+                       case 'error4':
+                               // Messages: feedback-error1, feedback-error2, feedback-error3, feedback-error4
+                               return new OO.ui.Error( mw.msg( 'feedback-' + this.status ) );
+               }
+       };
+
        /**
         * Posts the message
         *
                                if ( secondaryCode === 'http' ) {
                                        fb.status = 'error3';
                                        // ajax request failed
-                                       mw.log.warn( 'Feedback report failed with HTTP error: ' +  details.textStatus );
+                                       mw.log.warn( 'Feedback report failed with HTTP error: ' + details.textStatus );
                                } else {
                                        fb.status = 'error2';
-                                       mw.log.warn( 'Feedback report failed with API error: ' +  secondaryCode );
+                                       mw.log.warn( 'Feedback report failed with API error: ' + secondaryCode );
                                }
                        } else {
                                fb.status = 'error1';
index 882affe..72bf3d7 100644 (file)
@@ -4,7 +4,6 @@
  * @author Mark Holmquist, 2015
  * @since 1.25
  */
-/*global OO*/
 ( function ( mw, $, oo ) {
        var warningConfig = mw.config.get( 'wgFileWarning' ),
                warningMessages = warningConfig.messages,
index a74aef3..fdaa989 100644 (file)
@@ -4,7 +4,9 @@
  * @author Ori Livneh
  * @since 1.22
  */
-/*jshint devel:true */
+
+/* eslint-disable no-console */
+
 ( function ( mw, $ ) {
 
        var inspect,
        }
 
        function humanSize( bytes ) {
-               if ( !$.isNumeric( bytes ) || bytes === 0 ) { return bytes; }
-               var i = 0,
+               var i,
                        units = [ '', ' KiB', ' MiB', ' GiB', ' TiB', ' PiB' ];
 
-               for ( ; bytes >= 1024; bytes /= 1024 ) { i++; }
+               if ( !$.isNumeric( bytes ) || bytes === 0 ) { return bytes; }
+
+               for ( i = 0; bytes >= 1024; bytes /= 1024 ) { i++; }
                // Maintain one decimal for kB and above, but don't
                // add ".0" for bytes.
                return bytes.toFixed( i > 0 ? 1 : 0 ) + units[ i ];
                        /**
                         * Generate a breakdown of all loaded modules and their size in
                         * kilobytes. Modules are ordered from largest to smallest.
+                        *
+                        * @return {Object[]} Size reports
                         */
                        size: function () {
                                // Map each module to a descriptor object.
                        /**
                         * For each module with styles, count the number of selectors, and
                         * count how many match against some element currently in the DOM.
+                        *
+                        * @return {Object[]} CSS reports
                         */
                        css: function () {
                                var modules = [];
                                                allSelectors: stats.total,
                                                matchedSelectors: stats.matched,
                                                percentMatched: stats.total !== 0 ?
-                                                       ( stats.matched / stats.total * 100 ).toFixed( 2 )  + '%' : null
+                                                       ( stats.matched / stats.total * 100 ).toFixed( 2 ) + '%' : null
                                        } );
                                } );
                                sortByProperty( modules, 'allSelectors', true );
                         * Report stats on mw.loader.store: the number of localStorage
                         * cache hits and misses, the number of items purged from the
                         * cache, and the total size of the module blob in localStorage.
+                        *
+                        * @return {Object[]} Store stats
                         */
                        store: function () {
                                var raw, stats = { enabled: mw.loader.store.enabled };
                                        $.extend( stats, mw.loader.store.stats );
                                        try {
                                                raw = localStorage.getItem( mw.loader.store.getStoreKey() );
-                                               stats.totalSizeInBytes =  $.byteLength( raw );
+                                               stats.totalSizeInBytes = $.byteLength( raw );
                                                stats.totalSize = humanSize( $.byteLength( raw ) );
                                        } catch ( e ) {}
                                }
 
                                // Grep module's CSS
                                if (
-                                       $.isPlainObject( module.style ) && $.isArray( module.style.css )
-                                       && pattern.test( module.style.css.join( '' ) )
+                                       $.isPlainObject( module.style ) && $.isArray( module.style.css ) &&
+                                       pattern.test( module.style.css.join( '' ) )
                                ) {
                                        // Module's CSS source matches
                                        return true;
index 44b9117..c82b9cb 100644 (file)
        function getFailableParserFn( options ) {
                return function ( args ) {
                        var fallback,
+                               // eslint-disable-next-line new-cap
                                parser = new mw.jqueryMsg.parser( options ),
                                key = args[ 0 ],
                                argsArray = $.isArray( args[ 1 ] ) ? args[ 1 ] : slice.call( args, 1 );
                }
 
                return function () {
+                       var failableResult;
                        if ( !failableParserFn ) {
                                failableParserFn = getFailableParserFn( options );
                        }
-                       var failableResult = failableParserFn( arguments );
+                       failableResult = failableParserFn( arguments );
                        if ( format === 'text' || format === 'escaped' ) {
                                return failableResult.text();
                        } else {
                var failableParserFn;
 
                return function () {
+                       var $target;
                        if ( !failableParserFn ) {
                                failableParserFn = getFailableParserFn( options );
                        }
-                       var $target = this.empty();
+                       $target = this.empty();
                        appendWithoutParsing( $target, failableParserFn( arguments ) );
                        return $target;
                };
                this.settings.onlyCurlyBraceTransform = ( this.settings.format === 'text' || this.settings.format === 'escaped' );
                this.astCache = {};
 
+               // eslint-disable-next-line new-cap
                this.emitter = new mw.jqueryMsg.htmlEmitter( this.settings.language, this.settings.magic );
        };
 
 
                /**
                 * Fetch the message string associated with a key, return parsed structure. Memoized.
-                * Note that we pass '[' + key + ']' back for a missing message here.
+                * Note that we pass '⧼' + key + '⧽' back for a missing message here.
                 *
                 * @param {string} key
-                * @return {string|Array} string of '[key]' if message missing, simple string if possible, array of arrays if needs parsing
+                * @return {string|Array} string of '⧼key⧽' if message missing, simple string if possible, array of arrays if needs parsing
                 */
                getAst: function ( key ) {
                        var wikiText;
                        if ( !this.astCache.hasOwnProperty( key ) ) {
                                wikiText = this.settings.messages.get( key );
                                if ( typeof wikiText !== 'string' ) {
-                                       wikiText = '\\[' + key + '\\]';
+                                       wikiText = '⧼' + key + '⧽';
                                }
                                this.astCache[ key ] = this.wikiTextToAst( wikiText );
                        }
                        /**
                         * Starts the parse
                         *
-                        * @param {Function} rootExpression root parse function
+                        * @param {Function} rootExpression Root parse function
+                        * @return {Array|null}
                         */
                        function start( rootExpression ) {
                                var result = nOrMore( 0, rootExpression )();
 
        /**
         * htmlEmitter - object which primarily exists to emit HTML from parser ASTs
+        *
+        * @param {Object} language
+        * @param {Object} magic
         */
        mw.jqueryMsg.htmlEmitter = function ( language, magic ) {
-               this.language = language;
                var jmsg = this;
+               this.language = language;
                $.each( magic, function ( key, val ) {
                        jmsg[ key.toLowerCase() ] = function () {
                                return val;
                 * It may, though, if the wikitext appears in extension-controlled content.
                 *
                 * @param {string[]} nodes
+                * @return {jQuery}
                 */
                wikilink: function ( nodes ) {
                        var page, anchor, url, $el;
                        } else {
                                $el = $( '<a>' );
                                if ( typeof arg === 'function' ) {
-                                       $el.attr( 'href', '#' )
-                                       .click( function ( e ) {
-                                               e.preventDefault();
+                                       $el.attr( {
+                                               role: 'button',
+                                               tabindex: 0
                                        } )
-                                       .click( arg );
+                                       .on( 'click keypress', function ( e ) {
+                                               if (
+                                                       e.type === 'click' ||
+                                                       e.type === 'keypress' && e.which === 13
+                                               ) {
+                                                       arg.call( this, e );
+                                               }
+                                       } );
                                } else {
                                        $el.attr( 'href', textify( arg ) );
                                }
                 * @return {number|string} Formatted number
                 */
                formatnum: function ( nodes ) {
-                       var isInteger = ( nodes[ 1 ] && nodes[ 1 ] === 'R' ) ? true : false,
+                       var isInteger = !!nodes[ 1 ] && nodes[ 1 ] === 'R',
                                number = nodes[ 0 ];
 
                        return this.language.convertNumber( number, isInteger );
                return function () {
                        return reusableParent.msg( this.key, this.parameters ).contents().detach();
                };
-       } )();
+       }() );
 
 }( mediaWiki, jQuery ) );
index 3122d42..2d73042 100644 (file)
@@ -7,7 +7,9 @@
  * @alternateClassName mediaWiki
  * @singleton
  */
-/*jshint latedef:false */
+
+/* eslint-disable no-use-before-define */
+
 ( function ( $ ) {
        'use strict';
 
@@ -31,7 +33,7 @@
         * @return {string} hash as an seven-character base 36 string
         */
        function fnv132( str ) {
-               /*jshint bitwise:false */
+               /* eslint-disable no-bitwise */
                var hash = 0x811C9DC5,
                        i;
 
@@ -46,6 +48,7 @@
                }
 
                return hash;
+               /* eslint-enable no-bitwise */
        }
 
        StringSet = window.Set || ( function () {
        }() );
 
        /**
-        * Create an object that can be read from or written to from methods that allow
+        * Create an object that can be read from or written to via methods that allow
         * interaction both with single and multiple properties at once.
         *
-        *     @example
-        *
-        *     var collection, query, results;
-        *
-        *     // Create your address book
-        *     collection = new mw.Map();
-        *
-        *     // This data could be coming from an external source (eg. API/AJAX)
-        *     collection.set( {
-        *         'John Doe': 'john@example.org',
-        *         'Jane Doe': 'jane@example.org',
-        *         'George van Halen': 'gvanhalen@example.org'
-        *     } );
-        *
-        *     wanted = ['John Doe', 'Jane Doe', 'Daniel Jackson'];
-        *
-        *     // You can detect missing keys first
-        *     if ( !collection.exists( wanted ) ) {
-        *         // One or more are missing (in this case: "Daniel Jackson")
-        *         mw.log( 'One or more names were not found in your address book' );
-        *     }
-        *
-        *     // Or just let it give you what it can. Optionally fill in from a default.
-        *     results = collection.get( wanted, 'nobody@example.com' );
-        *     mw.log( results['Jane Doe'] ); // "jane@example.org"
-        *     mw.log( results['Daniel Jackson'] ); // "nobody@example.com"
-        *
+        * @private
         * @class mw.Map
         *
         * @constructor
-        * @param {Object|boolean} [values] The value-baring object to be mapped. Defaults to an
-        *  empty object.
-        *  For backwards-compatibility with mw.config, this can also be `true` in which case values
-        *  are copied to the Window object as global variables (T72470). Values are copied in
-        *  one direction only. Changes to globals are not reflected in the map.
+        * @param {boolean} [global=false] Whether to synchronise =values to the global
+        *  window object (for backwards-compatibility with mw.config; T72470). Values are
+        *  copied in one direction only. Changes to globals do not reflect in the map.
         */
-       function Map( values ) {
-               if ( values === true ) {
-                       this.values = {};
+       function Map( global ) {
+               this.internalValues = {};
+               if ( global === true ) {
 
                        // Override #set to also set the global variable
                        this.set = function ( selection, value ) {
                                }
                                return false;
                        };
-
-                       return;
                }
 
-               this.values = values || {};
+               // Deprecated since MediaWiki 1.28
+               log.deprecate(
+                       this,
+                       'values',
+                       this.internalValues,
+                       'mw.Map#values is deprecated. Use mw.Map#get() instead.',
+                       'Map-values'
+               );
        }
 
        /**
         * @param {Mixed} value
         */
        function setGlobalMapValue( map, key, value ) {
-               map.values[ key ] = value;
-               mw.log.deprecate(
+               map.internalValues[ key ] = value;
+               log.deprecate(
                                window,
                                key,
                                value,
        }
 
        Map.prototype = {
+               constructor: Map,
+
                /**
                 * Get the value of one or more keys.
                 *
                 * @param {Mixed} [fallback=null] Value for keys that don't exist.
                 * @return {Mixed|Object| null} If selection was a string, returns the value,
                 *  If selection was an array, returns an object of key/values.
-                *  If no selection is passed, the 'values' container is returned. (Beware that,
+                *  If no selection is passed, the internal container is returned. (Beware that,
                 *  as is the default in JavaScript, the object is returned by reference.)
                 */
                get: function ( selection, fallback ) {
                        }
 
                        if ( typeof selection === 'string' ) {
-                               if ( !hasOwn.call( this.values, selection ) ) {
+                               if ( !hasOwn.call( this.internalValues, selection ) ) {
                                        return fallback;
                                }
-                               return this.values[ selection ];
+                               return this.internalValues[ selection ];
                        }
 
                        if ( selection === undefined ) {
-                               return this.values;
+                               return this.internalValues;
                        }
 
                        // Invalid selection key
 
                        if ( $.isPlainObject( selection ) ) {
                                for ( s in selection ) {
-                                       this.values[ s ] = selection[ s ];
+                                       this.internalValues[ s ] = selection[ s ];
                                }
                                return true;
                        }
                        if ( typeof selection === 'string' && arguments.length > 1 ) {
-                               this.values[ selection ] = value;
+                               this.internalValues[ selection ] = value;
                                return true;
                        }
                        return false;
 
                        if ( $.isArray( selection ) ) {
                                for ( s = 0; s < selection.length; s++ ) {
-                                       if ( typeof selection[ s ] !== 'string' || !hasOwn.call( this.values, selection[ s ] ) ) {
+                                       if ( typeof selection[ s ] !== 'string' || !hasOwn.call( this.internalValues, selection[ s ] ) ) {
                                                return false;
                                        }
                                }
                                return true;
                        }
-                       return typeof selection === 'string' && hasOwn.call( this.values, selection );
+                       return typeof selection === 'string' && hasOwn.call( this.internalValues, selection );
                }
        };
 
                        return mw.format.apply( null, [ this.map.get( this.key ) ].concat( this.parameters ) );
                },
 
+               // eslint-disable-next-line valid-jsdoc
                /**
                 * Add (does not replace) parameters for `$N` placeholder values.
                 *
                        var text;
 
                        if ( !this.exists() ) {
-                               // Use <key> as text if key does not exist
-                               if ( this.format === 'escaped' || this.format === 'parse' ) {
-                                       // format 'escaped' and 'parse' need to have the brackets and key html escaped
-                                       return mw.html.escape( '<' + this.key + '>' );
-                               }
-                               return '<' + this.key + '>';
+                               // Use ⧼key⧽ as text if key does not exist
+                               // Err on the side of safety, ensure that the output
+                               // is always html safe in the event the message key is
+                               // missing, since in that case its highly likely the
+                               // message key is user-controlled.
+                               // '⧼' is used instead of '<' to side-step any
+                               // double-escaping issues.
+                               // (Keep synchronised with Message::toString() in PHP.)
+                               return '⧼' + mw.html.escape( this.key ) + '⧽';
                        }
 
                        if ( this.format === 'plain' || this.format === 'text' || this.format === 'parse' ) {
                }
        };
 
+       /* eslint-disable no-console */
        log = ( function () {
                // Also update the restoration of methods in mediawiki.log.js
                // when adding or removing methods here.
                 * @param {string} key Name of property to create in `obj`
                 * @param {Mixed} val The value this property should return when accessed
                 * @param {string} [msg] Optional text to include in the deprecation message
+                * @param {string} [logName=key] Optional custom name for the feature.
+                *  This is used instead of `key` in the message and `mw.deprecate` tracking.
                 */
                log.deprecate = !Object.defineProperty ? function ( obj, key, val ) {
                        obj[ key ] = val;
-               } : function ( obj, key, val, msg ) {
-                       msg = 'Use of "' + key + '" is deprecated.' + ( msg ? ( ' ' + msg ) : '' );
+               } : function ( obj, key, val, msg, logName ) {
                        var logged = new StringSet();
+                       logName = logName || key;
+                       msg = 'Use of "' + logName + '" is deprecated.' + ( msg ? ( ' ' + msg ) : '' );
                        function uniqueTrace() {
                                var trace = new Error().stack;
                                if ( logged.has( trace ) ) {
                                logged.add( trace );
                                return true;
                        }
-                       Object.defineProperty( obj, key, {
-                               configurable: true,
-                               enumerable: true,
-                               get: function () {
-                                       if ( uniqueTrace() ) {
-                                               mw.track( 'mw.deprecate', key );
-                                               mw.log.warn( msg );
-                                       }
-                                       return val;
-                               },
-                               set: function ( newVal ) {
-                                       if ( uniqueTrace() ) {
-                                               mw.track( 'mw.deprecate', key );
-                                               mw.log.warn( msg );
+                       // Support: Safari 5.0
+                       // Throws "not supported on DOM Objects" for Node or Element objects (incl. document)
+                       // Safari 4.0 doesn't have this method, and it was fixed in Safari 5.1.
+                       try {
+                               Object.defineProperty( obj, key, {
+                                       configurable: true,
+                                       enumerable: true,
+                                       get: function () {
+                                               if ( uniqueTrace() ) {
+                                                       mw.track( 'mw.deprecate', logName );
+                                                       mw.log.warn( msg );
+                                               }
+                                               return val;
+                                       },
+                                       set: function ( newVal ) {
+                                               if ( uniqueTrace() ) {
+                                                       mw.track( 'mw.deprecate', logName );
+                                                       mw.log.warn( msg );
+                                               }
+                                               val = newVal;
                                        }
-                                       val = newVal;
-                               }
-                       } );
-
+                               } );
+                       } catch ( err ) {
+                               obj[ key ] = val;
+                       }
                };
 
                return log;
        }() );
+       /* eslint-enable no-console */
 
        /**
         * @class mw
                                }
 
                                if ( registry[ module ].skip !== null ) {
-                                       /*jshint evil:true */
+                                       // eslint-disable-next-line no-new-func
                                        skip = new Function( registry[ module ].skip );
                                        registry[ module ].skip = null;
                                        if ( skip() ) {
                                                        ) );
                                                }
 
-                                               unresolved.add(  module );
+                                               unresolved.add( module );
                                                sortDependencies( deps[ i ], resolved, unresolved );
                                        }
                                }
                         * @private
                         * @param {string[]} modules Array of string module names
                         * @return {Array} List of dependencies, including 'module'.
+                        * @throws {Error} If an unregistered module or a dependency loop is encountered
                         */
                        function resolve( modules ) {
                                var resolved = [];
 
                                pendingRequests.push( function () {
                                        if ( moduleName && hasOwn.call( registry, moduleName ) ) {
+                                               // Emulate runScript() part of execute()
                                                window.require = mw.loader.require;
                                                window.module = registry[ moduleName ].module;
                                        }
                                        addScript( src ).always( function () {
-                                               // Clear environment
-                                               delete window.require;
+                                               // 'module.exports' should not persist after the file is executed to
+                                               // avoid leakage to unrelated code. 'require' should be kept, however,
+                                               // as asynchronous access to 'require' is allowed and expected. (T144879)
                                                delete window.module;
                                                r.resolve();
 
                         * Utility function for execute()
                         *
                         * @ignore
+                        * @param {string} [media] Media attribute
+                        * @param {string} url URL
                         */
                        function addLink( media, url ) {
                                var el = document.createElement( 'link' );
                                                } );
                                        };
 
-                                       implicitDependencies = ( $.inArray( module, legacyModules ) !== -1 )
-                                               ? []
-                                               legacyModules;
+                                       implicitDependencies = ( $.inArray( module, legacyModules ) !== -1 ) ?
+                                               [] :
+                                               legacyModules;
 
                                        if ( module === 'user' ) {
                                                // Implicit dependency on the site module. Not real dependency because
                                                implicitDependencies.push( 'site' );
                                        }
 
-                                       legacyWait = implicitDependencies.length
-                                               ? mw.loader.using( implicitDependencies )
-                                               $.Deferred().resolve();
+                                       legacyWait = implicitDependencies.length ?
+                                               mw.loader.using( implicitDependencies ) :
+                                               $.Deferred().resolve();
 
                                        legacyWait.always( function () {
                                                try {
                         * to a query string of the form foo.bar,baz|bar.baz,quux
                         *
                         * @private
+                        * @param {Object} moduleMap Module map
+                        * @return {string} Module query string
                         */
                        function buildModulesString( moduleMap ) {
                                var p, prefix,
                                                        prefix = modules[ i ].substr( 0, lastDotIndex );
                                                        suffix = modules[ i ].slice( lastDotIndex + 1 );
 
-                                                       bytesAdded = hasOwn.call( moduleMap, prefix )
-                                                               ? suffix.length + 3 // '%2C'.length == 3
-                                                               modules[ i ].length + 3; // '%7C'.length == 3
+                                                       bytesAdded = hasOwn.call( moduleMap, prefix ) ?
+                                                               suffix.length + 3 : // '%2C'.length == 3
+                                                               modules[ i ].length + 3; // '%7C'.length == 3
 
                                                        // If the url would become too long, create a new one,
                                                        // but don't create empty requests
                                }
                        }
 
+                       /**
+                        * @private
+                        * @param {string[]} implementations Array containing pieces of JavaScript code in the
+                        *  form of calls to mw.loader#implement().
+                        * @param {Function} cb Callback in case of failure
+                        * @param {Error} cb.err
+                        */
+                       function asyncEval( implementations, cb ) {
+                               if ( !implementations.length ) {
+                                       return;
+                               }
+                               mw.requestIdleCallback( function () {
+                                       try {
+                                               $.globalEval( implementations.join( ';' ) );
+                                       } catch ( err ) {
+                                               cb( err );
+                                       }
+                               } );
+                       }
+
+                       /**
+                        * Make a versioned key for a specific module.
+                        *
+                        * @private
+                        * @param {string} module Module name
+                        * @return {string|null} Module key in format '`[name]@[version]`',
+                        *  or null if the module does not exist
+                        */
+                       function getModuleKey( module ) {
+                               return hasOwn.call( registry, module ) ?
+                                       ( module + '@' + registry[ module ].version ) : null;
+                       }
+
+                       /**
+                        * @private
+                        * @param {string} key Module name or '`[name]@[version]`'
+                        * @return {Object}
+                        */
+                       function splitModuleKey( key ) {
+                               var index = key.indexOf( '@' );
+                               if ( index === -1 ) {
+                                       return { name: key };
+                               }
+                               return {
+                                       name: key.slice( 0, index ),
+                                       version: key.slice( index + 1 )
+                               };
+                       }
+
                        /* Public Members */
                        return {
                                /**
                                 * @protected
                                 */
                                work: function () {
-                                       var q, batch, concatSource, origBatch;
+                                       var q, batch, implementations, sourceModules;
 
                                        batch = [];
 
 
                                        mw.loader.store.init();
                                        if ( mw.loader.store.enabled ) {
-                                               concatSource = [];
-                                               origBatch = batch;
+                                               implementations = [];
+                                               sourceModules = [];
                                                batch = $.grep( batch, function ( module ) {
-                                                       var source = mw.loader.store.get( module );
-                                                       if ( source ) {
-                                                               concatSource.push( source );
+                                                       var implementation = mw.loader.store.get( module );
+                                                       if ( implementation ) {
+                                                               implementations.push( implementation );
+                                                               sourceModules.push( module );
                                                                return false;
                                                        }
                                                        return true;
                                                } );
-                                               try {
-                                                       $.globalEval( concatSource.join( ';' ) );
-                                               } catch ( err ) {
+                                               asyncEval( implementations, function ( err ) {
+                                                       var failed;
                                                        // Not good, the cached mw.loader.implement calls failed! This should
                                                        // never happen, barring ResourceLoader bugs, browser bugs and PEBKACs.
                                                        // Depending on how corrupt the string is, it is likely that some
                                                        // modules' implement() succeeded while the ones after the error will
                                                        // never run and leave their modules in the 'loading' state forever.
+                                                       mw.loader.store.stats.failed++;
 
                                                        // Since this is an error not caused by an individual module but by
                                                        // something that infected the implement call itself, don't take any
                                                        // risks and clear everything in this cache.
                                                        mw.loader.store.clear();
-                                                       // Re-add the ones still pending back to the batch and let the server
-                                                       // repopulate these modules to the cache.
-                                                       // This means that at most one module will be useless (the one that had
-                                                       // the error) instead of all of them.
+
                                                        mw.track( 'resourceloader.exception', { exception: err, source: 'store-eval' } );
-                                                       origBatch = $.grep( origBatch, function ( module ) {
+                                                       // Re-add the failed ones that are still pending back to the batch
+                                                       failed = $.grep( sourceModules, function ( module ) {
                                                                return registry[ module ].state === 'loading';
                                                        } );
-                                                       batch = batch.concat( origBatch );
-                                               }
+                                                       batchRequest( failed );
+                                               } );
                                        }
 
                                        batchRequest( batch );
                                 * When #load() or #using() requests one or more modules, the server
                                 * response contain calls to this function.
                                 *
-                                * @param {string} module Name of module
+                                * @param {string} module Name of module and current module version. Formatted
+                                *  as '`[name]@[version]`". This version should match the requested version
+                                *  (from #batchRequest and #registry). This avoids race conditions (T117587).
+                                *  For back-compat with MediaWiki 1.27 and earlier, the version may be omitted.
                                 * @param {Function|Array|string} [script] Function with module code, list of URLs
                                 *  to load via `<script src>`, or string of module code for `$.globalEval()`.
                                 * @param {Object} [style] Should follow one of the following patterns:
                                 * @param {Object} [templates] List of key/value pairs to be added to mw#templates.
                                 */
                                implement: function ( module, script, style, messages, templates ) {
+                                       var split = splitModuleKey( module ),
+                                               name = split.name,
+                                               version = split.version;
                                        // Automatically register module
-                                       if ( !hasOwn.call( registry, module ) ) {
-                                               mw.loader.register( module );
+                                       if ( !hasOwn.call( registry, name ) ) {
+                                               mw.loader.register( name );
                                        }
                                        // Check for duplicate implementation
-                                       if ( hasOwn.call( registry, module ) && registry[ module ].script !== undefined ) {
-                                               throw new Error( 'module already implemented: ' + module );
+                                       if ( hasOwn.call( registry, name ) && registry[ name ].script !== undefined ) {
+                                               throw new Error( 'module already implemented: ' + name );
+                                       }
+                                       if ( version ) {
+                                               // Without this reset, if there is a version mismatch between the
+                                               // requested and received module version, then mw.loader.store would
+                                               // cache the response under the requested key. Thus poisoning the cache
+                                               // indefinitely with a stale value. (T117587)
+                                               registry[ name ].version = version;
                                        }
                                        // Attach components
-                                       registry[ module ].script = script || null;
-                                       registry[ module ].style = style || null;
-                                       registry[ module ].messages = messages || null;
-                                       registry[ module ].templates = templates || null;
+                                       registry[ name ].script = script || null;
+                                       registry[ name ].style = style || null;
+                                       registry[ name ].messages = messages || null;
+                                       registry[ name ].templates = templates || null;
                                        // The module may already have been marked as erroneous
-                                       if ( $.inArray( registry[ module ].state, [ 'error', 'missing' ] ) === -1 ) {
-                                               registry[ module ].state = 'loaded';
-                                               if ( allReady( registry[ module ].dependencies ) ) {
-                                                       execute( module );
+                                       if ( $.inArray( registry[ name ].state, [ 'error', 'missing' ] ) === -1 ) {
+                                               registry[ name ].state = 'loaded';
+                                               if ( allReady( registry[ name ].dependencies ) ) {
+                                                       execute( name );
                                                }
                                        }
                                },
                                                deferred.fail( error );
                                        }
 
-                                       // Resolve entire dependency map
-                                       dependencies = resolve( dependencies );
+                                       try {
+                                               // Resolve entire dependency map
+                                               dependencies = resolve( dependencies );
+                                       } catch ( e ) {
+                                               return deferred.reject( e ).promise();
+                                       }
                                        if ( allReady( dependencies ) ) {
                                                // Run ready immediately
                                                deferred.resolve( mw.loader.require );
                                 *
                                 * @protected
                                 * @since 1.27
+                                * @param {string} moduleName Module name
+                                * @return {Mixed} Exported value
                                 */
                                require: function ( moduleName ) {
                                        var state = mw.loader.getState( moduleName );
 
                                        MODULE_SIZE_MAX: 100 * 1000,
 
-                                       // The contents of the store, mapping '[module name]@[version]' keys
+                                       // The contents of the store, mapping '[name]@[version]' keys
                                        // to module implementations.
                                        items: {},
 
                                        // Cache hit stats
-                                       stats: { hits: 0, misses: 0, expired: 0 },
+                                       stats: { hits: 0, misses: 0, expired: 0, failed: 0 },
 
                                        /**
                                         * Construct a JSON-serializable object representing the content of the store.
                                                ].join( ':' );
                                        },
 
-                                       /**
-                                        * Get a key for a specific module. The key format is '[name]@[version]'.
-                                        *
-                                        * @param {string} module Module name
-                                        * @return {string|null} Module key or null if module does not exist
-                                        */
-                                       getModuleKey: function ( module ) {
-                                               return hasOwn.call( registry, module ) ?
-                                                       ( module + '@' + registry[ module ].version ) : null;
-                                       },
-
                                        /**
                                         * Initialize the store.
                                         *
                                                        return false;
                                                }
 
-                                               key = mw.loader.store.getModuleKey( module );
+                                               key = getModuleKey( module );
                                                if ( key in mw.loader.store.items ) {
                                                        mw.loader.store.stats.hits++;
                                                        return mw.loader.store.items[ key ];
                                         *
                                         * @param {string} module Module name
                                         * @param {Object} descriptor The module's descriptor as set in the registry
+                                        * @return {boolean} Module was set
                                         */
                                        set: function ( module, descriptor ) {
                                                var args, key, src;
                                                        return false;
                                                }
 
-                                               key = mw.loader.store.getModuleKey( module );
+                                               key = getModuleKey( module );
 
                                                if (
                                                        // Already stored a copy of this exact version
                                                        // Partial descriptor
                                                        // (e.g. skipped module, or style module with state=ready)
                                                        $.inArray( undefined, [ descriptor.script, descriptor.style,
-                                                                       descriptor.messages, descriptor.templates ] ) !== -1
+                                                               descriptor.messages, descriptor.templates ] ) !== -1
                                                ) {
                                                        // Decline to store
                                                        return false;
 
                                                try {
                                                        args = [
-                                                               JSON.stringify( module ),
+                                                               JSON.stringify( key ),
                                                                typeof descriptor.script === 'function' ?
                                                                        String( descriptor.script ) :
                                                                        JSON.stringify( descriptor.script ),
                                                        }
                                                } catch ( e ) {
                                                        mw.track( 'resourceloader.exception', { exception: e, source: 'store-localstorage-json' } );
-                                                       return;
+                                                       return false;
                                                }
 
                                                src = 'mw.loader.implement(' + args.join( ',' ) + ');';
                                                }
                                                mw.loader.store.items[ key ] = src;
                                                mw.loader.store.update();
+                                               return true;
                                        },
 
                                        /**
                                         * Iterate through the module store, removing any item that does not correspond
                                         * (in name and version) to an item in the module registry.
+                                        *
+                                        * @return {boolean} Store was pruned
                                         */
                                        prune: function () {
                                                var key, module;
 
                                                for ( key in mw.loader.store.items ) {
                                                        module = key.slice( 0, key.indexOf( '@' ) );
-                                                       if ( mw.loader.store.getModuleKey( module ) !== key ) {
+                                                       if ( getModuleKey( module ) !== key ) {
                                                                mw.loader.store.stats.expired++;
                                                                delete mw.loader.store.items[ key ];
                                                        } else if ( mw.loader.store.items[ key ].length > mw.loader.store.MODULE_SIZE_MAX ) {
                                                                delete mw.loader.store.items[ key ];
                                                        }
                                                }
+                                               return true;
                                        },
 
                                        /**
                                 *  - this.Raw: The raw value is directly included.
                                 *  - this.Cdata: The raw value is directly included. An exception is
                                 *    thrown if it contains any illegal ETAGO delimiter.
-                                *    See <http://www.w3.org/TR/html401/appendix/notes.html#h-B.3.2>.
+                                *    See <https://www.w3.org/TR/html401/appendix/notes.html#h-B.3.2>.
                                 * @return {string} HTML
                                 */
                                element: function ( name, attrs, contents ) {
                                 * Wrapper object for raw HTML passed to mw.html.element().
                                 *
                                 * @class mw.html.Raw
+                                * @constructor
+                                * @param {string} value
                                 */
                                Raw: function ( value ) {
                                        this.value = value;
                                 * Wrapper object for CDATA element contents passed to mw.html.element()
                                 *
                                 * @class mw.html.Cdata
+                                * @constructor
+                                * @param {string} value
                                 */
                                Cdata: function ( value ) {
                                        this.value = value;
                                         */
                                        remove: list.remove,
 
+                                       // eslint-disable-next-line valid-jsdoc
                                        /**
                                         * Run a hook.
                                         *
         * @param {string} [data.module] Name of module which caused the error
         */
        function logError( topic, data ) {
+               /* eslint-disable no-console */
                var msg,
                        e = data.exception,
                        source = data.source,
                                console.error( String( e ), e );
                        }
                }
+               /* eslint-enable no-console */
        }
 
        // Subscribe to error streams
index c886817..4d23604 100644 (file)
 
                        if ( !$log.length ) {
                                $log = $( '<div id="mw-log-console"></div>' ).css( {
-                                               overflow: 'auto',
-                                               height: '150px',
-                                               backgroundColor: 'white',
-                                               borderTop: 'solid 2px #ADADAD'
-                                       } );
+                                       overflow: 'auto',
+                                       height: '150px',
+                                       backgroundColor: 'white',
+                                       borderTop: 'solid 2px #ADADAD'
+                               } );
                                hovzer = $.getFootHovzer();
                                hovzer.$.append( $log );
                                hovzer.update();
index 36b45f1..926f8c5 100644 (file)
         * @alternateClassName mw.Notification
         * @constructor
         * @private
+        * @param {mw.Message|jQuery|HTMLElement|string} message
+        * @param {Object} options
         */
        function Notification( message, options ) {
-               var $notification, $notificationTitle, $notificationContent;
+               var $notification, $notificationContent;
 
                $notification = $( '<div class="mw-notification"></div>' )
                        .data( 'mw.notification', this )
@@ -48,7 +50,7 @@
                }
 
                if ( options.title ) {
-                       $notificationTitle = $( '<div class="mw-notification-title"></div>' )
+                       $( '<div class="mw-notification-title"></div>' )
                                .text( options.title )
                                .appendTo( $notification );
                }
                                        $area.hide();
                                        notif.$notification.remove();
                                } else {
-                                       notif.$notification.slideUp( 'fast',  function () {
+                                       notif.$notification.slideUp( 'fast', function () {
                                                $( this ).remove();
                                        } );
                                }
index 7c7aca3..cbbd254 100644 (file)
                }
 
                /**
-                * defines the location of autocomplete. Typically either
+                * Defines the location of autocomplete. Typically either
                 * header, which is in the top right of vector (for example)
                 * and content which identifies the main search bar on
-                * Special:Search.  Defaults to header for skins that don't set
+                * Special:Search. Defaults to header for skins that don't set
                 * explicitly.
                 *
                 * @ignore
+                * @param {Object} context
+                * @return {string}
                 */
                function getInputLocation( context ) {
                        return context.config.$region
                 * 'this' is the search input box (jQuery object)
                 *
                 * @ignore
+                * @param {Object} metadata
                 */
                function onAfterUpdate( metadata ) {
                        var context = this.data( 'suggestionsContext' );
index cb62fbf..a9d17ff 100644 (file)
         */
        mw.storage = {
 
-               localStorage: window.localStorage,
+               localStorage: ( function () {
+                       // Catch exceptions to avoid fatal in Chrome's "Block data storage" mode
+                       // which throws when accessing the localStorage property itself, as opposed
+                       // to the standard behaviour of throwing on getItem/setItem. (T148998)
+                       try {
+                               return window.localStorage;
+                       } catch ( e ) {}
+               }() ),
 
                /**
                 * Retrieve value from device storage.
index 7f62256..9f5e5c4 100644 (file)
@@ -1,4 +1,4 @@
-/*global Mustache */
+/* global Mustache */
 ( function ( mw, $ ) {
        // Register mustache compiler
        mw.template.registerCompiler( 'mustache', {
@@ -16,6 +16,7 @@
                                 * @param {Object} data Data to render
                                 * @param {Object} partialTemplates Map partial names to Mustache template objects
                                 *  returned by mw.template.get()
+                                * @return {jQuery} Rendered HTML
                                 */
                                render: function ( data, partialTemplates ) {
                                        var partials = {};
index 7bf73b6..0955c23 100644 (file)
@@ -10,8 +10,7 @@
                $tocList = $toc.find( 'ul' ).eq( 0 );
 
                // Hide/show the table of contents element
-               function toggleToc( e ) {
-                       e.preventDefault();
+               function toggleToc() {
                        if ( $tocList.is( ':hidden' ) ) {
                                $tocList.slideDown( 'fast' );
                                $tocToggleLink.text( mw.msg( 'hidetoc' ) );
                if ( $toc.length && $tocTitle.length && $tocList.length && !$tocToggleLink.length ) {
                        hideToc = mw.cookie.get( 'hidetoc' ) === '1';
 
-                       $tocToggleLink = $( '<a href="#" id="togglelink"></a>' )
+                       $tocToggleLink = $( '<a role="button" tabindex="0" id="togglelink"></a>' )
                                .text( mw.msg( hideToc ? 'showtoc' : 'hidetoc' ) )
-                               .click( toggleToc );
+                               .on( 'click keypress', function ( e ) {
+                                       if (
+                                               e.type === 'click' ||
+                                               e.type === 'keypress' && e.which === 13
+                                       ) {
+                                               toggleToc();
+                                       }
+                               } );
 
                        $tocTitle.append(
                                $tocToggleLink
diff --git a/resources/src/mediawiki/mediawiki.user.blockcookie.js b/resources/src/mediawiki/mediawiki.user.blockcookie.js
new file mode 100644 (file)
index 0000000..ffff039
--- /dev/null
@@ -0,0 +1,23 @@
+( function ( mw ) {
+
+       // If a user has been autoblocked, a cookie is set.
+       // Its value is replicated here in localStorage to guard against cookie-removal.
+       // This module will only be loaded when $wgCookieSetOnAutoblock is true.
+       // Ref: https://phabricator.wikimedia.org/T5233
+
+       if ( !mw.cookie.get( 'BlockID' ) && mw.storage.get( 'blockID' ) ) {
+               // The block ID exists in storage, but not in the cookie.
+               mw.cookie.set( 'BlockID', mw.storage.get( 'blockID' ) );
+
+       } else if ( parseInt( mw.cookie.get( 'BlockID' ), 10 ) > 0 && !mw.storage.get( 'blockID' ) ) {
+               // The block ID exists in the cookie, but not in storage.
+               // (When a block expires the cookie remains but its value is '', hence the integer check above.)
+               mw.storage.set( 'blockID', mw.cookie.get( 'BlockID' ) );
+
+       } else if ( mw.cookie.get( 'BlockID' ) === '' && mw.storage.get( 'blockID' ) ) {
+               // If only the empty string is in the cookie, remove the storage value. The block is no longer valid.
+               mw.storage.remove( 'blockID' );
+
+       }
+
+}( mediaWiki ) );
index 52a1efb..240d1bd 100644 (file)
@@ -2,6 +2,7 @@
  * @class mw.user
  * @singleton
  */
+/* global Uint8Array */
 ( function ( mw, $ ) {
        var i,
                userInfoPromise,
@@ -50,7 +51,7 @@
                 * @return {string} 64 bit integer in hex format, padded
                 */
                generateRandomSessionId: function () {
-                       /*jshint bitwise:false */
+                       /* eslint-disable no-bitwise */
                        var rnds, i, r,
                                hexRnds = new Array( 8 ),
                                // Support: IE 11
@@ -79,6 +80,7 @@
                        // Concatenation of two random integers with entropy n and m
                        // returns a string with entropy n+m if those strings are independent
                        return hexRnds.join( '' );
+                       /* eslint-enable no-bitwise */
                },
 
                /**
@@ -89,7 +91,7 @@
                 * @return {number} Current user's id, or 0 if user is anonymous
                 */
                getId: function () {
-                       return mw.config.get( 'wgUserId', 0 );
+                       return mw.config.get( 'wgUserId' ) || 0;
                },
 
                /**
                 *  unavailable, or Date for when the user registered.
                 */
                getRegistration: function () {
+                       var registration;
                        if ( mw.user.isAnon() ) {
                                return false;
                        }
-                       var registration = mw.config.get( 'wgUserRegistration' );
+                       registration = mw.config.get( 'wgUserRegistration' );
                        // Registration may be unavailable if the user signed up before MediaWiki
                        // began tracking this.
                        return !registration ? null : new Date( registration );
index 294b5de..a8188db 100644 (file)
@@ -50,6 +50,7 @@
                 * Encode the string like PHP's rawurlencode
                 *
                 * @param {string} str String to be encoded.
+                * @return {string} Encoded string
                 */
                rawurlencode: function ( str ) {
                        str = String( str );
@@ -62,6 +63,7 @@
                 * Encode the string like Sanitizer::escapeId in PHP
                 *
                 * @param {string} str String to be encoded.
+                * @return {string} Encoded string
                 */
                escapeId: function ( str ) {
                        str = String( str );
@@ -80,6 +82,7 @@
                 * of `wfUrlencode` in PHP.
                 *
                 * @param {string} str String to be encoded.
+                * @return {string} Encoded string
                 */
                wikiUrlencode: function ( str ) {
                        return util.rawurlencode( str )
                                query = $.param( params );
                        }
                        if ( query ) {
-                               url = title
-                                       ? util.wikiScript() + '?title=' + util.wikiUrlencode( title ) + '&' + query
-                                       util.wikiScript() + '?' + query;
+                               url = title ?
+                                       util.wikiScript() + '?title=' + util.wikiUrlencode( title ) + '&' + query :
+                                       util.wikiScript() + '?' + query;
                        } else {
-                               url = mw.config.get( 'wgArticlePath' ).replace( '$1', util.wikiUrlencode( title ) );
+                               url = mw.config.get( 'wgArticlePath' )
+                                       .replace( '$1', util.wikiUrlencode( title ).replace( /\$/g, '$$$$' ) );
                        }
 
                        // Append the encoded fragment
                 * @return {Mixed} Parameter value or null.
                 */
                getParamValue: function ( param, url ) {
-                       if ( url === undefined ) {
-                               url = location.href;
-                       }
                        // Get last match, stop at hash
                        var     re = new RegExp( '^[^#]*[&?]' + mw.RegExp.escape( param ) + '=([^&#]*)' ),
-                               m = re.exec( url );
+                               m = re.exec( url !== undefined ? url : location.href );
+
                        if ( m ) {
                                // Beware that decodeURIComponent is not required to understand '+'
                                // by spec, as encodeURIComponent does not produce it.
                        // - atext   : defined in RFC 5322 section 3.2.3
                        // - ldh-str : defined in RFC 1034 section 3.5
                        //
-                       // (see STD 68 / RFC 5234 http://tools.ietf.org/html/std68)
+                       // (see STD 68 / RFC 5234 https://tools.ietf.org/html/std68)
                        // First, define the RFC 5322 'atext' which is pretty easy:
                        // atext = ALPHA / DIGIT / ; Printable US-ASCII
                        //     "!" / "#" /    ; characters not including
 
                        html5EmailRegexp = new RegExp(
                                // start of string
-                               '^'
-                               +
+                               '^' +
                                // User part which is liberal :p
-                               '[' + rfc5322Atext + '\\.]+'
-                               +
+                               '[' + rfc5322Atext + '\\.]+' +
                                // 'at'
-                               '@'
-                               +
+                               '@' +
                                // Domain first part
-                               '[' + rfc1034LdhStr + ']+'
-                               +
+                               '[' + rfc1034LdhStr + ']+' +
                                // Optional second part and following are separated by a dot
-                               '(?:\\.[' + rfc1034LdhStr + ']+)*'
-                               +
+                               '(?:\\.[' + rfc1034LdhStr + ']+)*' +
                                // End of string
                                '$',
                                // RegExp is case insensitive
                 * @return {boolean}
                 */
                isIPv4Address: function ( address, allowBlock ) {
+                       var block, RE_IP_BYTE, RE_IP_ADD;
+
                        if ( typeof address !== 'string' ) {
                                return false;
                        }
 
-                       var     block = allowBlock ? '(?:\\/(?:3[0-2]|[12]?\\d))?' : '',
-                               RE_IP_BYTE = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|0?[0-9]?[0-9])',
-                               RE_IP_ADD = '(?:' + RE_IP_BYTE + '\\.){3}' + RE_IP_BYTE;
+                       block = allowBlock ? '(?:\\/(?:3[0-2]|[12]?\\d))?' : '';
+                       RE_IP_BYTE = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|0?[0-9]?[0-9])';
+                       RE_IP_ADD = '(?:' + RE_IP_BYTE + '\\.){3}' + RE_IP_BYTE;
 
                        return ( new RegExp( '^' + RE_IP_ADD + block + '$' ).test( address ) );
                },
                 * @return {boolean}
                 */
                isIPv6Address: function ( address, allowBlock ) {
+                       var block, RE_IPV6_ADD;
+
                        if ( typeof address !== 'string' ) {
                                return false;
                        }
 
-                       var     block = allowBlock ? '(?:\\/(?:12[0-8]|1[01][0-9]|[1-9]?\\d))?' : '',
-                               RE_IPV6_ADD =
-                       '(?:' + // starts with "::" (including "::")
-                       ':(?::|(?::' + '[0-9A-Fa-f]{1,4}' + '){1,7})' +
-                       '|' + // ends with "::" (except "::")
-                       '[0-9A-Fa-f]{1,4}' + '(?::' + '[0-9A-Fa-f]{1,4}' + '){0,6}::' +
-                       '|' + // contains no "::"
-                       '[0-9A-Fa-f]{1,4}' + '(?::' + '[0-9A-Fa-f]{1,4}' + '){7}' +
-                       ')';
+                       block = allowBlock ? '(?:\\/(?:12[0-8]|1[01][0-9]|[1-9]?\\d))?' : '';
+                       RE_IPV6_ADD =
+                               '(?:' + // starts with "::" (including "::")
+                               ':(?::|(?::' + '[0-9A-Fa-f]{1,4}' + '){1,7})' +
+                               '|' + // ends with "::" (except "::")
+                               '[0-9A-Fa-f]{1,4}' + '(?::' + '[0-9A-Fa-f]{1,4}' + '){0,6}::' +
+                               '|' + // contains no "::"
+                               '[0-9A-Fa-f]{1,4}' + '(?::' + '[0-9A-Fa-f]{1,4}' + '){7}' +
+                               ')';
 
                        if ( new RegExp( '^' + RE_IPV6_ADD + block + '$' ).test( address ) ) {
                                return true;
                        RE_IPV6_ADD = '[0-9A-Fa-f]{1,4}' + '(?:::?' + '[0-9A-Fa-f]{1,4}' + '){1,6}';
 
                        return (
-                               new RegExp( '^' + RE_IPV6_ADD + block + '$' ).test( address )
-                               && /::/.test( address )
-                               && !/::.*::/.test( address )
+                               new RegExp( '^' + RE_IPV6_ADD + block + '$' ).test( address ) &&
+                               /::/.test( address ) &&
+                               !/::.*::/.test( address )
                        );
                },
 
index 6396331..b453ac8 100644 (file)
@@ -18,6 +18,7 @@
                 *
                 * @ignore
                 * @private
+                * @return {Object} Viewport positions
                 */
                makeViewportFromWindow: function () {
                        var $window = $( window ),
@@ -85,7 +86,7 @@
                 */
                isElementCloseToViewport: function ( el, threshold, rectangle ) {
                        var viewport = rectangle ? $.extend( {}, rectangle ) : this.makeViewportFromWindow();
-                       threshold = threshold || 50 ;
+                       threshold = threshold || 50;
 
                        viewport.top -= threshold;
                        viewport.left -= threshold;
index 3b2c86e..094c4df 100644 (file)
 
                toggle = new OO.ui.ButtonWidget( {
                        framed: false,
-                       icon: 'imageGallery'
+                       icon: 'imageGallery',
+                       title: mw.msg( 'gallery-slideshow-toggle' )
                } ).on( 'click', this.toggleThumbnails.bind( this ) );
 
                interfaceElements = new OO.ui.PanelLayout( {
        /**
         * Gets the height of the interface elements and the
         * gallery's caption.
+        *
+        * @return {number} Height
         */
        mw.GallerySlideshow.prototype.getChromeHeight = function () {
                return this.$interface.outerHeight() + this.$galleryCaption.outerHeight();
                // Show thumbnail stretched to the right size while the image loads
                this.$thumbnail = imageLi.find( 'img' );
                this.$img.attr( 'src', this.$thumbnail.attr( 'src' ) );
+               this.$img.attr( 'alt', this.$thumbnail.attr( 'alt' ) );
                this.$imgLink.attr( 'href', imageLi.find( 'a' ).eq( 0 ).attr( 'href' ) );
                this.setImageSize();
 
                if ( this.imageInfoCache[ imageSrc ] === undefined ) {
                        api = new mw.Api();
                        // TODO: This supports only gallery of images
-                       title = new mw.Title.newFromImg( $img );
+                       title = mw.Title.newFromImg( $img );
                        params = {
                                action: 'query',
                                formatversion: 2,
        };
 
        // Bootstrap all slideshow galleries
-       $( function () {
-               $( '.mw-gallery-slideshow' ).each( function () {
-                       /*jshint -W031 */
+       mw.hook( 'wikipage.content' ).add( function ( $content ) {
+               $content.find( '.mw-gallery-slideshow' ).each( function () {
+                       // eslint-disable-next-line no-new
                        new mw.GallerySlideshow( this );
-                       /*jshint +W031 */
                } );
        } );
 }( mediaWiki, jQuery, OO ) );
index 02bc1de..6038a57 100644 (file)
@@ -1,8 +1,10 @@
 /*!
  * Implement AJAX navigation for multi-page images so the user may browse without a full page reload.
  */
+
+/* eslint-disable no-use-before-define */
+
 ( function ( mw, $ ) {
-       /*jshint latedef:false */
        var jqXhr, $multipageimage, $spinner,
                cache = {},
                cacheOrder = [];
index 89bbbe7..6d6d46d 100644 (file)
                                rcid: rcid
                        } )
                        .done( function ( data ) {
+                               var title;
                                // Remove all patrollinks from the page (including any spinners inside).
                                $patrolLinks.closest( '.patrollink' ).remove();
                                if ( data.patrol !== undefined ) {
                                        // Success
-                                       var title = new mw.Title( data.patrol.title );
+                                       title = new mw.Title( data.patrol.title );
                                        mw.notify( mw.msg( 'markedaspatrollednotify', title.toText() ) );
                                } else {
                                        // This should never happen as errors should trigger fail
index 83d14b3..cb46b11 100644 (file)
@@ -43,9 +43,9 @@
                                        }
                                        $( e.delegateTarget ).remove();
                                }, function ( errorCode, data ) {
-                                       var message = data && data.error && data.error.messageHtml
-                                               ? $.parseHTML( data.error.messageHtml )
-                                               mw.msg( 'rollbackfailed' ),
+                                       var message = data && data.error && data.error.messageHtml ?
+                                               $.parseHTML( data.error.messageHtml ) :
+                                               mw.msg( 'rollbackfailed' ),
                                                type = errorCode === 'alreadyrolled' ? 'warn' : 'error';
 
                                        mw.notify( message, {
index 282799a..076357a 100644 (file)
@@ -3,6 +3,7 @@
        mw.page = {};
 
        $( function () {
+               var $diff;
                mw.util.init();
 
                /**
@@ -23,7 +24,7 @@
                 */
                mw.hook( 'wikipage.content' ).fire( $( '#mw-content-text' ) );
 
-               var $diff = $( 'table.diff[data-mw="interface"]' );
+               $diff = $( 'table.diff[data-mw="interface"]' );
                if ( $diff.length ) {
                        /**
                         * Fired when the diff is added to a page containing a diff
index c67b93e..0abb957 100644 (file)
@@ -1,7 +1,7 @@
 // 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 */
+/* global moment */
 moment.locale( 'en', {
        longDateFormat: {
                // Unchanged, but have to be repeated here:
index dd33b00..13f26f0 100644 (file)
@@ -1,4 +1,4 @@
-/*global moment, mw */
+/* global moment, mw */
 
 // HACK: Overwrite moment's i18n with MediaWiki's for the current language so that
 // wgTranslateNumerals is respected.
index 84ec92d..99d9784 100644 (file)
@@ -1,5 +1,10 @@
-// Connect OOjs UI to MediaWiki's localisation system
 ( function ( mw ) {
+       // Connect OOjs UI to MediaWiki's localisation system
        OO.ui.getUserLanguages = mw.language.getFallbackLanguageChain;
        OO.ui.msg = mw.msg;
+       // Connect OOjs UI's deprecation warnings to MediaWiki's logging system
+       OO.ui.warnDeprecation = function ( message ) {
+               mw.track( 'mw.deprecate', 'oojs-ui' );
+               mw.log.warn( message );
+       };
 }( mediaWiki ) );
index 556b51b..c8acc86 100644 (file)
@@ -1,19 +1,19 @@
 /**
  * Adds window.Node with node types according to:
- * http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247
+ * https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247
  */
 
 window.Node = window.Node || {
-       ELEMENT_NODE:                1,
-       ATTRIBUTE_NODE:              2,
-       TEXT_NODE:                   3,
-       CDATA_SECTION_NODE:          4,
-       ENTITY_REFERENCE_NODE:       5,
-       ENTITY_NODE:                 6,
+       ELEMENT_NODE: 1,
+       ATTRIBUTE_NODE: 2,
+       TEXT_NODE: 3,
+       CDATA_SECTION_NODE: 4,
+       ENTITY_REFERENCE_NODE: 5,
+       ENTITY_NODE: 6,
        PROCESSING_INSTRUCTION_NODE: 7,
-       COMMENT_NODE:                8,
-       DOCUMENT_NODE:               9,
-       DOCUMENT_TYPE_NODE:          10,
-       DOCUMENT_FRAGMENT_NODE:      11,
-       NOTATION_NODE:               12
+       COMMENT_NODE: 8,
+       DOCUMENT_NODE: 9,
+       DOCUMENT_TYPE_NODE: 10,
+       DOCUMENT_FRAGMENT_NODE: 11,
+       NOTATION_NODE: 12
 };
index d026cb0..2050ca9 100644 (file)
@@ -3,11 +3,11 @@
  *
  * This file is where we decide whether to initialise the modern run-time.
  */
-/*jshint unused: false */
-/*globals mw, RLQ: true, NORLQ: true, $VARS, $CODE, performance */
 
-var mediaWikiLoadStart = ( new Date() ).getTime(),
+/* global mw, $VARS, $CODE */
 
+// eslint-disable-next-line no-unused-vars
+var mediaWikiLoadStart = ( new Date() ).getTime(),
        mwPerformance = ( window.performance && performance.mark ) ? performance : {
                mark: function () {}
        };
@@ -46,28 +46,31 @@ mwPerformance.mark( 'mwLoadStart' );
  * - Google Glass
  *
  * Other browsers that pass the check are considered Grade X.
+ *
+ * @param {string} [str] User agent, defaults to navigator.userAgent
+ * @return {boolean} User agent is compatible with MediaWiki JS
  */
 function isCompatible( str ) {
        var ua = str || navigator.userAgent;
        return !!(
                // http://caniuse.com/#feat=queryselector
-               'querySelector' in document
+               'querySelector' in document &&
 
                // http://caniuse.com/#feat=namevalue-storage
                // https://developer.blackberry.com/html5/apis/v1_0/localstorage.html
                // https://blog.whatwg.org/this-week-in-html-5-episode-30
-               && 'localStorage' in window
+               'localStorage' in window &&
 
                // http://caniuse.com/#feat=addeventlistener
-               && 'addEventListener' in window
+               'addEventListener' in window &&
 
                // Hardcoded exceptions for browsers that pass the requirement but we don't want to
                // support in the modern run-time.
-               && !(
-                       ua.match( /webOS\/1\.[0-4]/ ) ||
+               !(
+                       ua.match( /webOS\/1\.[0-4]|SymbianOS|Series60|NetFront|Opera Mini|S40OviBrowser|MeeGo|Android.+Glass/ ) ||
                        ua.match( /PlayStation/i ) ||
-                       ua.match( /SymbianOS|Series60|NetFront|Opera Mini|S40OviBrowser|MeeGo/ ) ||
-                       ( ua.match( /Glass/ ) && ua.match( /Android/ ) )
+                       // UC Mini (speed mode on)
+                       ua.match( /^Mozilla\/5\.0 .+ Gecko\/$/ )
                )
        );
 }
@@ -112,6 +115,7 @@ function isCompatible( str ) {
 
                // Must be after mw.config.set because these callbacks may use mw.loader which
                // needs to have values 'skin', 'debug' etc. from mw.config.
+               // eslint-disable-next-line vars-on-top
                var RLQ = window.RLQ || [];
                while ( RLQ.length ) {
                        RLQ.shift()();
index 6c3ad07..53e724b 100644 (file)
@@ -15,6 +15,7 @@ class TestSetup {
                global $wgMainStash;
                global $wgLanguageConverterCacheType, $wgUseDatabaseMessages;
                global $wgLocaltimezone, $wgLocalisationCacheConf;
+               global $wgSearchType;
                global $wgDevelopmentWarnings;
                global $wgSessionProviders, $wgSessionPbkdf2Iterations;
                global $wgJobTypeConf;
@@ -50,6 +51,9 @@ class TestSetup {
 
                $wgLocalisationCacheConf['storeClass'] = 'LCStoreNull';
 
+               // Do not bother updating search tables
+               $wgSearchType = 'SearchEngineDummy';
+
                // Generic MediaWiki\Session\SessionManager configuration for tests
                // We use CookieSessionProvider because things might be expecting
                // cookies to show up in a FauxRequest somewhere.
index a19fea1..66df315 100644 (file)
@@ -35,12 +35,14 @@ $wgAutoloadClasses += [
        'DjVuSupport' => "$testDir/parser/DjVuSupport.php",
        'TestRecorder' => "$testDir/parser/TestRecorder.php",
        'MultiTestRecorder' => "$testDir/parser/MultiTestRecorder.php",
+       'ParserTestMockParser' => "$testDir/parser/ParserTestMockParser.php",
        'ParserTestRunner' => "$testDir/parser/ParserTestRunner.php",
        'ParserTestParserHook' => "$testDir/parser/ParserTestParserHook.php",
        'ParserTestPrinter' => "$testDir/parser/ParserTestPrinter.php",
        'ParserTestResult' => "$testDir/parser/ParserTestResult.php",
        'ParserTestResultNormalizer' => "$testDir/parser/ParserTestResultNormalizer.php",
        'PhpunitTestRecorder' => "$testDir/parser/PhpunitTestRecorder.php",
+       'TestFileEditor' => "$testDir/parser/TestFileEditor.php",
        'TestFileReader' => "$testDir/parser/TestFileReader.php",
        'TestRecorder' => "$testDir/parser/TestRecorder.php",
        'TidySupport' => "$testDir/parser/TidySupport.php",
diff --git a/tests/parser/ParserTestMockParser.php b/tests/parser/ParserTestMockParser.php
new file mode 100644 (file)
index 0000000..0757b34
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * A parser used during article insertion which does nothing, to avoid
+ * unnecessary log noise and other interference with debugging.
+ */
+class ParserTestMockParser {
+       public function preSaveTransform( $text, Title $title, User $user,
+               ParserOptions $options, $clearState = true
+       ) {
+               return $text;
+       }
+
+       public function parse(
+               $text, Title $title, ParserOptions $options,
+               $linestart = true, $clearState = true, $revid = null
+       ) {
+               return new ParserOutput;
+       }
+}
index 369cd0e..04c142a 100644 (file)
@@ -26,6 +26,7 @@
  * @ingroup Testing
  */
 use MediaWiki\MediaWikiServices;
+use Wikimedia\ScopedCallback;
 
 /**
  * @ingroup Testing
@@ -59,11 +60,6 @@ class ParserTestRunner {
         */
        private $dbClone;
 
-       /**
-        * @var DjVuSupport
-        */
-       private $djVuSupport;
-
        /**
         * @var TidySupport
         */
@@ -138,7 +134,6 @@ class ParserTestRunner {
                $this->runDisabled = !empty( $options['run-disabled'] );
                $this->runParsoid = !empty( $options['run-parsoid'] );
 
-               $this->djVuSupport = new DjVuSupport();
                $this->tidySupport = new TidySupport( !empty( $options['use-tidy-config'] ) );
                if ( !$this->tidySupport->isEnabled() ) {
                        $this->recorder->warning(
@@ -181,7 +176,7 @@ class ParserTestRunner {
                // arrays: $setup and $teardown. The code snippets in the $setup array
                // are executed at the end of the method, before it returns, and the
                // code snippets in the $teardown array are executed in reverse order
-               // when the ScopedCallback object is consumed.
+               // when the Wikimedia\ScopedCallback object is consumed.
 
                // Because it is a common operation to save, set and restore global
                // variables, we have an additional convention: when the array key of
@@ -431,7 +426,7 @@ class ParserTestRunner {
         * @param ScopedCallback|null A ScopedCallback to consume
         * @return ScopedCallback
         */
-       protected function createTeardownObject( $teardown, $nextTeardown ) {
+       protected function createTeardownObject( $teardown, $nextTeardown = null ) {
                return new ScopedCallback( function() use ( $teardown, $nextTeardown ) {
                        // Schedule teardown snippets in reverse order
                        $teardown = array_reverse( $teardown );
@@ -456,7 +451,6 @@ class ParserTestRunner {
                }
                $this->setupDone[$funcName] = true;
                return function () use ( $funcName ) {
-                       wfDebug( "markSetupDone unmarked $funcName" );
                        $this->setupDone[$funcName] = false;
                };
        }
@@ -752,14 +746,6 @@ class ParserTestRunner {
                $user = $context->getUser();
                $options = ParserOptions::newFromContext( $context );
 
-               if ( isset( $opts['djvu'] ) ) {
-                       if ( !$this->djVuSupport->isEnabled() ) {
-                               $this->recorder->skipped( $test,
-                                       'djvu binaries do not exist or are not executable' );
-                               return false;
-                       }
-               }
-
                if ( isset( $opts['tidy'] ) ) {
                        if ( !$this->tidySupport->isEnabled() ) {
                                $this->recorder->skipped( $test, 'tidy extension is not installed' );
@@ -1028,7 +1014,6 @@ class ParserTestRunner {
                };
 
                // Set content language. This invalidates the magic word cache and title services
-               wfDebug( "Setting up language $langCode" );
                $lang = Language::factory( $langCode );
                $setup['wgContLang'] = $lang;
                $reset = function () {
@@ -1518,13 +1503,20 @@ class ParserTestRunner {
                        throw new MWException( "duplicate article '$name' at $file:$line\n" );
                }
 
+               // Use mock parser, to make debugging of actual parser tests simpler.
+               // But initialise the MessageCache clone first, don't let MessageCache
+               // get a reference to the mock object.
+               MessageCache::singleton()->getParser();
+               $restore = $this->executeSetupSnippets( [ 'wgParser' => new ParserTestMockParser ] );
                $status = $page->doEditContent( ContentHandler::makeContent( $text, $title ), '', EDIT_NEW );
+               $restore();
+
                if ( !$status->isOK() ) {
                        throw new MWException( $status->getWikiText( false, false, 'en' ) );
                }
 
                // The RepoGroup cache is invalidated by the creation of file redirects
-               if ( $title->getNamespace() === NS_IMAGE ) {
+               if ( $title->inNamespace( NS_FILE ) ) {
                        RepoGroup::singleton()->clearCache( $title );
                }
        }
diff --git a/tests/parser/TestFileEditor.php b/tests/parser/TestFileEditor.php
new file mode 100644 (file)
index 0000000..05b1216
--- /dev/null
@@ -0,0 +1,196 @@
+<?php
+
+class TestFileEditor {
+       private $lines;
+       private $numLines;
+       private $deletions;
+       private $changes;
+       private $pos;
+       private $warningCallback;
+       private $result;
+
+       public static function edit( $text, array $deletions, array $changes, $warningCallback = null ) {
+               $editor = new self( $text, $deletions, $changes, $warningCallback );
+               $editor->execute();
+               return $editor->result;
+       }
+
+       private function __construct( $text, array $deletions, array $changes, $warningCallback ) {
+               $this->lines = explode( "\n", $text );
+               $this->numLines = count( $this->lines );
+               $this->deletions = array_flip( $deletions );
+               $this->changes = $changes;
+               $this->pos = 0;
+               $this->warningCallback = $warningCallback;
+               $this->result = '';
+       }
+
+       private function execute() {
+               while ( $this->pos < $this->numLines ) {
+                       $line = $this->lines[$this->pos];
+                       switch ( $this->getHeading( $line ) ) {
+                               case 'test':
+                                       $this->parseTest();
+                                       break;
+                               case 'hooks':
+                               case 'functionhooks':
+                               case 'transparenthooks':
+                                       $this->parseHooks();
+                                       break;
+                               default:
+                                       if ( $this->pos < $this->numLines - 1 ) {
+                                               $line .= "\n";
+                                       }
+                                       $this->emitComment( $line );
+                                       $this->pos++;
+                       }
+               }
+               foreach ( $this->deletions as $deletion => $unused ) {
+                       $this->warning( "Could not find test \"$deletion\" to delete it" );
+               }
+               foreach ( $this->changes as $test => $sectionChanges ) {
+                       foreach ( $sectionChanges as $section => $change ) {
+                               $this->warning( "Could not find section \"$section\" in test \"$test\" " .
+                                       "to {$change['op']} it" );
+                       }
+               }
+       }
+
+       private function warning( $text ) {
+               $cb = $this->warningCallback;
+               if ( $cb ) {
+                       $cb( $text );
+               }
+       }
+
+       private function getHeading( $line ) {
+               if ( preg_match( '/^!!\s*(\S+)/', $line, $m ) ) {
+                       return $m[1];
+               } else {
+                       return false;
+               }
+       }
+
+       private function parseTest() {
+               $test = [];
+               $line = $this->lines[$this->pos++];
+               $heading = $this->getHeading( $line );
+               $section = [
+                       'name' => $heading,
+                       'headingLine' => $line,
+                       'contents' => ''
+               ];
+
+               while ( $this->pos < $this->numLines ) {
+                       $line = $this->lines[$this->pos++];
+                       $nextHeading = $this->getHeading( $line );
+                       if ( $nextHeading === 'end' ) {
+                               $test[] = $section;
+
+                               // Add trailing line breaks to the "end" section, to allow for neat deletions
+                               $trail = '';
+                               for ( $i = 0; $i < $this->numLines - $this->pos - 1; $i++ ) {
+                                       if ( $this->lines[$this->pos + $i] === '' ) {
+                                               $trail .= "\n";
+                                       } else {
+                                               break;
+                                       }
+                               }
+                               $this->pos += strlen( $trail );
+
+                               $test[] = [
+                                       'name' => 'end',
+                                       'headingLine' => $line,
+                                       'contents' => $trail
+                               ];
+                               $this->emitTest( $test );
+                               return;
+                       } elseif ( $nextHeading !== false ) {
+                               $test[] = $section;
+                               $heading = $nextHeading;
+                               $section = [
+                                       'name' => $heading,
+                                       'headingLine' => $line,
+                                       'contents' => ''
+                               ];
+                       } else {
+                               $section['contents'] .= "$line\n";
+                       }
+               }
+
+               throw new Exception( 'Unexpected end of file' );
+       }
+
+       private function parseHooks() {
+               $line = $this->lines[$this->pos++];
+               $heading = $this->getHeading( $line );
+               $expectedEnd = 'end' . $heading;
+               $contents = $line;
+
+               do {
+                       $line = $this->lines[$this->pos++];
+                       $nextHeading = $this->getHeading( $line );
+                       $contents .= "$line\n";
+               } while ( $this->pos < $this->numLines && $nextHeading !== $expectedEnd );
+
+               if ( $nextHeading !== $expectedEnd ) {
+                       throw new Exception( 'Unexpected end of file' );
+               }
+               $this->emitHooks( $heading, $contents );
+       }
+
+       protected function emitComment( $contents ) {
+               $this->result .= $contents;
+       }
+
+       protected function emitTest( $test ) {
+               $testName = false;
+               foreach ( $test as $section ) {
+                       if ( $section['name'] === 'test' ) {
+                               $testName = rtrim( $section['contents'], "\n" );
+                       }
+               }
+               if ( isset( $this->deletions[$testName] ) ) {
+                       // Acknowledge deletion
+                       unset( $this->deletions[$testName] );
+                       return;
+               }
+               if ( isset( $this->changes[$testName] ) ) {
+                       $changes =& $this->changes[$testName];
+                       foreach ( $test as $i => $section ) {
+                               $sectionName = $section['name'];
+                               if ( isset( $changes[$sectionName] ) ) {
+                                       $change = $changes[$sectionName];
+                                       switch ( $change['op'] ) {
+                                       case 'rename':
+                                               $test[$i]['name'] = $change['value'];
+                                               $test[$i]['headingLine'] = "!! {$change['value']}";
+                                               break;
+                                       case 'update':
+                                               $test[$i]['contents'] = $change['value'];
+                                               break;
+                                       case 'delete':
+                                               $test[$i]['deleted'] = true;
+                                               break;
+                                       default:
+                                               throw new Exception( "Unknown op: ${change['op']}" );
+                                       }
+                                       // Acknowledge
+                                       // Note that we use the old section name for the rename op
+                                       unset( $changes[$sectionName] );
+                               }
+                       }
+               }
+               foreach ( $test as $section ) {
+                       if ( isset( $section['deleted'] ) ) {
+                               continue;
+                       }
+                       $this->result .= $section['headingLine'] . "\n";
+                       $this->result .= $section['contents'];
+               }
+       }
+
+       protected function emitHooks( $heading, $contents ) {
+               $this->result .= $contents;
+       }
+}
index a1a8d19..b6e811b 100644 (file)
@@ -25,6 +25,7 @@ class TestFileReader {
        private $section = null;
        /** String|null: current test section being analyzed */
        private $sectionData = [];
+       private $sectionLineNum = [];
        private $lineNum = 0;
        private $runDisabled;
        private $runParsoid;
@@ -77,44 +78,89 @@ class TestFileReader {
                // "input" and "result" are old section names allowed
                // for backwards-compatibility.
                $input = $this->checkSection( [ 'wikitext', 'input' ], false );
-               $result = $this->checkSection( [ 'html/php', 'html/*', 'html', 'result' ], false );
+               $nonTidySection = $this->checkSection(
+                       [ 'html/php', 'html/*', 'html', 'result' ], false );
                // Some tests have "with tidy" and "without tidy" variants
-               $tidy = $this->checkSection( [ 'html/php+tidy', 'html+tidy' ], false );
+               $tidySection = $this->checkSection( [ 'html/php+tidy', 'html+tidy' ], false );
 
-               if ( !isset( $this->sectionData['options'] ) ) {
-                       $this->sectionData['options'] = '';
+               // Remove trailing newline
+               $data = array_map( 'ParserTestRunner::chomp', $this->sectionData );
+
+               // Apply defaults
+               $data += [
+                       'options' => '',
+                       'config' => ''
+               ];
+
+               if ( $input === false ) {
+                       throw new MWException( "Test at {$this->file}:{$this->sectionLineNum['test']} " .
+                               "lacks input section" );
+               }
+
+               if ( preg_match( '/\\bdisabled\\b/i', $data['options'] ) &&     !$this->runDisabled ) {
+                       // Disabled
+                       return;
+               }
+
+               if ( $tidySection === false && $nonTidySection === false ) {
+                       if ( isset( $data['html/parsoid'] ) || isset( $data['wikitext/edited'] ) ) {
+                               // Parsoid only
+                               return;
+                       } else {
+                               throw new MWException( "Test at {$this->file}:{$this->sectionLineNum['test']} " .
+                                       "lacks result section" );
+                       }
                }
 
-               if ( !isset( $this->sectionData['config'] ) ) {
-                       $this->sectionData['config'] = '';
+               if ( preg_match( '/\\bparsoid\\b/i', $data['options'] ) && $nonTidySection === 'html'
+                       && !$this->runParsoid
+               ) {
+                       // A test which normally runs on Parsoid but can optionally be run with MW
+                       return;
                }
 
-               $isDisabled = preg_match( '/\\bdisabled\\b/i', $this->sectionData['options'] ) &&
-                       !$this->runDisabled;
-               $isParsoidOnly = preg_match( '/\\bparsoid\\b/i', $this->sectionData['options'] ) &&
-                       $result == 'html' &&
-                       !$this->runParsoid;
-               $isFiltered = !preg_match( $this->regex, $this->sectionData['test'] );
-               if ( $input == false || $result == false || $isDisabled || $isParsoidOnly || $isFiltered ) {
-                       // Disabled test
+               if ( !preg_match( $this->regex, $data['test'] ) ) {
+                       // Filtered test
                        return;
                }
 
-               $test = [
-                       'test' => ParserTestRunner::chomp( $this->sectionData['test'] ),
-                       'input' => ParserTestRunner::chomp( $this->sectionData[$input] ),
-                       'result' => ParserTestRunner::chomp( $this->sectionData[$result] ),
-                       'options' => ParserTestRunner::chomp( $this->sectionData['options'] ),
-                       'config' => ParserTestRunner::chomp( $this->sectionData['config'] ),
+               $commonInfo = [
+                       'test' => $data['test'],
+                       'desc' => $data['test'],
+                       'input' => $data[$input],
+                       'options' => $data['options'],
+                       'config' => $data['config'],
+                       'line' => $this->sectionLineNum['test'],
+                       'file' => $this->file
                ];
-               $test['desc'] = $test['test'];
-               $this->tests[] = $test;
-
-               if ( $tidy !== false ) {
-                       $test['options'] .= " tidy";
-                       $test['desc'] .= ' (with tidy)';
-                       $test['result'] = ParserTestRunner::chomp( $this->sectionData[$tidy] );
-                       $this->tests[] = $test;
+
+               if ( $nonTidySection !== false ) {
+                       // Add non-tidy test
+                       $this->tests[] = [
+                               'result' => $data[$nonTidySection],
+                               'resultSection' => $nonTidySection
+                       ] + $commonInfo;
+
+                       if ( $tidySection !== false ) {
+                               // Add tidy subtest
+                               $this->tests[] = [
+                                       'desc' => $data['test'] . ' (with tidy)',
+                                       'result' => $data[$tidySection],
+                                       'resultSection' => $tidySection,
+                                       'options' => $data['options'] . ' tidy',
+                                       'isSubtest' => true,
+                               ] + $commonInfo;
+                       }
+               } elseif ( $tidySection !== false ) {
+                       // No need to override desc when there is no subtest
+                       $this->tests[] = [
+                               'result' => $data[$tidySection],
+                               'resultSection' => $tidySection,
+                               'options' => $data['options'] . ' tidy'
+                       ] + $commonInfo;
+               } else {
+                       throw new MWException( "Test at {$this->file}:{$this->sectionLineNum['test']} " .
+                               "lacks result section" );
                }
        }
 
@@ -199,6 +245,7 @@ class TestFileReader {
                                                . "at line {$this->lineNum} of $this->file\n" );
                                }
 
+                               $this->sectionLineNum[$this->section] = $this->lineNum;
                                $this->sectionData[$this->section] = '';
 
                                continue;
@@ -214,9 +261,9 @@ class TestFileReader {
         * Clear section name and its data
         */
        private function clearSection() {
+               $this->sectionLineNum = [];
                $this->sectionData = [];
                $this->section = null;
-
        }
 
        /**
index 70215b6..4b81699 100644 (file)
@@ -32,7 +32,7 @@
  *
  * @since 1.22
  */
-abstract class TestRecorder {
+class TestRecorder {
 
        /**
         * Called at beginning of the parser test run
diff --git a/tests/parser/editTests.php b/tests/parser/editTests.php
new file mode 100644 (file)
index 0000000..a9704e6
--- /dev/null
@@ -0,0 +1,490 @@
+<?php
+
+require __DIR__.'/../../maintenance/Maintenance.php';
+
+define( 'MW_PARSER_TEST', true );
+
+/**
+ * Interactive parser test runner and test file editor
+ */
+class ParserEditTests extends Maintenance {
+       private $termWidth;
+       private $testFiles;
+       private $testCount;
+       private $recorder;
+       private $runner;
+       private $numExecuted;
+       private $numSkipped;
+       private $numFailed;
+
+       function __construct() {
+               parent::__construct();
+               $this->addOption( 'session-data', 'internal option, do not use', false, true );
+               $this->addOption( 'use-tidy-config',
+                       'Use the wiki\'s Tidy configuration instead of known-good' .
+                       'defaults.' );
+       }
+
+       public function finalSetup() {
+               parent::finalSetup();
+               self::requireTestsAutoloader();
+               TestSetup::applyInitialConfig();
+       }
+
+       public function execute() {
+               $this->termWidth = $this->getTermSize()[0] - 1;
+
+               $this->recorder = new TestRecorder();
+               $this->setupFileData();
+
+               if ( $this->hasOption( 'session-data' ) ) {
+                       $this->session = json_decode( $this->getOption( 'session-data' ), true );
+               } else {
+                       $this->session = [ 'options' => [] ];
+               }
+               if ( $this->hasOption( 'use-tidy-config' ) ) {
+                       $this->session['options']['use-tidy-config'] = true;
+               }
+               $this->runner = new ParserTestRunner( $this->recorder, $this->session['options'] );
+
+               $this->runTests();
+
+               if ( $this->numFailed === 0 ) {
+                       if ( $this->numSkipped === 0 ) {
+                               print "All tests passed!\n";
+                       } else {
+                               print "All tests passed (but skipped {$this->numSkipped})\n";
+                       }
+                       return;
+               }
+               print "{$this->numFailed} test(s) failed.\n";
+               $this->showResults();
+       }
+
+       protected function setupFileData() {
+               global $wgParserTestFiles;
+               $this->testFiles = [];
+               $this->testCount = 0;
+               foreach ( $wgParserTestFiles as $file ) {
+                       $fileInfo = TestFileReader::read( $file );
+                       $this->testFiles[$file] = $fileInfo;
+                       $this->testCount += count( $fileInfo['tests'] );
+               }
+       }
+
+       protected function runTests() {
+               $teardown = $this->runner->staticSetup();
+               $teardown = $this->runner->setupDatabase( $teardown );
+               $teardown = $this->runner->setupUploads( $teardown );
+
+               print "Running tests...\n";
+               $this->results = [];
+               $this->numExecuted = 0;
+               $this->numSkipped = 0;
+               $this->numFailed = 0;
+               foreach ( $this->testFiles as $fileName => $fileInfo ) {
+                       $this->runner->addArticles( $fileInfo['articles'] );
+                       foreach ( $fileInfo['tests'] as $testInfo ) {
+                               $result = $this->runner->runTest( $testInfo );
+                               if ( $result === false ) {
+                                       $this->numSkipped++;
+                               } elseif ( !$result->isSuccess() ) {
+                                       $this->results[$fileName][$testInfo['desc']] = $result;
+                                       $this->numFailed++;
+                               }
+                               $this->numExecuted++;
+                               $this->showProgress();
+                       }
+               }
+               print "\n";
+       }
+
+       protected function showProgress() {
+               $done = $this->numExecuted;
+               $total = $this->testCount;
+               $width = $this->termWidth - 9;
+               $pos = round( $width * $done / $total );
+               printf( '│' . str_repeat( '█', $pos ) . str_repeat( '-', $width - $pos ) .
+                       "│ %5.1f%%\r", $done / $total * 100 );
+       }
+
+       protected function showResults() {
+               if ( isset( $this->session['startFile'] ) ) {
+                       $startFile = $this->session['startFile'];
+                       $startTest = $this->session['startTest'];
+                       $foundStart = false;
+               } else {
+                       $startFile = false;
+                       $startTest = false;
+                       $foundStart = true;
+               }
+
+               $testIndex = 0;
+               foreach ( $this->testFiles as $fileName => $fileInfo ) {
+                       if ( !isset( $this->results[$fileName] ) ) {
+                               continue;
+                       }
+                       if ( !$foundStart && $startFile !== false && $fileName !== $startFile ) {
+                               $testIndex += count( $this->results[$fileName] );
+                               continue;
+                       }
+                       foreach ( $fileInfo['tests'] as $testInfo ) {
+                               if ( !isset( $this->results[$fileName][$testInfo['desc']] ) ) {
+                                       continue;
+                               }
+                               $result = $this->results[$fileName][$testInfo['desc']];
+                               $testIndex++;
+                               if ( !$foundStart && $startTest !== false ) {
+                                       if ( $testInfo['desc'] !== $startTest ) {
+                                               continue;
+                                       }
+                                       $foundStart = true;
+                               }
+
+                               $this->handleFailure( $testIndex, $testInfo, $result );
+                       }
+               }
+
+               if ( !$foundStart ) {
+                       print "Could not find the test after a restart, did you rename it?";
+                       unset( $this->session['startFile'] );
+                       unset( $this->session['startTest'] );
+                       $this->showResults();
+               }
+               print "All done\n";
+       }
+
+       protected function heading( $text ) {
+               $term = new AnsiTermColorer;
+               $heading = "─── $text ";
+               $heading .= str_repeat( '─', $this->termWidth - mb_strlen( $heading ) );
+               $heading = $term->color( 34 ) . $heading . $term->reset() . "\n";
+               return $heading;
+       }
+
+       protected function unifiedDiff( $left, $right ) {
+               $fromLines = explode( "\n", $left );
+               $toLines = explode( "\n", $right );
+               $formatter = new UnifiedDiffFormatter;
+               return $formatter->format( new Diff( $fromLines, $toLines ) );
+       }
+
+       protected function handleFailure( $index, $testInfo, $result ) {
+               $term = new AnsiTermColorer;
+               $div1 = $term->color( 34 ) . str_repeat( '━', $this->termWidth ) .
+                       $term->reset() . "\n";
+               $div2 = $term->color( 34 ) . str_repeat( '─', $this->termWidth ) .
+                       $term->reset() . "\n";
+
+               print $div1;
+               print "Failure $index/{$this->numFailed}: {$testInfo['file']} line {$testInfo['line']}\n" .
+                       "{$testInfo['desc']}\n";
+
+               print $this->heading( 'Input' );
+               print "{$testInfo['input']}\n";
+
+               print $this->heading( 'Alternating expected/actual output' );
+               print $this->alternatingAligned( $result->expected, $result->actual );
+
+               print $this->heading( 'Diff' );
+
+               $dwdiff = $this->dwdiff( $result->expected, $result->actual );
+               if ( $dwdiff !== false ) {
+                       $diff = $dwdiff;
+               } else {
+                       $diff = $this->unifiedDiff( $result->expected, $result->actual );
+               }
+               print $diff;
+
+               if ( $testInfo['options'] || $testInfo['config'] ) {
+                       print $this->heading( 'Options / Config' );
+                       if ( $testInfo['options'] ) {
+                               print $testInfo['options'] . "\n";
+                       }
+                       if ( $testInfo['config'] ) {
+                               print $testInfo['config'] . "\n";
+                       }
+               }
+
+               print $div2;
+               print "What do you want to do?\n";
+               $specs = [
+                       '[R]eload code and run again',
+                       '[U]pdate source file, copy actual to expected',
+                       '[I]gnore' ];
+
+               if ( strpos( $testInfo['options'], ' tidy' ) === false ) {
+                       if ( empty( $testInfo['isSubtest'] ) ) {
+                               $specs[] = "Enable [T]idy";
+                       }
+               } else {
+                       $specs[] = 'Disable [T]idy';
+               }
+
+               if ( !empty( $testInfo['isSubtest'] ) ) {
+                       $specs[] = 'Delete [s]ubtest';
+               }
+               $specs[] = '[D]elete test';
+               $specs[] = '[Q]uit';
+
+               $options = [];
+               foreach ( $specs as $spec ) {
+                       if ( !preg_match( '/^(.*\[)(.)(\].*)$/', $spec, $m ) ) {
+                               throw new MWException( 'Invalid option spec: ' . $spec );
+                       }
+                       print '* ' . $m[1] . $term->color( 35 ) . $m[2] . $term->color( 0 ) . $m[3] . "\n";
+                       $options[strtoupper( $m[2] )] = true;
+               }
+
+               do {
+                       $response = $this->readconsole();
+                       $cmdResult = false;
+                       if ( $response === false ) {
+                               exit( 0 );
+                       }
+
+                       $response = strtoupper( trim( $response ) );
+                       if ( !isset( $options[$response] ) ) {
+                               print "Invalid response, please enter a single letter from the list above\n";
+                               continue;
+                       }
+
+                       switch ( strtoupper( trim( $response ) ) ) {
+                               case 'R':
+                                       $cmdResult = $this->reload( $testInfo );
+                                       break;
+                               case 'U':
+                                       $cmdResult = $this->update( $testInfo, $result );
+                                       break;
+                               case 'I':
+                                       return;
+                               case 'T':
+                                       $cmdResult = $this->switchTidy( $testInfo );
+                                       break;
+                               case 'S':
+                                       $cmdResult = $this->deleteSubtest( $testInfo );
+                                       break;
+                               case 'D':
+                                       $cmdResult = $this->deleteTest( $testInfo );
+                                       break;
+                               case 'Q':
+                                       exit( 0 );
+                       }
+               } while ( !$cmdResult );
+       }
+
+       protected function dwdiff( $expected, $actual ) {
+               if ( !is_executable( '/usr/bin/dwdiff' ) ) {
+                       return false;
+               }
+
+               $markers = [
+                       "\n" => '¶',
+                       ' ' => '·',
+                       "\t" => '→'
+               ];
+               $markedExpected = strtr( $expected, $markers );
+               $markedActual = strtr( $actual, $markers );
+               $diff = $this->unifiedDiff( $markedExpected, $markedActual );
+
+               $tempFile = tmpfile();
+               fwrite( $tempFile, $diff );
+               fseek( $tempFile, 0 );
+               $pipes = [];
+               $proc = proc_open( '/usr/bin/dwdiff -Pc --diff-input',
+                       [ 0 => $tempFile, 1 => [ 'pipe', 'w' ], 2 => STDERR ],
+                       $pipes );
+
+               if ( !$proc ) {
+                       return false;
+               }
+
+               $result = stream_get_contents( $pipes[1] );
+               proc_close( $proc );
+               fclose( $tempFile );
+               return $result;
+       }
+
+       protected function alternatingAligned( $expectedStr, $actualStr ) {
+               $expectedLines = explode( "\n", $expectedStr );
+               $actualLines = explode( "\n", $actualStr );
+               $maxLines = max( count( $expectedLines ), count( $actualLines ) );
+               $result = '';
+               for ( $i = 0; $i < $maxLines; $i++ ) {
+                       if ( $i < count( $expectedLines ) ) {
+                               $expectedLine = $expectedLines[$i];
+                               $expectedChunks = str_split( $expectedLine, $this->termWidth - 3 );
+                       } else {
+                               $expectedChunks = [];
+                       }
+
+                       if ( $i < count( $actualLines ) ) {
+                               $actualLine = $actualLines[$i];
+                               $actualChunks = str_split( $actualLine, $this->termWidth - 3 );
+                       } else {
+                               $actualChunks = [];
+                       }
+
+                       $maxChunks = max( count( $expectedChunks ), count( $actualChunks ) );
+
+                       for ( $j = 0; $j < $maxChunks; $j++ ) {
+                               if ( isset( $expectedChunks[$j] ) ) {
+                                       $result .= "E: " . $expectedChunks[$j];
+                                       if ( $j === count( $expectedChunks ) - 1 ) {
+                                               $result .= "¶";
+                                       }
+                                       $result .= "\n";
+                               } else {
+                                       $result .= "E:\n";
+                               }
+                               $result .= "\33[4m" . // underline
+                                       "A: ";
+                               if ( isset( $actualChunks[$j] ) ) {
+                                       $result .= $actualChunks[$j];
+                                       if ( $j === count( $actualChunks ) - 1 ) {
+                                               $result .= "¶";
+                                       }
+                               }
+                               $result .= "\33[0m\n"; // reset
+                       }
+               }
+               return $result;
+       }
+
+       protected function reload( $testInfo ) {
+               global $argv;
+               pcntl_exec( PHP_BINARY, [
+                       $argv[0],
+                       '--session-data',
+                       json_encode( [
+                               'startFile' => $testInfo['file'],
+                               'startTest' => $testInfo['desc']
+                       ] + $this->session ) ] );
+
+               print "pcntl_exec() failed\n";
+               return false;
+       }
+
+       protected function findTest( $file, $testInfo ) {
+               $initialPart = '';
+               for ( $i = 1; $i < $testInfo['line']; $i++ ) {
+                       $line = fgets( $file );
+                       if ( $line === false ) {
+                               print "Error reading from file\n";
+                               return false;
+                       }
+                       $initialPart .= $line;
+               }
+
+               $line = fgets( $file );
+               if ( !preg_match( '/^!!\s*test/', $line ) ) {
+                       print "Test has moved, cannot edit\n";
+                       return false;
+               }
+
+               $testPart = $line;
+
+               $desc = fgets( $file );
+               if ( trim( $desc ) !== $testInfo['desc'] ) {
+                       print "Description does not match, cannot edit\n";
+                       return false;
+               }
+               $testPart .= $desc;
+               return [ $initialPart, $testPart ];
+       }
+
+       protected function getOutputFileName( $inputFileName ) {
+               if ( is_writable( $inputFileName ) ) {
+                       $outputFileName = $inputFileName;
+               } else {
+                       $outputFileName = wfTempDir() . '/' . basename( $inputFileName );
+                       print "Cannot write to input file, writing to $outputFileName instead\n";
+               }
+               return $outputFileName;
+       }
+
+       protected function editTest( $fileName, $deletions, $changes ) {
+               $text = file_get_contents( $fileName );
+               if ( $text === false ) {
+                       print "Unable to open test file!";
+                       return false;
+               }
+               $result = TestFileEditor::edit( $text, $deletions, $changes,
+                       function ( $msg ) {
+                               print "$msg\n";
+                       }
+               );
+               if ( is_writable( $fileName ) ) {
+                       file_put_contents( $fileName, $result );
+                       print "Wrote updated file\n";
+               } else {
+                       print "Cannot write updated file, here is a patch you can paste:\n\n";
+                       print
+                               "--- {$fileName}\n" .
+                               "+++ {$fileName}~\n" .
+                               $this->unifiedDiff( $text, $result ) .
+                               "\n";
+               }
+       }
+
+       protected function update( $testInfo, $result ) {
+               $this->editTest( $testInfo['file'],
+                       [], // deletions
+                       [ // changes
+                               $testInfo['test'] => [
+                                       $testInfo['resultSection'] => [
+                                               'op' => 'update',
+                                               'value' => $result->actual . "\n"
+                                       ]
+                               ]
+                       ]
+               );
+       }
+
+       protected function deleteTest( $testInfo ) {
+               $this->editTest( $testInfo['file'],
+                       [ $testInfo['test'] ], // deletions
+                       [] // changes
+               );
+       }
+
+       protected function switchTidy( $testInfo ) {
+               $resultSection = $testInfo['resultSection'];
+               if ( in_array( $resultSection, [ 'html/php', 'html/*', 'html', 'result' ] ) ) {
+                       $newSection = 'html+tidy';
+               } elseif ( in_array( $resultSection, [ 'html/php+tidy', 'html+tidy' ] ) ) {
+                       $newSection = 'html';
+               } else {
+                       print "Unrecognised result section name \"$resultSection\"";
+                       return;
+               }
+
+               $this->editTest( $testInfo['file'],
+                       [], // deletions
+                       [ // changes
+                               $testInfo['test'] => [
+                                       $resultSection => [
+                                               'op' => 'rename',
+                                               'value' => $newSection
+                                       ]
+                               ]
+                       ]
+               );
+       }
+
+       protected function deleteSubtest( $testInfo ) {
+               $this->editTest( $testInfo['file'],
+                       [], // deletions
+                       [ // changes
+                               $testInfo['test'] => [
+                                       $testInfo['resultSection'] => [
+                                               'op' => 'delete'
+                                       ]
+                               ]
+                       ]
+               );
+       }
+}
+
+$maintClass = 'ParserEditTests';
+require RUN_MAINTENANCE_IF_MAIN;
index 7437053..9a2a9c9 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Wikimedia\ScopedCallback;
+
 require __DIR__ . '/../../maintenance/Maintenance.php';
 
 // Make RequestContext::resetMain() happy
index 38923f0..1d0867a 100644 (file)
@@ -68,7 +68,8 @@ class ParserTestsMaintenance extends Maintenance {
                        'are: removeTbody to remove <tbody> tags; and trimWhitespace ' .
                        'to trim whitespace from the start and end of text nodes.',
                        false, true );
-               $this->addOption( 'use-tidy-config', 'Use the wiki\'s Tidy configuration instead of known-good' .
+               $this->addOption( 'use-tidy-config',
+                       'Use the wiki\'s Tidy configuration instead of known-good' .
                        'defaults.' );
        }
 
index 1e511f6..5b17eac 100644 (file)
@@ -1,5 +1,5 @@
 # MediaWiki Parser test cases
-# Some taken from http://meta.wikimedia.org/wiki/Parser_testing
+# Some taken from https://meta.wikimedia.org/wiki/Parser_testing
 # All (C) their respective authors and released under the GPL
 #
 # The syntax should be fairly self-explanatory.
@@ -524,7 +524,7 @@ http://fr.wikipedia.org/wiki/🍺
 !! end
 
 # Note that the html+tidy output removes the spaces after the <li>,
-# which is a bug (http://sourceforge.net/p/tidy/bugs/945/, etc).
+# which is a bug (https://sourceforge.net/p/tidy/bugs/945/, etc).
 # This is an issue for all tests with lists.  We intentionally do
 # *not* add html+tidy clauses for these, as we don't want to
 # document/test the broken behavior.  (Parsoid matches the non-tidy
@@ -1230,7 +1230,7 @@ Text-level semantic html elements in wikitext
 !! end
 
 # test cases taken from
-# http://www.w3.org/TR/html5/text-level-semantics.html#the-ruby-element
+# https://www.w3.org/TR/html5/text-level-semantics.html#the-ruby-element
 !! test
 Ruby markup (W3C-style)
 !! wikitext
@@ -1293,7 +1293,7 @@ Non-word characters don't terminate tag names (bug 17663, 40670, 52022)
 </p>
 !! end
 
-# There is a tidy bug here: http://sourceforge.net/p/tidy/bugs/946/
+# There is a tidy bug here: https://sourceforge.net/p/tidy/bugs/946/
 # If the non-word-character tag made it through the sanitizer, tidy
 # would munge it up.
 !! test
@@ -1420,6 +1420,15 @@ sed abit.
 </span></p>
 !! end
 
+!! test
+Don't parse <nowiki><span class="error"></nowiki> (T149622)
+!! wikitext
+<nowiki><span class="error"></nowiki>
+!! html/php
+<p>&lt;span class="error"&gt;
+</p>
+!! end
+
 !! test
 nowiki 3
 !! wikitext
@@ -2703,10 +2712,12 @@ Templates: Handle empty comment-and-ws-only lines correctly
 <!--should be ignored-->
  <!--should be ignored as well-->
 bar}}
-!! html
+!! html/php
 <p>foo
 bar
 </p>
+!! html/parsoid
+<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo\n&lt;!--should be ignored-->\n &lt;!--should be ignored as well-->\nbar"}},"i":0}}]}'>foo <!--should be ignored--> <!--should be ignored as well--> bar</p>
 !! end
 
 !! test
@@ -2722,7 +2733,13 @@ Templates: Handle comments in the target
 {{echo<!-- should be ignored -->|foo}}
 
 {{<!-- should be ignored -->echo|foo}}
-!!html/parsoid
+!! html/php
+<p>foo
+</p><p>foo
+</p><p>foo
+</p><p>foo
+</p>
+!! html/parsoid
 <p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo\n&lt;!-- should be ignored -->\n","href":"./Template:Echo"},"params":{"1":{"wt":"foo"}},"i":0}}]}'>foo</p>
 
 <p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo&lt;!-- should be ignored -->\n","href":"./Template:Echo"},"params":{"1":{"wt":"foo"}},"i":0}}]}'>foo</p>
@@ -2746,7 +2763,13 @@ Templates: Handle comments in parameter names (bug 67657)
 {{echo|1<!-- should be ignored -->=foo}}
 
 {{echo|<!-- should be ignored -->1=foo}}
-!!html/parsoid
+!! html/php
+<p>foo
+</p><p>foo
+</p><p>foo
+</p><p>foo
+</p>
+!! html/parsoid
 <p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo","key":{"wt":"1\n&lt;!-- should be ignored -->"}}},"i":0}}]}'>foo</p>
 
 <p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo","key":{"wt":"&lt;!-- should be ignored -->\n1"}}},"i":0}}]}'>foo</p>
@@ -2760,11 +2783,11 @@ Templates: Handle comments in parameter names (bug 67657)
 Templates: Other wikitext in parameter names (bug 67657)
 !! wikitext
 {{echo|''1''=foo}}
-!!html/parsoid
-<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"&#39;&#39;1&#39;&#39;":{"wt":"foo"}},"i":0}}]}'>{{{1}}}</p>
-!!html/php
+!! html/php
 <p>{{{1}}}
 </p>
+!! html/parsoid
+<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"&#39;&#39;1&#39;&#39;":{"wt":"foo"}},"i":0}}]}'>{{{1}}}</p>
 !!end
 
 #--------------------------------------------------------------------
@@ -3681,6 +3704,10 @@ Nested definition lists using html syntax
 <dl><dt>x</dt>
 <dd>a</dd>
 <dd>b</dd></dl>
+!! html
+<dl><dt>x</dt>
+<dd>a</dd>
+<dd>b</dd></dl>
 
 !! end
 
@@ -3836,7 +3863,7 @@ Definition Lists: Hacky use to indent tables (WS-insensitive)
 ## All Parsoid only definition list tests have this difference.
 ##
 ## See also: https://phabricator.wikimedia.org/T8569
-## and http://lists.wikimedia.org/pipermail/wikitext-l/2011-November/000483.html
+## and https://lists.wikimedia.org/pipermail/wikitext-l/2011-November/000483.html
 
 !! test
 Table / list interaction: indented table with lists in table contents
@@ -5190,7 +5217,7 @@ http://www.example.com/?title=AT%26T
 <p><a rel="mw:ExtLink" href="http://www.example.com/?title=AT%26T">http://www.example.com/?title=AT%26T</a></p>
 !! end
 
-# According to http://www.w3.org/TR/2011/WD-html5-20110525/Overview.html#parsing-urls a plain
+# According to https://www.w3.org/TR/2011/WD-html5-20110525/Overview.html#parsing-urls a plain
 # % is actually legal in HTML5. Any change in output would need testing though.
 !! test
 Bug 4781, 5267: %25 in URL
@@ -5777,7 +5804,7 @@ Plain ''italic'''s plain
 
 # This should not produce <table></table> as <table><tr><td></td></tr></table>
 # is the bare minimum required by the spec, see:
-# http://www.w3.org/TR/xhtml-modularization/dtd_module_defs.html#a_module_Basic_Tables
+# https://www.w3.org/TR/xhtml-modularization/dtd_module_defs.html#a_module_Basic_Tables
 # Parsoid team replies: empty table tags are legal in HTML5
 !! test
 A table with no data.
@@ -7413,6 +7440,23 @@ Piped link with no link text
 <p>[[Thomas Bek (bishop of St David's)|]]</p>
 !! end
 
+!! test
+Piped link with empty link text
+!! wikitext
+[[Main Page|<nowiki />]] - empty nowiki
+[[Main Page| ]] - empty space
+[[Main Page|&nbsp;]] - empty non breaking space
+!! html/php
+<p><a href="/wiki/Main_Page" title="Main Page"></a> - empty nowiki
+<a href="/wiki/Main_Page" title="Main Page"> </a> - empty space
+<a href="/wiki/Main_Page" title="Main Page">&#160;</a> - empty non breaking space
+</p>
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="./Main_Page" title="Main Page"><meta typeof="mw:Placeholder" data-parsoid='{"src":"&lt;nowiki />"}'/></a> - empty nowiki
+<a rel="mw:WikiLink" href="./Main_Page" title="Main Page"> </a> - empty space
+<a rel="mw:WikiLink" href="./Main_Page" title="Main Page"><span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span></a> - empty non breaking space</p>
+!! end
+
 !! test
 Broken link
 !! wikitext
@@ -14726,8 +14770,10 @@ Simple category
 cat
 !! wikitext
 [[Category:MediaWiki User's Guide]]
-!! html
+!! html/php
 cat=MediaWiki_User's_Guide sort=
+!! html/parsoid
+<link rel="mw:PageProp/Category" href="./Category:MediaWiki_User's_Guide" data-parsoid='{"stx":"simple","a":{"href":"./Category:MediaWiki_User&#39;s_Guide"},"sa":{"href":"Category:MediaWiki User&#39;s Guide"}}'/>
 !! end
 
 !! test
@@ -14745,8 +14791,10 @@ Category with different sort key
 cat
 !! wikitext
 [[Category:MediaWiki User's Guide|Foo]]
-!! html
+!! html/php
 cat=MediaWiki_User's_Guide sort=Foo
+!! html/parsoid
+<link rel="mw:PageProp/Category" href="./Category:MediaWiki_User's_Guide#Foo" data-parsoid='{"stx":"piped","a":{"href":"./Category:MediaWiki_User&#39;s_Guide"},"sa":{"href":"Category:MediaWiki User&#39;s Guide"}}'/>
 !! end
 
 !! test
@@ -14755,8 +14803,10 @@ Category with identical sort key
 cat
 !! wikitext
 [[Category:MediaWiki User's Guide|MediaWiki User's Guide]]
-!! html
+!! html/php
 cat=MediaWiki_User's_Guide sort=MediaWiki User's Guide
+!! html/parsoid
+<link rel="mw:PageProp/Category" href="./Category:MediaWiki_User's_Guide#MediaWiki%20User's%20Guide" data-parsoid='{"stx":"piped","a":{"href":"./Category:MediaWiki_User&#39;s_Guide"},"sa":{"href":"Category:MediaWiki User&#39;s Guide"}}'/>
 !! end
 
 !! test
@@ -14781,22 +14831,15 @@ pst
 [[Category:Foo (bar)|Foo]]
 !! end
 
-## We used to, but no longer wt2wt this test since the default serializer
-## will normalize all categories to serialize on their own line.
-## This wikitext usage is going to be fairly uncommon in production and
-## selser will take care of preserving formatting in those scenarios.
 !! test
 Category with link tail
 !! options
 cat
 pst
-parsoid=wt2html
 !! wikitext
 123[[Category:Foo]]456
 !! html/php
 123[[Category:Foo]]456
-!! html/parsoid
-<p>123<link rel="mw:PageProp/Category" href="Category:Foo"/>456</p>
 !! end
 
 !! test
@@ -16707,11 +16750,11 @@ Expansion of multi-line templates in attribute values (bug 6255 sanity check 2)
 !! end
 
 !! test
-evil <math>-wiki-tags without Extension:Math enabled
+Tags which are hidden from Tidy cannot pass through the Sanitizer
 !! wikitext
-<math><img src="some evil external link"><script>some_evil_javascript();</script></math>
+<mw:toc><script>alert();</script></mw:toc>
 !! html+tidy
-<p>&lt;math&gt;&lt;img src="some evil external link"&gt;&lt;script&gt;some_evil_javascript();&lt;/script&gt;&lt;/math&gt;</p>
+<p>&lt;mw:toc&gt;&lt;script&gt;alert();&lt;/script&gt;&lt;/mw:toc&gt;</p>
 !! end
 
 ###
@@ -19095,7 +19138,7 @@ parsoid=wt2html,wt2wt,html2html
 <p><span typeof="mw:Entity">î</span><span typeof="mw:Entity">î</span></p>
 !! end
 
-# See: http://www.w3.org/TR/html5/syntax.html#character-references
+# See: https://www.w3.org/TR/html5/syntax.html#character-references
 # Note that U+000C (form feed) is not a valid XML character, so
 # it is banned even though allowed in HTML5.
 !! test
@@ -19860,18 +19903,18 @@ language=sr
 </p>
 !! end
 
-
 !! test
 Simple category in language variants
 !! options
 language=sr cat
 !! wikitext
 [[Category:МедиаWики Усер'с Гуиде]]
-!! html
+!! html/php
 cat=МедиаWики_Усер'с_Гуиде sort=
+!! html/parsoid
+<link rel="mw:PageProp/Category" href="./Категорија:МедиаWики_Усер'с_Гуиде" data-parsoid='{"stx":"simple","a":{"href":"./Категорија:МедиаWики_Усер&#39;с_Гуиде"},"sa":{"href":"Category:МедиаWики Усер&#39;с Гуиде"}}'/>
 !! end
 
-
 !! article
 Category:分类
 !! text
@@ -21651,6 +21694,22 @@ __TOC__
 
 !! end
 
+!! test
+T35715: s/strike element in ToC
+!! wikitext
+__TOC__
+== <s>test</s> test <strike>test</strike> ==
+!! html
+<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#test_test_test"><span class="tocnumber">1</span> <span class="toctext"><s>test</s> test <strike>test</strike></span></a></li>
+</ul>
+</div>
+
+<h2><span class="mw-headline" id="test_test_test"><s>test</s> test <strike>test</strike></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: test test test">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+
+!! end
+
 # Note that the html output does not have the <p></p>, but the
 # html+tidy output *does*.  This is because the empty <p></p> is
 # removed by the sanitizer, but only when tidy is *not* enabled (!).
@@ -24804,9 +24863,16 @@ Improperly nested inline or quotes tags with whitespace in between
 Encapsulate protected attributes from wt
 !! wikitext
 <div typeof="mw:placeholder stuff" data-mw="whoo" data-parsoid="weird" data-parsoid-other="no" about="time" rel="mw:true">foo</div>
+
+{| typeof="mw:placeholder stuff" data-mw="whoo" data-parsoid="weird" data-parsoid-other="no" about="time" rel="mw:true"
+| ok
+|}
 !! html/parsoid
-<body><div data-x-typeof="mw:placeholder stuff" data-x-data-mw="whoo" data-x-data-parsoid="weird" data-x-data-parsoid-other="no" data-x-about="time" data-x-rel="mw:true">foo</div>
-</body>
+<div data-x-typeof="mw:placeholder stuff" data-x-data-mw="whoo" data-x-data-parsoid="weird" data-x-data-parsoid-other="no" data-x-about="time" data-x-rel="mw:true">foo</div>
+
+<table data-x-typeof="mw:placeholder stuff" data-x-data-mw="whoo" data-x-data-parsoid="weird" data-x-data-parsoid-other="no" data-x-about="time" data-x-rel="mw:true">
+<tbody><tr><td data-parsoid='{"autoInsertedEnd":true}'> ok</td></tr>
+</tbody></table>
 !!end
 
 ## Currently the p-wrapper is fragile in how it adds / removes transformations.
index 45a7ce5..db1df5c 100644 (file)
@@ -81,6 +81,13 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         */
        private $mwGlobals = [];
 
+       /**
+        * Holds list of MediaWiki configuration settings to be unset in tearDown().
+        * See also setMwGlobals().
+        * @var array
+        */
+       private $mwGlobalsToUnset = [];
+
        /**
         * Holds original loggers which have been replaced by setLogger()
         * @var LoggerInterface[]
@@ -242,7 +249,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                 * 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.
                 */
-               $hashCache = [ 'class' => 'HashBagOStuff' ];
+               $hashCache = [ 'class' => 'HashBagOStuff', 'reportDupes' => false ];
                $objectCaches = [
                                CACHE_DB => $hashCache,
                                CACHE_ACCEL => $hashCache,
@@ -336,6 +343,10 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                JobQueueGroup::destroySingletons();
                ObjectCache::clear();
+               $services = MediaWikiServices::getInstance();
+               $services->resetServiceForTesting( 'MainObjectStash' );
+               $services->resetServiceForTesting( 'LocalServerObjectCache' );
+               $services->getMainWANObjectCache()->clearProcessCache();
                FileBackendGroup::destroySingleton();
 
                // TODO: move global state into MediaWikiServices
@@ -531,7 +542,11 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                foreach ( $this->mwGlobals as $key => $value ) {
                        $GLOBALS[$key] = $value;
                }
+               foreach ( $this->mwGlobalsToUnset as $value ) {
+                       unset( $GLOBALS[$value] );
+               }
                $this->mwGlobals = [];
+               $this->mwGlobalsToUnset = [];
                $this->restoreLoggers();
 
                if ( self::$serviceLocator && MediaWikiServices::getInstance() !== self::$serviceLocator ) {
@@ -680,8 +695,6 @@ 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().
         *
@@ -696,9 +709,13 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                        // NOTE: make sure we only save the global once or a second call to
                        // setMwGlobals() on the same global would override the original
                        // value.
-                       if ( !array_key_exists( $globalKey, $this->mwGlobals ) ) {
+                       if (
+                               !array_key_exists( $globalKey, $this->mwGlobals ) &&
+                               !array_key_exists( $globalKey, $this->mwGlobalsToUnset )
+                       ) {
                                if ( !array_key_exists( $globalKey, $GLOBALS ) ) {
-                                       throw new Exception( "Global with key {$globalKey} doesn't exist and cant be stashed" );
+                                       $this->mwGlobalsToUnset[$globalKey] = $globalKey;
+                                       continue;
                                }
                                // NOTE: we serialize then unserialize the value in case it is an object
                                // this stops any objects being passed by reference. We could use clone
@@ -1186,7 +1203,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                /** @var ExternalStoreDB $externalStoreDB */
                $externalStoreDB = ExternalStore::getStoreObject( 'DB' );
-               $defaultArray = (array) $wgDefaultExternalStore;
+               $defaultArray = (array)$wgDefaultExternalStore;
                $dbws = [];
                foreach ( $defaultArray as $url ) {
                        if ( strpos( $url, 'DB://' ) === 0 ) {
@@ -1213,7 +1230,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                        return false;
                }
 
-               $defaultArray = (array) $wgDefaultExternalStore;
+               $defaultArray = (array)$wgDefaultExternalStore;
                foreach ( $defaultArray as $url ) {
                        if ( strpos( $url, 'DB://' ) === 0 ) {
                                return true;
index f0eb12e..8eb1fd5 100644 (file)
@@ -4,6 +4,11 @@ use Psr\Log\LoggerInterface;
 use Psr\Log\NullLogger;
 
 abstract class ResourceLoaderTestCase extends MediaWikiTestCase {
+       // Version hash for a blank file module.
+       // Result of ResourceLoader::makeHash(), ResourceLoaderTestModule
+       // and ResourceLoaderFileModule::getDefinitionSummary().
+       const BLANK_VERSION = '09p30q0';
+
        /**
         * @param string $lang
         * @param string $dir
diff --git a/tests/phpunit/data/upload/buggynamespace-bad.svg b/tests/phpunit/data/upload/buggynamespace-bad.svg
new file mode 100644 (file)
index 0000000..974fac0
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1"
+        id="svg2" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:cc="http://creativecommons.org/ns#" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" inkscape:output_extension="org.inkscape.output.svg.inkscape" sodipodi:version="0.32" sodipodi:docname="India_location_map.svg" inkscape:version="0.46"
+        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1500px"
+        height="1614.844px" viewBox="0 0 1500 1614.844" enable-background="new 0 0 1500 1614.844" xml:space="preserve">
+<switch>
+       <foreignObject requiredExtensions="&ns_ai;" x="0" y="0" width="1" height="1">
+               <i:pgfRef  xlink:href="#adobe_illustrator_pgf">
+               </i:pgfRef>
+       </foreignObject>
+       <g i:extraneous="self">
+               <circle cx="750" cy="750" r="500" />
+       </g>
+</switch>
+<i:pgf  id="adobe_illustrator_pgf">
+       <![CDATA[
+       eJzsvWl3XjXyL3pf91r9HZ50MyQkfrw1awcIZCBAYyAQaEIzBMd+krjx1LYDzf/F+exXNUml/Qwx
+d1/++qv/+P2XX3/z1fc//9mvf/jyH796+/Lbc2Z9+eNXvzn/9Pbr77/64cfvvv/q7Ye//+53hNBH
++sFf/MXf/Nv/5ec/+38A7g2BFw==
+       ]]>
+</i:pgf>
+</svg>
diff --git a/tests/phpunit/data/upload/buggynamespace-evilhtml.svg b/tests/phpunit/data/upload/buggynamespace-evilhtml.svg
new file mode 100644 (file)
index 0000000..f4be479
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+       <!ENTITY ns_html "http://www.w3.org/1999/xhtml">
+]>
+<svg:svg version="1.1"
+        id="svg2"
+        xmlns="&ns_html;"
+        xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1500px"
+        height="1614.844px" viewBox="0 0 1500 1614.844" enable-background="new 0 0 1500 1614.844" xml:space="preserve">
+       <svg:g><div>foo</div></svg:g>
+</svg:svg>
diff --git a/tests/phpunit/data/upload/buggynamespace-okay.svg b/tests/phpunit/data/upload/buggynamespace-okay.svg
new file mode 100644 (file)
index 0000000..4a5c6aa
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   version="1.1"
+   width="1500"
+   height="1614.844"
+   viewBox="0 0 1500 1614.844"
+   id="svg2"
+   xml:space="preserve"><metadata
+   id="metadata15"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+   id="defs13" />
+<switch
+   id="switch3">
+       <foreignObject
+   id="foreignObject5"
+   height="1"
+   width="1"
+   y="0"
+   x="0"
+   requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/">
+               <i:pgfRef
+   xlink:href="#adobe_illustrator_pgf">
+               </i:pgfRef>
+       </foreignObject>
+       <g
+   id="g7">
+               <circle
+   cx="750"
+   cy="750"
+   r="500"
+   id="circle9" />
+       </g>
+</switch>
+<i:pgf
+   id="adobe_illustrator_pgf">
+       
+       eJzsvWl3XjXyL3pf91r9HZ50MyQkfrw1awcIZCBAYyAQaEIzBMd+krjx1LYDzf/F+exXNUml/Qwx
+d1/++qv/+P2XX3/z1fc//9mvf/jyH796+/Lbc2Z9+eNXvzn/9Pbr77/64cfvvv/q7Ye//+53hNBH
++sFf/MXf/Nv/5ec/+38A7g2BFw==
+       
+</i:pgf>
+</svg>
\ No newline at end of file
diff --git a/tests/phpunit/data/upload/buggynamespace-okay2.svg b/tests/phpunit/data/upload/buggynamespace-okay2.svg
new file mode 100644 (file)
index 0000000..fe42310
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:i="&amp;#38;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   version="1.1"
+   width="1500"
+   height="1614.844"
+   viewBox="0 0 1500 1614.844"
+   id="svg2"
+   xml:space="preserve"><metadata
+   id="metadata15"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+   id="defs13" />
+<switch
+   id="switch3">
+       <foreignObject
+   requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/"
+   x="0"
+   y="0"
+   width="1"
+   height="1"
+   id="foreignObject5">
+               <i:pgfRef
+   xlink:href="#adobe_illustrator_pgf">
+               </i:pgfRef>
+       </foreignObject>
+       <g
+   id="g7">
+               <circle
+   cx="750"
+   cy="750"
+   r="500"
+   id="circle9" />
+       </g>
+</switch>
+<i:pgf
+   id="adobe_illustrator_pgf">
+       
+       eJzsvWl3XjXyL3pf91r9HZ50MyQkfrw1awcIZCBAYyAQaEIzBMd+krjx1LYDzf/F+exXNUml/Qwx
+d1/++qv/+P2XX3/z1fc//9mvf/jyH796+/Lbc2Z9+eNXvzn/9Pbr77/64cfvvv/q7Ye//+53hNBH
++sFf/MXf/Nv/5ec/+38A7g2BFw==
+       
+</i:pgf>
+</svg>
\ No newline at end of file
diff --git a/tests/phpunit/data/upload/buggynamespace-original.svg b/tests/phpunit/data/upload/buggynamespace-original.svg
new file mode 100644 (file)
index 0000000..c61c91c
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+       <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
+       <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
+       <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
+       <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
+       <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
+       <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
+       <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
+       <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
+]>
+<svg version="1.1"
+        id="svg2" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:cc="http://creativecommons.org/ns#" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" inkscape:output_extension="org.inkscape.output.svg.inkscape" sodipodi:version="0.32" sodipodi:docname="India_location_map.svg" inkscape:version="0.46"
+        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1500px"
+        height="1614.844px" viewBox="0 0 1500 1614.844" enable-background="new 0 0 1500 1614.844" xml:space="preserve">
+<switch>
+       <foreignObject requiredExtensions="&ns_ai;" x="0" y="0" width="1" height="1">
+               <i:pgfRef  xlink:href="#adobe_illustrator_pgf">
+               </i:pgfRef>
+       </foreignObject>
+       <g i:extraneous="self">
+               <circle cx="750" cy="750" r="500" />
+       </g>
+</switch>
+<i:pgf  id="adobe_illustrator_pgf">
+       <![CDATA[
+       eJzsvWl3XjXyL3pf91r9HZ50MyQkfrw1awcIZCBAYyAQaEIzBMd+krjx1LYDzf/F+exXNUml/Qwx
+d1/++qv/+P2XX3/z1fc//9mvf/jyH796+/Lbc2Z9+eNXvzn/9Pbr77/64cfvvv/q7Ye//+53hNBH
++sFf/MXf/Nv/5ec/+38A7g2BFw==
+       ]]>
+</i:pgf>
+</svg>
index 5c4d1c0..e491d61 100644 (file)
@@ -52,6 +52,9 @@ class FormOptionsTest extends MediaWikiTestCase {
        private function assertGuessString( $data ) {
                $this->guess( FormOptions::STRING, $data );
        }
+       private function assertGuessArray( $data ) {
+               $this->guess( FormOptions::ARR, $data );
+       }
 
        /** Generic helper */
        private function guess( $expected, $data ) {
@@ -84,15 +87,10 @@ class FormOptionsTest extends MediaWikiTestCase {
                $this->assertGuessString( '5' );
                $this->assertGuessString( '0' );
                $this->assertGuessString( '1.5' );
-       }
 
-       /**
-        * @expectedException MWException
-        * @covers FormOptions::guessType
-        */
-       public function testGuessTypeOnArrayThrowException() {
-               $this->object->guessType( [ 'foo' ] );
+               $this->assertGuessArray( [ 'foo' ] );
        }
+
        /**
         * @expectedException MWException
         * @covers FormOptions::guessType
index 9f4a01c..89416f2 100644 (file)
@@ -18,7 +18,6 @@ class GitInfoTest extends MediaWikiTestCase {
                $this->assertEquals( 'master', $gitInfo->getCurrentBranch() );
                $this->assertContains( '0123456789abcdef0123456789abcdef01234567',
                        $gitInfo->getHeadViewUrl() );
-
        }
 
        public function testValidJsonData() {
index c76666d..8fbca6c 100644 (file)
@@ -11,7 +11,7 @@ class WfBCP47Test extends MediaWikiTestCase {
         * This test is used to verify our formatting against all lower and
         * all upper cases language code.
         *
-        * @see http://tools.ietf.org/html/bcp47
+        * @see https://tools.ietf.org/html/bcp47
         * @dataProvider provideLanguageCodes()
         */
        public function testBCP47( $code, $expected ) {
index bc50966..e2ee193 100644 (file)
@@ -92,7 +92,6 @@ class HtmlTest extends MediaWikiTestCase {
         * @covers Html::expandAttributes
         */
        public function testExpandAttributesSkipsNullAndFalse() {
-
                # ## EMPTY ########
                $this->assertEmpty(
                        Html::expandAttributes( [ 'foo' => null ] ),
@@ -190,7 +189,6 @@ class HtmlTest extends MediaWikiTestCase {
                        Html::expandAttributes( [ 'zero' => 0 ] ),
                        'Number 0 value needs no quotes'
                );
-
        }
 
        /**
@@ -447,7 +445,7 @@ class HtmlTest extends MediaWikiTestCase {
 
        /**
         * List of input element types values introduced by HTML5
-        * Full list at http://www.w3.org/TR/html-markup/input.html
+        * Full list at https://www.w3.org/TR/html-markup/input.html
         */
        public static function provideHtml5InputTypes() {
                $types = [
index ae0b4be..c3804c6 100644 (file)
@@ -188,7 +188,7 @@ class HttpTest extends MediaWikiTestCase {
 
        /**
         * Constant values are from PHP 5.3.28 using cURL 7.24.0
-        * @see http://php.net/manual/en/curl.constants.php
+        * @see https://secure.php.net/manual/en/curl.constants.php
         *
         * All constant values are present so that developers don’t need to remember
         * to add them if added at a later date. The commented out constants were
index 61b165a..428b012 100644 (file)
@@ -6,7 +6,6 @@
 class LinkFilterTest extends MediaWikiLangTestCase {
 
        protected function setUp() {
-
                parent::setUp();
 
                $this->setMwGlobals( 'wgUrlProtocols', [
@@ -26,7 +25,6 @@ class LinkFilterTest extends MediaWikiLangTestCase {
                        'mms://',
                        '//',
                ] );
-
        }
 
        /**
@@ -38,11 +36,9 @@ class LinkFilterTest extends MediaWikiLangTestCase {
         * @return string Regex
         */
        function createRegexFromLIKE( $like ) {
-
                $regex = '!^';
 
                foreach ( $like as $item ) {
-
                        if ( $item instanceof LikeMatch ) {
                                if ( $item->toString() == '%' ) {
                                        $regex .= '.*';
@@ -58,7 +54,6 @@ class LinkFilterTest extends MediaWikiLangTestCase {
                $regex .= '$!';
 
                return $regex;
-
        }
 
        /**
@@ -67,7 +62,6 @@ class LinkFilterTest extends MediaWikiLangTestCase {
         * @return array
         */
        public static function provideValidPatterns() {
-
                return [
                        // Protocol, Search pattern, URL which matches the pattern
                        [ 'http://', '*.test.com', 'http://www.test.com' ],
@@ -164,7 +158,6 @@ class LinkFilterTest extends MediaWikiLangTestCase {
                        // [ '', 'https://*.wikimedia.org/r/#/q/status:open,n,z',
                        //      'https://gerrit.wikimedia.org/XXX/r/#/q/status:open,n,z', false ],
                ];
-
        }
 
        /**
@@ -181,7 +174,6 @@ class LinkFilterTest extends MediaWikiLangTestCase {
         * @param bool $shouldBeFound Should the URL be found? (defaults true)
         */
        function testMakeLikeArrayWithValidPatterns( $protocol, $pattern, $url, $shouldBeFound = true ) {
-
                $indexes = wfMakeUrlIndexes( $url );
                $likeArray = LinkFilter::makeLikeArray( $pattern, $protocol );
 
@@ -211,7 +203,6 @@ class LinkFilterTest extends MediaWikiLangTestCase {
                                "Search pattern '$protocol$pattern' should not find url '$url' \n$debugmsg"
                        );
                }
-
        }
 
        /**
@@ -220,7 +211,6 @@ class LinkFilterTest extends MediaWikiLangTestCase {
         * @return array
         */
        public static function provideInvalidPatterns() {
-
                return [
                        [ '' ],
                        [ '*' ],
@@ -240,7 +230,6 @@ class LinkFilterTest extends MediaWikiLangTestCase {
                        [ 'test.com/*/index' ],
                        [ 'test.com/dir/index?arg=*' ],
                ];
-
        }
 
        /**
@@ -253,12 +242,10 @@ class LinkFilterTest extends MediaWikiLangTestCase {
         * @param string $pattern Invalid search pattern
         */
        function testMakeLikeArrayWithInvalidPatterns( $pattern ) {
-
                $this->assertFalse(
                        LinkFilter::makeLikeArray( $pattern ),
                        "'$pattern' is not a valid pattern and should be rejected"
                );
-
        }
 
 }
index a05e39d..dc0c64c 100644 (file)
@@ -312,16 +312,23 @@ class MediaWikiServicesTest extends MediaWikiTestCase {
                        'DBLoadBalancer' => [ 'DBLoadBalancer', 'LoadBalancer' ],
                        'WatchedItemStore' => [ 'WatchedItemStore', WatchedItemStore::class ],
                        'WatchedItemQueryService' => [ 'WatchedItemQueryService', WatchedItemQueryService::class ],
+                       'CryptRand' => [ 'CryptRand', CryptRand::class ],
+                       'CryptHKDF' => [ 'CryptHKDF', CryptHKDF::class ],
                        'MediaHandlerFactory' => [ 'MediaHandlerFactory', MediaHandlerFactory::class ],
+                       'Parser' => [ 'Parser', Parser::class ],
                        'GenderCache' => [ 'GenderCache', GenderCache::class ],
                        'LinkCache' => [ 'LinkCache', LinkCache::class ],
                        'LinkRenderer' => [ 'LinkRenderer', LinkRenderer::class ],
                        'LinkRendererFactory' => [ 'LinkRendererFactory', LinkRendererFactory::class ],
                        '_MediaWikiTitleCodec' => [ '_MediaWikiTitleCodec', MediaWikiTitleCodec::class ],
+                       'MimeAnalyzer' => [ 'MimeAnalyzer', MimeAnalyzer::class ],
                        'TitleFormatter' => [ 'TitleFormatter', TitleFormatter::class ],
                        'TitleParser' => [ 'TitleParser', TitleParser::class ],
-                       'VirtualRESTServiceClient' => [ 'VirtualRESTServiceClient', VirtualRESTServiceClient::class ],
-                       'ProxyLookup' => [ 'ProxyLookup', ProxyLookup::class ]
+                       'ProxyLookup' => [ 'ProxyLookup', ProxyLookup::class ],
+                       'MainObjectStash' => [ 'MainObjectStash', BagOStuff::class ],
+                       'MainWANObjectCache' => [ 'MainWANObjectCache', WANObjectCache::class ],
+                       'LocalServerObjectCache' => [ 'LocalServerObjectCache', BagOStuff::class ],
+                       'VirtualRESTServiceClient' => [ 'VirtualRESTServiceClient', VirtualRESTServiceClient::class ]
                ];
        }
 
index df92012..a8d1e33 100644 (file)
@@ -34,7 +34,7 @@ class MediaWikiTest extends MediaWikiTestCase {
                                'url' => 'http://example.org/w/index.php?title=Foo_Bar',
                                'query' => [ 'title' => 'Foo_Bar' ],
                                'title' => 'Foo_Bar',
-                               'redirect' => 'http://example.org/wiki/Foo_Bar',
+                               'redirect' => false,
                        ],
                        [
                                // View: Script path with implicit title from page id
@@ -76,21 +76,21 @@ class MediaWikiTest extends MediaWikiTestCase {
                                'url' => 'http://example.org/w/?title=Foo_Bar',
                                'query' => [ 'title' => 'Foo_Bar' ],
                                'title' => 'Foo_Bar',
-                               'redirect' => 'http://example.org/wiki/Foo_Bar',
+                               'redirect' => false,
                        ],
                        [
                                // View: Root path with escaped title
                                'url' => 'http://example.org/?title=Foo_Bar',
                                'query' => [ 'title' => 'Foo_Bar' ],
                                'title' => 'Foo_Bar',
-                               'redirect' => 'http://example.org/wiki/Foo_Bar',
+                               'redirect' => false,
                        ],
                        [
                                // View: Canonical with redundant query
                                'url' => 'http://example.org/wiki/Foo_Bar?action=view',
                                'query' => [ 'action' => 'view' ],
                                'title' => 'Foo_Bar',
-                               'redirect' => 'http://example.org/wiki/Foo_Bar',
+                               'redirect' => false,
                        ],
                        [
                                // Edit: Canonical view url with action query
@@ -104,7 +104,7 @@ class MediaWikiTest extends MediaWikiTestCase {
                                'url' => 'http://example.org/w/index.php?title=Foo_Bar&action=view',
                                'query' => [ 'title' => 'Foo_Bar', 'action' => 'view' ],
                                'title' => 'Foo_Bar',
-                               'redirect' => 'http://example.org/wiki/Foo_Bar',
+                               'redirect' => false,
                        ],
                        [
                                // Edit: Index with action query
index 4c689ab..8390e1f 100644 (file)
@@ -18,8 +18,8 @@ class MessageTest extends MediaWikiLangTestCase {
        public function testConstructor( $expectedLang, $key, $params, $language ) {
                $message = new Message( $key, $params, $language );
 
-               $this->assertEquals( $key, $message->getKey() );
-               $this->assertEquals( $params, $message->getParams() );
+               $this->assertSame( $key, $message->getKey() );
+               $this->assertSame( $params, $message->getParams() );
                $this->assertEquals( $expectedLang, $message->getLanguage() );
 
                $messageSpecifier = $this->getMockForAbstractClass( 'MessageSpecifier' );
@@ -29,8 +29,8 @@ class MessageTest extends MediaWikiLangTestCase {
                        ->method( 'getParams' )->will( $this->returnValue( $params ) );
                $message = new Message( $messageSpecifier, [], $language );
 
-               $this->assertEquals( $key, $message->getKey() );
-               $this->assertEquals( $params, $message->getParams() );
+               $this->assertSame( $key, $message->getKey() );
+               $this->assertSame( $params, $message->getParams() );
                $this->assertEquals( $expectedLang, $message->getLanguage() );
        }
 
@@ -97,7 +97,7 @@ class MessageTest extends MediaWikiLangTestCase {
                $returned = call_user_func_array( [ $msg, 'params' ], $args );
 
                $this->assertSame( $msg, $returned );
-               $this->assertEquals( $expected, $msg->getParams() );
+               $this->assertSame( $expected, $msg->getParams() );
        }
 
        public static function provideConstructorLanguage() {
@@ -165,8 +165,8 @@ class MessageTest extends MediaWikiLangTestCase {
 
                $msg = new Message( $key );
                $this->assertContains( $msg->getKey(), $expected );
-               $this->assertEquals( $expected, $msg->getKeysToTry() );
-               $this->assertEquals( count( $expected ) > 1, $msg->isMultiKey() );
+               $this->assertSame( $expected, $msg->getKeysToTry() );
+               $this->assertSame( count( $expected ) > 1, $msg->isMultiKey() );
        }
 
        /**
@@ -190,13 +190,13 @@ class MessageTest extends MediaWikiLangTestCase {
         * @covers Message::__construct
         */
        public function testWfMessageParams() {
-               $this->assertEquals( 'Return to $1.', wfMessage( 'returnto' )->text() );
-               $this->assertEquals( 'Return to $1.', wfMessage( 'returnto', [] )->text() );
-               $this->assertEquals(
+               $this->assertSame( 'Return to $1.', wfMessage( 'returnto' )->text() );
+               $this->assertSame( 'Return to $1.', wfMessage( 'returnto', [] )->text() );
+               $this->assertSame(
                        'You have foo (bar).',
                        wfMessage( 'youhavenewmessages', 'foo', 'bar' )->text()
                );
-               $this->assertEquals(
+               $this->assertSame(
                        'You have foo (bar).',
                        wfMessage( 'youhavenewmessages', [ 'foo', 'bar' ] )->text()
                );
@@ -222,13 +222,13 @@ class MessageTest extends MediaWikiLangTestCase {
         * @covers Message::toString
         */
        public function testToStringKey() {
-               $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->text() );
-               $this->assertEquals( '⧼i-dont-exist-evar⧽', wfMessage( 'i-dont-exist-evar' )->text() );
-               $this->assertEquals( '⧼i&lt;dont&gt;exist-evar⧽', wfMessage( 'i<dont>exist-evar' )->text() );
-               $this->assertEquals( '⧼i-dont-exist-evar⧽', wfMessage( 'i-dont-exist-evar' )->plain() );
-               $this->assertEquals( '⧼i&lt;dont&gt;exist-evar⧽', wfMessage( 'i<dont>exist-evar' )->plain() );
-               $this->assertEquals( '⧼i-dont-exist-evar⧽', wfMessage( 'i-dont-exist-evar' )->escaped() );
-               $this->assertEquals(
+               $this->assertSame( 'Main Page', wfMessage( 'mainpage' )->text() );
+               $this->assertSame( '⧼i-dont-exist-evar⧽', wfMessage( 'i-dont-exist-evar' )->text() );
+               $this->assertSame( '⧼i&lt;dont&gt;exist-evar⧽', wfMessage( 'i<dont>exist-evar' )->text() );
+               $this->assertSame( '⧼i-dont-exist-evar⧽', wfMessage( 'i-dont-exist-evar' )->plain() );
+               $this->assertSame( '⧼i&lt;dont&gt;exist-evar⧽', wfMessage( 'i<dont>exist-evar' )->plain() );
+               $this->assertSame( '⧼i-dont-exist-evar⧽', wfMessage( 'i-dont-exist-evar' )->escaped() );
+               $this->assertSame(
                        '⧼i&lt;dont&gt;exist-evar⧽',
                        wfMessage( 'i<dont>exist-evar' )->escaped()
                );
@@ -236,11 +236,14 @@ class MessageTest extends MediaWikiLangTestCase {
 
        public static function provideToString() {
                return [
-                       [ 'mainpage', 'Main Page' ],
-                       [ 'i-dont-exist-evar', '⧼i-dont-exist-evar⧽' ],
-                       [ 'i-dont-exist-evar', '⧼i-dont-exist-evar⧽', 'escaped' ],
-                       [ 'script>alert(1)</script', '⧼script&gt;alert(1)&lt;/script⧽', 'escaped' ],
-                       [ 'script>alert(1)</script', '⧼script&gt;alert(1)&lt;/script⧽' ],
+                       // key, transformation, transformed, transformed implicitly
+                       [ 'mainpage', 'plain', 'Main Page', 'Main Page' ],
+                       [ 'i-dont-exist-evar', 'plain', '⧼i-dont-exist-evar⧽', '⧼i-dont-exist-evar⧽' ],
+                       [ 'i-dont-exist-evar', 'escaped', '⧼i-dont-exist-evar⧽', '⧼i-dont-exist-evar⧽' ],
+                       [ 'script>alert(1)</script', 'escaped', '⧼script&gt;alert(1)&lt;/script⧽',
+                               '⧼script&gt;alert(1)&lt;/script⧽' ],
+                       [ 'script>alert(1)</script', 'plain', '⧼script&gt;alert(1)&lt;/script⧽',
+                               '⧼script&gt;alert(1)&lt;/script⧽' ],
                ];
        }
 
@@ -249,25 +252,59 @@ class MessageTest extends MediaWikiLangTestCase {
         * @covers Message::__toString
         * @dataProvider provideToString
         */
-       public function testToString( $key, $expect, $format = 'plain' ) {
+       public function testToString( $key, $format, $expect, $expectImplicit ) {
                $msg = new Message( $key );
-               $msg->$format();
-               $this->assertEquals( $expect, $msg->toString() );
-               $this->assertEquals( $expect, $msg->__toString() );
+               $this->assertSame( $expect, $msg->$format() );
+               $this->assertSame( $expect, $msg->toString(), 'toString is unaffected by previous call' );
+               $this->assertSame( $expectImplicit, $msg->__toString() );
+               $this->assertSame( $expect, $msg->toString(), 'toString is unaffected by __toString' );
+       }
+
+       public static function provideToString_raw() {
+               return [
+                       [ '<span>foo</span>', 'parse', '<span>foo</span>', '<span>foo</span>' ],
+                       [ '<span>foo</span>', 'escaped', '&lt;span&gt;foo&lt;/span&gt;',
+                         '<span>foo</span>' ],
+                       [ '<span>foo</span>', 'plain', '<span>foo</span>', '<span>foo</span>' ],
+                       [ '<script>alert(1)</script>', 'parse', '&lt;script&gt;alert(1)&lt;/script&gt;',
+                               '&lt;script&gt;alert(1)&lt;/script&gt;' ],
+                       [ '<script>alert(1)</script>', 'escaped', '&lt;script&gt;alert(1)&lt;/script&gt;',
+                               '&lt;script&gt;alert(1)&lt;/script&gt;' ],
+                       [ '<script>alert(1)</script>', 'plain', '<script>alert(1)</script>',
+                         '&lt;script&gt;alert(1)&lt;/script&gt;' ],
+               ];
+       }
+
+       /**
+        * @covers Message::toString
+        * @covers Message::__toString
+        * @dataProvider provideToString_raw
+        */
+       public function testToString_raw( $message, $format, $expect, $expectImplicit ) {
+               // make the message behave like RawMessage and use the key as-is
+               $msg = $this->getMockBuilder( Message::class )->setMethods( [ 'fetchMessage' ] )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $msg->expects( $this->any() )->method( 'fetchMessage' )->willReturn( $message );
+               /** @var Message $msg */
+               $this->assertSame( $expect, $msg->$format() );
+               $this->assertSame( $expect, $msg->toString(), 'toString is unaffected by previous call' );
+               $this->assertSame( $expectImplicit, $msg->__toString() );
+               $this->assertSame( $expect, $msg->toString(), 'toString is unaffected by __toString' );
        }
 
        /**
         * @covers Message::inLanguage
         */
        public function testInLanguage() {
-               $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inLanguage( 'en' )->text() );
-               $this->assertEquals( 'Заглавная страница',
+               $this->assertSame( 'Main Page', wfMessage( 'mainpage' )->inLanguage( 'en' )->text() );
+               $this->assertSame( 'Заглавная страница',
                        wfMessage( 'mainpage' )->inLanguage( 'ru' )->text() );
 
                // NOTE: make sure internal caching of the message text is reset appropriately
                $msg = wfMessage( 'mainpage' );
-               $this->assertEquals( 'Main Page', $msg->inLanguage( Language::factory( 'en' ) )->text() );
-               $this->assertEquals(
+               $this->assertSame( 'Main Page', $msg->inLanguage( Language::factory( 'en' ) )->text() );
+               $this->assertSame(
                        'Заглавная страница',
                        $msg->inLanguage( Language::factory( 'ru' ) )->text()
                );
@@ -278,19 +315,19 @@ class MessageTest extends MediaWikiLangTestCase {
         * @covers Message::rawParams
         */
        public function testRawParams() {
-               $this->assertEquals(
+               $this->assertSame(
                        '(Заглавная страница)',
                        wfMessage( 'parentheses', 'Заглавная страница' )->plain()
                );
-               $this->assertEquals(
+               $this->assertSame(
                        '(Заглавная страница $1)',
                        wfMessage( 'parentheses', 'Заглавная страница $1' )->plain()
                );
-               $this->assertEquals(
+               $this->assertSame(
                        '(Заглавная страница)',
                        wfMessage( 'parentheses' )->rawParams( 'Заглавная страница' )->plain()
                );
-               $this->assertEquals(
+               $this->assertSame(
                        '(Заглавная страница $1)',
                        wfMessage( 'parentheses' )->rawParams( 'Заглавная страница $1' )->plain()
                );
@@ -302,8 +339,8 @@ class MessageTest extends MediaWikiLangTestCase {
         */
        public function testRawMessage() {
                $msg = new RawMessage( 'example &' );
-               $this->assertEquals( 'example &', $msg->plain() );
-               $this->assertEquals( 'example &amp;', $msg->escaped() );
+               $this->assertSame( 'example &', $msg->plain() );
+               $this->assertSame( 'example &amp;', $msg->escaped() );
        }
 
        /**
@@ -315,7 +352,7 @@ class MessageTest extends MediaWikiLangTestCase {
                $msg = new RawMessage( '$1$2$3$4$5$6$7$8$9$10$11$12' );
                // One less than above has placeholders
                $params = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k' ];
-               $this->assertEquals(
+               $this->assertSame(
                        'abcdefghijka2',
                        $msg->params( $params )->plain(),
                        'Params > 9 are replaced correctly'
@@ -323,7 +360,7 @@ class MessageTest extends MediaWikiLangTestCase {
 
                $msg = new RawMessage( 'Params$*' );
                $params = [ 'ab', 'bc', 'cd' ];
-               $this->assertEquals(
+               $this->assertSame(
                        'Params: ab, bc, cd',
                        $msg->params( $params )->text()
                );
@@ -337,7 +374,7 @@ class MessageTest extends MediaWikiLangTestCase {
                $lang = Language::factory( 'en' );
                $msg = new RawMessage( '$1' );
 
-               $this->assertEquals(
+               $this->assertSame(
                        $lang->formatNum( 123456.789 ),
                        $msg->inLanguage( $lang )->numParams( 123456.789 )->plain(),
                        'numParams is handled correctly'
@@ -352,7 +389,7 @@ class MessageTest extends MediaWikiLangTestCase {
                $lang = Language::factory( 'en' );
                $msg = new RawMessage( '$1' );
 
-               $this->assertEquals(
+               $this->assertSame(
                        $lang->formatDuration( 1234 ),
                        $msg->inLanguage( $lang )->durationParams( 1234 )->plain(),
                        'durationParams is handled correctly'
@@ -369,7 +406,7 @@ class MessageTest extends MediaWikiLangTestCase {
                $lang = Language::factory( 'en' );
                $msg = new RawMessage( '$1' );
 
-               $this->assertEquals(
+               $this->assertSame(
                        $lang->formatExpiry( wfTimestampNow() ),
                        $msg->inLanguage( $lang )->expiryParams( wfTimestampNow() )->plain(),
                        'expiryParams is handled correctly'
@@ -384,7 +421,7 @@ class MessageTest extends MediaWikiLangTestCase {
                $lang = Language::factory( 'en' );
                $msg = new RawMessage( '$1' );
 
-               $this->assertEquals(
+               $this->assertSame(
                        $lang->formatTimePeriod( 1234 ),
                        $msg->inLanguage( $lang )->timeperiodParams( 1234 )->plain(),
                        'timeperiodParams is handled correctly'
@@ -399,7 +436,7 @@ class MessageTest extends MediaWikiLangTestCase {
                $lang = Language::factory( 'en' );
                $msg = new RawMessage( '$1' );
 
-               $this->assertEquals(
+               $this->assertSame(
                        $lang->formatSize( 123456 ),
                        $msg->inLanguage( $lang )->sizeParams( 123456 )->plain(),
                        'sizeParams is handled correctly'
@@ -414,7 +451,7 @@ class MessageTest extends MediaWikiLangTestCase {
                $lang = Language::factory( 'en' );
                $msg = new RawMessage( '$1' );
 
-               $this->assertEquals(
+               $this->assertSame(
                        $lang->formatBitrate( 123456 ),
                        $msg->inLanguage( $lang )->bitrateParams( 123456 )->plain(),
                        'bitrateParams is handled correctly'
@@ -468,7 +505,7 @@ class MessageTest extends MediaWikiLangTestCase {
                        'one $2',
                        '<div>foo</div> [[Bar]] {{Baz}} &lt;',
                ];
-               $this->assertEquals(
+               $this->assertSame(
                        $expect,
                        $msg->inLanguage( $lang )->plaintextParams( $params )->$format(),
                        "Fail formatting for $format"
@@ -509,7 +546,7 @@ class MessageTest extends MediaWikiLangTestCase {
         */
        public function testParser( $expect, $format ) {
                $msg = new RawMessage( "''&'' <x><!-- x -->" );
-               $this->assertEquals(
+               $this->assertSame(
                        $expect,
                        $msg->inLanguage( 'en' )->$format()
                );
@@ -523,9 +560,9 @@ class MessageTest extends MediaWikiLangTestCase {
 
                // NOTE: make sure internal caching of the message text is reset appropriately
                $msg = wfMessage( 'mainpage' );
-               $this->assertEquals( 'Hauptseite', $msg->inLanguage( 'de' )->plain(), "inLanguage( 'de' )" );
-               $this->assertEquals( 'Main Page', $msg->inContentLanguage()->plain(), "inContentLanguage()" );
-               $this->assertEquals( 'Accueil', $msg->inLanguage( 'fr' )->plain(), "inLanguage( 'fr' )" );
+               $this->assertSame( 'Hauptseite', $msg->inLanguage( 'de' )->plain(), "inLanguage( 'de' )" );
+               $this->assertSame( 'Main Page', $msg->inContentLanguage()->plain(), "inContentLanguage()" );
+               $this->assertSame( 'Accueil', $msg->inLanguage( 'fr' )->plain(), "inLanguage( 'fr' )" );
        }
 
        /**
@@ -540,18 +577,18 @@ class MessageTest extends MediaWikiLangTestCase {
                // NOTE: make sure internal caching of the message text is reset appropriately.
                // NOTE: wgForceUIMsgAsContentMsg forces the messages *current* language to be used.
                $msg = wfMessage( 'mainpage' );
-               $this->assertEquals(
+               $this->assertSame(
                        'Accueil',
                        $msg->inContentLanguage()->plain(),
                        'inContentLanguage() with ForceUIMsg override enabled'
                );
-               $this->assertEquals( 'Main Page', $msg->inLanguage( 'en' )->plain(), "inLanguage( 'en' )" );
-               $this->assertEquals(
+               $this->assertSame( 'Main Page', $msg->inLanguage( 'en' )->plain(), "inLanguage( 'en' )" );
+               $this->assertSame(
                        'Main Page',
                        $msg->inContentLanguage()->plain(),
                        'inContentLanguage() with ForceUIMsg override enabled'
                );
-               $this->assertEquals( 'Hauptseite', $msg->inLanguage( 'de' )->plain(), "inLanguage( 'de' )" );
+               $this->assertSame( 'Hauptseite', $msg->inLanguage( 'de' )->plain(), "inLanguage( 'de' )" );
        }
 
        /**
@@ -570,18 +607,18 @@ class MessageTest extends MediaWikiLangTestCase {
                $msg = new Message( 'parentheses' );
                $msg->rawParams( '<a>foo</a>' );
                $msg->title( Title::newFromText( 'Testing' ) );
-               $this->assertEquals( '(<a>foo</a>)', $msg->parse(), 'Sanity check' );
+               $this->assertSame( '(<a>foo</a>)', $msg->parse(), 'Sanity check' );
                $msg = unserialize( serialize( $msg ) );
-               $this->assertEquals( '(<a>foo</a>)', $msg->parse() );
+               $this->assertSame( '(<a>foo</a>)', $msg->parse() );
                $title = TestingAccessWrapper::newFromObject( $msg )->title;
                $this->assertInstanceOf( 'Title', $title );
-               $this->assertEquals( 'Testing', $title->getFullText() );
+               $this->assertSame( 'Testing', $title->getFullText() );
 
                $msg = new Message( 'mainpage' );
                $msg->inLanguage( 'de' );
-               $this->assertEquals( 'Hauptseite', $msg->plain(), 'Sanity check' );
+               $this->assertSame( 'Hauptseite', $msg->plain(), 'Sanity check' );
                $msg = unserialize( serialize( $msg ) );
-               $this->assertEquals( 'Hauptseite', $msg->plain() );
+               $this->assertSame( 'Hauptseite', $msg->plain() );
        }
 
        /**
@@ -614,4 +651,3 @@ class MessageTest extends MediaWikiLangTestCase {
                ];
        }
 }
-
diff --git a/tests/phpunit/includes/MimeMagicTest.php b/tests/phpunit/includes/MimeMagicTest.php
deleted file mode 100644 (file)
index e00cf0c..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-class MimeMagicTest extends PHPUnit_Framework_TestCase {
-
-       /** @var MimeMagic */
-       private $mimeMagic;
-
-       function setUp() {
-               $this->mimeMagic = MimeMagic::singleton();
-               parent::setUp();
-       }
-
-       /**
-        * @dataProvider providerImproveTypeFromExtension
-        * @param string $ext File extension (no leading dot)
-        * @param string $oldMime Initially detected MIME
-        * @param string $expectedMime MIME type after taking extension into account
-        */
-       function testImproveTypeFromExtension( $ext, $oldMime, $expectedMime ) {
-               $actualMime = $this->mimeMagic->improveTypeFromExtension( $oldMime, $ext );
-               $this->assertEquals( $expectedMime, $actualMime );
-       }
-
-       function providerImproveTypeFromExtension() {
-               return [
-                       [ 'gif', 'image/gif', 'image/gif' ],
-                       [ 'gif', 'unknown/unknown', 'unknown/unknown' ],
-                       [ 'wrl', 'unknown/unknown', 'model/vrml' ],
-                       [ 'txt', 'text/plain', 'text/plain' ],
-                       [ 'csv', 'text/plain', 'text/csv' ],
-                       [ 'tsv', 'text/plain', 'text/tab-separated-values' ],
-                       [ 'js', 'text/javascript', 'application/javascript' ],
-                       [ 'js', 'application/x-javascript', 'application/javascript' ],
-                       [ 'json', 'text/plain', 'application/json' ],
-                       [ 'foo', 'application/x-opc+zip', 'application/zip' ],
-                       [ 'docx', 'application/x-opc+zip',
-                               'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ],
-                       [ 'djvu', 'image/x-djvu', 'image/vnd.djvu' ],
-                       [ 'wav', 'audio/wav', 'audio/wav' ],
-               ];
-       }
-
-       /**
-        * Test to make sure that encoder=ffmpeg2theora doesn't trigger
-        * MEDIATYPE_VIDEO (bug 63584)
-        */
-       function testOggRecognize() {
-               $oggFile = __DIR__ . '/../data/media/say-test.ogg';
-               $actualType = $this->mimeMagic->getMediaType( $oggFile, 'application/ogg' );
-               $this->assertEquals( $actualType, MEDIATYPE_AUDIO );
-       }
-}
index cc1708a..29c9e22 100644 (file)
@@ -266,11 +266,9 @@ class TestPageProps extends MediaWikiLangTestCase {
        }
 
        protected function setProperties( $pageID, $properties ) {
-
                $rows = [];
 
                foreach ( $properties as $propertyName => $propertyValue ) {
-
                        $row = [
                                'pp_page' => $pageID,
                                'pp_propname' => $propertyName,
@@ -295,11 +293,9 @@ class TestPageProps extends MediaWikiLangTestCase {
        }
 
        protected function setProperty( $pageID, $propertyName, $propertyValue ) {
-
                $properties = [];
                $properties[$propertyName] = $propertyValue;
 
                $this->setProperties( $pageID, $properties );
-
        }
 }
index 7c31384..02935a5 100644 (file)
@@ -32,7 +32,7 @@ class TestSample extends MediaWikiLangTestCase {
         * they run.  While MediaWiki isn't strictly an Agile Programming
         * project, you are encouraged to use the naming described under
         * "Agile Documentation" at
-        * http://www.phpunit.de/manual/3.4/en/other-uses-for-tests.html
+        * https://www.phpunit.de/manual/3.4/en/other-uses-for-tests.html
         */
        public function testTitleObjectStringConversion() {
                $title = Title::newFromText( "text" );
@@ -45,7 +45,7 @@ class TestSample extends MediaWikiLangTestCase {
 
        /**
         * If you want to run a the same test with a variety of data, use a data provider.
-        * see: http://www.phpunit.de/manual/3.4/en/writing-tests-for-phpunit.html
+        * see: https://www.phpunit.de/manual/3.4/en/writing-tests-for-phpunit.html
         */
        public static function provideTitles() {
                return [
@@ -60,7 +60,7 @@ class TestSample extends MediaWikiLangTestCase {
        // @codingStandardsIgnoreStart Generic.Files.LineLength
        /**
         * @dataProvider provideTitles
-        * See http://phpunit.de/manual/3.7/en/appendixes.annotations.html#appendixes.annotations.dataProvider
+        * See https://phpunit.de/manual/3.7/en/appendixes.annotations.html#appendixes.annotations.dataProvider
         */
        // @codingStandardsIgnoreEnd
        public function testCreateBasicListOfTitles( $titleName, $ns, $text ) {
@@ -89,7 +89,7 @@ class TestSample extends MediaWikiLangTestCase {
 
        /**
         * @depends testSetUpMainPageTitleForNextTest
-        * See http://phpunit.de/manual/3.7/en/appendixes.annotations.html#appendixes.annotations.depends
+        * See https://phpunit.de/manual/3.7/en/appendixes.annotations.html#appendixes.annotations.depends
         */
        public function testCheckMainPageTitleIsConsideredLocal( $title ) {
                $this->assertTrue( $title->isLocal() );
@@ -98,7 +98,7 @@ class TestSample extends MediaWikiLangTestCase {
        // @codingStandardsIgnoreStart Generic.Files.LineLength
        /**
         * @expectedException InvalidArgumentException
-        * See http://phpunit.de/manual/3.7/en/appendixes.annotations.html#appendixes.annotations.expectedException
+        * See https://phpunit.de/manual/3.7/en/appendixes.annotations.html#appendixes.annotations.expectedException
         */
        // @codingStandardsIgnoreEnd
        public function testTitleObjectFromObject() {
index 26529e8..12db1a1 100644 (file)
@@ -134,19 +134,19 @@ class SanitizerTest extends MediaWikiTestCase {
                                'Self-closing closing div'
                        ],
                        // Make sure special nested HTML5 semantics are not broken
-                       // http://www.whatwg.org/html/text-level-semantics.html#the-kbd-element
+                       // https://html.spec.whatwg.org/multipage/semantics.html#the-kbd-element
                        [
                                '<kbd><kbd>Shift</kbd>+<kbd>F3</kbd></kbd>',
                                '<kbd><kbd>Shift</kbd>+<kbd>F3</kbd></kbd>',
                                'Nested <kbd>.'
                        ],
-                       // http://www.whatwg.org/html/text-level-semantics.html#the-sub-and-sup-elements
+                       // https://html.spec.whatwg.org/multipage/semantics.html#the-sub-and-sup-elements
                        [
                                '<var>x<sub><var>i</var></sub></var>, <var>y<sub><var>i</var></sub></var>',
                                '<var>x<sub><var>i</var></sub></var>, <var>y<sub><var>i</var></sub></var>',
                                'Nested <var>.'
                        ],
-                       // http://www.whatwg.org/html/text-level-semantics.html#the-dfn-element
+                       // https://html.spec.whatwg.org/multipage/semantics.html#the-dfn-element
                        [
                                '<dfn><abbr title="Garage Door Opener">GDO</abbr></dfn>',
                                '<dfn><abbr title="Garage Door Opener">GDO</abbr></dfn>',
@@ -314,6 +314,8 @@ class SanitizerTest extends MediaWikiTestCase {
                                '/* insecure input */',
                                'background-image: -moz-image-set("asdf.png" 1x, "asdf.png" 2x);'
                        ],
+                       [ '/* insecure input */', 'foo: attr( title, url );' ],
+                       [ '/* insecure input */', 'foo: attr( title url );' ],
                ];
        }
 
index 9359568..152602a 100644 (file)
@@ -91,6 +91,5 @@ class TemplateCategoriesTest extends MediaWikiLangTestCase {
                        $title->getParentCategories(),
                        'Verify that the page is no longer in the category after template deletion'
                );
-
        }
 }
index 93e0b57..93687df 100644 (file)
@@ -55,7 +55,7 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                        ->disableOriginalConstructor()
                        ->getMock();
                $mock->expects( $this->any() )
-                       ->method( 'getConnection' )
+                       ->method( 'getConnectionRef' )
                        ->with( DB_SLAVE )
                        ->will( $this->returnValue( $mockDb ) );
                return $mock;
@@ -180,7 +180,9 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                                        '(rc_this_oldid=page_latest) OR (rc_type=3)',
                                ],
                                $this->isType( 'string' ),
-                               [],
+                               [
+                                       'LIMIT' => 3,
+                               ],
                                [
                                        'watchlist' => [
                                                'INNER JOIN',
@@ -214,12 +216,184 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                                        'rc_deleted' => 0,
                                        'wl_notificationtimestamp' => null,
                                ] ),
+                               $this->getFakeRow( [
+                                       'rc_id' => 3,
+                                       'rc_namespace' => 1,
+                                       'rc_title' => 'Foo3',
+                                       'rc_timestamp' => '20151212010103',
+                                       'rc_type' => RC_NEW,
+                                       'rc_deleted' => 0,
+                                       'wl_notificationtimestamp' => null,
+                               ] ),
                        ] ) );
 
                $queryService = new WatchedItemQueryService( $this->getMockLoadBalancer( $mockDb ) );
                $user = $this->getMockUnrestrictedNonAnonUserWithId( 1 );
 
-               $items = $queryService->getWatchedItemsWithRecentChangeInfo( $user );
+               $startFrom = null;
+               $items = $queryService->getWatchedItemsWithRecentChangeInfo(
+                       $user, [ 'limit' => 2 ], $startFrom
+               );
+
+               $this->assertInternalType( 'array', $items );
+               $this->assertCount( 2, $items );
+
+               foreach ( $items as list( $watchedItem, $recentChangeInfo ) ) {
+                       $this->assertInstanceOf( WatchedItem::class, $watchedItem );
+                       $this->assertInternalType( 'array', $recentChangeInfo );
+               }
+
+               $this->assertEquals(
+                       new WatchedItem( $user, new TitleValue( 0, 'Foo1' ), '20151212010101' ),
+                       $items[0][0]
+               );
+               $this->assertEquals(
+                       [
+                               'rc_id' => 1,
+                               'rc_namespace' => 0,
+                               'rc_title' => 'Foo1',
+                               'rc_timestamp' => '20151212010101',
+                               'rc_type' => RC_NEW,
+                               'rc_deleted' => 0,
+                       ],
+                       $items[0][1]
+               );
+
+               $this->assertEquals(
+                       new WatchedItem( $user, new TitleValue( 1, 'Foo2' ), null ),
+                       $items[1][0]
+               );
+               $this->assertEquals(
+                       [
+                               'rc_id' => 2,
+                               'rc_namespace' => 1,
+                               'rc_title' => 'Foo2',
+                               'rc_timestamp' => '20151212010102',
+                               'rc_type' => RC_NEW,
+                               'rc_deleted' => 0,
+                       ],
+                       $items[1][1]
+               );
+
+               $this->assertEquals( [ '20151212010103', 3 ], $startFrom );
+       }
+
+       public function testGetWatchedItemsWithRecentChangeInfo_extension() {
+               $mockDb = $this->getMockDb();
+               $mockDb->expects( $this->once() )
+                       ->method( 'select' )
+                       ->with(
+                               [ 'recentchanges', 'watchlist', 'page', 'extension_dummy_table' ],
+                               [
+                                       'rc_id',
+                                       'rc_namespace',
+                                       'rc_title',
+                                       'rc_timestamp',
+                                       'rc_type',
+                                       'rc_deleted',
+                                       'wl_notificationtimestamp',
+                                       'rc_cur_id',
+                                       'rc_this_oldid',
+                                       'rc_last_oldid',
+                                       'extension_dummy_field',
+                               ],
+                               [
+                                       'wl_user' => 1,
+                                       '(rc_this_oldid=page_latest) OR (rc_type=3)',
+                                       'extension_dummy_cond',
+                               ],
+                               $this->isType( 'string' ),
+                               [
+                                       'extension_dummy_option',
+                               ],
+                               [
+                                       'watchlist' => [
+                                               'INNER JOIN',
+                                               [
+                                                       'wl_namespace=rc_namespace',
+                                                       'wl_title=rc_title'
+                                               ]
+                                       ],
+                                       'page' => [
+                                               'LEFT JOIN',
+                                               'rc_cur_id=page_id',
+                                       ],
+                                       'extension_dummy_join_cond' => [],
+                               ]
+                       )
+                       ->will( $this->returnValue( [
+                               $this->getFakeRow( [
+                                       'rc_id' => 1,
+                                       'rc_namespace' => 0,
+                                       'rc_title' => 'Foo1',
+                                       'rc_timestamp' => '20151212010101',
+                                       'rc_type' => RC_NEW,
+                                       'rc_deleted' => 0,
+                                       'wl_notificationtimestamp' => '20151212010101',
+                               ] ),
+                               $this->getFakeRow( [
+                                       'rc_id' => 2,
+                                       'rc_namespace' => 1,
+                                       'rc_title' => 'Foo2',
+                                       'rc_timestamp' => '20151212010102',
+                                       'rc_type' => RC_NEW,
+                                       'rc_deleted' => 0,
+                                       'wl_notificationtimestamp' => null,
+                               ] ),
+                       ] ) );
+
+               $user = $this->getMockUnrestrictedNonAnonUserWithId( 1 );
+
+               $mockExtension = $this->getMockBuilder( WatchedItemQueryServiceExtension::class )
+                       ->getMock();
+               $mockExtension->expects( $this->once() )
+                       ->method( 'modifyWatchedItemsWithRCInfoQuery' )
+                       ->with(
+                               $this->identicalTo( $user ),
+                               $this->isType( 'array' ),
+                               $this->isInstanceOf( IDatabase::class ),
+                               $this->isType( 'array' ),
+                               $this->isType( 'array' ),
+                               $this->isType( 'array' ),
+                               $this->isType( 'array' ),
+                               $this->isType( 'array' )
+                       )
+                       ->will( $this->returnCallback( function (
+                               $user, $options, $db, &$tables, &$fields, &$conds, &$dbOptions, &$joinConds
+                       ) {
+                               $tables[] = 'extension_dummy_table';
+                               $fields[] = 'extension_dummy_field';
+                               $conds[] = 'extension_dummy_cond';
+                               $dbOptions[] = 'extension_dummy_option';
+                               $joinConds['extension_dummy_join_cond'] = [];
+                       } ) );
+               $mockExtension->expects( $this->once() )
+                       ->method( 'modifyWatchedItemsWithRCInfo' )
+                       ->with(
+                               $this->identicalTo( $user ),
+                               $this->isType( 'array' ),
+                               $this->isInstanceOf( IDatabase::class ),
+                               $this->isType( 'array' ),
+                               $this->anything(),
+                               $this->anything() // Can't test for null here, PHPUnit applies this after the callback
+                       )
+                       ->will( $this->returnCallback( function ( $user, $options, $db, &$items, $res, &$startFrom ) {
+                               foreach ( $items as $i => &$item ) {
+                                       $item[1]['extension_dummy_field'] = $i;
+                               }
+                               unset( $item );
+
+                               $this->assertNull( $startFrom );
+                               $startFrom = [ '20160203123456', 42 ];
+                       } ) );
+
+               $queryService = new WatchedItemQueryService( $this->getMockLoadBalancer( $mockDb ) );
+               TestingAccessWrapper::newFromObject( $queryService )->extensions = [ $mockExtension ];
+
+               $startFrom = null;
+               $items = $queryService->getWatchedItemsWithRecentChangeInfo(
+                       $user, [], $startFrom
+               );
 
                $this->assertInternalType( 'array', $items );
                $this->assertCount( 2, $items );
@@ -241,6 +415,7 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                                'rc_timestamp' => '20151212010101',
                                'rc_type' => RC_NEW,
                                'rc_deleted' => 0,
+                               'extension_dummy_field' => 0,
                        ],
                        $items[0][1]
                );
@@ -257,93 +432,110 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                                'rc_timestamp' => '20151212010102',
                                'rc_type' => RC_NEW,
                                'rc_deleted' => 0,
+                               'extension_dummy_field' => 1,
                        ],
                        $items[1][1]
                );
+
+               $this->assertEquals( [ '20160203123456', 42 ], $startFrom );
        }
 
        public function getWatchedItemsWithRecentChangeInfoOptionsProvider() {
                return [
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_FLAGS ] ],
+                               null,
                                [ 'rc_type', 'rc_minor', 'rc_bot' ],
                                [],
                                [],
                        ],
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_USER ] ],
+                               null,
                                [ 'rc_user_text' ],
                                [],
                                [],
                        ],
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_USER_ID ] ],
+                               null,
                                [ 'rc_user' ],
                                [],
                                [],
                        ],
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_COMMENT ] ],
+                               null,
                                [ 'rc_comment' ],
                                [],
                                [],
                        ],
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_PATROL_INFO ] ],
+                               null,
                                [ 'rc_patrolled', 'rc_log_type' ],
                                [],
                                [],
                        ],
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_SIZES ] ],
+                               null,
                                [ 'rc_old_len', 'rc_new_len' ],
                                [],
                                [],
                        ],
                        [
                                [ 'includeFields' => [ WatchedItemQueryService::INCLUDE_LOG_INFO ] ],
+                               null,
                                [ 'rc_logid', 'rc_log_type', 'rc_log_action', 'rc_params' ],
                                [],
                                [],
                        ],
                        [
                                [ 'namespaceIds' => [ 0, 1 ] ],
+                               null,
                                [],
                                [ 'wl_namespace' => [ 0, 1 ] ],
                                [],
                        ],
                        [
                                [ 'namespaceIds' => [ 0, "1; DROP TABLE watchlist;\n--" ] ],
+                               null,
                                [],
                                [ 'wl_namespace' => [ 0, 1 ] ],
                                [],
                        ],
                        [
                                [ 'rcTypes' => [ RC_EDIT, RC_NEW ] ],
+                               null,
                                [],
                                [ 'rc_type' => [ RC_EDIT, RC_NEW ] ],
                                [],
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_OLDER ],
+                               null,
                                [],
                                [],
                                [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ]
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_NEWER ],
+                               null,
                                [],
                                [],
                                [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ]
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_OLDER, 'start' => '20151212010101' ],
+                               null,
                                [],
                                [ "rc_timestamp <= '20151212010101'" ],
                                [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ]
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_OLDER, 'end' => '20151212010101' ],
+                               null,
                                [],
                                [ "rc_timestamp >= '20151212010101'" ],
                                [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ]
@@ -354,18 +546,21 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                                        'start' => '20151212020101',
                                        'end' => '20151212010101'
                                ],
+                               null,
                                [],
                                [ "rc_timestamp <= '20151212020101'", "rc_timestamp >= '20151212010101'" ],
                                [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ]
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_NEWER, 'start' => '20151212010101' ],
+                               null,
                                [],
                                [ "rc_timestamp >= '20151212010101'" ],
                                [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ]
                        ],
                        [
                                [ 'dir' => WatchedItemQueryService::DIR_NEWER, 'end' => '20151212010101' ],
+                               null,
                                [],
                                [ "rc_timestamp <= '20151212010101'" ],
                                [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ]
@@ -376,96 +571,112 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                                        'start' => '20151212010101',
                                        'end' => '20151212020101'
                                ],
+                               null,
                                [],
                                [ "rc_timestamp >= '20151212010101'", "rc_timestamp <= '20151212020101'" ],
                                [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ]
                        ],
                        [
                                [ 'limit' => 10 ],
+                               null,
                                [],
                                [],
-                               [ 'LIMIT' => 10 ],
+                               [ 'LIMIT' => 11 ],
                        ],
                        [
                                [ 'limit' => "10; DROP TABLE watchlist;\n--" ],
+                               null,
                                [],
                                [],
-                               [ 'LIMIT' => 10 ],
+                               [ 'LIMIT' => 11 ],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_MINOR ] ],
+                               null,
                                [],
                                [ 'rc_minor != 0' ],
                                [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_NOT_MINOR ] ],
+                               null,
                                [],
                                [ 'rc_minor = 0' ],
                                [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_BOT ] ],
+                               null,
                                [],
                                [ 'rc_bot != 0' ],
                                [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_NOT_BOT ] ],
+                               null,
                                [],
                                [ 'rc_bot = 0' ],
                                [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_ANON ] ],
+                               null,
                                [],
                                [ 'rc_user = 0' ],
                                [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_NOT_ANON ] ],
+                               null,
                                [],
                                [ 'rc_user != 0' ],
                                [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_PATROLLED ] ],
+                               null,
                                [],
                                [ 'rc_patrolled != 0' ],
                                [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_NOT_PATROLLED ] ],
+                               null,
                                [],
                                [ 'rc_patrolled = 0' ],
                                [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_UNREAD ] ],
+                               null,
                                [],
                                [ 'rc_timestamp >= wl_notificationtimestamp' ],
                                [],
                        ],
                        [
                                [ 'filters' => [ WatchedItemQueryService::FILTER_NOT_UNREAD ] ],
+                               null,
                                [],
                                [ 'wl_notificationtimestamp IS NULL OR rc_timestamp < wl_notificationtimestamp' ],
                                [],
                        ],
                        [
                                [ 'onlyByUser' => 'SomeOtherUser' ],
+                               null,
                                [],
                                [ 'rc_user_text' => 'SomeOtherUser' ],
                                [],
                        ],
                        [
                                [ 'notByUser' => 'SomeOtherUser' ],
+                               null,
                                [],
                                [ "rc_user_text != 'SomeOtherUser'" ],
                                [],
                        ],
                        [
-                               [ 'startFrom' => [ '20151212010101', 123 ], 'dir' => WatchedItemQueryService::DIR_OLDER ],
+                               [ 'dir' => WatchedItemQueryService::DIR_OLDER ],
+                               [ '20151212010101', 123 ],
                                [],
                                [
                                        "(rc_timestamp < '20151212010101') OR ((rc_timestamp = '20151212010101') AND (rc_id <= 123))"
@@ -473,7 +684,8 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                                [ 'ORDER BY' => [ 'rc_timestamp DESC', 'rc_id DESC' ] ],
                        ],
                        [
-                               [ 'startFrom' => [ '20151212010101', 123 ], 'dir' => WatchedItemQueryService::DIR_NEWER ],
+                               [ 'dir' => WatchedItemQueryService::DIR_NEWER ],
+                               [ '20151212010101', 123 ],
                                [],
                                [
                                        "(rc_timestamp > '20151212010101') OR ((rc_timestamp = '20151212010101') AND (rc_id >= 123))"
@@ -481,10 +693,8 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                                [ 'ORDER BY' => [ 'rc_timestamp', 'rc_id' ] ],
                        ],
                        [
-                               [
-                                       'startFrom' => [ '20151212010101', "123; DROP TABLE watchlist;\n--" ],
-                                       'dir' => WatchedItemQueryService::DIR_OLDER
-                               ],
+                               [ 'dir' => WatchedItemQueryService::DIR_OLDER ],
+                               [ '20151212010101', "123; DROP TABLE watchlist;\n--" ],
                                [],
                                [
                                        "(rc_timestamp < '20151212010101') OR ((rc_timestamp = '20151212010101') AND (rc_id <= 123))"
@@ -499,6 +709,7 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
         */
        public function testGetWatchedItemsWithRecentChangeInfo_optionsAndEmptyResult(
                array $options,
+               $startFrom,
                array $expectedExtraFields,
                array $expectedExtraConds,
                array $expectedDbOptions
@@ -552,9 +763,10 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                $queryService = new WatchedItemQueryService( $this->getMockLoadBalancer( $mockDb ) );
                $user = $this->getMockUnrestrictedNonAnonUserWithId( 1 );
 
-               $items = $queryService->getWatchedItemsWithRecentChangeInfo( $user, $options );
+               $items = $queryService->getWatchedItemsWithRecentChangeInfo( $user, $options, $startFrom );
 
                $this->assertEmpty( $items );
+               $this->assertNull( $startFrom );
        }
 
        public function filterPatrolledOptionProvider() {
@@ -797,53 +1009,62 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                return [
                        [
                                [ 'rcTypes' => [ 1337 ] ],
+                               null,
                                'Bad value for parameter $options[\'rcTypes\']',
                        ],
                        [
                                [ 'rcTypes' => [ 'edit' ] ],
+                               null,
                                'Bad value for parameter $options[\'rcTypes\']',
                        ],
                        [
                                [ 'rcTypes' => [ RC_EDIT, 1337 ] ],
+                               null,
                                'Bad value for parameter $options[\'rcTypes\']',
                        ],
                        [
                                [ 'dir' => 'foo' ],
+                               null,
                                'Bad value for parameter $options[\'dir\']',
                        ],
                        [
                                [ 'start' => '20151212010101' ],
+                               null,
                                'Bad value for parameter $options[\'dir\']: must be provided',
                        ],
                        [
                                [ 'end' => '20151212010101' ],
+                               null,
                                'Bad value for parameter $options[\'dir\']: must be provided',
                        ],
                        [
-                               [ 'startFrom' => [ '20151212010101', 123 ] ],
+                               [],
+                               [ '20151212010101', 123 ],
                                'Bad value for parameter $options[\'dir\']: must be provided',
                        ],
                        [
-                               [ 'dir' => WatchedItemQueryService::DIR_OLDER, 'startFrom' => '20151212010101' ],
-                               'Bad value for parameter $options[\'startFrom\']: must be a two-element array',
+                               [ 'dir' => WatchedItemQueryService::DIR_OLDER ],
+                               '20151212010101',
+                               'Bad value for parameter $startFrom: must be a two-element array',
                        ],
                        [
-                               [ 'dir' => WatchedItemQueryService::DIR_OLDER, 'startFrom' => [ '20151212010101' ] ],
-                               'Bad value for parameter $options[\'startFrom\']: must be a two-element array',
+                               [ 'dir' => WatchedItemQueryService::DIR_OLDER ],
+                               [ '20151212010101' ],
+                               'Bad value for parameter $startFrom: must be a two-element array',
                        ],
                        [
-                               [
-                                       'dir' => WatchedItemQueryService::DIR_OLDER,
-                                       'startFrom' => [ '20151212010101', 123, 'foo' ]
-                               ],
-                               'Bad value for parameter $options[\'startFrom\']: must be a two-element array',
+                               [ 'dir' => WatchedItemQueryService::DIR_OLDER ],
+                               [ '20151212010101', 123, 'foo' ],
+                               'Bad value for parameter $startFrom: must be a two-element array',
                        ],
                        [
                                [ 'watchlistOwner' => $this->getMockUnrestrictedNonAnonUserWithId( 2 ) ],
+                               null,
                                'Bad value for parameter $options[\'watchlistOwnerToken\']',
                        ],
                        [
                                [ 'watchlistOwner' => 'Other User', 'watchlistOwnerToken' => 'some-token' ],
+                               null,
                                'Bad value for parameter $options[\'watchlistOwner\']',
                        ],
                ];
@@ -854,6 +1075,7 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
         */
        public function testGetWatchedItemsWithRecentChangeInfo_invalidOptions(
                array $options,
+               $startFrom,
                $expectedInExceptionMessage
        ) {
                $mockDb = $this->getMockDb();
@@ -864,7 +1086,7 @@ class WatchedItemQueryServiceUnitTest extends PHPUnit_Framework_TestCase {
                $user = $this->getMockUnrestrictedNonAnonUserWithId( 1 );
 
                $this->setExpectedException( InvalidArgumentException::class, $expectedInExceptionMessage );
-               $queryService->getWatchedItemsWithRecentChangeInfo( $user, $options );
+               $queryService->getWatchedItemsWithRecentChangeInfo( $user, $options, $startFrom );
        }
 
        public function testGetWatchedItemsWithRecentChangeInfo_usedInGeneratorOptionAndEmptyResult() {
index 030d9d5..ba47059 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 use MediaWiki\Linker\LinkTarget;
+use Wikimedia\ScopedCallback;
 
 /**
  * @author Addshore
@@ -28,12 +29,12 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                        ->getMock();
                if ( $expectedConnectionType !== null ) {
                        $mock->expects( $this->any() )
-                               ->method( 'getConnection' )
+                               ->method( 'getConnectionRef' )
                                ->with( $expectedConnectionType )
                                ->will( $this->returnValue( $mockDb ) );
                } else {
                        $mock->expects( $this->any() )
-                               ->method( 'getConnection' )
+                               ->method( 'getConnectionRef' )
                                ->will( $this->returnValue( $mockDb ) );
                }
                $mock->expects( $this->any() )
index f80f512..52e20bd 100644 (file)
@@ -50,7 +50,7 @@ class XmlSelectTest extends MediaWikiTestCase {
                        /**
                         * Values are set following a 3-bit Gray code where two successive
                         * values differ by only one value.
-                        * See http://en.wikipedia.org/wiki/Gray_code
+                        * See https://en.wikipedia.org/wiki/Gray_code
                         */
                        #      $name   $id    $default
                        [ false, false, false, '<select></select>' ],
index 6da16a0..3ad16d1 100644 (file)
@@ -195,7 +195,6 @@ class ApiContinuationManagerTest extends MediaWikiTestCase {
                                'Expected exception'
                        );
                }
-
        }
 
 }
index 97681eb..ea8c9ca 100644 (file)
@@ -188,7 +188,6 @@ class ApiLoginTest extends ApiTestCase {
                $this->assertArrayHasKey( "login", $data[0] );
                $this->assertArrayHasKey( "result", $data[0]['login'] );
                $this->assertEquals( "Success", $data[0]['login']['result'] );
-               $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] );
        }
 
        public function testBotPassword() {
index 334e3b8..c111949 100644 (file)
@@ -58,6 +58,29 @@ class ApiMainTest extends ApiTestCase {
                }
        }
 
+       /**
+        * Tests the assertuser= functionality
+        *
+        * @covers ApiMain::checkAsserts
+        */
+       public function testAssertUser() {
+               $user = $this->getTestUser()->getUser();
+               $this->doApiRequest( [
+                       'action' => 'query',
+                       'assertuser' => $user->getName(),
+               ], null, null, $user );
+
+               try {
+                       $this->doApiRequest( [
+                               'action' => 'query',
+                               'assertuser' => $user->getName() . 'X',
+                       ], null, null, $user );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( UsageException $e ) {
+                       $this->assertEquals( $e->getCodeString(), 'assertnameduserfailed' );
+               }
+       }
+
        /**
         * Test if all classes in the main module manager exists
         */
index a45015a..8764b41 100644 (file)
@@ -5,17 +5,17 @@
  */
 class ApiMessageTest extends MediaWikiTestCase {
 
-       private function compareMessages( $msg, $msg2 ) {
+       private function compareMessages( Message $msg, Message $msg2 ) {
                $this->assertSame( $msg->getKey(), $msg2->getKey(), 'getKey' );
                $this->assertSame( $msg->getKeysToTry(), $msg2->getKeysToTry(), 'getKeysToTry' );
                $this->assertSame( $msg->getParams(), $msg2->getParams(), 'getParams' );
-               $this->assertSame( $msg->getFormat(), $msg2->getFormat(), 'getFormat' );
                $this->assertSame( $msg->getLanguage(), $msg2->getLanguage(), 'getLanguage' );
 
                $msg = TestingAccessWrapper::newFromObject( $msg );
                $msg2 = TestingAccessWrapper::newFromObject( $msg2 );
                $this->assertSame( $msg->interface, $msg2->interface, 'interface' );
                $this->assertSame( $msg->useDatabase, $msg2->useDatabase, 'useDatabase' );
+               $this->assertSame( $msg->format, $msg2->format, 'format' );
                $this->assertSame(
                        $msg->title ? $msg->title->getFullText() : null,
                        $msg2->title ? $msg2->title->getFullText() : null,
index 582c076..d6f315d 100644 (file)
@@ -477,6 +477,7 @@ class ApiQueryWatchlistRawIntegrationTest extends ApiTestCase {
                        new TitleValue( 1, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
                ] );
 
+               ObjectCache::getMainWANInstance()->clearProcessCache();
                $result = $this->doListWatchlistRawRequest( [
                        'wrowner' => $otherUser->getName(),
                        'wrtoken' => '1234567890',
index 48472cf..98e24fb 100644 (file)
@@ -1230,7 +1230,6 @@ class ApiResultTest extends MediaWikiTestCase {
                                ],
                        ],
                ];
-
        }
 
        /**
@@ -1380,7 +1379,6 @@ class ApiResultTest extends MediaWikiTestCase {
                        'two' => 2,
                ], $arr['foo'] );
        }
-
 }
 
 class ApiResultTestStringifiableObject {
index 6359983..d8282be 100644 (file)
@@ -25,7 +25,6 @@ class ApiRevisionDeleteTest extends ApiTestCase {
                        $this->revs[] = Title::newFromText( self::$page )
                                ->getLatestRevID( Title::GAID_FOR_UPDATE );
                }
-
        }
 
        public function testHidingRevisions() {
index f679f63..f57db11 100644 (file)
@@ -6,6 +6,7 @@ use MediaWiki\Session\SessionInfo;
 use MediaWiki\Session\UserInfo;
 use Psr\Log\LogLevel;
 use StatusValue;
+use Wikimedia\ScopedCallback;
 
 /**
  * @group AuthManager
@@ -184,7 +185,7 @@ class AuthManagerTest extends \MediaWikiTestCase {
                $rProp = new \ReflectionProperty( AuthManager::class, 'instance' );
                $rProp->setAccessible( true );
                $old = $rProp->getValue();
-               $cb = new \ScopedCallback( [ $rProp, 'setValue' ], [ $old ] );
+               $cb = new ScopedCallback( [ $rProp, 'setValue' ], [ $old ] );
                $rProp->setValue( null );
 
                $singleton = AuthManager::singleton();
@@ -202,11 +203,11 @@ class AuthManagerTest extends \MediaWikiTestCase {
 
                list( $provider, $reset ) = $this->getMockSessionProvider( false );
                $this->assertFalse( $this->manager->canAuthenticateNow() );
-               \ScopedCallback::consume( $reset );
+               ScopedCallback::consume( $reset );
 
                list( $provider, $reset ) = $this->getMockSessionProvider( true );
                $this->assertTrue( $this->manager->canAuthenticateNow() );
-               \ScopedCallback::consume( $reset );
+               ScopedCallback::consume( $reset );
        }
 
        public function testNormalizeUsername() {
@@ -385,7 +386,7 @@ class AuthManagerTest extends \MediaWikiTestCase {
                        $this->unhook( 'SecuritySensitiveOperationStatus' );
                }
 
-               \ScopedCallback::consume( $reset );
+               ScopedCallback::consume( $reset );
        }
 
        public function onSecuritySensitiveOperationStatus( &$status, $operation, $session, $time ) {
@@ -585,7 +586,7 @@ class AuthManagerTest extends \MediaWikiTestCase {
                $this->initializeManager();
 
                $context = \RequestContext::getMain();
-               $reset = new \ScopedCallback( [ $context, 'setLanguage' ], [ $context->getLanguage() ] );
+               $reset = new ScopedCallback( [ $context, 'setLanguage' ], [ $context->getLanguage() ] );
                $context->setLanguage( 'de' );
                $this->setMwGlobals( 'wgContLang', \Language::factory( 'zh' ) );
 
@@ -694,7 +695,6 @@ class AuthManagerTest extends \MediaWikiTestCase {
                                $ex->getMessage()
                        );
                }
-
        }
 
        public function testBeginAuthentication() {
@@ -712,7 +712,7 @@ class AuthManagerTest extends \MediaWikiTestCase {
                }
                $this->unhook( 'UserLoggedIn' );
                $this->assertNull( $this->request->getSession()->getSecret( 'AuthManager::authnState' ) );
-               \ScopedCallback::consume( $reset );
+               ScopedCallback::consume( $reset );
                $this->initializeManager( true );
 
                // CreatedAccountAuthenticationRequest
@@ -1449,11 +1449,11 @@ class AuthManagerTest extends \MediaWikiTestCase {
                ];
                $block = new \Block( $blockOptions );
                $block->insert();
-               $scopeVariable = new \ScopedCallback( [ $block, 'delete' ] );
+               $scopeVariable = new ScopedCallback( [ $block, 'delete' ] );
                $status = $this->manager->checkAccountCreatePermissions( new \User );
                $this->assertFalse( $status->isOK() );
                $this->assertTrue( $status->hasMessage( 'cantcreateaccount-range-text' ) );
-               \ScopedCallback::consume( $scopeVariable );
+               ScopedCallback::consume( $scopeVariable );
 
                $this->setMwGlobals( [
                        'wgEnableDnsBlacklist' => true,
@@ -2674,7 +2674,7 @@ class AuthManagerTest extends \MediaWikiTestCase {
                $this->assertEquals( 0, $session->getUser()->getId() );
                $this->assertSame( [
                        [ LogLevel::INFO, 'creating new user ({username}) - from: {from}' ],
-                       [ LogLevel::ERROR, '{username} failed with message {message}' ],
+                       [ LogLevel::ERROR, '{username} failed with message {msg}' ],
                ], $logger->getBuffer() );
                $logger->clearBuffer();
                $this->assertSame( null, $session->get( 'AuthManager::AutoCreateBlacklist' ) );
@@ -3264,7 +3264,6 @@ class AuthManagerTest extends \MediaWikiTestCase {
                $this->manager->removeAuthenticationSessionData( null );
                $this->assertNull( $this->manager->getAuthenticationSessionData( 'foo' ) );
                $this->assertNull( $this->manager->getAuthenticationSessionData( 'bar' ) );
-
        }
 
        public function testCanLinkAccounts() {
index e6d3ecf..68f574b 100644 (file)
@@ -152,7 +152,7 @@ class CheckBlocksSecondaryAuthenticationProviderTest extends \MediaWikiTestCase
                ];
                $block = new \Block( $blockOptions );
                $block->insert();
-               $scopeVariable = new \ScopedCallback( [ $block, 'delete' ] );
+               $scopeVariable = new \Wikimedia\ScopedCallback( [ $block, 'delete' ] );
 
                $user = \User::newFromName( 'UTNormalUser' );
                if ( $user->getID() == 0 ) {
index c52c3e9..ec4bea1 100644 (file)
@@ -104,6 +104,5 @@ class EmailNotificationSecondaryAuthenticationProviderTest extends \PHPUnit_Fram
                $authManager->setAuthenticationSessionData( 'no-email', true );
                $provider->setManager( $authManager );
                $provider->beginSecondaryAccountCreation( $userNotExpectsConfirmation, $creator, [] );
-
        }
 }
index 088dd00..caf1680 100644 (file)
@@ -328,7 +328,6 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                        AuthenticationResponse::newPass( $userName ),
                        $provider->beginPrimaryAuthentication( $reqs )
                );
-
        }
 
        /**
@@ -645,7 +644,6 @@ class LocalPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestCase
                $this->assertNull( $provider->finishAccountCreation( $user, $user, $res2 ) );
                $ret = $provider->beginPrimaryAuthentication( $reqs );
                $this->assertEquals( AuthenticationResponse::PASS, $ret->status, 'new password is set' );
-
        }
 
 }
index 515a5b3..d4ebe34 100644 (file)
@@ -2,6 +2,8 @@
 
 namespace MediaWiki\Auth;
 
+use Wikimedia\ScopedCallback;
+
 /**
  * @group AuthManager
  * @group Database
@@ -70,7 +72,7 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                        } );
                }
 
-               return new \ScopedCallback( function () {
+               return new ScopedCallback( function () {
                        \Hooks::clear( 'AlternateUserMailer' );
                        \Hooks::register( 'AlternateUserMailer', function () {
                                return false;
@@ -122,6 +124,8 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
        }
 
        public function testTestUserCanAuthenticate() {
+               $user = self::getMutableTestUser()->getUser();
+
                $dbw = wfGetDB( DB_MASTER );
 
                $passwordFactory = new \PasswordFactory();
@@ -142,9 +146,9 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                                'user_newpassword' => \PasswordFactory::newInvalidPassword()->toString(),
                                'user_newpass_time' => null,
                        ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
-               $this->assertFalse( $provider->testUserCanAuthenticate( 'UTSysop' ) );
+               $this->assertFalse( $provider->testUserCanAuthenticate( $user->getName() ) );
 
                $dbw->update(
                        'user',
@@ -152,10 +156,10 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                                'user_newpassword' => $pwhash,
                                'user_newpass_time' => null,
                        ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
-               $this->assertTrue( $provider->testUserCanAuthenticate( 'UTSysop' ) );
-               $this->assertTrue( $provider->testUserCanAuthenticate( 'uTSysop' ) );
+               $this->assertTrue( $provider->testUserCanAuthenticate( $user->getName() ) );
+               $this->assertTrue( $provider->testUserCanAuthenticate( lcfirst( $user->getName() ) ) );
 
                $dbw->update(
                        'user',
@@ -163,12 +167,12 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                                'user_newpassword' => $pwhash,
                                'user_newpass_time' => $dbw->timestamp( time() - 10 ),
                        ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
                $providerPriv->newPasswordExpiry = 100;
-               $this->assertTrue( $provider->testUserCanAuthenticate( 'UTSysop' ) );
+               $this->assertTrue( $provider->testUserCanAuthenticate( $user->getName() ) );
                $providerPriv->newPasswordExpiry = 1;
-               $this->assertFalse( $provider->testUserCanAuthenticate( 'UTSysop' ) );
+               $this->assertFalse( $provider->testUserCanAuthenticate( $user->getName() ) );
 
                $dbw->update(
                        'user',
@@ -176,7 +180,7 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                                'user_newpassword' => \PasswordFactory::newInvalidPassword()->toString(),
                                'user_newpass_time' => null,
                        ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
        }
 
@@ -229,13 +233,15 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
        }
 
        public function testAuthentication() {
+               $user = self::getMutableTestUser()->getUser();
+
                $password = 'TemporaryPassword';
                $hash = ':A:' . md5( $password );
                $dbw = wfGetDB( DB_MASTER );
                $dbw->update(
                        'user',
                        [ 'user_newpassword' => $hash, 'user_newpass_time' => $dbw->timestamp( time() - 10 ) ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
 
                $req = new PasswordAuthenticationRequest();
@@ -284,7 +290,7 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                );
 
                // Validation failure
-               $req->username = 'UTSysop';
+               $req->username = $user->getName();
                $req->password = $password;
                $this->validity = \Status::newFatal( 'arbitrary-failure' );
                $ret = $provider->beginPrimaryAuthentication( $reqs );
@@ -301,20 +307,20 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                $this->manager->removeAuthenticationSessionData( null );
                $this->validity = \Status::newGood();
                $this->assertEquals(
-                       AuthenticationResponse::newPass( 'UTSysop' ),
+                       AuthenticationResponse::newPass( $user->getName() ),
                        $provider->beginPrimaryAuthentication( $reqs )
                );
                $this->assertNotNull( $this->manager->getAuthenticationSessionData( 'reset-pass' ) );
 
                $this->manager->removeAuthenticationSessionData( null );
                $this->validity = \Status::newGood();
-               $req->username = 'uTSysop';
+               $req->username = lcfirst( $user->getName() );
                $this->assertEquals(
-                       AuthenticationResponse::newPass( 'UTSysop' ),
+                       AuthenticationResponse::newPass( $user->getName() ),
                        $provider->beginPrimaryAuthentication( $reqs )
                );
                $this->assertNotNull( $this->manager->getAuthenticationSessionData( 'reset-pass' ) );
-               $req->username = 'UTSysop';
+               $req->username = $user->getName();
 
                // Expired password
                $providerPriv->newPasswordExpiry = 1;
@@ -341,7 +347,6 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                        'wrongpassword',
                        $ret->message->getKey()
                );
-
        }
 
        /**
@@ -408,20 +413,19 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                $oldpass = 'OldTempPassword';
                $newpass = 'NewTempPassword';
 
-               $hash = ':A:' . md5( $oldpass );
                $dbw = wfGetDB( DB_MASTER );
+               $oldHash = $dbw->selectField( 'user', 'user_newpassword', [ 'user_name' => $cuser ] );
+               $cb = new ScopedCallback( function () use ( $dbw, $cuser, $oldHash ) {
+                       $dbw->update( 'user', [ 'user_newpassword' => $oldHash ], [ 'user_name' => $cuser ] );
+               } );
+
+               $hash = ':A:' . md5( $oldpass );
                $dbw->update(
                        'user',
                        [ 'user_newpassword' => $hash, 'user_newpass_time' => $dbw->timestamp( time() + 10 ) ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_name' => $cuser ]
                );
 
-               $dbw = wfGetDB( DB_MASTER );
-               $oldHash = $dbw->selectField( 'user', 'user_newpassword', [ 'user_name' => $cuser ] );
-               $cb = new \ScopedCallback( function () use ( $dbw, $cuser, $oldHash ) {
-                       $dbw->update( 'user', [ 'user_newpassword' => $oldHash ], [ 'user_name' => $cuser ] );
-               } );
-
                $provider = $this->getProvider();
 
                // Sanity check
@@ -448,7 +452,7 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                $changeReq->password = $newpass;
                $resetMailer = $this->hookMailer();
                $provider->providerChangeAuthenticationData( $changeReq );
-               \ScopedCallback::consume( $resetMailer );
+               ScopedCallback::consume( $resetMailer );
 
                $loginReq->password = $oldpass;
                $ret = $provider->beginPrimaryAuthentication( $loginReqs );
@@ -500,22 +504,15 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
        }
 
        public function testProviderChangeAuthenticationDataEmail() {
+               $user = self::getMutableTestUser()->getUser();
+
                $dbw = wfGetDB( DB_MASTER );
                $dbw->update(
                        'user',
                        [ 'user_newpass_time' => $dbw->timestamp( time() - 5 * 3600 ) ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
 
-               $user = \User::newFromName( 'UTSysop' );
-               $reset = new \ScopedCallback( function ( $email ) use ( $user ) {
-                       $user->setEmail( $email );
-                       $user->saveSettings();
-               }, [ $user->getEmail() ] );
-
-               $user->setEmail( 'test@localhost.localdomain' );
-               $user->saveSettings();
-
                $req = TemporaryPasswordAuthenticationRequest::newRandom();
                $req->username = $user->getName();
                $req->mailpassword = true;
@@ -539,7 +536,7 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                $dbw->update(
                        'user',
                        [ 'user_newpass_time' => $dbw->timestamp( time() + 5 * 3600 ) ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
                $provider = $this->getProvider( [ 'passwordReminderResendTime' => 0 ] );
                $status = $provider->providerAllowsAuthenticationDataChange( $req, true );
@@ -563,21 +560,21 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                $status = $provider->providerAllowsAuthenticationDataChange( $req, true );
                $this->assertEquals( \StatusValue::newGood(), $status );
 
-               $req->caller = 'UTSysop';
+               $req->caller = $user->getName();
                $status = $provider->providerAllowsAuthenticationDataChange( $req, true );
                $this->assertEquals( \StatusValue::newGood(), $status );
 
                $mailed = false;
                $resetMailer = $this->hookMailer( function ( $headers, $to, $from, $subject, $body )
-                       use ( &$mailed, $req )
+                       use ( &$mailed, $req, $user )
                {
                        $mailed = true;
-                       $this->assertSame( 'test@localhost.localdomain', $to[0]->address );
+                       $this->assertSame( $user->getEmail(), $to[0]->address );
                        $this->assertContains( $req->password, $body );
                        return false;
                } );
                $provider->providerChangeAuthenticationData( $req );
-               \ScopedCallback::consume( $resetMailer );
+               ScopedCallback::consume( $resetMailer );
                $this->assertTrue( $mailed );
 
                $priv = \TestingAccessWrapper::newFromObject( $provider );
@@ -658,12 +655,10 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                $this->assertEquals( $expect, $provider->beginPrimaryAccountCreation( $user, $user, $reqs ) );
                $this->assertNull( $this->manager->getAuthenticationSessionData( 'no-email' ) );
 
-               // We have to cheat a bit to avoid having to add a new user to
-               // the database to test the actual setting of the password works right
-               $user = \User::newFromName( 'UTSysop' );
+               $user = self::getMutableTestUser()->getUser();
                $req->username = $authreq->username = $user->getName();
                $req->password = $authreq->password = 'NewPassword';
-               $expect = AuthenticationResponse::newPass( 'UTSysop' );
+               $expect = AuthenticationResponse::newPass( $user->getName() );
                $expect->createRequest = $req;
 
                $res2 = $provider->beginPrimaryAccountCreation( $user, $user, $reqs );
@@ -680,12 +675,8 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
 
        public function testAccountCreationEmail() {
                $creator = \User::newFromName( 'Foo' );
-               $user = \User::newFromName( 'UTSysop' );
-               $reset = new \ScopedCallback( function ( $email ) use ( $user ) {
-                       $user->setEmail( $email );
-                       $user->saveSettings();
-               }, [ $user->getEmail() ] );
 
+               $user = self::getMutableTestUser()->getUser();
                $user->setEmail( null );
 
                $req = TemporaryPasswordAuthenticationRequest::newRandom();
@@ -722,9 +713,9 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                        return false;
                } );
 
-               $expect = AuthenticationResponse::newPass( 'UTSysop' );
+               $expect = AuthenticationResponse::newPass( $user->getName() );
                $expect->createRequest = clone( $req );
-               $expect->createRequest->username = 'UTSysop';
+               $expect->createRequest->username = $user->getName();
                $res = $provider->beginPrimaryAccountCreation( $user, $creator, [ $req ] );
                $this->assertEquals( $expect, $res );
                $this->assertTrue( $this->manager->getAuthenticationSessionData( 'no-email' ) );
@@ -733,7 +724,7 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                $this->assertSame( 'byemail', $provider->finishAccountCreation( $user, $creator, $res ) );
                $this->assertTrue( $mailed );
 
-               \ScopedCallback::consume( $resetMailer );
+               ScopedCallback::consume( $resetMailer );
                $this->assertTrue( $mailed );
        }
 
index 5806003..c945885 100644 (file)
@@ -196,7 +196,7 @@ class ThrottlerTest extends \MediaWikiTestCase {
                        ->setMethods( [ 'log' ] )
                        ->getMockForAbstractClass();
                $logger->expects( $this->once() )->method( 'log' )->with( $this->anything(), $this->anything(), [
-                       'type' => 'custom',
+                       'throttle' => 'custom',
                        'index' => 0,
                        'ip' => '1.2.3.4',
                        'username' => 'SomeUser',
index 7fe3351..7dea123 100644 (file)
@@ -36,7 +36,6 @@ class UserDataAuthenticationRequestTest extends AuthenticationRequestTestCase {
                        $this->assertSame( $email ?: 'default@example.com', $user->getEmail() );
                        $this->assertSame( $realname ?: 'Fake Name', $user->getRealName() );
                }
-
        }
 
        public static function providePopulateUser() {
index 0f4484e..d8773f8 100644 (file)
@@ -43,7 +43,7 @@ class LBFactoryTest extends MediaWikiTestCase {
                ];
 
                $this->hideDeprecated( '$wgLBFactoryConf must be updated. See RELEASE-NOTES for details' );
-               $result = LBFactoryMW::getLBFactoryClass( $config );
+               $result = MWLBFactory::getLBFactoryClass( $config );
 
                $this->assertEquals( $expected, $result );
        }
@@ -58,17 +58,18 @@ class LBFactoryTest extends MediaWikiTestCase {
        }
 
        public function testLBFactorySimpleServer() {
-               global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype;
+               global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype, $wgSQLiteDataDir;
 
                $servers = [
                        [
-                               'host'      => $wgDBserver,
-                               'dbname'    => $wgDBname,
-                               'user'      => $wgDBuser,
-                               'password'  => $wgDBpassword,
-                               'type'      => $wgDBtype,
-                               'load'      => 0,
-                               'flags'     => DBO_TRX // REPEATABLE-READ for consistency
+                               'host'        => $wgDBserver,
+                               'dbname'      => $wgDBname,
+                               'user'        => $wgDBuser,
+                               'password'    => $wgDBpassword,
+                               'type'        => $wgDBtype,
+                               'dbDirectory' => $wgSQLiteDataDir,
+                               'load'        => 0,
+                               'flags'       => DBO_TRX // REPEATABLE-READ for consistency
                        ],
                ];
 
@@ -86,26 +87,28 @@ class LBFactoryTest extends MediaWikiTestCase {
        }
 
        public function testLBFactorySimpleServers() {
-               global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype;
+               global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype, $wgSQLiteDataDir;
 
                $servers = [
                        [ // master
-                               'host'     => $wgDBserver,
-                               'dbname'   => $wgDBname,
-                               'user'     => $wgDBuser,
-                               'password' => $wgDBpassword,
-                               'type'     => $wgDBtype,
-                               'load'     => 0,
-                               'flags'    => DBO_TRX // REPEATABLE-READ for consistency
+                               'host'        => $wgDBserver,
+                               'dbname'      => $wgDBname,
+                               'user'        => $wgDBuser,
+                               'password'    => $wgDBpassword,
+                               'type'        => $wgDBtype,
+                               'dbDirectory' => $wgSQLiteDataDir,
+                               'load'        => 0,
+                               'flags'       => DBO_TRX // REPEATABLE-READ for consistency
                        ],
                        [ // emulated slave
-                               'host'     => $wgDBserver,
-                               'dbname'   => $wgDBname,
-                               'user'     => $wgDBuser,
-                               'password' => $wgDBpassword,
-                               'type'     => $wgDBtype,
-                               'load'     => 100,
-                               'flags'    => DBO_TRX // REPEATABLE-READ for consistency
+                               'host'        => $wgDBserver,
+                               'dbname'      => $wgDBname,
+                               'user'        => $wgDBuser,
+                               'password'    => $wgDBpassword,
+                               'type'        => $wgDBtype,
+                               'dbDirectory' => $wgSQLiteDataDir,
+                               'load'        => 100,
+                               'flags'       => DBO_TRX // REPEATABLE-READ for consistency
                        ]
                ];
 
@@ -118,19 +121,23 @@ class LBFactoryTest extends MediaWikiTestCase {
                $dbw = $lb->getConnection( DB_MASTER );
                $this->assertTrue( $dbw->getLBInfo( 'master' ), 'master shows as master' );
                $this->assertEquals(
-                       $wgDBserver, $dbw->getLBInfo( 'clusterMasterHost' ), 'cluster master set' );
+                       ( $wgDBserver != '' ) ? $wgDBserver : 'localhost',
+                       $dbw->getLBInfo( 'clusterMasterHost' ),
+                       'cluster master set' );
 
                $dbr = $lb->getConnection( DB_SLAVE );
                $this->assertTrue( $dbr->getLBInfo( 'replica' ), 'slave shows as slave' );
                $this->assertEquals(
-                       $wgDBserver, $dbr->getLBInfo( 'clusterMasterHost' ), 'cluster master set' );
+                       ( $wgDBserver != '' ) ? $wgDBserver : 'localhost',
+                       $dbr->getLBInfo( 'clusterMasterHost' ),
+                       'cluster master set' );
 
                $factory->shutdown();
                $lb->closeAll();
        }
 
        public function testLBFactoryMulti() {
-               global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype;
+               global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype, $wgSQLiteDataDir;
 
                $factory = new LBFactoryMulti( [
                        'sectionsByDB' => [],
@@ -145,6 +152,7 @@ class LBFactoryTest extends MediaWikiTestCase {
                                'user'            => $wgDBuser,
                                'password'        => $wgDBpassword,
                                'type'            => $wgDBtype,
+                               'dbDirectory' => $wgSQLiteDataDir,
                                'flags'           => DBO_DEFAULT
                        ],
                        'hostsByName' => [
@@ -233,7 +241,7 @@ class LBFactoryTest extends MediaWikiTestCase {
        }
 
        private function newLBFactoryMulti( array $baseOverride = [], array $serverOverride = [] ) {
-               global $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, $wgDBtype;
+               global $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, $wgDBtype, $wgSQLiteDataDir;
 
                return new LBFactoryMulti( $baseOverride + [
                        'sectionsByDB' => [],
@@ -247,6 +255,7 @@ class LBFactoryTest extends MediaWikiTestCase {
                                'user' => $wgDBuser,
                                'password' => $wgDBpassword,
                                'type' => $wgDBtype,
+                               'dbDirectory' => $wgSQLiteDataDir,
                                'flags' => DBO_DEFAULT
                        ],
                        'hostsByName' => [
@@ -258,17 +267,32 @@ class LBFactoryTest extends MediaWikiTestCase {
        }
 
        public function testNiceDomains() {
-               global $wgDBname;
+               global $wgDBname, $wgDBtype;
+
+               if ( $wgDBtype === 'sqlite' ) {
+                       $tmpDir = $this->getNewTempDirectory();
+                       $dbPath = "$tmpDir/unit_test_db.sqlite";
+                       file_put_contents( $dbPath, '' );
+                       $tempFsFile = new TempFSFile( $dbPath );
+                       $tempFsFile->autocollect();
+               } else {
+                       $dbPath = null;
+               }
 
-               $factory = $this->newLBFactoryMulti();
+               $factory = $this->newLBFactoryMulti(
+                       [],
+                       [ 'dbFilePath' => $dbPath ]
+               );
                $lb = $factory->getMainLB();
 
-               $db = $lb->getConnectionRef( DB_MASTER );
-               $this->assertEquals(
-                       $wgDBname,
-                       $db->getDomainID()
-               );
-               unset( $db );
+               if ( $wgDBtype !== 'sqlite' ) {
+                       $db = $lb->getConnectionRef( DB_MASTER );
+                       $this->assertEquals(
+                               $wgDBname,
+                               $db->getDomainID()
+                       );
+                       unset( $db );
+               }
 
                /** @var Database $db */
                $db = $lb->getConnection( DB_MASTER, [], '' );
@@ -280,19 +304,19 @@ class LBFactoryTest extends MediaWikiTestCase {
                );
 
                $this->assertEquals(
-                       $db->addIdentifierQuotes( 'page' ),
+                       $this->quoteTable( $db, 'page' ),
                        $db->tableName( 'page' ),
                        "Correct full table name"
                );
 
                $this->assertEquals(
-                       $db->addIdentifierQuotes( $wgDBname ) . '.' . $db->addIdentifierQuotes( 'page' ),
+                       $this->quoteTable( $db, $wgDBname ) . '.' . $this->quoteTable( $db, 'page' ),
                        $db->tableName( "$wgDBname.page" ),
                        "Correct full table name"
                );
 
                $this->assertEquals(
-                       $db->addIdentifierQuotes( 'nice_db' ) . '.' . $db->addIdentifierQuotes( 'page' ),
+                       $this->quoteTable( $db, 'nice_db' ) . '.' . $this->quoteTable( $db, 'page' ),
                        $db->tableName( 'nice_db.page' ),
                        "Correct full table name"
                );
@@ -303,12 +327,12 @@ class LBFactoryTest extends MediaWikiTestCase {
                        $db->getDomainID()
                );
                $this->assertEquals(
-                       $db->addIdentifierQuotes( 'my_page' ),
+                       $this->quoteTable( $db, 'my_page' ),
                        $db->tableName( 'page' ),
                        "Correct full table name"
                );
                $this->assertEquals(
-                       $db->addIdentifierQuotes( 'other_nice_db' ) . '.' . $db->addIdentifierQuotes( 'page' ),
+                       $this->quoteTable( $db, 'other_nice_db' ) . '.' . $this->quoteTable( $db, 'page' ),
                        $db->tableName( 'other_nice_db.page' ),
                        "Correct full table name"
                );
@@ -318,9 +342,23 @@ class LBFactoryTest extends MediaWikiTestCase {
        }
 
        public function testTrickyDomain() {
+               global $wgDBtype;
+
+               if ( $wgDBtype === 'sqlite' ) {
+                       $tmpDir = $this->getNewTempDirectory();
+                       $dbPath = "$tmpDir/unit_test_db.sqlite";
+                       file_put_contents( $dbPath, '' );
+                       $tempFsFile = new TempFSFile( $dbPath );
+                       $tempFsFile->autocollect();
+               } else {
+                       $dbPath = null;
+               }
+
                $dbname = 'unittest-domain';
                $factory = $this->newLBFactoryMulti(
-                       [ 'localDomain' => $dbname ], [ 'dbname' => $dbname ] );
+                       [ 'localDomain' => $dbname ],
+                       [ 'dbname' => $dbname, 'dbFilePath' => $dbPath ]
+               );
                $lb = $factory->getMainLB();
                /** @var Database $db */
                $db = $lb->getConnection( DB_MASTER, [], '' );
@@ -332,19 +370,19 @@ class LBFactoryTest extends MediaWikiTestCase {
                );
 
                $this->assertEquals(
-                       $db->addIdentifierQuotes( 'page' ),
+                       $this->quoteTable( $db, 'page' ),
                        $db->tableName( 'page' ),
                        "Correct full table name"
                );
 
                $this->assertEquals(
-                       $db->addIdentifierQuotes( $dbname ) . '.' . $db->addIdentifierQuotes( 'page' ),
+                       $this->quoteTable( $db, $dbname ) . '.' . $this->quoteTable( $db, 'page' ),
                        $db->tableName( "$dbname.page" ),
                        "Correct full table name"
                );
 
                $this->assertEquals(
-                       $db->addIdentifierQuotes( 'nice_db' ) . '.' . $db->addIdentifierQuotes( 'page' ),
+                       $this->quoteTable( $db, 'nice_db' ) . '.' . $this->quoteTable( $db, 'page' ),
                        $db->tableName( 'nice_db.page' ),
                        "Correct full table name"
                );
@@ -352,12 +390,12 @@ class LBFactoryTest extends MediaWikiTestCase {
                $factory->setDomainPrefix( 'my_' );
 
                $this->assertEquals(
-                       $db->addIdentifierQuotes( 'my_page' ),
+                       $this->quoteTable( $db, 'my_page' ),
                        $db->tableName( 'page' ),
                        "Correct full table name"
                );
                $this->assertEquals(
-                       $db->addIdentifierQuotes( 'other_nice_db' ) . '.' . $db->addIdentifierQuotes( 'page' ),
+                       $this->quoteTable( $db, 'other_nice_db' ) . '.' . $this->quoteTable( $db, 'page' ),
                        $db->tableName( 'other_nice_db.page' ),
                        "Correct full table name"
                );
@@ -367,7 +405,7 @@ class LBFactoryTest extends MediaWikiTestCase {
                \MediaWiki\restoreWarnings();
 
                $this->assertEquals(
-                       $db->addIdentifierQuotes( 'garbage-db' ) . '.' . $db->addIdentifierQuotes( 'page' ),
+                       $this->quoteTable( $db, 'garbage-db' ) . '.' . $this->quoteTable( $db, 'page' ),
                        $db->tableName( 'garbage-db.page' ),
                        "Correct full table name"
                );
@@ -375,4 +413,12 @@ class LBFactoryTest extends MediaWikiTestCase {
                $factory->closeAll();
                $factory->destroy();
        }
+
+       private function quoteTable( Database $db, $table ) {
+               if ( $db->getType() === 'sqlite' ) {
+                       return $table;
+               } else {
+                       return $db->addIdentifierQuotes( $table );
+               }
+       }
 }
index 0e87ffa..7c36f7d 100644 (file)
@@ -173,7 +173,6 @@ class MWExceptionTest extends MediaWikiTestCase {
         * @dataProvider provideJsonSerializedKeys
         */
        public function testJsonserializeexceptionKeys( $expectedKeyType, $exClass, $key ) {
-
                # Make sure we log a backtrace:
                $this->setMwGlobals( [ 'wgLogExceptionBacktrace' => true ] );
 
@@ -235,7 +234,6 @@ class MWExceptionTest extends MediaWikiTestCase {
                        MWExceptionHandler::jsonSerializeException( new Exception() )
                );
                $this->assertObjectNotHasAttribute( 'backtrace', $json );
-
        }
 
 }
index fbabf7f..33e3a25 100644 (file)
@@ -49,9 +49,9 @@ class HtmlAutoCompleteSelectFieldTest extends MediaWikiTestCase {
         */
        function testOptionalSelectElement() {
                $params = [
-                       'fieldname'    => 'Test',
-                       'autocomplete' => $this->options,
-                       'options'      => $this->options,
+                       'fieldname'         => 'Test',
+                       'autocomplete-data' => $this->options,
+                       'options'           => $this->options,
                ];
 
                $field = new HTMLAutoCompleteSelectField( $params );
index 22d52f0..2a75cf4 100644 (file)
@@ -103,7 +103,7 @@ class FakeDatabase extends Database {
 
        /**
         * Get the number of fields in a result object
-        * @see http://www.php.net/mysql_num_fields
+        * @see https://secure.php.net/mysql_num_fields
         *
         * @param mixed $res A SQL result
         * @return int
@@ -114,7 +114,7 @@ class FakeDatabase extends Database {
 
        /**
         * Get a field name in a result object
-        * @see http://www.php.net/mysql_field_name
+        * @see https://secure.php.net/mysql_field_name
         *
         * @param mixed $res A SQL result
         * @param int $n
@@ -142,7 +142,7 @@ class FakeDatabase extends Database {
 
        /**
         * Change the position of the cursor in a result object
-        * @see http://www.php.net/mysql_data_seek
+        * @see https://secure.php.net/mysql_data_seek
         *
         * @param mixed $res A SQL result
         * @param int $row
@@ -153,7 +153,7 @@ class FakeDatabase extends Database {
 
        /**
         * Get the last error number
-        * @see http://www.php.net/mysql_errno
+        * @see https://secure.php.net/mysql_errno
         *
         * @return int
         */
@@ -163,7 +163,7 @@ class FakeDatabase extends Database {
 
        /**
         * Get a description of the last error
-        * @see http://www.php.net/mysql_error
+        * @see https://secure.php.net/mysql_error
         *
         * @return string
         */
@@ -197,7 +197,7 @@ class FakeDatabase extends Database {
 
        /**
         * Get the number of rows affected by the last write query
-        * @see http://www.php.net/mysql_affected_rows
+        * @see https://secure.php.net/mysql_affected_rows
         *
         * @return int
         */
@@ -217,7 +217,7 @@ class FakeDatabase extends Database {
 
        /**
         * Returns a wikitext link to the DB's website, e.g.,
-        *   return "[http://www.mysql.com/ MySQL]";
+        *   return "[https://www.mysql.com/ MySQL]";
         * Should at least contain plain text, if for some reason
         * your database has no website.
         *
diff --git a/tests/phpunit/includes/interwiki/InterwikiLookupAdapterTest.php b/tests/phpunit/includes/interwiki/InterwikiLookupAdapterTest.php
new file mode 100644 (file)
index 0000000..4754b04
--- /dev/null
@@ -0,0 +1,117 @@
+<?php
+
+/**
+ * @covers MediaWiki\Interwiki\InterwikiLookupAdapter
+ *
+ * @group MediaWiki
+ * @group Interwiki
+ */
+use MediaWiki\Interwiki\InterwikiLookupAdapter;
+
+class InterwikiLookupAdapterTest extends MediaWikiTestCase {
+
+       /**
+        * @var InterwikiLookupAdapter
+        */
+       private $interwikiLookup;
+
+       protected function setUp() {
+               parent::setUp();
+
+               $this->interwikiLookup = new InterwikiLookupAdapter(
+                       $this->getSiteLookup( $this->getSites() )
+               );
+       }
+
+       public function testIsValidInterwiki() {
+               $this->assertTrue(
+                       $this->interwikiLookup->isValidInterwiki( 'enwt' ),
+                       'enwt known prefix is valid'
+               );
+               $this->assertTrue(
+                       $this->interwikiLookup->isValidInterwiki( 'foo' ),
+                       'foo site known prefix is valid'
+               );
+               $this->assertFalse(
+                       $this->interwikiLookup->isValidInterwiki( 'xyz' ),
+                       'unknown prefix is not valid'
+               );
+       }
+
+       public function testFetch() {
+
+               $interwiki = $this->interwikiLookup->fetch( '' );
+               $this->assertNull( $interwiki );
+
+               $interwiki = $this->interwikiLookup->fetch( 'xyz' );
+               $this->assertFalse( $interwiki );
+
+               $interwiki = $this->interwikiLookup->fetch( 'foo' );
+               $this->assertInstanceOf( Interwiki::class, $interwiki );
+               $this->assertSame( 'foobar', $interwiki->getWikiID() );
+
+               $interwiki = $this->interwikiLookup->fetch( 'enwt' );
+               $this->assertInstanceOf( Interwiki::class, $interwiki );
+
+               $this->assertSame( 'https://en.wiktionary.org/wiki/$1', $interwiki->getURL(), 'getURL' );
+               $this->assertSame( 'https://en.wiktionary.org/w/api.php', $interwiki->getAPI(), 'getAPI' );
+               $this->assertSame( 'enwiktionary', $interwiki->getWikiID(), 'getWikiID' );
+               $this->assertTrue( $interwiki->isLocal(), 'isLocal' );
+       }
+
+       public function testGetAllPrefixes() {
+               $this->assertEquals(
+                       [ 'foo', 'enwt' ],
+                       $this->interwikiLookup->getAllPrefixes(),
+                       'getAllPrefixes()'
+               );
+
+               $this->assertEquals(
+                       [ 'foo' ],
+                       $this->interwikiLookup->getAllPrefixes( false ),
+                       'get external prefixes'
+               );
+
+               $this->assertEquals(
+                       [ 'enwt' ],
+                       $this->interwikiLookup->getAllPrefixes( true ),
+                       'get local prefixes'
+               );
+       }
+
+       private function getSiteLookup( SiteList $sites ) {
+               $siteLookup = $this->getMockBuilder( SiteLookup::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $siteLookup->expects( $this->any() )
+                       ->method( 'getSites' )
+                       ->will( $this->returnValue( $sites ) );
+
+               return $siteLookup;
+       }
+
+       private function getSites() {
+               $sites = [];
+
+               $site = new Site();
+               $site->setGlobalId( 'foobar' );
+               $site->addInterwikiId( 'foo' );
+               $site->setSource( 'external' );
+               $sites[] = $site;
+
+               $site = new MediaWikiSite();
+               $site->setGlobalId( 'enwiktionary' );
+               $site->setGroup( 'wiktionary' );
+               $site->setLanguageCode( 'en' );
+               $site->addNavigationId( 'enwiktionary' );
+               $site->addInterwikiId( 'enwt' );
+               $site->setSource( 'local' );
+               $site->setPath( MediaWikiSite::PATH_PAGE, "https://en.wiktionary.org/wiki/$1" );
+               $site->setPath( MediaWikiSite::PATH_FILE, "https://en.wiktionary.org/w/$1" );
+               $sites[] = $site;
+
+               return new SiteList( $sites );
+       }
+
+}
index 01b575c..d252c80 100644 (file)
@@ -146,7 +146,7 @@ class FormatJsonTest extends MediaWikiTestCase {
         * @return stdClass|string|bool|int|float|null
         */
        public static function toObject( $value ) {
-               return !is_array( $value ) ? $value : (object) array_map( __METHOD__, $value );
+               return !is_array( $value ) ? $value : (object)array_map( __METHOD__, $value );
        }
 
        /**
index 5f5a1e8..366714b 100644 (file)
@@ -129,8 +129,8 @@ class CSSMinTest extends MediaWikiTestCase {
         * @covers CSSMin::remap
         */
        public function testRemapRemapping( $message, $input, $expectedOutput ) {
-               $localPath = __DIR__ . '/../../data/cssmin/';
-               $remotePath = 'http://localhost/w/';
+               $localPath = __DIR__ . '/../../data/cssmin';
+               $remotePath = 'http://localhost/w';
 
                $realOutput = CSSMin::remap( $input, $localPath, $remotePath );
                $this->assertEquals( $expectedOutput, $realOutput, "CSSMin::remap: $message" );
index 6eb96b1..881f5e1 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /**
  * A MemoizedCallable subclass that stores function return values
- * in an instance property rather than APC.
+ * in an instance property rather than APC or APCu.
  */
 class ArrayBackedMemoizedCallable extends MemoizedCallable {
        private $cache = [];
@@ -44,7 +44,7 @@ class MemoizedCallableTest extends PHPUnit_Framework_TestCase {
         * Consecutive calls to the memoized callable with the same arguments
         * should result in just one invocation of the underlying callable.
         *
-        * @requires function apc_store
+        * @requires function apc_store/apcu_store
         */
        public function testCallableMemoized() {
                $observer = $this->getMock( 'stdClass', [ 'computeSomething' ] );
diff --git a/tests/phpunit/includes/libs/WaitConditionLoopTest.php b/tests/phpunit/includes/libs/WaitConditionLoopTest.php
deleted file mode 100644 (file)
index 9ce93d6..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-<?php
-
-class WaitConditionLoopFakeTime extends WaitConditionLoop {
-       protected $wallClock = 1;
-
-       function __construct( callable $condition, $timeout, array $busyCallbacks ) {
-               parent::__construct( $condition, $timeout, $busyCallbacks );
-       }
-
-       function usleep( $microseconds ) {
-               $this->wallClock += $microseconds / 1e6;
-       }
-
-       function getCpuTime() {
-               return 0.0;
-       }
-
-       function getWallTime() {
-               return $this->wallClock;
-       }
-
-       public function setWallClock( &$timestamp ) {
-               $this->wallClock =& $timestamp;
-       }
-}
-
-class WaitConditionLoopTest extends PHPUnit_Framework_TestCase {
-       public function testCallbackReached() {
-               $wallClock = microtime( true );
-
-               $count = 0;
-               $status = new StatusValue();
-               $loop = new WaitConditionLoopFakeTime(
-                       function () use ( &$count, $status ) {
-                               ++$count;
-                               $status->value = 'cookie';
-
-                               return WaitConditionLoop::CONDITION_REACHED;
-                       },
-                       10.0,
-                       $this->newBusyWork( $x, $y, $z )
-               );
-               $this->assertEquals( $loop::CONDITION_REACHED, $loop->invoke() );
-               $this->assertEquals( 1, $count );
-               $this->assertEquals( 'cookie', $status->value );
-               $this->assertEquals( [ 0, 0, 0 ], [ $x, $y, $z ], "No busy work done" );
-
-               $count = 0;
-               $loop = new WaitConditionLoopFakeTime(
-                       function () use ( &$count, &$wallClock ) {
-                               $wallClock += 1;
-                               ++$count;
-
-                               return $count >= 2 ? WaitConditionLoop::CONDITION_REACHED : false;
-                       },
-                       7.0,
-                       $this->newBusyWork( $x, $y, $z, $wallClock )
-               );
-               $this->assertEquals( $loop::CONDITION_REACHED, $loop->invoke(),
-                       "Busy work did not cause timeout" );
-               $this->assertEquals( [ 1, 0, 0 ], [ $x, $y, $z ] );
-
-               $count = 0;
-               $loop = new WaitConditionLoopFakeTime(
-                       function () use ( &$count, &$wallClock ) {
-                               $wallClock += .1;
-                               ++$count;
-
-                               return $count > 80 ? true : false;
-                       },
-                       50.0,
-                       $this->newBusyWork( $x, $y, $z, $wallClock, $dontCallMe, $badCalls )
-               );
-               $this->assertEquals( 0, $badCalls, "Callback exception not yet called" );
-               $this->assertEquals( $loop::CONDITION_REACHED, $loop->invoke() );
-               $this->assertEquals( [ 1, 1, 1 ], [ $x, $y, $z ], "Busy work done" );
-               $this->assertEquals( 1, $badCalls, "Bad callback ran and was exception caught" );
-
-               try {
-                       $e = null;
-                       $dontCallMe();
-               } catch ( Exception $e ) {
-               }
-
-               $this->assertInstanceOf( 'RunTimeException', $e );
-               $this->assertEquals( 1, $badCalls, "Callback exception cached" );
-       }
-
-       public function testCallbackTimeout() {
-               $count = 0;
-               $wallClock = microtime( true );
-               $loop = new WaitConditionLoopFakeTime(
-                       function () use ( &$count, &$wallClock ) {
-                               $wallClock += 3;
-                               ++$count;
-
-                               return $count > 300 ? true : false;
-                       },
-                       50.0,
-                       $this->newBusyWork( $x, $y, $z, $wallClock )
-               );
-               $loop->setWallClock( $wallClock );
-               $this->assertEquals( $loop::CONDITION_TIMED_OUT, $loop->invoke() );
-               $this->assertEquals( [ 1, 1, 1 ], [ $x, $y, $z ], "Busy work done" );
-
-               $loop = new WaitConditionLoopFakeTime(
-                       function () use ( &$count, &$wallClock ) {
-                               $wallClock += 3;
-                               ++$count;
-
-                               return true;
-                       },
-                       0.0,
-                       $this->newBusyWork( $x, $y, $z, $wallClock )
-               );
-               $this->assertEquals( $loop::CONDITION_REACHED, $loop->invoke() );
-
-               $count = 0;
-               $loop = new WaitConditionLoopFakeTime(
-                       function () use ( &$count, &$wallClock ) {
-                               $wallClock += 3;
-                               ++$count;
-
-                               return $count > 10 ? true : false;
-                       },
-                       0,
-                       $this->newBusyWork( $x, $y, $z, $wallClock )
-               );
-               $this->assertEquals( $loop::CONDITION_FAILED, $loop->invoke() );
-       }
-
-       public function testCallbackAborted() {
-               $x = 0;
-               $wallClock = microtime( true );
-               $loop = new WaitConditionLoopFakeTime(
-                       function () use ( &$x, &$wallClock ) {
-                               $wallClock += 2;
-                               ++$x;
-
-                               return $x > 2 ? WaitConditionLoop::CONDITION_ABORTED : false;
-                       },
-                       10.0,
-                       $this->newBusyWork( $x, $y, $z, $wallClock )
-               );
-               $loop->setWallClock( $wallClock );
-               $this->assertEquals( $loop::CONDITION_ABORTED, $loop->invoke() );
-       }
-
-       private function newBusyWork(
-               &$x, &$y, &$z, &$wallClock = 1, &$dontCallMe = null, &$badCalls = 0
-       ) {
-               $x = $y = $z = 0;
-               $badCalls = 0;
-
-               $list = [];
-               $list[] = function () use ( &$x, &$wallClock ) {
-                       $wallClock += 1;
-
-                       return ++$x;
-               };
-               $dontCallMe = function () use ( &$badCalls ) {
-                       ++$badCalls;
-                       throw new RuntimeException( "TrollyMcTrollFace" );
-               };
-               $list[] =& $dontCallMe;
-               $list[] = function () use ( &$y, &$wallClock ) {
-                       $wallClock += 15;
-
-                       return ++$y;
-               };
-               $list[] = function () use ( &$z, &$wallClock ) {
-                       $wallClock += 0.1;
-
-                       return ++$z;
-               };
-
-               return $list;
-       }
-}
index 2072752..ded5f8f 100644 (file)
@@ -11,23 +11,8 @@ class ComposerJsonTest extends MediaWikiTestCase {
                $this->json2 = "$IP/tests/phpunit/data/composer/new-composer.json";
        }
 
-       public static function provideGetHash() {
-               return [
-                       [ 'json', 'cc6e7fc565b246cb30b0cac103a2b31e' ],
-                       [ 'json2', '19921dd1fc457f1b00561da932432001' ],
-               ];
-       }
-
-       /**
-        * @dataProvider provideGetHash
-        * @covers ComposerJson::getHash
-        */
-       public function testIsHashUpToDate( $file, $expected ) {
-               $json = new ComposerJson( $this->$file );
-               $this->assertEquals( $expected, $json->getHash() );
-       }
-
        /**
+        * @covers ComposerJson::__construct
         * @covers ComposerJson::getRequiredDependencies
         */
        public function testGetRequiredDependencies() {
index 75eb62c..eef7e27 100644 (file)
@@ -11,14 +11,7 @@ class ComposerLockTest extends MediaWikiTestCase {
        }
 
        /**
-        * @covers ComposerLock::getHash
-        */
-       public function testGetHash() {
-               $lock = new ComposerLock( $this->lock );
-               $this->assertEquals( 'a3bb80b0ac4c4a31e52574d48c032923', $lock->getHash() );
-       }
-
-       /**
+        * @covers ComposerLock::__construct
         * @covers ComposerLock::getInstalledDependencies
         */
        public function testGetInstalledDependencies() {
diff --git a/tests/phpunit/includes/libs/mime/MimeAnalyzerTest.php b/tests/phpunit/includes/libs/mime/MimeAnalyzerTest.php
new file mode 100644 (file)
index 0000000..85927a3
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+class MimeMagicTest extends PHPUnit_Framework_TestCase {
+       /** @var MimeAnalyzer */
+       private $mimeAnalyzer;
+
+       function setUp() {
+               global $IP;
+
+               $this->mimeAnalyzer = new MimeAnalyzer( [
+                       'infoFile' => $IP . "/includes/libs/mime/mime.info",
+                       'typeFile' => $IP . "/includes/libs/mime/mime.types",
+                       'xmlTypes' => [
+                               'http://www.w3.org/2000/svg:svg' => 'image/svg+xml',
+                               'svg' => 'image/svg+xml',
+                               'http://www.lysator.liu.se/~alla/dia/:diagram' => 'application/x-dia-diagram',
+                               'http://www.w3.org/1999/xhtml:html' => 'text/html', // application/xhtml+xml?
+                               'html' => 'text/html', // application/xhtml+xml?
+                       ]
+               ] );
+               parent::setUp();
+       }
+
+       /**
+        * @dataProvider providerImproveTypeFromExtension
+        * @param string $ext File extension (no leading dot)
+        * @param string $oldMime Initially detected MIME
+        * @param string $expectedMime MIME type after taking extension into account
+        */
+       function testImproveTypeFromExtension( $ext, $oldMime, $expectedMime ) {
+               $actualMime = $this->mimeAnalyzer->improveTypeFromExtension( $oldMime, $ext );
+               $this->assertEquals( $expectedMime, $actualMime );
+       }
+
+       function providerImproveTypeFromExtension() {
+               return [
+                       [ 'gif', 'image/gif', 'image/gif' ],
+                       [ 'gif', 'unknown/unknown', 'unknown/unknown' ],
+                       [ 'wrl', 'unknown/unknown', 'model/vrml' ],
+                       [ 'txt', 'text/plain', 'text/plain' ],
+                       [ 'csv', 'text/plain', 'text/csv' ],
+                       [ 'tsv', 'text/plain', 'text/tab-separated-values' ],
+                       [ 'js', 'text/javascript', 'application/javascript' ],
+                       [ 'js', 'application/x-javascript', 'application/javascript' ],
+                       [ 'json', 'text/plain', 'application/json' ],
+                       [ 'foo', 'application/x-opc+zip', 'application/zip' ],
+                       [ 'docx', 'application/x-opc+zip',
+                               'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ],
+                       [ 'djvu', 'image/x-djvu', 'image/vnd.djvu' ],
+                       [ 'wav', 'audio/wav', 'audio/wav' ],
+               ];
+       }
+
+       /**
+        * Test to make sure that encoder=ffmpeg2theora doesn't trigger
+        * MEDIATYPE_VIDEO (bug 63584)
+        */
+       function testOggRecognize() {
+               $oggFile = __DIR__ . '/../../../data/media/say-test.ogg';
+               $actualType = $this->mimeAnalyzer->getMediaType( $oggFile, 'application/ogg' );
+               $this->assertEquals( $actualType, MEDIATYPE_AUDIO );
+       }
+}
index 92fb954..a1afa77 100644 (file)
@@ -1,4 +1,7 @@
 <?php
+
+use Wikimedia\ScopedCallback;
+
 /**
  * @author Matthias Mullie <mmullie@wikimedia.org>
  * @group BagOStuff
@@ -251,20 +254,20 @@ class BagOStuffTest extends MediaWikiTestCase {
                $value1 = $this->cache->getScopedLock( $key, 0 );
                $value2 = $this->cache->getScopedLock( $key, 0 );
 
-               $this->assertType( 'ScopedCallback', $value1, 'First call returned lock' );
+               $this->assertType( ScopedCallback::class, $value1, 'First call returned lock' );
                $this->assertNull( $value2, 'Duplicate call returned no lock' );
 
                unset( $value1 );
 
                $value3 = $this->cache->getScopedLock( $key, 0 );
-               $this->assertType( 'ScopedCallback', $value3, 'Lock returned callback after release' );
+               $this->assertType( ScopedCallback::class, $value3, 'Lock returned callback after release' );
                unset( $value3 );
 
                $value1 = $this->cache->getScopedLock( $key, 0, 5, 'reentry' );
                $value2 = $this->cache->getScopedLock( $key, 0, 5, 'reentry' );
 
-               $this->assertType( 'ScopedCallback', $value1, 'First reentrant call returned lock' );
-               $this->assertType( 'ScopedCallback', $value1, 'Second reentrant call returned lock' );
+               $this->assertType( ScopedCallback::class, $value1, 'First reentrant call returned lock' );
+               $this->assertType( ScopedCallback::class, $value1, 'Second reentrant call returned lock' );
        }
 
        /**
index 99b959b..aa46c96 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-class WANObjectCacheTest extends MediaWikiTestCase {
+class WANObjectCacheTest extends PHPUnit_Framework_TestCase  {
        /** @var WANObjectCache */
        private $cache;
        /**@var BagOStuff */
@@ -9,19 +9,14 @@ class WANObjectCacheTest extends MediaWikiTestCase {
        protected function setUp() {
                parent::setUp();
 
-               if ( $this->getCliArg( 'use-wanobjectcache' ) ) {
-                       $name = $this->getCliArg( 'use-wanobjectcache' );
-
-                       $this->cache = ObjectCache::getWANInstance( $name );
-               } else {
-                       $this->cache = new WANObjectCache( [
-                               'cache' => new HashBagOStuff(),
-                               'pool' => 'testcache-hash',
-                               'relayer' => new EventRelayerNull( [] )
-                       ] );
-               }
+               $this->cache = new WANObjectCache( [
+                       'cache' => new HashBagOStuff(),
+                       'pool' => 'testcache-hash',
+                       'relayer' => new EventRelayerNull( [] )
+               ] );
 
                $wanCache = TestingAccessWrapper::newFromObject( $this->cache );
+               /** @noinspection PhpUndefinedFieldInspection */
                $this->internalCache = $wanCache->cache;
        }
 
@@ -29,13 +24,14 @@ class WANObjectCacheTest extends MediaWikiTestCase {
         * @dataProvider provideSetAndGet
         * @covers WANObjectCache::set()
         * @covers WANObjectCache::get()
+        * @covers WANObjectCache::makeKey()
         * @param mixed $value
         * @param integer $ttl
         */
        public function testSetAndGet( $value, $ttl ) {
                $curTTL = null;
                $asOf = null;
-               $key = wfRandomString();
+               $key = $this->cache->makeKey( 'x', wfRandomString() );
 
                $this->cache->get( $key, $curTTL, [], $asOf );
                $this->assertNull( $curTTL, "Current TTL is null" );
@@ -71,9 +67,10 @@ class WANObjectCacheTest extends MediaWikiTestCase {
 
        /**
         * @covers WANObjectCache::get()
+        * @covers WANObjectCache::makeGlobalKey()
         */
        public function testGetNotExists() {
-               $key = wfRandomString();
+               $key = $this->cache->makeGlobalKey( 'y', wfRandomString(), 'p' );
                $curTTL = null;
                $value = $this->cache->get( $key, $curTTL );
 
@@ -144,6 +141,19 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                                $key, 100, $callback, [ 'pcTTL' => 5, 'pcGroup' => $groups[$i] ] );
                }
                $this->assertEquals( 9, $hit, "Values evicted" );
+
+               $key = reset( $keys );
+               // Get into cache
+               $this->cache->getWithSetCallback( $key, 100, $callback, [ 'pcTTL' => 5 ] );
+               $this->cache->getWithSetCallback( $key, 100, $callback, [ 'pcTTL' => 5 ] );
+               $this->assertEquals( 10, $hit, "Value cached" );
+               $outerCallback = function () use ( &$callback, $key ) {
+                       $v = $this->cache->getWithSetCallback( $key, 100, $callback, [ 'pcTTL' => 5 ] );
+
+                       return 43 + $v;
+               };
+               $this->cache->getWithSetCallback( $key, 100, $outerCallback );
+               $this->assertEquals( 11, $hit, "Nested callback value process cache skipped" );
        }
 
        /**
@@ -165,7 +175,7 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                $priorAsOf = null;
                $wasSet = 0;
                $func = function( $old, &$ttl, &$opts, $asOf )
-                       use ( &$wasSet, &$priorValue, &$priorAsOf, $value )
+               use ( &$wasSet, &$priorValue, &$priorAsOf, $value )
                {
                        ++$wasSet;
                        $priorValue = $old;
@@ -188,9 +198,9 @@ class WANObjectCacheTest extends MediaWikiTestCase {
 
                $wasSet = 0;
                $v = $cache->getWithSetCallback( $key, 30, $func, [
-                       'lowTTL' => 0,
-                       'lockTSE' => 5,
-               ] + $extOpts );
+                               'lowTTL' => 0,
+                               'lockTSE' => 5,
+                       ] + $extOpts );
                $this->assertEquals( $value, $v, "Value returned" );
                $this->assertEquals( 0, $wasSet, "Value not regenerated" );
 
@@ -203,7 +213,7 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                $this->assertEquals( $value, $v, "Value returned" );
                $this->assertEquals( 1, $wasSet, "Value regenerated due to check keys" );
                $this->assertEquals( $value, $priorValue, "Has prior value" );
-               $this->assertType( 'float', $priorAsOf, "Has prior value" );
+               $this->assertInternalType( 'float', $priorAsOf, "Has prior value" );
                $t1 = $cache->getCheckKeyTime( $cKey1 );
                $this->assertGreaterThanOrEqual( $priorTime, $t1, 'Check keys generated on miss' );
                $t2 = $cache->getCheckKeyTime( $cKey2 );
@@ -247,6 +257,150 @@ class WANObjectCacheTest extends MediaWikiTestCase {
                ];
        }
 
+       /**
+        * @dataProvider getMultiWithSetCallback_provider
+        * @covers WANObjectCache::getMultiWithSetCallback()
+        * @covers WANObjectCache::makeMultiKeys()
+        * @param array $extOpts
+        * @param bool $versioned
+        */
+       public function testGetMultiWithSetCallback( array $extOpts, $versioned ) {
+               $cache = $this->cache;
+
+               $keyA = wfRandomString();
+               $keyB = wfRandomString();
+               $keyC = wfRandomString();
+               $cKey1 = wfRandomString();
+               $cKey2 = wfRandomString();
+
+               $priorValue = null;
+               $priorAsOf = null;
+               $wasSet = 0;
+               $genFunc = function ( $id, $old, &$ttl, &$opts, $asOf ) use (
+                       &$wasSet, &$priorValue, &$priorAsOf
+               ) {
+                       ++$wasSet;
+                       $priorValue = $old;
+                       $priorAsOf = $asOf;
+                       $ttl = 20; // override with another value
+                       return "@$id$";
+               };
+
+               $wasSet = 0;
+               $keyedIds = new ArrayIterator( [ $keyA => 3353 ] );
+               $value = "@3353$";
+               $v = $cache->getMultiWithSetCallback(
+                       $keyedIds, 30, $genFunc, [ 'lockTSE' => 5 ] + $extOpts );
+               $this->assertEquals( $value, $v[$keyA], "Value returned" );
+               $this->assertEquals( 1, $wasSet, "Value regenerated" );
+               $this->assertFalse( $priorValue, "No prior value" );
+               $this->assertNull( $priorAsOf, "No prior value" );
+
+               $curTTL = null;
+               $cache->get( $keyA, $curTTL );
+               $this->assertLessThanOrEqual( 20, $curTTL, 'Current TTL between 19-20 (overriden)' );
+               $this->assertGreaterThanOrEqual( 19, $curTTL, 'Current TTL between 19-20 (overriden)' );
+
+               $wasSet = 0;
+               $value = "@efef$";
+               $keyedIds = new ArrayIterator( [ $keyB => 'efef' ] );
+               $v = $cache->getMultiWithSetCallback(
+                       $keyedIds, 30, $genFunc, [ 'lowTTL' => 0, 'lockTSE' => 5, ] + $extOpts );
+               $this->assertEquals( $value, $v[$keyB], "Value returned" );
+               $this->assertEquals( 1, $wasSet, "Value regenerated" );
+               $v = $cache->getMultiWithSetCallback(
+                       $keyedIds, 30, $genFunc, [ 'lowTTL' => 0, 'lockTSE' => 5, ] + $extOpts );
+               $this->assertEquals( $value, $v[$keyB], "Value returned" );
+               $this->assertEquals( 1, $wasSet, "Value not regenerated" );
+
+               $priorTime = microtime( true );
+               usleep( 1 );
+               $wasSet = 0;
+               $keyedIds = new ArrayIterator( [ $keyB => 'efef' ] );
+               $v = $cache->getMultiWithSetCallback(
+                       $keyedIds, 30, $genFunc, [ 'checkKeys' => [ $cKey1, $cKey2 ] ] + $extOpts
+               );
+               $this->assertEquals( $value, $v[$keyB], "Value returned" );
+               $this->assertEquals( 1, $wasSet, "Value regenerated due to check keys" );
+               $this->assertEquals( $value, $priorValue, "Has prior value" );
+               $this->assertInternalType( 'float', $priorAsOf, "Has prior value" );
+               $t1 = $cache->getCheckKeyTime( $cKey1 );
+               $this->assertGreaterThanOrEqual( $priorTime, $t1, 'Check keys generated on miss' );
+               $t2 = $cache->getCheckKeyTime( $cKey2 );
+               $this->assertGreaterThanOrEqual( $priorTime, $t2, 'Check keys generated on miss' );
+
+               $priorTime = microtime( true );
+               $value = "@43636$";
+               $wasSet = 0;
+               $keyedIds = new ArrayIterator( [ $keyC => 43636 ] );
+               $v = $cache->getMultiWithSetCallback(
+                       $keyedIds, 30, $genFunc, [ 'checkKeys' => [ $cKey1, $cKey2 ] ] + $extOpts
+               );
+               $this->assertEquals( $value, $v[$keyC], "Value returned" );
+               $this->assertEquals( 1, $wasSet, "Value regenerated due to still-recent check keys" );
+               $t1 = $cache->getCheckKeyTime( $cKey1 );
+               $this->assertLessThanOrEqual( $priorTime, $t1, 'Check keys did not change again' );
+               $t2 = $cache->getCheckKeyTime( $cKey2 );
+               $this->assertLessThanOrEqual( $priorTime, $t2, 'Check keys did not change again' );
+
+               $curTTL = null;
+               $v = $cache->get( $keyC, $curTTL, [ $cKey1, $cKey2 ] );
+               if ( $versioned ) {
+                       $this->assertEquals( $value, $v[$cache::VFLD_DATA], "Value returned" );
+               } else {
+                       $this->assertEquals( $value, $v, "Value returned" );
+               }
+               $this->assertLessThanOrEqual( 0, $curTTL, "Value has current TTL < 0 due to check keys" );
+
+               $wasSet = 0;
+               $key = wfRandomString();
+               $keyedIds = new ArrayIterator( [ $key => 242424 ] );
+               $v = $cache->getMultiWithSetCallback(
+                       $keyedIds, 30, $genFunc, [ 'pcTTL' => 5 ] + $extOpts );
+               $this->assertEquals( "@{$keyedIds[$key]}$", $v[$key], "Value returned" );
+               $cache->delete( $key );
+               $keyedIds = new ArrayIterator( [ $key => 242424 ] );
+               $v = $cache->getMultiWithSetCallback(
+                       $keyedIds, 30, $genFunc, [ 'pcTTL' => 5 ] + $extOpts );
+               $this->assertEquals( "@{$keyedIds[$key]}$", $v[$key], "Value still returned after deleted" );
+               $this->assertEquals( 1, $wasSet, "Value process cached while deleted" );
+
+               $calls = 0;
+               $ids = [ 1, 2, 3, 4, 5, 6 ];
+               $keyFunc = function ( $id, WANObjectCache $wanCache ) {
+                       return $wanCache->makeKey( 'test', $id );
+               };
+               $keyedIds = $cache->makeMultiKeys( $ids, $keyFunc );
+               $genFunc = function ( $id, $oldValue, &$ttl, array &$setops ) use ( &$calls ) {
+                       ++$calls;
+
+                       return "val-{$id}";
+               };
+               $values = $cache->getMultiWithSetCallback( $keyedIds, 10, $genFunc );
+
+               $this->assertEquals(
+                       [ "val-1", "val-2", "val-3", "val-4", "val-5", "val-6" ],
+                       array_values( $values ),
+                       "Correct values in correct order"
+               );
+               $this->assertEquals(
+                       array_map( $keyFunc, $ids, array_fill( 0, count( $ids ), $this->cache ) ),
+                       array_keys( $values ),
+                       "Correct keys in correct order"
+               );
+               $this->assertEquals( count( $ids ), $calls );
+
+               $cache->getMultiWithSetCallback( $keyedIds, 10, $genFunc );
+               $this->assertEquals( count( $ids ), $calls, "Values cached" );
+       }
+
+       public static function getMultiWithSetCallback_provider() {
+               return [
+                       [ [], false ],
+                       [ [ 'version' => 1 ], true ]
+               ];
+       }
+
        /**
         * @covers WANObjectCache::getWithSetCallback()
         * @covers WANObjectCache::doGetWithSetCallback()
@@ -777,9 +931,14 @@ class WANObjectCacheTest extends MediaWikiTestCase {
        /**
         * @dataProvider provideAdaptiveTTL
         * @covers WANObjectCache::adaptiveTTL()
+        * @param float|int $ago
+        * @param int $maxTTL
+        * @param int $minTTL
+        * @param float $factor
+        * @param int $adaptiveTTL
         */
        public function testAdaptiveTTL( $ago, $maxTTL, $minTTL, $factor, $adaptiveTTL ) {
-               $mtime = is_int( $ago ) ? time() - $ago : $ago;
+               $mtime = $ago ? time() - $ago : $ago;
                $margin = 5;
                $ttl = $this->cache->adaptiveTTL( $mtime, $maxTTL, $minTTL, $factor );
 
index 70c0ece..6d096c2 100644 (file)
@@ -24,7 +24,6 @@ class LinkRendererTest extends MediaWikiLangTestCase {
                        'wgScript' => '/w/index.php',
                ] );
                $this->factory = MediaWikiServices::getInstance()->getLinkRendererFactory();
-
        }
 
        public function testMergeAttribs() {
index f70b42d..47ed67b 100644 (file)
@@ -17,7 +17,6 @@ class ExifBitmapTest extends MediaWikiMediaTestCase {
                $this->setMwGlobals( 'wgShowEXIF', true );
 
                $this->handler = new ExifBitmapHandler;
-
        }
 
        /**
index 9f4e1fa..5f1bf0c 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Wikimedia\ScopedCallback;
+
 class WikiCategoryPageTest extends MediaWikiLangTestCase {
 
        /**
index e55efee..4b7ebd3 100644 (file)
@@ -92,6 +92,9 @@ class WikiPageTest extends MediaWikiLangTestCase {
 
        /**
         * @covers WikiPage::doEditContent
+        * @covers WikiPage::doModify
+        * @covers WikiPage::doCreate
+        * @covers WikiPage::doEditUpdates
         */
        public function testDoEditContent() {
                $page = $this->newPage( "WikiPageTest_testDoEditContent" );
@@ -213,30 +216,6 @@ class WikiPageTest extends MediaWikiLangTestCase {
                $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' );
        }
 
-       /**
-        * @covers WikiPage::doQuickEditContent
-        */
-       public function testDoQuickEditContent() {
-               global $wgUser;
-
-               $page = $this->createPage(
-                       "WikiPageTest_testDoQuickEditContent",
-                       "original text",
-                       CONTENT_MODEL_WIKITEXT
-               );
-
-               $content = ContentHandler::makeContent(
-                       "quick text",
-                       $page->getTitle(),
-                       CONTENT_MODEL_WIKITEXT
-               );
-               $page->doQuickEditContent( $content, $wgUser, "testing q" );
-
-               # ---------------------
-               $page = new WikiPage( $page->getTitle() );
-               $this->assertTrue( $content->equals( $page->getContent() ) );
-       }
-
        /**
         * @covers WikiPage::doDeleteArticle
         */
index b38c98d..c920982 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+use Wikimedia\ScopedCallback;
 
 /**
  * This is the TestCase subclass for running a single parser test via the
index 6710b19..c491e6b 100644 (file)
@@ -210,10 +210,10 @@ class PreprocessorTest extends MediaWikiTestCase {
        public static function provideFiles() {
                // @codingStandardsIgnoreStart Ignore Generic.Files.LineLength.TooLong
                return self::addClassArg( [
-                       [ "QuoteQuran" ], # http://en.wikipedia.org/w/index.php?title=Template:QuoteQuran/sandbox&oldid=237348988 GFDL + CC BY-SA by Striver
-                       [ "Factorial" ], # http://en.wikipedia.org/w/index.php?title=Template:Factorial&oldid=98548758 GFDL + CC BY-SA by Polonium
-                       [ "All_system_messages" ], # http://tl.wiktionary.org/w/index.php?title=Suleras:All_system_messages&oldid=2765 GPL text generated by MediaWiki
-                       [ "Fundraising" ], # http://tl.wiktionary.org/w/index.php?title=MediaWiki:Sitenotice&oldid=5716 GFDL + CC BY-SA, copied there by Sky Harbor.
+                       [ "QuoteQuran" ], # https://en.wikipedia.org/w/index.php?title=Template:QuoteQuran/sandbox&oldid=237348988 GFDL + CC BY-SA by Striver
+                       [ "Factorial" ], # https://en.wikipedia.org/w/index.php?title=Template:Factorial&oldid=98548758 GFDL + CC BY-SA by Polonium
+                       [ "All_system_messages" ], # https://tl.wiktionary.org/w/index.php?title=Suleras:All_system_messages&oldid=2765 GPL text generated by MediaWiki
+                       [ "Fundraising" ], # https://tl.wiktionary.org/w/index.php?title=MediaWiki:Sitenotice&oldid=5716 GFDL + CC BY-SA, copied there by Sky Harbor.
                        [ "NestedTemplates" ], # bug 27936
                ] );
                // @codingStandardsIgnoreEnd
index 167f52a..1de4265 100644 (file)
@@ -252,6 +252,41 @@ class ExtensionRegistryTest extends MediaWikiTestCase {
                                        'mwtestT100767' => false,
                                ],
                        ],
+                       [
+                               'test array_replace_recursive',
+                               [
+                                       'mwtestJsonConfigs' => [
+                                               'JsonZeroConfig' => [
+                                                       'namespace' => 480,
+                                                       'nsName' => 'Zero',
+                                                       'isLocal' => false,
+                                               ],
+                                       ],
+                               ],
+                               [
+                                       'mwtestJsonConfigs' => [
+                                               'JsonZeroConfig' => [
+                                                       'isLocal' => false,
+                                                       'remote' => [
+                                                               'username' => 'foo',
+                                                       ],
+                                               ],
+                                               ExtensionRegistry::MERGE_STRATEGY => 'array_replace_recursive',
+                                       ],
+                               ],
+                               [
+                                       'mwtestJsonConfigs' => [
+                                               'JsonZeroConfig' => [
+                                                       'namespace' => 480,
+                                                       'nsName' => 'Zero',
+                                                       'isLocal' => false,
+                                                       'remote' => [
+                                                               'username' => 'foo',
+                                                       ],
+                                               ],
+                                       ],
+                               ],
+                       ],
                ];
        }
 }
index 0965b9f..528c322 100644 (file)
@@ -5,6 +5,12 @@
  */
 class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
 
+       protected static function expandVariables( $text ) {
+               return strtr( $text, [
+                       '{blankVer}' => ResourceLoaderTestCase::BLANK_VERSION
+               ] );
+       }
+
        protected static function makeContext( $extraQuery = [] ) {
                $conf = new HashConfig( [
                        'ResourceLoaderSources' => [],
@@ -108,22 +114,22 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                                'test.scripts.mixed.user.empty' => 'ready',
                        ],
                        'general' => [
-                               'top' => [ 'test.top' ],
-                               'bottom' => [ 'test' ],
+                               'test',
+                               'test.top',
                        ],
                        'styles' => [
                                'test.styles.mixed',
                                'test.styles.pure',
                        ],
                        'scripts' => [
-                               'top' => [ 'test.scripts.top' ],
-                               'bottom' => [ 'test.scripts' ],
+                               'test.scripts',
+                               'test.scripts.top',
                        ],
                        'embed' => [
                                'styles' => [ 'test.styles.private' ],
                                'general' => [
-                                       'top' => [ 'test.private.top' ],
-                                       'bottom' => [ 'test.private.bottom' ],
+                                       'test.private.bottom',
+                                       'test.private.top',
                                ],
                        ],
                ];
@@ -165,7 +171,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                        . '<script>(window.RLQ=window.RLQ||[]).push(function(){'
                        . 'mw.config.set({"key":"value"});'
                        . 'mw.loader.state({"test.exempt":"ready","test.private.top":"loading","test.styles.pure":"ready","test.styles.private":"ready","test.scripts.top":"loading"});'
-                       . 'mw.loader.implement("test.private.top",function($,jQuery,require,module){},{"css":[]});'
+                       . 'mw.loader.implement("test.private.top@{blankVer}",function($,jQuery,require,module){},{"css":[]});'
                        . 'mw.loader.load(["test.top"]);'
                        . 'mw.loader.load("/w/load.php?debug=false\u0026lang=nl\u0026modules=test.scripts.top\u0026only=scripts\u0026skin=fallback");'
                        . '});</script>' . "\n"
@@ -173,6 +179,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                        . '<style>.private{}</style>' . "\n"
                        . '<script async="" src="/w/load.php?debug=false&amp;lang=nl&amp;modules=startup&amp;only=scripts&amp;skin=fallback"></script>';
                // @codingStandardsIgnoreEnd
+               $expected = self::expandVariables( $expected );
 
                $this->assertEquals( $expected, $client->getHeadHtml() );
        }
@@ -195,13 +202,8 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                        'test.scripts',
                ] );
 
-               // @codingStandardsIgnoreStart Generic.Files.LineLength
-               $expected = '<script>(window.RLQ=window.RLQ||[]).push(function(){'
-                       . 'mw.loader.implement("test.private.bottom",function($,jQuery,require,module){},{"css":[]});'
-                       . 'mw.loader.load("/w/load.php?debug=false\u0026lang=nl\u0026modules=test.scripts\u0026only=scripts\u0026skin=fallback");'
-                       . 'mw.loader.load(["test"]);'
-                       . '});</script>';
-               // @codingStandardsIgnoreEnd
+               $expected = '';
+               $expected = self::expandVariables( $expected );
 
                $this->assertEquals( $expected, $client->getBodyHtml() );
        }
@@ -225,7 +227,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                                'context' => [],
                                'modules' => [ 'test.private.top' ],
                                'only' => ResourceLoaderModule::TYPE_COMBINED,
-                               'output' => '<script>(window.RLQ=window.RLQ||[]).push(function(){mw.loader.implement("test.private.top",function($,jQuery,require,module){},{"css":[]});});</script>',
+                               'output' => '<script>(window.RLQ=window.RLQ||[]).push(function(){mw.loader.implement("test.private.top@{blankVer}",function($,jQuery,require,module){},{"css":[]});});</script>',
                        ],
                        [
                                'context' => [],
@@ -273,6 +275,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit_Framework_TestCase {
                $context = self::makeContext( $extraQuery );
                $context->getResourceLoader()->register( self::makeSampleModules() );
                $actual = ResourceLoaderClientHtml::makeLoad( $context, $modules, $type );
+               $expected = self::expandVariables( $expected );
                $this->assertEquals( $expected, (string)$actual );
        }
 }
index ab1323e..1b756be 100644 (file)
@@ -2,14 +2,9 @@
 
 class ResourceLoaderStartUpModuleTest extends ResourceLoaderTestCase {
 
-       // Version hash for a blank file module.
-       // Result of ResourceLoader::makeHash(), ResourceLoaderTestModule
-       // and ResourceLoaderFileModule::getDefinitionSummary().
-       protected static $blankVersion = '09p30q0';
-
        protected static function expandPlaceholders( $text ) {
                return strtr( $text, [
-                       '{blankVer}' => self::$blankVersion
+                       '{blankVer}' => self::BLANK_VERSION
                ] );
        }
 
index c24a321..1ecdf21 100644 (file)
@@ -51,6 +51,16 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
                $this->assertEquals( $module, $resourceLoader->getModule( 'test' ) );
        }
 
+       /**
+        * @covers ResourceLoader::register
+        */
+       public function testRegisterEmptyString() {
+               $module = new ResourceLoaderTestModule();
+               $resourceLoader = new EmptyResourceLoader();
+               $resourceLoader->register( '', $module );
+               $this->assertEquals( $module, $resourceLoader->getModule( '' ) );
+       }
+
        /**
         * @covers ResourceLoader::register
         */
index b12d235..a332528 100644 (file)
@@ -199,6 +199,12 @@ class ResourceLoaderWikiModuleTest extends ResourceLoaderTestCase {
                $rl->register( 'testmodule', $module );
                $context = new ResourceLoaderContext( $rl, new FauxRequest() );
 
+               TestResourceLoaderWikiModule::invalidateModuleCache(
+                       Title::newFromText( 'MediaWiki:Common.css' ),
+                       null,
+                       null,
+                       wfWikiID()
+               );
                TestResourceLoaderWikiModule::preloadTitleInfo(
                        $context,
                        wfGetDB( DB_REPLICA ),
index 799a97b..34e5e44 100644 (file)
@@ -21,7 +21,7 @@ class PHPSessionHandlerTest extends MediaWikiTestCase {
                        }
                        return false;
                } );
-               $reset[] = new \ScopedCallback( 'restore_error_handler' );
+               $reset[] = new \Wikimedia\ScopedCallback( 'restore_error_handler' );
 
                $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
                $rProp->setAccessible( true );
@@ -30,7 +30,7 @@ class PHPSessionHandlerTest extends MediaWikiTestCase {
                        $oldManager = $old->manager;
                        $oldStore = $old->store;
                        $oldLogger = $old->logger;
-                       $reset[] = new \ScopedCallback(
+                       $reset[] = new \Wikimedia\ScopedCallback(
                                [ PHPSessionHandler::class, 'install' ],
                                [ $oldManager, $oldStore, $oldLogger ]
                        );
@@ -49,7 +49,7 @@ class PHPSessionHandlerTest extends MediaWikiTestCase {
 
                $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
                $rProp->setAccessible( true );
-               $reset = new \ScopedCallback( [ $rProp, 'setValue' ], [ $rProp->getValue() ] );
+               $reset = new \Wikimedia\ScopedCallback( [ $rProp, 'setValue' ], [ $rProp->getValue() ] );
                $rProp->setValue( $handler );
 
                $handler->setEnableFlags( 'enable' );
@@ -123,7 +123,7 @@ class PHPSessionHandlerTest extends MediaWikiTestCase {
                ] );
                PHPSessionHandler::install( $manager );
                $wrap = \TestingAccessWrapper::newFromObject( $rProp->getValue() );
-               $reset[] = new \ScopedCallback(
+               $reset[] = new \Wikimedia\ScopedCallback(
                        [ $wrap, 'setEnableFlags' ],
                        [ $wrap->enable ? $wrap->warn ? 'warn' : 'enable' : 'disable' ]
                );
@@ -326,7 +326,7 @@ class PHPSessionHandlerTest extends MediaWikiTestCase {
                \TestingAccessWrapper::newFromObject( $handler )->setEnableFlags( 'disable' );
                $oldValue = $rProp->getValue();
                $rProp->setValue( $handler );
-               $reset = new \ScopedCallback( [ $rProp, 'setValue' ], [ $oldValue ] );
+               $reset = new \Wikimedia\ScopedCallback( [ $rProp, 'setValue' ], [ $oldValue ] );
 
                call_user_func_array( [ $handler, $method ], $args );
        }
index a3d5de7..8a0adba 100644 (file)
@@ -464,7 +464,7 @@ class SessionBackendTest extends MediaWikiTestCase {
                // Save happens when delay is consumed
                $this->onSessionMetadataCalled = false;
                $priv->metaDirty = true;
-               \ScopedCallback::consume( $delay );
+               \Wikimedia\ScopedCallback::consume( $delay );
                $this->assertTrue( $this->onSessionMetadataCalled );
 
                // Test multiple delays
@@ -475,11 +475,11 @@ class SessionBackendTest extends MediaWikiTestCase {
                $priv->metaDirty = true;
                $priv->autosave();
                $this->assertFalse( $this->onSessionMetadataCalled );
-               \ScopedCallback::consume( $delay3 );
+               \Wikimedia\ScopedCallback::consume( $delay3 );
                $this->assertFalse( $this->onSessionMetadataCalled );
-               \ScopedCallback::consume( $delay1 );
+               \Wikimedia\ScopedCallback::consume( $delay1 );
                $this->assertFalse( $this->onSessionMetadataCalled );
-               \ScopedCallback::consume( $delay2 );
+               \Wikimedia\ScopedCallback::consume( $delay2 );
                $this->assertTrue( $this->onSessionMetadataCalled );
        }
 
@@ -822,7 +822,7 @@ class SessionBackendTest extends MediaWikiTestCase {
                        $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
                        $rProp->setAccessible( true );
                        $handler = \TestingAccessWrapper::newFromObject( $rProp->getValue() );
-                       $resetHandler = new \ScopedCallback( function () use ( $handler ) {
+                       $resetHandler = new \Wikimedia\ScopedCallback( function () use ( $handler ) {
                                session_write_close();
                                $handler->enable = false;
                        } );
@@ -862,7 +862,7 @@ class SessionBackendTest extends MediaWikiTestCase {
                        $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
                        $rProp->setAccessible( true );
                        $handler = \TestingAccessWrapper::newFromObject( $rProp->getValue() );
-                       $resetHandler = new \ScopedCallback( function () use ( $handler ) {
+                       $resetHandler = new \Wikimedia\ScopedCallback( function () use ( $handler ) {
                                session_write_close();
                                $handler->enable = false;
                        } );
@@ -898,7 +898,7 @@ class SessionBackendTest extends MediaWikiTestCase {
                        $rProp = new \ReflectionProperty( PHPSessionHandler::class, 'instance' );
                        $rProp->setAccessible( true );
                        $handler = \TestingAccessWrapper::newFromObject( $rProp->getValue() );
-                       $resetHandler = new \ScopedCallback( function () use ( $handler ) {
+                       $resetHandler = new \Wikimedia\ScopedCallback( function () use ( $handler ) {
                                session_write_close();
                                $handler->enable = false;
                        } );
index 1ebb07c..6273f47 100644 (file)
@@ -62,7 +62,7 @@ class SessionManagerTest extends MediaWikiTestCase {
                $rProp->setAccessible( true );
                $handler = \TestingAccessWrapper::newFromObject( $rProp->getValue() );
                $oldEnable = $handler->enable;
-               $reset[] = new \ScopedCallback( function () use ( $handler, $oldEnable ) {
+               $reset[] = new \Wikimedia\ScopedCallback( function () use ( $handler, $oldEnable ) {
                        if ( $handler->enable ) {
                                session_write_close();
                        }
index 4cbeeb9..8284d05 100644 (file)
@@ -138,7 +138,6 @@ class SessionProviderTest extends MediaWikiTestCase {
                                $ex->getMessage()
                        );
                }
-
        }
 
        public function testHashToSessionId() {
index 3815416..e6a6ad3 100644 (file)
@@ -299,7 +299,6 @@ class SessionTest extends MediaWikiTestCase {
 
                $session->resetAllTokens();
                $this->assertArrayNotHasKey( 'wsTokenSecrets', $backend->data );
-
        }
 
        /**
index f1dc9e9..f00de55 100644 (file)
@@ -12,7 +12,7 @@ class TestUtils {
        /**
         * Override the singleton for unit testing
         * @param SessionManager|null $manager
-        * @return \\ScopedCallback|null
+        * @return \\Wikimedia\ScopedCallback|null
         */
        public static function setSessionManagerSingleton( SessionManager $manager = null ) {
                session_write_close();
@@ -45,7 +45,7 @@ class TestUtils {
                        PHPSessionHandler::install( $manager );
                }
 
-               return new \ScopedCallback( function () use ( &$reset, $oldInstance ) {
+               return new \Wikimedia\ScopedCallback( function () use ( &$reset, $oldInstance ) {
                        foreach ( $reset as &$arr ) {
                                $arr[0]->setValue( $arr[1] );
                        }
index 3d407fb..f79f6e4 100644 (file)
@@ -1,4 +1,6 @@
 <?php
+use Wikimedia\ScopedCallback;
+
 /**
  * Factory for handling the special page list and generating SpecialPage objects.
  *
@@ -55,17 +57,19 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
                $specialPageTestHelper = new SpecialPageTestHelper();
 
                return [
-                       'class name' => [ 'SpecialAllPages' ],
+                       'class name' => [ 'SpecialAllPages', false ],
                        'closure' => [ function () {
                                return new SpecialAllPages();
-                       } ],
-                       'function' => [ [ $this, 'newSpecialAllPages' ] ],
-                       'callback string' => [ 'SpecialPageTestHelper::newSpecialAllPages' ],
+                       }, false ],
+                       'function' => [ [ $this, 'newSpecialAllPages' ], false ],
+                       'callback string' => [ 'SpecialPageTestHelper::newSpecialAllPages', false ],
                        'callback with object' => [
-                               [ $specialPageTestHelper, 'newSpecialAllPages' ]
+                               [ $specialPageTestHelper, 'newSpecialAllPages' ],
+                               false
                        ],
                        'callback array' => [
-                               [ 'SpecialPageTestHelper', 'newSpecialAllPages' ]
+                               [ 'SpecialPageTestHelper', 'newSpecialAllPages' ],
+                               false
                        ]
                ];
        }
@@ -74,7 +78,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
         * @covers SpecialPageFactory::getPage
         * @dataProvider specialPageProvider
         */
-       public function testGetPage( $spec ) {
+       public function testGetPage( $spec, $shouldReuseInstance ) {
                $this->mergeMwGlobalArrayValue( 'wgSpecialPages', [ 'testdummy' => $spec ] );
                SpecialPageFactory::resetList();
 
@@ -82,7 +86,7 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
                $this->assertInstanceOf( 'SpecialPage', $page );
 
                $page2 = SpecialPageFactory::getPage( 'testdummy' );
-               $this->assertEquals( true, $page2 === $page, "Should re-use instance:" );
+               $this->assertEquals( $shouldReuseInstance, $page2 === $page, "Should re-use instance:" );
        }
 
        /**
index 061e598..c1083af 100644 (file)
@@ -22,7 +22,7 @@ class QueryAllSpecialPagesTest extends MediaWikiTestCase {
         * Pages whose query use the same DB table more than once.
         * This is used to skip testing those pages when run against a MySQL backend
         * which does not support reopening a temporary table. See upstream bug:
-        * http://bugs.mysql.com/bug.php?id=10327
+        * https://bugs.mysql.com/bug.php?id=10327
         */
        protected $reopensTempTable = [
                'BrokenRedirects',
@@ -51,7 +51,7 @@ class QueryAllSpecialPagesTest extends MediaWikiTestCase {
 
                foreach ( $this->queryPages as $page ) {
                        // With MySQL, skips special pages reopening a temporary table
-                       // See http://bugs.mysql.com/bug.php?id=10327
+                       // See https://bugs.mysql.com/bug.php?id=10327
                        if (
                                $wgDBtype === 'mysql'
                                && in_array( $page->getName(), $this->reopensTempTable )
index 3310d02..074045d 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-class SpecialBooksourcesTest extends MediaWikiTestCase {
+class SpecialBooksourcesTest extends SpecialPageTestBase {
        public static function provideISBNs() {
                return [
                        [ '978-0-300-14424-6', true ],
@@ -33,4 +33,19 @@ class SpecialBooksourcesTest extends MediaWikiTestCase {
        public function testIsValidISBN( $isbn, $isValid ) {
                $this->assertSame( $isValid, SpecialBookSources::isValidISBN( $isbn ) );
        }
+
+       protected function newSpecialPage() {
+               return new SpecialBookSources();
+       }
+
+       /**
+        * @covers SpecialBookSources::execute
+        */
+       public function testExecute() {
+               list( $html, ) = $this->executeSpecialPage( 'Invalid', null, 'qqx' );
+               $this->assertContains( '(booksources-invalid-isbn)', $html );
+               list( $html, ) = $this->executeSpecialPage( '0-7475-3269-9', null, 'qqx' );
+               $this->assertNotContains( '(booksources-invalid-isbn)', $html );
+               $this->assertContains( '(booksources-text)', $html );
+       }
 }
index 3debe6e..6be272f 100644 (file)
@@ -349,7 +349,7 @@ class UploadBaseTest extends MediaWikiTestCase {
                        ],
                        [
                                // This currently doesn't seem to work in any browsers, but in case
-                               // http://www.w3.org/TR/css3-images/ is implemented for SVG files
+                               // https://www.w3.org/TR/css3-images/ is implemented for SVG files
                                '<svg xmlns="http://www.w3.org/2000/svg"> <rect width="100" height="100" style="background-image:image(\'sprites.svg#xywh=40,0,20,20\')"/> </svg>',
                                true,
                                true,
@@ -397,6 +397,46 @@ class UploadBaseTest extends MediaWikiTestCase {
                // @codingStandardsIgnoreEnd
        }
 
+       /**
+        * @dataProvider provideDetectScriptInSvg
+        */
+       public function testDetectScriptInSvg( $svg, $expected, $message ) {
+               // This only checks some weird cases, most tests are in testCheckSvgScriptCallback() above
+               $result = $this->upload->detectScriptInSvg( $svg, false );
+               $this->assertSame( $expected, $result, $message );
+       }
+
+       public static function provideDetectScriptInSvg() {
+               global $IP;
+               return [
+                       [
+                               "$IP/tests/phpunit/data/upload/buggynamespace-original.svg",
+                               false,
+                               'SVG with a weird but valid namespace definition created by Adobe Illustrator'
+                       ],
+                       [
+                               "$IP/tests/phpunit/data/upload/buggynamespace-okay.svg",
+                               false,
+                               'SVG with a namespace definition created by Adobe Illustrator and mangled by Inkscape'
+                       ],
+                       [
+                               "$IP/tests/phpunit/data/upload/buggynamespace-okay2.svg",
+                               false,
+                               'SVG with a namespace definition created by Adobe Illustrator and mangled by Inkscape (twice)'
+                       ],
+                       [
+                               "$IP/tests/phpunit/data/upload/buggynamespace-bad.svg",
+                               [ 'uploadscriptednamespace', 'i' ],
+                               'SVG with a namespace definition using an undefined entity'
+                       ],
+                       [
+                               "$IP/tests/phpunit/data/upload/buggynamespace-evilhtml.svg",
+                               [ 'uploadscriptednamespace', 'http://www.w3.org/1999/xhtml' ],
+                               'SVG with an html namespace encoded as an entity'
+                       ],
+               ];
+       }
+
        /**
         * @dataProvider provideCheckXMLEncodingMissmatch
         */
@@ -442,4 +482,11 @@ class UploadTestHandler extends UploadBase {
                );
                return [ $check->wellFormed, $check->filterMatch ];
        }
+
+       /**
+        * Same as parent function, but override visibility to 'public'.
+        */
+       public function detectScriptInSvg( $filename, $partial ) {
+               return parent::detectScriptInSvg( $filename, $partial );
+       }
 }
index cb27fde..81c84e8 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use MediaWiki\Session\SessionManager;
+use Wikimedia\ScopedCallback;
 
 /**
  * @covers BotPassword
index 34548c0..0819bf2 100644 (file)
@@ -3,6 +3,8 @@
 define( 'NS_UNITTEST', 5600 );
 define( 'NS_UNITTEST_TALK', 5601 );
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @group Database
  */
@@ -269,7 +271,6 @@ class UserTest extends MediaWikiTestCase {
                // let the user have a few (3) edits
                $page = WikiPage::factory( Title::newFromText( 'Help:UserTest_EditCount' ) );
                for ( $i = 0; $i < 3; $i++ ) {
-
                        $page->doEditContent(
                                ContentHandler::makeContent( (string)$i, $page->getTitle() ),
                                'test',
@@ -348,6 +349,12 @@ class UserTest extends MediaWikiTestCase {
                $user->saveSettings();
 
                $user = User::newFromName( $user->getName() );
+               $user->load( User::READ_LATEST );
+               $this->assertEquals( 'test', $user->getOption( 'userjs-someoption' ) );
+               $this->assertEquals( 200, $user->getOption( 'cols' ) );
+
+               $user = User::newFromName( $user->getName() );
+               MediaWikiServices::getInstance()->getMainWANObjectCache()->clearProcessCache();
                $this->assertEquals( 'test', $user->getOption( 'userjs-someoption' ) );
                $this->assertEquals( 200, $user->getOption( 'cols' ) );
        }
@@ -505,7 +512,6 @@ class UserTest extends MediaWikiTestCase {
        public function testGetId() {
                $user = static::getTestUser()->getUser();
                $this->assertTrue( $user->getId() > 0 );
-
        }
 
        /**
@@ -580,4 +586,162 @@ class UserTest extends MediaWikiTestCase {
                $users->rewind();
                $this->assertTrue( $user->equals( $users->current() ) );
        }
+
+       /**
+        * When a user is autoblocked a cookie is set with which to track them
+        * in case they log out and change IP addresses.
+        * @link https://phabricator.wikimedia.org/T5233
+        */
+       public function testAutoblockCookies() {
+               // Set up the bits of global configuration that we use.
+               $this->setMwGlobals( [
+                       'wgCookieSetOnAutoblock' => true,
+                       'wgCookiePrefix' => 'wmsitetitle',
+               ] );
+
+               // 1. Log in a test user, and block them.
+               $user1tmp = $this->getTestUser()->getUser();
+               $request1 = new FauxRequest();
+               $request1->getSession()->setUser( $user1tmp );
+               $expiryFiveDays = time() + ( 5 * 24 * 60 * 60 );
+               $block = new Block( [
+                       'enableAutoblock' => true,
+                       'expiry' => wfTimestamp( TS_MW, $expiryFiveDays ),
+               ] );
+               $block->setTarget( $user1tmp );
+               $block->insert();
+               $user1 = User::newFromSession( $request1 );
+               $user1->mBlock = $block;
+               $user1->load();
+
+               // Confirm that the block has been applied as required.
+               $this->assertTrue( $user1->isLoggedIn() );
+               $this->assertTrue( $user1->isBlocked() );
+               $this->assertEquals( Block::TYPE_USER, $block->getType() );
+               $this->assertTrue( $block->isAutoblocking() );
+               $this->assertGreaterThanOrEqual( 1, $block->getId() );
+
+               // Test for the desired cookie name, value, and expiry.
+               $cookies = $request1->response()->getCookies();
+               $this->assertArrayHasKey( 'wmsitetitleBlockID', $cookies );
+               $this->assertEquals( $block->getId(), $cookies['wmsitetitleBlockID']['value'] );
+               $this->assertEquals( $expiryFiveDays, $cookies['wmsitetitleBlockID']['expire'] );
+
+               // 2. Create a new request, set the cookies, and see if the (anon) user is blocked.
+               $request2 = new FauxRequest();
+               $request2->setCookie( 'BlockID', $block->getId() );
+               $user2 = User::newFromSession( $request2 );
+               $user2->load();
+               $this->assertNotEquals( $user1->getId(), $user2->getId() );
+               $this->assertNotEquals( $user1->getToken(), $user2->getToken() );
+               $this->assertTrue( $user2->isAnon() );
+               $this->assertFalse( $user2->isLoggedIn() );
+               $this->assertTrue( $user2->isBlocked() );
+               $this->assertEquals( true, $user2->getBlock()->isAutoblocking() ); // Non-strict type-check.
+               // Can't directly compare the objects becuase of member type differences.
+               // One day this will work: $this->assertEquals( $block, $user2->getBlock() );
+               $this->assertEquals( $block->getId(), $user2->getBlock()->getId() );
+               $this->assertEquals( $block->getExpiry(), $user2->getBlock()->getExpiry() );
+
+               // 3. Finally, set up a request as a new user, and the block should still be applied.
+               $user3tmp = $this->getTestUser()->getUser();
+               $request3 = new FauxRequest();
+               $request3->getSession()->setUser( $user3tmp );
+               $request3->setCookie( 'BlockID', $block->getId() );
+               $user3 = User::newFromSession( $request3 );
+               $user3->load();
+               $this->assertTrue( $user3->isLoggedIn() );
+               $this->assertTrue( $user3->isBlocked() );
+               $this->assertEquals( true, $user3->getBlock()->isAutoblocking() ); // Non-strict type-check.
+
+               // Clean up.
+               $block->delete();
+       }
+
+       /**
+        * Make sure that no cookie is set to track autoblocked users
+        * when $wgCookieSetOnAutoblock is false.
+        */
+       public function testAutoblockCookiesDisabled() {
+               // Set up the bits of global configuration that we use.
+               $this->setMwGlobals( [
+                       'wgCookieSetOnAutoblock' => false,
+                       'wgCookiePrefix' => 'wm_no_cookies',
+               ] );
+
+               // 1. Log in a test user, and block them.
+               $testUser = $this->getTestUser()->getUser();
+               $request1 = new FauxRequest();
+               $request1->getSession()->setUser( $testUser );
+               $block = new Block( [ 'enableAutoblock' => true ] );
+               $block->setTarget( $testUser );
+               $block->insert();
+               $user = User::newFromSession( $request1 );
+               $user->mBlock = $block;
+               $user->load();
+
+               // 2. Test that the cookie IS NOT present.
+               $this->assertTrue( $user->isLoggedIn() );
+               $this->assertTrue( $user->isBlocked() );
+               $this->assertEquals( Block::TYPE_USER, $block->getType() );
+               $this->assertTrue( $block->isAutoblocking() );
+               $this->assertGreaterThanOrEqual( 1, $user->getBlockId() );
+               $this->assertGreaterThanOrEqual( $block->getId(), $user->getBlockId() );
+               $cookies = $request1->response()->getCookies();
+               $this->assertArrayNotHasKey( 'wm_no_cookiesBlockID', $cookies );
+
+               // Clean up.
+               $block->delete();
+       }
+
+       /**
+        * When a user is autoblocked and a cookie is set to track them, the expiry time of the cookie
+        * should match the block's expiry. If the block is infinite, the cookie expiry time should
+        * match $wgCookieExpiration. If the expiry time is changed, the cookie's should change with it.
+        */
+       public function testAutoblockCookieInfiniteExpiry() {
+               $cookieExpiration = 20 * 24 * 60 * 60; // 20 days
+               $this->setMwGlobals( [
+                       'wgCookieSetOnAutoblock' => true,
+                       'wgCookieExpiration' => $cookieExpiration,
+                       'wgCookiePrefix' => 'wm_infinite_block',
+               ] );
+               // 1. Log in a test user, and block them indefinitely.
+               $user1Tmp = $this->getTestUser()->getUser();
+               $request1 = new FauxRequest();
+               $request1->getSession()->setUser( $user1Tmp );
+               $block = new Block( [ 'enableAutoblock' => true, 'expiry' => 'infinity' ] );
+               $block->setTarget( $user1Tmp );
+               $block->insert();
+               $user1 = User::newFromSession( $request1 );
+               $user1->mBlock = $block;
+               $user1->load();
+
+               // 2. Test the cookie's expiry timestamp.
+               $this->assertTrue( $user1->isLoggedIn() );
+               $this->assertTrue( $user1->isBlocked() );
+               $this->assertEquals( Block::TYPE_USER, $block->getType() );
+               $this->assertTrue( $block->isAutoblocking() );
+               $this->assertGreaterThanOrEqual( 1, $user1->getBlockId() );
+               $cookies = $request1->response()->getCookies();
+               // Calculate the expected cookie expiry date.
+               $this->assertArrayHasKey( 'wm_infinite_blockBlockID', $cookies );
+               $this->assertEquals( time() + $cookieExpiration, $cookies['wm_infinite_blockBlockID']['expire'] );
+
+               // 3. Change the block's expiry (to 2 days), and the cookie's should be changed also.
+               $newExpiry = time() + 2 * 24 * 60 * 60;
+               $block->mExpiry = wfTimestamp( TS_MW, $newExpiry );
+               $block->update();
+               $user2tmp = $this->getTestUser()->getUser();
+               $request2 = new FauxRequest();
+               $request2->getSession()->setUser( $user2tmp );
+               $user2 = User::newFromSession( $request2 );
+               $user2->mBlock = $block;
+               $user2->load();
+               $cookies = $request2->response()->getCookies();
+               $this->assertEquals( $newExpiry, $cookies['wm_infinite_blockBlockID']['expire'] );
+
+               // Clean up.
+               $block->delete();
+       }
 }
index ce6894e..cb1b3d2 100644 (file)
@@ -81,7 +81,7 @@ class BatchRowUpdateTest extends MediaWikiTestCase {
         */
        public function testReaderGetPrimaryKey( $message, array $expected, array $row ) {
                $reader = new BatchRowIterator( $this->mockDb(), 'some_table', array_keys( $expected ), 8675309 );
-               $this->assertEquals( $expected, $reader->extractPrimaryKeys( (object) $row ), $message );
+               $this->assertEquals( $expected, $reader->extractPrimaryKeys( (object)$row ), $message );
        }
 
        public static function provider_readerSetFetchColumns() {
@@ -226,7 +226,7 @@ class BatchRowUpdateTest extends MediaWikiTestCase {
                for ( $i = 0; $i < $numRows; $i += $batchSize ) {
                        $rows = [];
                        for ( $j = 0; $j < $batchSize && $i + $j < $numRows; $j++ ) {
-                               $rows [] = (object) call_user_func( $rowGenerator );
+                               $rows [] = (object)call_user_func( $rowGenerator );
                        }
                        $res[] = $rows;
                }
index fafd4fa..760d41e 100644 (file)
@@ -37,7 +37,7 @@ class MWCryptHKDFTest extends MediaWikiTestCase {
        }
 
        /**
-        * Test vectors from Appendix A on http://tools.ietf.org/html/rfc5869
+        * Test vectors from Appendix A on https://tools.ietf.org/html/rfc5869
         */
        public static function providerRfc5869() {
 
index 206e608..9a1823b 100644 (file)
@@ -14,7 +14,7 @@ class LanguageTrTest extends LanguageClassesTestCase {
         *  - berm
         *  - []LuCkY[]
         *  - Emperyan
-        * @see http://en.wikipedia.org/wiki/Dotted_and_dotless_I
+        * @see https://en.wikipedia.org/wiki/Dotted_and_dotless_I
         * @dataProvider provideDottedAndDotlessI
         * @covers Language::ucfirst
         * @covers Language::lcfirst
@@ -49,7 +49,7 @@ class LanguageTrTest extends LanguageClassesTestCase {
                        [ 'lcfirst', 'i', 'lower', 'i' ],
 
                        # A real example taken from bug 28040 using
-                       # http://tr.wikipedia.org/wiki/%C4%B0Phone
+                       # https://tr.wikipedia.org/wiki/%C4%B0Phone
                        [ 'lcfirst', 'iPhone', 'lower', 'iPhone' ],
 
                        # next case is valid in Turkish but are different words if we
index 018d978..0e0b943 100644 (file)
  */
 
 class MockDjVuHandler extends DjVuHandler {
+       function isEnabled() {
+               return true;
+       }
+
        function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) {
                if ( !$this->normaliseParams( $image, $params ) ) {
                        return new TransformParameterError( $params );
index 2049e38..bc5a6bd 100644 (file)
@@ -137,6 +137,8 @@ class ApiDocumentationTest extends MediaWikiTestCase {
 
                // Messages for examples.
                foreach ( $module->getExamplesMessages() as $qs => $msg ) {
+                       $this->assertStringStartsNotWith( 'api.php?', $qs,
+                               "Query string must not begin with 'api.php?'" );
                        $this->checkMessage( $msg, "Example $qs" );
                }
        }
index 711eab6..e11fd8a 100644 (file)
@@ -16,6 +16,9 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
+use Composer\Spdx\SpdxLicenses;
+use JsonSchema\Validator;
+
 /**
  * Validates all loaded extensions and skins using the ExtensionRegistry
  * against the extension.json schema in the docs/ folder.
@@ -24,7 +27,7 @@ class ExtensionJsonValidationTest extends PHPUnit_Framework_TestCase {
 
        public function setUp() {
                parent::setUp();
-               if ( !class_exists( 'JsonSchema\Uri\UriRetriever' ) ) {
+               if ( !class_exists( Validator::class ) ) {
                        $this->markTestSkipped(
                                'The JsonSchema library cannot be found,' .
                                ' please install it through composer to run extension.json validation tests.'
@@ -75,9 +78,22 @@ class ExtensionJsonValidationTest extends PHPUnit_Framework_TestCase {
                        "$path is using a non-supported schema version"
                );
 
-               $validator = new JsonSchema\Validator;
-               $validator->check( $data, (object) [ '$ref' => 'file://' . $schemaPath ] );
-               if ( $validator->isValid() ) {
+               $licenseError = false;
+               if ( class_exists( SpdxLicenses::class ) && isset( $data->{'license-name'} )
+                       // Check if it's a string, if not, schema validation will display an error
+                       && is_string( $data->{'license-name'} )
+               ) {
+                       $licenses = new SpdxLicenses();
+                       $valid = $licenses->validate( $data->{'license-name'} );
+                       if ( !$valid ) {
+                               $licenseError = '[license-name] Invalid SPDX license identifier, '
+                                       . 'see <https://spdx.org/licenses/>';
+                       }
+               }
+
+               $validator = new Validator;
+               $validator->check( $data, (object)[ '$ref' => 'file://' . $schemaPath ] );
+               if ( $validator->isValid() && !$licenseError ) {
                        // All good.
                        $this->assertTrue( true );
                } else {
@@ -85,6 +101,9 @@ class ExtensionJsonValidationTest extends PHPUnit_Framework_TestCase {
                        foreach ( $validator->getErrors() as $error ) {
                                $out .= "[{$error['property']}] {$error['message']}\n";
                        }
+                       if ( $licenseError ) {
+                               $out .= "$licenseError\n";
+                       }
                        $this->assertTrue( false, $out );
                }
        }
index 86ce53f..2e6bf37 100644 (file)
@@ -91,7 +91,6 @@ class ResourcesTest extends MediaWikiTestCase {
         */
        public function testMissingMessages() {
                $data = self::getAllModules();
-               $validDeps = array_keys( $data['modules'] );
                $lang = Language::factory( 'en' );
 
                /** @var ResourceLoaderModule $module */
@@ -114,7 +113,6 @@ class ResourcesTest extends MediaWikiTestCase {
         */
        public function testUnsatisfiableDependencies() {
                $data = self::getAllModules();
-               $validDeps = array_keys( $data['modules'] );
 
                /** @var ResourceLoaderModule $module */
                foreach ( $data['modules'] as $moduleName => $module ) {
index 16299aa..11a25c4 100644 (file)
@@ -43,6 +43,9 @@
                <testsuite name="structure">
                        <directory>structure</directory>
                </testsuite>
+               <testsuite name="tests">
+                       <directory>tests</directory>
+               </testsuite>
                <testsuite name="uploadfromurl">
                        <file>suites/UploadFromUrlTestSuite.php</file>
                </testsuite>
index 4284a77..5d5d693 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+use Wikimedia\ScopedCallback;
 
 /**
  * The UnitTest must be either a class that inherits from MediaWikiTestCase
@@ -107,7 +108,7 @@ class ParserTestTopLevelSuite extends PHPUnit_Framework_TestSuite {
                        $testsName = $extensionName . '__' . basename( $fileName, '.txt' );
                        $parserTestClassName = ucfirst( $testsName );
 
-                       // Official spec for class names: http://php.net/manual/en/language.oop5.basic.php
+                       // Official spec for class names: https://secure.php.net/manual/en/language.oop5.basic.php
                        // Prepend 'ParserTest_' to be paranoid about it not starting with a number
                        $parserTestClassName = 'ParserTest_' .
                                preg_replace( '/[^a-zA-Z0-9_\x7f-\xff]/', '_', $parserTestClassName );
index 5d2f37e..a2ef35f 100644 (file)
@@ -90,14 +90,22 @@ class MediaWikiTestCaseTest extends MediaWikiTestCase {
 
        /**
         * @covers MediaWikiTestCase::stashMwGlobals
+        * @covers MediaWikiTestCase::tearDown
         */
-       public function testExceptionThrownWhenStashingNonExistentGlobals() {
-               $this->setExpectedException(
-                       'Exception',
-                       'Global with key ' . self::GLOBAL_KEY_NONEXISTING . ' doesn\'t exist and cant be stashed'
+       public function testSetNonExistentGlobalsAreUnsetOnTearDown() {
+               $globalKey = 'abcdefg1234567';
+               $this->setMwGlobals( $globalKey, true );
+               $this->assertTrue(
+                       $GLOBALS[$globalKey],
+                       'Global failed to correctly set'
                );
 
-               $this->stashMwGlobals( self::GLOBAL_KEY_NONEXISTING );
+               $this->tearDown();
+
+               $this->assertFalse(
+                       isset( $GLOBALS[$globalKey] ),
+                       'Global failed to be correctly unset'
+               );
        }
 
        public function testOverrideMwServices() {
@@ -134,8 +142,7 @@ class MediaWikiTestCaseTest extends MediaWikiTestCase {
         * @covers MediaWikiTestCase::setLogger
         * @covers MediaWikiTestCase::restoreLogger
         */
-       public function testLoggersAreRestoredOnTearDown() {
-               // replacing an existing logger
+       public function testLoggersAreRestoredOnTearDown_replacingExistingLogger() {
                $logger1 = LoggerFactory::getInstance( 'foo' );
                $this->setLogger( 'foo', $this->getMock( LoggerInterface::class ) );
                $logger2 = LoggerFactory::getInstance( 'foo' );
@@ -144,17 +151,27 @@ class MediaWikiTestCaseTest extends MediaWikiTestCase {
 
                $this->assertSame( $logger1, $logger3 );
                $this->assertNotSame( $logger1, $logger2 );
+       }
 
-               // replacing a non-existing logger
+       /**
+        * @covers MediaWikiTestCase::setLogger
+        * @covers MediaWikiTestCase::restoreLogger
+        */
+       public function testLoggersAreRestoredOnTearDown_replacingNonExistingLogger() {
                $this->setLogger( 'foo', $this->getMock( LoggerInterface::class ) );
-               $logger1 = LoggerFactory::getInstance( 'bar' );
+               $logger1 = LoggerFactory::getInstance( 'foo' );
                $this->tearDown();
-               $logger2 = LoggerFactory::getInstance( 'bar' );
+               $logger2 = LoggerFactory::getInstance( 'foo' );
 
                $this->assertNotSame( $logger1, $logger2 );
                $this->assertInstanceOf( '\Psr\Log\LoggerInterface', $logger2 );
+       }
 
-               // replacing same logger twice
+       /**
+        * @covers MediaWikiTestCase::setLogger
+        * @covers MediaWikiTestCase::restoreLogger
+        */
+       public function testLoggersAreRestoredOnTearDown_replacingSameLoggerTwice() {
                $logger1 = LoggerFactory::getInstance( 'baz' );
                $this->setLogger( 'foo', $this->getMock( LoggerInterface::class ) );
                $this->setLogger( 'foo', $this->getMock( LoggerInterface::class ) );
index 8bc087b..815a3b4 100644 (file)
@@ -1,2 +1,6 @@
-var x = require( 'test.require.define' );
-module.exports = 'Require worked.' + x;
+module.exports = {
+       immediate: require( 'test.require.define' ),
+       later: function () {
+               return require( 'test.require.define' );
+       }
+};
index 79f37dc..b79c192 100644 (file)
         */
        QUnit.newMwEnvironment = ( function () {
                var warn, error, liveConfig, liveMessages,
+                       MwMap = mw.config.constructor, // internal use only
                        ajaxRequests = [];
 
-               liveConfig = mw.config.values;
-               liveMessages = mw.messages.values;
+               liveConfig = mw.config;
+               liveMessages = mw.messages;
 
                function suppressWarnings() {
                        warn = mw.log.warn;
                        // NOTE: It is important that we suppress warnings because extend() will also access
                        // deprecated properties and trigger deprecation warnings from mw.log#deprecate.
                        suppressWarnings();
-                       copy = $.extend( {}, liveConfig, custom );
+                       copy = $.extend( {}, liveConfig.get(), custom );
                        restoreWarnings();
 
                        return copy;
                }
 
                function freshMessagesCopy( custom ) {
-                       return $.extend( /*deep=*/true, {}, liveMessages, custom );
+                       return $.extend( /*deep=*/true, {}, liveMessages.get(), custom );
                }
 
                /**
                                setup: function () {
 
                                        // Greetings, mock environment!
-                                       mw.config.values = freshConfigCopy( localEnv.config );
-                                       mw.messages.values = freshMessagesCopy( localEnv.messages );
+                                       mw.config = new MwMap();
+                                       mw.config.set( freshConfigCopy( localEnv.config ) );
+                                       mw.messages = new MwMap();
+                                       mw.messages.set( freshMessagesCopy( localEnv.messages ) );
+                                       // Update reference to mw.messages
+                                       mw.jqueryMsg.setParserDefaults( {
+                                               messages: mw.messages
+                                       } );
+
                                        this.suppressWarnings = suppressWarnings;
                                        this.restoreWarnings = restoreWarnings;
 
                                        $( document ).off( 'ajaxSend', trackAjax );
 
                                        // Farewell, mock environment!
-                                       mw.config.values = liveConfig;
-                                       mw.messages.values = liveMessages;
+                                       mw.config = liveConfig;
+                                       mw.messages = liveMessages;
+                                       // Restore reference to mw.messages
+                                       mw.jqueryMsg.setParserDefaults( {
+                                               messages: liveMessages
+                                       } );
 
                                        // As a convenience feature, automatically restore warnings if they're
                                        // still suppressed by the end of the test.
index 886e2b6..910bcc1 100644 (file)
@@ -1,4 +1,3 @@
-/*jshint -W024 */
 ( function ( mw, $ ) {
        var repeat = function ( input, multiplier ) {
                return new Array( multiplier + 1 ).join( input );
index b12803d..97185fc 100644 (file)
@@ -1,4 +1,3 @@
-/*jshint -W024 */
 ( function ( mw, $ ) {
        QUnit.module( 'mediawiki.Uri', QUnit.newMwEnvironment( {
                setup: function () {
index 7133039..1218137 100644 (file)
                );
                assert.htmlEqual(
                        formatParse( 'external-link-replace', function () {} ),
-                       'Foo <a href="#">bar</a>',
+                       'Foo <a role="button" tabindex="0">bar</a>',
                        'External link message processed as function when format is \'parse\''
                );
 
 
                assert.equal(
                        formatParse( 'uses-missing-int' ),
-                       '[doesnt-exist]',
+                       '⧼doesnt-exist⧽',
                        'int: where nested message does not exist'
                );
        } );
index 41d800a..92d1326 100644 (file)
@@ -1,5 +1,12 @@
 ( function ( mw, $ ) {
-       QUnit.module( 'mediawiki (mw.loader)' );
+       QUnit.module( 'mediawiki (mw.loader)', QUnit.newMwEnvironment( {
+               setup: function () {
+                       mw.loader.store.enabled = false;
+               },
+               teardown: function () {
+                       mw.loader.store.enabled = false;
+               }
+       } ) );
 
        mw.loader.addSource(
                'testloader',
                } );
        } );
 
+       QUnit.test( '.using() Error: Circular dependency', function ( assert ) {
+               mw.loader.register( [
+                       [ 'test.circle1', '0', [ 'test.circle2' ] ],
+                       [ 'test.circle2', '0', [ 'test.circle3' ] ],
+                       [ 'test.circle3', '0', [ 'test.circle1' ] ]
+               ] );
+               mw.loader.using( 'test.circle3' ).then(
+                       function done() {
+                               assert.ok( false, 'Unexpected resolution, expected error.' );
+                       },
+                       function fail( e ) {
+                               assert.ok( /Circular/.test( String( e ) ), 'Detect circular dependency' );
+                       }
+               );
+       } );
+
+       QUnit.test( '.load() - Error: Circular dependency', function ( assert ) {
+               mw.loader.register( [
+                       [ 'test.circleA', '0', [ 'test.circleB' ] ],
+                       [ 'test.circleB', '0', [ 'test.circleC' ] ],
+                       [ 'test.circleC', '0', [ 'test.circleA' ] ]
+               ] );
+               assert.throws( function () {
+                       mw.loader.load( 'test.circleC' );
+               }, /Circular/, 'Detect circular dependency' );
+       } );
+
+       QUnit.test( '.using() - Error: Unregistered', function ( assert ) {
+               mw.loader.using( 'test.using.unreg' ).then(
+                       function done() {
+                               assert.ok( false, 'Unexpected resolution, expected error.' );
+                       },
+                       function fail( e ) {
+                               assert.ok( /Unknown/.test( String( e ) ), 'Detect unknown dependency' );
+                       }
+               );
+       } );
+
+       QUnit.test( '.load() - Error: Unregistered (ignored)', 0, function ( assert ) {
+               mw.loader.load( 'test.using.unreg2' );
+       } );
+
        QUnit.test( '.implement( styles={ "css": [text, ..] } )', 2, function ( assert ) {
                var $element = $( '<div class="mw-test-implement-a"></div>' ).appendTo( '#qunit-fixture' );
 
                assert.strictEqual( mw.track.callCount, 1 );
        } );
 
-       QUnit.test( 'Circular dependency', 1, function ( assert ) {
-               mw.loader.register( [
-                       [ 'test.circle1', '0', [ 'test.circle2' ] ],
-                       [ 'test.circle2', '0', [ 'test.circle3' ] ],
-                       [ 'test.circle3', '0', [ 'test.circle1' ] ]
-               ] );
-               assert.throws( function () {
-                       mw.loader.using( 'test.circle3' );
-               }, /Circular/, 'Detect circular dependency' );
-       } );
-
        QUnit.test( 'Out-of-order implementation', 9, function ( assert ) {
                mw.loader.register( [
                        [ 'test.module4', '0' ],
                mw.loader.load( target );
        } );
 
+       QUnit.test( 'Empty string module name - T28804', function ( assert ) {
+               var done = false;
+
+               assert.strictEqual( mw.loader.getState( '' ), null, 'State (unregistered)' );
+
+               mw.loader.register( '', 'v1' );
+               assert.strictEqual( mw.loader.getState( '' ), 'registered', 'State (registered)' );
+               assert.strictEqual( mw.loader.getVersion( '' ), 'v1', 'Version' );
+
+               mw.loader.implement( '', function () {
+                       done = true;
+               } );
+
+               return mw.loader.using( '', function () {
+                       assert.strictEqual( done, true, 'script ran' );
+                       assert.strictEqual( mw.loader.getState( '' ), 'ready', 'State (ready)' );
+               } );
+       } );
+
        QUnit.test( 'Executing race - T112232', 2, function ( assert ) {
                var done = false;
 
                } );
        } );
 
+       QUnit.test( 'Stale response caching - T117587', function ( assert ) {
+               var count = 0;
+               mw.loader.store.enabled = true;
+               mw.loader.register( 'test.stale', 'v2' );
+               assert.strictEqual( mw.loader.store.get( 'test.stale' ), false, 'Not in store' );
+
+               mw.loader.implement( 'test.stale@v1', function () {
+                       count++;
+               } );
+
+               return mw.loader.using( 'test.stale' )
+                       .then( function () {
+                               assert.strictEqual( count, 1 );
+                               // After implementing, registry contains version as implemented by the response.
+                               assert.strictEqual( mw.loader.getVersion( 'test.stale' ), 'v1', 'Override version' );
+                               assert.strictEqual( mw.loader.getState( 'test.stale' ), 'ready' );
+                               assert.ok( mw.loader.store.get( 'test.stale' ), 'In store' );
+                       } )
+                       .then( function () {
+                               // Reset run time, but keep mw.loader.store
+                               mw.loader.moduleRegistry[ 'test.stale' ].script = undefined;
+                               mw.loader.moduleRegistry[ 'test.stale' ].state = 'registered';
+                               mw.loader.moduleRegistry[ 'test.stale' ].version = 'v2';
+
+                               // Module was stored correctly as v1
+                               // On future navigations, it will be ignored until evicted
+                               assert.strictEqual( mw.loader.store.get( 'test.stale' ), false, 'Not in store' );
+                       } );
+       } );
+
+       QUnit.test( 'Stale response caching - backcompat', function ( assert ) {
+               var count = 0;
+               mw.loader.store.enabled = true;
+               mw.loader.register( 'test.stalebc', 'v2' );
+               assert.strictEqual( mw.loader.store.get( 'test.stalebc' ), false, 'Not in store' );
+
+               mw.loader.implement( 'test.stalebc', function () {
+                       count++;
+               } );
+
+               return mw.loader.using( 'test.stalebc' )
+                       .then( function () {
+                               assert.strictEqual( count, 1 );
+                               assert.strictEqual( mw.loader.getState( 'test.stalebc' ), 'ready' );
+                               assert.ok( mw.loader.store.get( 'test.stalebc' ), 'In store' );
+                       } )
+                       .then( function () {
+                               // Reset run time, but keep mw.loader.store
+                               mw.loader.moduleRegistry[ 'test.stalebc' ].script = undefined;
+                               mw.loader.moduleRegistry[ 'test.stalebc' ].state = 'registered';
+                               mw.loader.moduleRegistry[ 'test.stalebc' ].version = 'v2';
+
+                               // Legacy behaviour is storing under the expected version,
+                               // which woudl lead to whitewashing and stale values (T117587).
+                               assert.ok( mw.loader.store.get( 'test.stalebc' ), 'In store' );
+                       } );
+       } );
+
        QUnit.test( 'require()', 6, function ( assert ) {
                mw.loader.register( [
                        [ 'test.require1', '0' ],
                } );
        } );
 
-       QUnit.test( 'require() in debug mode', 1, function ( assert ) {
+       QUnit.test( 'require() in debug mode', function ( assert ) {
                var path = mw.config.get( 'wgScriptPath' );
                mw.loader.register( [
                        [ 'test.require.define', '0' ],
                mw.loader.implement( 'test.require.define', [ QUnit.fixurl( path + '/tests/qunit/data/defineCallMwLoaderTestCallback.js' ) ] );
 
                return mw.loader.using( 'test.require.callback' ).then( function ( require ) {
-                       var exported = require( 'test.require.callback' );
-                       assert.strictEqual( exported, 'Require worked.Define worked.',
-                               'module.exports worked in debug mode' );
+                       var cb = require( 'test.require.callback' );
+                       assert.strictEqual( cb.immediate, 'Defined.', 'module.exports and require work in debug mode' );
+                       // Must use try-catch because cb.later() will throw if require is undefined,
+                       // which doesn't work well inside Deferred.then() when using jQuery 1.x with QUnit
+                       try {
+                               assert.strictEqual( cb.later(), 'Defined.', 'require works asynchrously in debug mode' );
+                       } catch ( e ) {
+                               assert.equal( null, String( e ), 'require works asynchrously in debug mode' );
+                       }
                }, function () {
                        assert.ok( false, 'Error callback fired while loader.using "test.require.callback" module' );
                } );
index ab463a9..bac8274 100644 (file)
@@ -1,4 +1,3 @@
-/*jshint -W024 */
 ( function ( mw ) {
        var specialCharactersPageName,
                // Can't mock SITENAME since jqueryMsg caches it at load
                );
        } );
 
-       QUnit.test( 'mw.Map', 35, function ( assert ) {
+       QUnit.test( 'mw.Map', function ( assert ) {
                var arry, conf, funky, globalConf, nummy, someValues;
 
                conf = new mw.Map();
+
                // Dummy variables
                funky = function () {};
                arry = [];
                        lorem: 'ipsum'
                }, 'Map.get returns multiple values correctly as an object' );
 
-               assert.deepEqual( conf, new mw.Map( conf.values ), 'new mw.Map maps over existing values-bearing object' );
-
                assert.deepEqual( conf.get( [ 'foo', 'notExist' ] ), {
                        foo: 'bar',
                        notExist: null
                }, 'Map.get return includes keys that were not found as null values' );
 
                // Interacting with globals and accessing the values object
+               this.suppressWarnings();
                assert.strictEqual( conf.get(), conf.values, 'Map.get returns the entire values object by reference (if called without arguments)' );
+               this.restoreWarnings();
 
                conf.set( 'globalMapChecker', 'Hi' );
 
                }
        } );
 
-       QUnit.test( 'mw.config', 1, function ( assert ) {
-               assert.ok( mw.config instanceof mw.Map, 'mw.config instance of mw.Map' );
-       } );
-
-       QUnit.test( 'mw.message & mw.messages', 100, function ( assert ) {
+       QUnit.test( 'mw.message & mw.messages', function ( assert ) {
                var goodbye, hello;
 
                // Convenience method for asserting the same result for multiple formats
                }
 
                assert.ok( mw.messages, 'messages defined' );
-               assert.ok( mw.messages instanceof mw.Map, 'mw.messages instance of mw.Map' );
                assert.ok( mw.messages.set( 'hello', 'Hello <b>awesome</b> world' ), 'mw.messages.set: Register' );
 
                hello = mw.message( 'hello' );
                goodbye = mw.message( 'goodbye' );
                assert.strictEqual( goodbye.exists(), false, 'Message.exists returns false for nonexistent messages' );
 
-               assertMultipleFormats( [ 'goodbye' ], [ 'plain', 'text' ], '<goodbye>', 'Message.toString returns <key> if key does not exist' );
-               // bug 30684
-               assertMultipleFormats( [ 'goodbye' ], [ 'parse', 'escaped' ], '&lt;goodbye&gt;', 'Message.toString returns properly escaped &lt;key&gt; if key does not exist' );
+               assertMultipleFormats( [ 'good<>bye' ], [ 'plain', 'text', 'parse', 'escaped' ], '⧼good&lt;&gt;bye⧽', 'Message.toString returns ⧼key⧽ if key does not exist' );
 
                assert.ok( mw.messages.set( 'plural-test-msg', 'There {{PLURAL:$1|is|are}} $1 {{PLURAL:$1|result|results}}' ), 'mw.messages.set: Register' );
                assertMultipleFormats( [ 'plural-test-msg', 6 ], [ 'text', 'parse', 'escaped' ], 'There are 6 results', 'plural get resolved' );
        QUnit.test( 'mw.msg', 14, function ( assert ) {
                assert.ok( mw.messages.set( 'hello', 'Hello <b>awesome</b> world' ), 'mw.messages.set: Register' );
                assert.equal( mw.msg( 'hello' ), 'Hello <b>awesome</b> world', 'Gets message with default options (existing message)' );
-               assert.equal( mw.msg( 'goodbye' ), '<goodbye>', 'Gets message with default options (nonexistent message)' );
+               assert.equal( mw.msg( 'goodbye' ), '⧼goodbye⧽', 'Gets message with default options (nonexistent message)' );
 
                assert.ok( mw.messages.set( 'plural-item', 'Found $1 {{PLURAL:$1|item|items}}' ), 'mw.messages.set: Register' );
                assert.equal( mw.msg( 'plural-item', 5 ), 'Found 5 items', 'Apply plural for count 5' );
index 5122dcd..7f6efa0 100644 (file)
@@ -22,7 +22,7 @@
        QUnit.test( 'getters (anonymous)', function ( assert ) {
                // Forge an anonymous user
                mw.config.set( 'wgUserName', null );
-               delete mw.config.values.wgUserId;
+               mw.config.set( 'wgUserId', null );
 
                assert.strictEqual( mw.user.getName(), null, 'getName()' );
                assert.strictEqual( mw.user.isAnon(), true, 'isAnon()' );
index 4eac362..6dd17f1 100644 (file)
                } );
        } );
 
-       QUnit.test( 'getUrl', 13, function ( assert ) {
+       QUnit.test( 'getUrl', 14, function ( assert ) {
                var href;
                mw.config.set( {
                        wgScript: '/w/index.php',
                href = mw.util.getUrl( 'Foo:Sandbox? 5+5=10! (test)/sub ' );
                assert.equal( href, '/wiki/Foo:Sandbox%3F_5%2B5%3D10!_(test)/sub_', 'complex title' );
 
+               // T149767
+               href = mw.util.getUrl( 'My$$test$$$$$title' );
+               assert.equal( href, '/wiki/My$$test$$$$$title', 'title with multiple consecutive dollar signs' );
+
                href = mw.util.getUrl();
                assert.equal( href, '/wiki/Foobar', 'default title' );
 
index 2934b39..045b633 100644 (file)
@@ -10,6 +10,7 @@
                        'Mozilla/5.0 (Windows NT 6.1.1; rv:5.0) Gecko/20100101 Firefox/5.0',
                        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20100101 Firefox/9.0',
                        'Mozilla/5.0 (Macintosh; I; Intel Mac OS X 11_7_9; de-LI; rv:1.9b4) Gecko/2012010317 Firefox/10.0a4',
+                       'Mozilla/5.0 (X11; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0',
                        'Mozilla/5.0 (Windows NT 6.1; rv:12.0) Gecko/20120403211507 Firefox/12.0',
                        'Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:16.0.1) Gecko/20121011 Firefox/16.0.1',
                        // Kindle Fire
@@ -46,6 +47,8 @@
                        'Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3B48b Safari/419.3',
                        // Android
                        'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17',
+                       // UC Mini (speed mode off)
+                       'Mozilla/5.0 (Linux; U; Android 6.0.1; en-US; Nexus_5 Build/MMB29S) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1 UCBrowser/10.7.6.805 Mobile',
 
                        /* Grade C */
 
                        'Wget/1.10.1 (Red Hat modified)',
                        // Unknown
                        'I\'m an unknown browser',
+                       'I\'m an unknown Glass browser',
                        // Empty
                        ''
                ],
                blacklisted: [
                        /* Grade C */
 
+                       // PlayStation
+                       'Mozilla/5.0 (PLAYSTATION 3; 1.10)',
+                       'Mozilla/5.0 (PLAYSTATION 3; 3.55)',
+                       'Mozilla/5.0 (PLAYSTATION 3 4.21) AppleWebKit/531.22.8 (KHTML, like Gecko)',
+                       'Mozilla/5.0 (PlayStation 4 1.70) AppleWebKit/536.26 (KHTML, like Gecko)',
                        // Open WebOS < 1.5 (Palm Pre, Palm Pixi)
                        'Mozilla/5.0 (webOS/1.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/1.0',
                        'Mozilla/5.0 (webOS/1.4.0; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pixi/1.1 ',
                        // Google Glass
                        'Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; Glass 1 Build/IMM76L; XE11) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
                        // MeeGo
-                       'Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13'
+                       'Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13',
+                       // UC Mini (speed mode on)
+                       'Mozilla/5.0 (X11; U; Linux i686; zh-CN; r:1.2.3.4) Gecko/'
                ]
        };